From 970f281859c416928695dcb73789a94f3ed7b7f2 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Tue, 3 Aug 2021 20:45:25 -0600 Subject: [PATCH 1/4] backups: default is_successful to false (#3522) * backups: default is_successful to false * backups: properly query backups --- .../Api/Client/Servers/BackupController.php | 2 +- .../Remote/ReportBackupCompleteRequest.php | 2 +- app/Models/Backup.php | 2 +- .../Eloquent/BackupRepository.php | 5 ++- app/Services/Backups/DeleteBackupService.php | 2 +- .../Backups/InitiateBackupService.php | 8 +++- ...d_to_default_to_false_on_backups_table.php | 37 +++++++++++++++++++ .../components/server/backups/BackupRow.tsx | 6 +-- 8 files changed, 54 insertions(+), 10 deletions(-) create mode 100644 database/migrations/2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table.php diff --git a/app/Http/Controllers/Api/Client/Servers/BackupController.php b/app/Http/Controllers/Api/Client/Servers/BackupController.php index 5bc58a81..fe9232e8 100644 --- a/app/Http/Controllers/Api/Client/Servers/BackupController.php +++ b/app/Http/Controllers/Api/Client/Servers/BackupController.php @@ -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.'); } - 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.'); } diff --git a/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php b/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php index a90a2b2b..0c96b3f0 100644 --- a/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php +++ b/app/Http/Requests/Api/Remote/ReportBackupCompleteRequest.php @@ -12,7 +12,7 @@ class ReportBackupCompleteRequest extends FormRequest public function rules() { return [ - 'successful' => 'present|boolean', + 'successful' => 'required|boolean', 'checksum' => 'nullable|string|required_if:successful,true', 'checksum_type' => 'nullable|string|required_if:successful,true', 'size' => 'nullable|numeric|required_if:successful,true', diff --git a/app/Models/Backup.php b/app/Models/Backup.php index 26dcc724..9ad03fd3 100644 --- a/app/Models/Backup.php +++ b/app/Models/Backup.php @@ -64,7 +64,7 @@ class Backup extends Model * @var array */ protected $attributes = [ - 'is_successful' => true, + 'is_successful' => false, 'is_locked' => false, 'checksum' => null, 'bytes' => 0, diff --git a/app/Repositories/Eloquent/BackupRepository.php b/app/Repositories/Eloquent/BackupRepository.php index b53547e4..fef80c48 100644 --- a/app/Repositories/Eloquent/BackupRepository.php +++ b/app/Repositories/Eloquent/BackupRepository.php @@ -25,7 +25,10 @@ class BackupRepository extends EloquentRepository return $this->getBuilder() ->withTrashed() ->where('server_id', $server) - ->where('is_successful', true) + ->where(function ($query) { + $query->whereNull('completed_at') + ->orWhere('is_successful', '=', true); + }) ->where('created_at', '>=', Carbon::now()->subSeconds($seconds)->toDateTimeString()) ->get() ->toBase(); diff --git a/app/Services/Backups/DeleteBackupService.php b/app/Services/Backups/DeleteBackupService.php index 80d6374b..66eefe67 100644 --- a/app/Services/Backups/DeleteBackupService.php +++ b/app/Services/Backups/DeleteBackupService.php @@ -63,7 +63,7 @@ class DeleteBackupService // 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 // 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(); } diff --git a/app/Services/Backups/InitiateBackupService.php b/app/Services/Backups/InitiateBackupService.php index 347740dc..f51279f6 100644 --- a/app/Services/Backups/InitiateBackupService.php +++ b/app/Services/Backups/InitiateBackupService.php @@ -132,8 +132,12 @@ class InitiateBackupService } } - // Check if the server has reached or exceeded it's backup limit. - $successful = $server->backups()->where('is_successful', true); + // Check if the server has reached or exceeded its backup limit. + // completed_at == null will cover any ongoing backups, while is_successful == true will cover any completed backups. + $successful = $server->backups()->where(function ($query) { + $query->whereNull('completed_at') + ->orWhere('is_successful', true); + }); 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. if (!$override || $server->backup_limit <= 0) { diff --git a/database/migrations/2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table.php b/database/migrations/2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table.php new file mode 100644 index 00000000..1dddb7f3 --- /dev/null +++ b/database/migrations/2021_08_03_210600_change_successful_field_to_default_to_false_on_backups_table.php @@ -0,0 +1,37 @@ +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(); + }); + } +} diff --git a/resources/scripts/components/server/backups/BackupRow.tsx b/resources/scripts/components/server/backups/BackupRow.tsx index 139ce33b..459a0e40 100644 --- a/resources/scripts/components/server/backups/BackupRow.tsx +++ b/resources/scripts/components/server/backups/BackupRow.tsx @@ -44,7 +44,7 @@ export default ({ backup, className }: Props) => {
- {backup.completedAt ? + {backup.completedAt !== null ? backup.isLocked ? : @@ -55,7 +55,7 @@ export default ({ backup, className }: Props) => {
- {!backup.isSuccessful && + {backup.completedAt !== null && !backup.isSuccessful && Failed @@ -63,7 +63,7 @@ export default ({ backup, className }: Props) => {

{backup.name}

- {(backup.completedAt && backup.isSuccessful) && + {(backup.completedAt !== null && backup.isSuccessful) && }
From 1c071b05aa3b0b3e1577aa14dac104098b1ee284 Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Tue, 3 Aug 2021 20:46:00 -0600 Subject: [PATCH 2/4] ui: fix spinner z-index (#3520) --- resources/scripts/components/elements/SpinnerOverlay.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/resources/scripts/components/elements/SpinnerOverlay.tsx b/resources/scripts/components/elements/SpinnerOverlay.tsx index fb18b66e..ab4b7295 100644 --- a/resources/scripts/components/elements/SpinnerOverlay.tsx +++ b/resources/scripts/components/elements/SpinnerOverlay.tsx @@ -14,10 +14,10 @@ const SpinnerOverlay: React.FC = ({ size, fixed, visible, backgroundOpaci
{children && (typeof children === 'string' ?

{children}

: children)} From 81c788f524b81810f10183c86dd636cf8498378f Mon Sep 17 00:00:00 2001 From: Matthew Penner Date: Tue, 3 Aug 2021 20:48:34 -0600 Subject: [PATCH 3/4] cmd(upgrade): fix force and seed flags being ignored (#3519) --- app/Console/Commands/UpgradeCommand.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/Console/Commands/UpgradeCommand.php b/app/Console/Commands/UpgradeCommand.php index db0e23fd..feb21ec6 100644 --- a/app/Console/Commands/UpgradeCommand.php +++ b/app/Console/Commands/UpgradeCommand.php @@ -68,7 +68,7 @@ class UpgradeCommand extends Command ); } } - + if (is_null($this->option('group'))) { $groupDetails = posix_getgrgid(filegroup('public')); $group = $groupDetails['name'] ?? 'www-data'; @@ -150,8 +150,8 @@ class UpgradeCommand extends Command }); $this->withProgress($bar, function () { - $this->line('$upgrader> php artisan migrate --seed --force'); - $this->call('migrate', ['--seed' => '', '--force' => '']); + $this->line('$upgrader> php artisan migrate --force --seed'); + $this->call('migrate', ['--force' => true, '--seed' => true]); }); $this->withProgress($bar, function () use ($user, $group) { From 0074c84001d315a721aa5eab67841b8cb9e9f747 Mon Sep 17 00:00:00 2001 From: Charles Morgan Date: Tue, 3 Aug 2021 23:11:45 -0400 Subject: [PATCH 4/4] Add javaversion to java eggs. (#3518) Co-authored-by: Matthew Penner --- database/Seeders/eggs/minecraft/egg-bungeecord.json | 5 +++-- database/Seeders/eggs/minecraft/egg-forge-minecraft.json | 5 +++-- database/Seeders/eggs/minecraft/egg-paper.json | 3 ++- .../Seeders/eggs/minecraft/egg-sponge--sponge-vanilla.json | 3 ++- database/Seeders/eggs/minecraft/egg-vanilla-minecraft.json | 5 +++-- resources/scripts/components/server/ServerConsole.tsx | 6 ++---- resources/scripts/components/server/features/index.ts | 2 +- 7 files changed, 16 insertions(+), 13 deletions(-) diff --git a/database/Seeders/eggs/minecraft/egg-bungeecord.json b/database/Seeders/eggs/minecraft/egg-bungeecord.json index d822e1f8..0df945cf 100644 --- a/database/Seeders/eggs/minecraft/egg-bungeecord.json +++ b/database/Seeders/eggs/minecraft/egg-bungeecord.json @@ -9,7 +9,8 @@ "author": "support@pterodactyl.io", "description": "For a long time, Minecraft server owners have had a dream that encompasses a free, easy, and reliable way to connect multiple Minecraft servers together. BungeeCord is the answer to said dream. Whether you are a small server wishing to string multiple game-modes together, or the owner of the ShotBow Network, BungeeCord is the ideal solution for you. With the help of BungeeCord, you will be able to unlock your community's full potential.", "features": [ - "eula" + "eula", + "java_version" ], "images": [ "ghcr.io\/pterodactyl\/yolks:java_8", @@ -51,4 +52,4 @@ "rules": "required|regex:\/^([\\w\\d._-]+)(\\.jar)$\/" } ] -} \ No newline at end of file +} diff --git a/database/Seeders/eggs/minecraft/egg-forge-minecraft.json b/database/Seeders/eggs/minecraft/egg-forge-minecraft.json index 6508d3e3..fa750a44 100644 --- a/database/Seeders/eggs/minecraft/egg-forge-minecraft.json +++ b/database/Seeders/eggs/minecraft/egg-forge-minecraft.json @@ -9,7 +9,8 @@ "author": "support@pterodactyl.io", "description": "Minecraft Forge Server. Minecraft Forge is a modding API (Application Programming Interface), which makes it easier to create mods, and also make sure mods are compatible with each other.", "features": [ - "eula" + "eula", + "java_version" ], "images": [ "ghcr.io\/pterodactyl\/yolks:java_8", @@ -69,4 +70,4 @@ "rules": "nullable|string|max:20" } ] -} \ No newline at end of file +} diff --git a/database/Seeders/eggs/minecraft/egg-paper.json b/database/Seeders/eggs/minecraft/egg-paper.json index 5665b369..4153227a 100644 --- a/database/Seeders/eggs/minecraft/egg-paper.json +++ b/database/Seeders/eggs/minecraft/egg-paper.json @@ -9,7 +9,8 @@ "author": "parker@pterodactyl.io", "description": "High performance Spigot fork that aims to fix gameplay and mechanics inconsistencies.", "features": [ - "eula" + "eula", + "java_version" ], "images": [ "ghcr.io\/pterodactyl\/yolks:java_8", diff --git a/database/Seeders/eggs/minecraft/egg-sponge--sponge-vanilla.json b/database/Seeders/eggs/minecraft/egg-sponge--sponge-vanilla.json index 1b5aaf35..c25fda1c 100644 --- a/database/Seeders/eggs/minecraft/egg-sponge--sponge-vanilla.json +++ b/database/Seeders/eggs/minecraft/egg-sponge--sponge-vanilla.json @@ -9,7 +9,8 @@ "author": "support@pterodactyl.io", "description": "SpongeVanilla is the SpongeAPI implementation for Vanilla Minecraft.", "features": [ - "eula" + "eula", + "java_version" ], "images": [ "ghcr.io\/pterodactyl\/yolks:java_8", diff --git a/database/Seeders/eggs/minecraft/egg-vanilla-minecraft.json b/database/Seeders/eggs/minecraft/egg-vanilla-minecraft.json index 69055ca2..236a0cff 100644 --- a/database/Seeders/eggs/minecraft/egg-vanilla-minecraft.json +++ b/database/Seeders/eggs/minecraft/egg-vanilla-minecraft.json @@ -9,7 +9,8 @@ "author": "support@pterodactyl.io", "description": "Minecraft is a game about placing blocks and going on adventures. Explore randomly generated worlds and build amazing things from the simplest of homes to the grandest of castles. Play in Creative Mode with unlimited resources or mine deep in Survival Mode, crafting weapons and armor to fend off dangerous mobs. Do all this alone or with friends.", "features": [ - "eula" + "eula", + "java_version" ], "images": [ "ghcr.io\/pterodactyl\/yolks:java_8", @@ -51,4 +52,4 @@ "rules": "required|string|between:3,15" } ] -} \ No newline at end of file +} diff --git a/resources/scripts/components/server/ServerConsole.tsx b/resources/scripts/components/server/ServerConsole.tsx index 95d595ad..1c6aca4d 100644 --- a/resources/scripts/components/server/ServerConsole.tsx +++ b/resources/scripts/components/server/ServerConsole.tsx @@ -57,12 +57,10 @@ const ServerConsole = () => { - {eggFeatures.includes('eula') && - - + {eggFeatures.includes('eula') && } + {eggFeatures.includes('java_version') && } - }
); diff --git a/resources/scripts/components/server/features/index.ts b/resources/scripts/components/server/features/index.ts index 9ffe0118..d59a59cb 100644 --- a/resources/scripts/components/server/features/index.ts +++ b/resources/scripts/components/server/features/index.ts @@ -7,6 +7,6 @@ import { lazy } from 'react'; * on the feature and the egg). */ const EulaModalFeature = lazy(() => import(/* webpackChunkName: "feature.eula" */'@feature/eula/EulaModalFeature')); -const JavaVersionModalFeature = lazy(() => import(/* webpackChunkName: "feature.javaVersion" */'@feature/JavaVersionModalFeature')); +const JavaVersionModalFeature = lazy(() => import(/* webpackChunkName: "feature.java_version" */'@feature/JavaVersionModalFeature')); export { EulaModalFeature, JavaVersionModalFeature };