Skip to content

Commit 92cd659

Browse files
committed
Add underlying data changes necessary for new task & schedule features
1 parent cf1ac04 commit 92cd659

File tree

13 files changed

+201
-107
lines changed

13 files changed

+201
-107
lines changed

app/Http/Controllers/Api/Client/Servers/ScheduleController.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
use Pterodactyl\Transformers\Api\Client\ScheduleTransformer;
1717
use Pterodactyl\Http\Controllers\Api\Client\ClientApiController;
1818
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
19-
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
2019
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\ViewScheduleRequest;
2120
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\StoreScheduleRequest;
2221
use Pterodactyl\Http\Requests\Api\Client\Servers\Schedules\DeleteScheduleRequest;
@@ -81,6 +80,7 @@ public function store(StoreScheduleRequest $request, Server $server)
8180
'cron_hour' => $request->input('hour'),
8281
'cron_minute' => $request->input('minute'),
8382
'is_active' => (bool) $request->input('is_active'),
83+
'only_when_online' => (bool) $request->input('only_when_online'),
8484
'next_run_at' => $this->getNextRunAt($request),
8585
]);
8686

@@ -128,6 +128,7 @@ public function update(UpdateScheduleRequest $request, Server $server, Schedule
128128
'cron_hour' => $request->input('hour'),
129129
'cron_minute' => $request->input('minute'),
130130
'is_active' => $active,
131+
'only_when_online' => (bool) $request->input('only_when_online'),
131132
'next_run_at' => $this->getNextRunAt($request),
132133
];
133134

app/Http/Controllers/Api/Client/Servers/ScheduleTaskController.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ public function store(StoreTaskRequest $request, Server $server, Schedule $sched
5959
'action' => $request->input('action'),
6060
'payload' => $request->input('payload') ?? '',
6161
'time_offset' => $request->input('time_offset'),
62+
'continue_on_failure' => (bool) $request->input('continue_on_failure'),
6263
]);
6364

6465
return $this->fractal->item($task)
@@ -84,6 +85,7 @@ public function update(StoreTaskRequest $request, Server $server, Schedule $sche
8485
'action' => $request->input('action'),
8586
'payload' => $request->input('payload') ?? '',
8687
'time_offset' => $request->input('time_offset'),
88+
'continue_on_failure' => (bool) $request->input('continue_on_failure'),
8789
]);
8890

8991
return $this->fractal->item($task->refresh())

app/Jobs/Schedule/RunTaskJob.php

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Carbon\CarbonImmutable;
88
use Pterodactyl\Models\Task;
99
use InvalidArgumentException;
10+
use Illuminate\Http\Response;
1011
use Pterodactyl\Models\Schedule;
1112
use Illuminate\Queue\SerializesModels;
1213
use Illuminate\Queue\InteractsWithQueue;
@@ -15,6 +16,7 @@
1516
use Pterodactyl\Services\Backups\InitiateBackupService;
1617
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
1718
use Pterodactyl\Repositories\Wings\DaemonCommandRepository;
19+
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
1820

1921
class RunTaskJob extends Job implements ShouldQueue
2022
{
@@ -62,18 +64,32 @@ public function handle(
6264

6365
$server = $this->task->server;
6466
// Perform the provided task against the daemon.
65-
switch ($this->task->action) {
66-
case 'power':
67-
$powerRepository->setServer($server)->send($this->task->payload);
68-
break;
69-
case 'command':
70-
$commandRepository->setServer($server)->send($this->task->payload);
71-
break;
72-
case 'backup':
73-
$backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null, true);
74-
break;
75-
default:
76-
throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.');
67+
try {
68+
switch ($this->task->action) {
69+
case Task::ACTION_POWER:
70+
$powerRepository->setServer($server)->send($this->task->payload);
71+
break;
72+
case Task::ACTION_COMMAND:
73+
$commandRepository->setServer($server)->send($this->task->payload);
74+
break;
75+
case Task::ACTION_BACKUP:
76+
$backupService->setIgnoredFiles(explode(PHP_EOL, $this->task->payload))->handle($server, null, true);
77+
break;
78+
default:
79+
throw new InvalidArgumentException('Cannot run a task that points to a non-existent action.');
80+
}
81+
} catch (Exception $exception) {
82+
if ($exception instanceof DaemonConnectionException) {
83+
// If the task "failed" because the server is offline and it was sending a command or
84+
// executing a power action (which shouldn't happen?) then just stop trying to process
85+
// the schedule, but don't actually log the failure.
86+
if ($this->task->action === Task::ACTION_POWER || $this->task->action === Task::ACTION_COMMAND) {
87+
// Do the thing
88+
if ($exception->getStatusCode() === Response::HTTP_CONFLICT) {
89+
}
90+
}
91+
}
92+
throw $exception;
7793
}
7894

7995
$this->markTaskNotQueued();

app/Models/Schedule.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
* @property string $cron_minute
1919
* @property bool $is_active
2020
* @property bool $is_processing
21+
* @property bool $only_when_online
2122
* @property \Carbon\Carbon|null $last_run_at
2223
* @property \Carbon\Carbon|null $next_run_at
2324
* @property \Carbon\Carbon $created_at
@@ -63,6 +64,7 @@ class Schedule extends Model
6364
'cron_minute',
6465
'is_active',
6566
'is_processing',
67+
'only_when_online',
6668
'last_run_at',
6769
'next_run_at',
6870
];
@@ -75,6 +77,7 @@ class Schedule extends Model
7577
'server_id' => 'integer',
7678
'is_active' => 'boolean',
7779
'is_processing' => 'boolean',
80+
'only_when_online' => 'boolean',
7881
];
7982

8083
/**
@@ -99,6 +102,7 @@ class Schedule extends Model
99102
'cron_minute' => '*',
100103
'is_active' => true,
101104
'is_processing' => false,
105+
'only_when_online' => false,
102106
];
103107

104108
/**
@@ -114,6 +118,7 @@ class Schedule extends Model
114118
'cron_minute' => 'required|string',
115119
'is_active' => 'boolean',
116120
'is_processing' => 'boolean',
121+
'only_when_online' => 'boolean',
117122
'last_run_at' => 'nullable|date',
118123
'next_run_at' => 'nullable|date',
119124
];
@@ -122,6 +127,7 @@ class Schedule extends Model
122127
* Returns the schedule's execution crontab entry as a string.
123128
*
124129
* @return \Carbon\CarbonImmutable
130+
*
125131
* @throws \Exception
126132
*/
127133
public function getNextRunDate()

app/Models/Task.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
* @property string $payload
1515
* @property int $time_offset
1616
* @property bool $is_queued
17+
* @property bool $continue_on_failure
1718
* @property \Carbon\Carbon $created_at
1819
* @property \Carbon\Carbon $updated_at
1920
* @property string $hashid
@@ -30,6 +31,13 @@ class Task extends Model
3031
*/
3132
public const RESOURCE_NAME = 'schedule_task';
3233

34+
/**
35+
* The default actions that can exist for a task in Pterodactyl.
36+
*/
37+
public const ACTION_POWER = 'power';
38+
public const ACTION_COMMAND = 'command';
39+
public const ACTION_BACKUP = 'backup';
40+
3341
/**
3442
* The table associated with the model.
3543
*
@@ -56,6 +64,7 @@ class Task extends Model
5664
'payload',
5765
'time_offset',
5866
'is_queued',
67+
'continue_on_failure',
5968
];
6069

6170
/**
@@ -69,6 +78,7 @@ class Task extends Model
6978
'sequence_id' => 'integer',
7079
'time_offset' => 'integer',
7180
'is_queued' => 'boolean',
81+
'continue_on_failure' => 'boolean',
7282
];
7383

7484
/**
@@ -79,6 +89,7 @@ class Task extends Model
7989
protected $attributes = [
8090
'time_offset' => 0,
8191
'is_queued' => false,
92+
'continue_on_failure' => false,
8293
];
8394

8495
/**
@@ -91,6 +102,7 @@ class Task extends Model
91102
'payload' => 'required_unless:action,backup|string',
92103
'time_offset' => 'required|numeric|between:0,900',
93104
'is_queued' => 'boolean',
105+
'continue_on_failure' => 'boolean',
94106
];
95107

96108
/**

app/Transformers/Api/Client/ScheduleTransformer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ public function transform(Schedule $model)
4545
],
4646
'is_active' => $model->is_active,
4747
'is_processing' => $model->is_processing,
48+
'only_when_online' => $model->only_when_online,
4849
'last_run_at' => $model->last_run_at ? $model->last_run_at->toIso8601String() : null,
4950
'next_run_at' => $model->next_run_at ? $model->next_run_at->toIso8601String() : null,
5051
'created_at' => $model->created_at->toIso8601String(),

app/Transformers/Api/Client/TaskTransformer.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public function transform(Task $model)
2828
'payload' => $model->payload,
2929
'time_offset' => $model->time_offset,
3030
'is_queued' => $model->is_queued,
31+
'continue_on_failure' => $model->continue_on_failure,
3132
'created_at' => $model->created_at->toIso8601String(),
3233
'updated_at' => $model->updated_at->toIso8601String(),
3334
];
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class AddContinueOnFailureOptionToTasks extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('tasks', function (Blueprint $table) {
17+
$table->unsignedTinyInteger('continue_on_failure')->after('is_queued')->default(0);
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('tasks', function (Blueprint $table) {
29+
$table->dropColumn('continue_on_failure');
30+
});
31+
}
32+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?php
2+
3+
use Illuminate\Database\Migrations\Migration;
4+
use Illuminate\Database\Schema\Blueprint;
5+
use Illuminate\Support\Facades\Schema;
6+
7+
class AddOnlyRunWhenServerOnlineOptionToSchedules extends Migration
8+
{
9+
/**
10+
* Run the migrations.
11+
*
12+
* @return void
13+
*/
14+
public function up()
15+
{
16+
Schema::table('schedules', function (Blueprint $table) {
17+
$table->unsignedTinyInteger('only_when_online')->after('is_processing')->default(0);
18+
});
19+
}
20+
21+
/**
22+
* Reverse the migrations.
23+
*
24+
* @return void
25+
*/
26+
public function down()
27+
{
28+
Schema::table('schedules', function (Blueprint $table) {
29+
$table->dropColumn('only_when_online');
30+
});
31+
}
32+
}
Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,19 @@
11
import { rawDataToServerSchedule, Schedule } from '@/api/server/schedules/getServerSchedules';
22
import http from '@/api/http';
33

4-
type Data = Pick<Schedule, 'cron' | 'name' | 'isActive'> & { id?: number }
4+
type Data = Pick<Schedule, 'cron' | 'name' | 'onlyWhenOnline' | 'isActive'> & { id?: number }
55

6-
export default (uuid: string, schedule: Data): Promise<Schedule> => {
7-
return new Promise((resolve, reject) => {
8-
http.post(`/api/client/servers/${uuid}/schedules${schedule.id ? `/${schedule.id}` : ''}`, {
9-
is_active: schedule.isActive,
10-
name: schedule.name,
11-
minute: schedule.cron.minute,
12-
hour: schedule.cron.hour,
13-
day_of_month: schedule.cron.dayOfMonth,
14-
month: schedule.cron.month,
15-
day_of_week: schedule.cron.dayOfWeek,
16-
})
17-
.then(({ data }) => resolve(rawDataToServerSchedule(data.attributes)))
18-
.catch(reject);
6+
export default async (uuid: string, schedule: Data): Promise<Schedule> => {
7+
const { data } = await http.post(`/api/client/servers/${uuid}/schedules${schedule.id ? `/${schedule.id}` : ''}`, {
8+
is_active: schedule.isActive,
9+
only_when_online: schedule.onlyWhenOnline,
10+
name: schedule.name,
11+
minute: schedule.cron.minute,
12+
hour: schedule.cron.hour,
13+
day_of_month: schedule.cron.dayOfMonth,
14+
month: schedule.cron.month,
15+
day_of_week: schedule.cron.dayOfWeek,
1916
});
17+
18+
return rawDataToServerSchedule(data.attributes);
2019
};

0 commit comments

Comments
 (0)