Un-butcher task system.
This commit is contained in:
		
							parent
							
								
									0fe9a4566e
								
							
						
					
					
						commit
						7f1a97184b
					
				| @ -25,7 +25,7 @@ | ||||
| namespace Pterodactyl\Console\Commands; | ||||
| 
 | ||||
| use Carbon; | ||||
| use Pterodactyl\Models; | ||||
| use Pterodactyl\Models\Task; | ||||
| use Illuminate\Console\Command; | ||||
| use Pterodactyl\Jobs\SendScheduledTask; | ||||
| use Illuminate\Foundation\Bus\DispatchesJobs; | ||||
| @ -65,14 +65,14 @@ class RunTasks extends Command | ||||
|      */ | ||||
|     public function handle() | ||||
|     { | ||||
|         $tasks = Models\Task::where('queued', 0)->where('active', 1)->where('next_run', '<=', Carbon::now()->toAtomString())->get(); | ||||
|         $tasks = Task::where('queued', false)->where('active', true)->where('next_run', '<=', Carbon::now()->toAtomString())->get(); | ||||
| 
 | ||||
|         $this->info(sprintf('Preparing to queue %d tasks.', count($tasks))); | ||||
|         $bar = $this->output->createProgressBar(count($tasks)); | ||||
| 
 | ||||
|         foreach ($tasks as &$task) { | ||||
|             $bar->advance(); | ||||
|             $this->dispatch((new SendScheduledTask(Models\Server::findOrFail($task->server), $task))->onQueue(config('pterodactyl.queues.low'))); | ||||
|             $this->dispatch((new SendScheduledTask($task))->onQueue(config('pterodactyl.queues.low'))); | ||||
|         } | ||||
| 
 | ||||
|         $bar->finish(); | ||||
|  | ||||
| @ -70,7 +70,7 @@ class ServerController extends Controller | ||||
|         $server = Server::byUuid($uuid); | ||||
|         $request->user()->can('power-' . $request->input('action'), $server); | ||||
| 
 | ||||
|         $repo = new PowerRepository($server); | ||||
|         $repo = new PowerRepository($server, $request->user()); | ||||
|         $repo->do($request->input('action')); | ||||
| 
 | ||||
|         return response('', 204)->header('Content-Type', 'application/json'); | ||||
| @ -90,7 +90,7 @@ class ServerController extends Controller | ||||
|         $server = Server::byUuid($uuid); | ||||
|         $request->user()->can('send-command', $server); | ||||
| 
 | ||||
|         $repo = new CommandRepository($server); | ||||
|         $repo = new CommandRepository($server, $request->user()); | ||||
|         $repo->send($request->input('command')); | ||||
| 
 | ||||
|         return response('', 204)->header('Content-Type', 'application/json'); | ||||
|  | ||||
| @ -26,9 +26,9 @@ namespace Pterodactyl\Http\Controllers\Server; | ||||
| 
 | ||||
| use Log; | ||||
| use Alert; | ||||
| use Pterodactyl\Models; | ||||
| use Illuminate\Http\Request; | ||||
| use Pterodactyl\Repositories; | ||||
| use Pterodactyl\Models\Server; | ||||
| use Pterodactyl\Repositories\TaskRepository; | ||||
| use Pterodactyl\Exceptions\DisplayException; | ||||
| use Pterodactyl\Http\Controllers\Controller; | ||||
| use Pterodactyl\Exceptions\DisplayValidationException; | ||||
| @ -44,7 +44,7 @@ class TaskController extends Controller | ||||
|      */ | ||||
|     public function index(Request $request, $uuid) | ||||
|     { | ||||
|         $server = Models\Server::byUuid($uuid)->load('tasks'); | ||||
|         $server = Server::byUuid($uuid)->load('tasks'); | ||||
|         $this->authorize('list-tasks', $server); | ||||
|         $server->js(); | ||||
| 
 | ||||
| @ -68,7 +68,7 @@ class TaskController extends Controller | ||||
|      */ | ||||
|     public function create(Request $request, $uuid) | ||||
|     { | ||||
|         $server = Models\Server::byUuid($uuid); | ||||
|         $server = Server::byUuid($uuid); | ||||
|         $this->authorize('create-task', $server); | ||||
|         $server->js(); | ||||
| 
 | ||||
| @ -87,12 +87,12 @@ class TaskController extends Controller | ||||
|      */ | ||||
|     public function store(Request $request, $uuid) | ||||
|     { | ||||
|         $server = Models\Server::byUuid($uuid); | ||||
|         $server = Server::byUuid($uuid); | ||||
|         $this->authorize('create-task', $server); | ||||
| 
 | ||||
|         $repo = new TaskRepository; | ||||
|         try { | ||||
|             $repo = new Repositories\TaskRepository; | ||||
|             $repo->create($server->id, $request->except([ | ||||
|             $repo->create($server->id, $request->user()->id, $request->except([ | ||||
|                 '_token', | ||||
|             ])); | ||||
| 
 | ||||
| @ -119,7 +119,7 @@ class TaskController extends Controller | ||||
|      */ | ||||
|     public function delete(Request $request, $uuid, $id) | ||||
|     { | ||||
|         $server = Models\Server::byUuid($uuid)->load('tasks'); | ||||
|         $server = Server::byUuid($uuid)->load('tasks'); | ||||
|         $this->authorize('delete-task', $server); | ||||
| 
 | ||||
|         $task = $server->tasks->where('id', $id)->first(); | ||||
| @ -129,8 +129,8 @@ class TaskController extends Controller | ||||
|             ], 404); | ||||
|         } | ||||
| 
 | ||||
|         $repo = new TaskRepository; | ||||
|         try { | ||||
|             $repo = new Repositories\TaskRepository; | ||||
|             $repo->delete($id); | ||||
| 
 | ||||
|             return response()->json([], 204); | ||||
| @ -153,7 +153,7 @@ class TaskController extends Controller | ||||
|      */ | ||||
|     public function toggle(Request $request, $uuid, $id) | ||||
|     { | ||||
|         $server = Models\Server::byUuid($uuid)->load('tasks'); | ||||
|         $server = Server::byUuid($uuid)->load('tasks'); | ||||
|         $this->authorize('toggle-task', $server); | ||||
| 
 | ||||
|         $task = $server->tasks->where('id', $id)->first(); | ||||
| @ -163,8 +163,8 @@ class TaskController extends Controller | ||||
|             ], 404); | ||||
|         } | ||||
| 
 | ||||
|         $repo = new TaskRepository; | ||||
|         try { | ||||
|             $repo = new Repositories\TaskRepository; | ||||
|             $resp = $repo->toggle($id); | ||||
| 
 | ||||
|             return response()->json([ | ||||
|  | ||||
| @ -26,7 +26,10 @@ namespace Pterodactyl\Jobs; | ||||
| 
 | ||||
| use Cron; | ||||
| use Carbon; | ||||
| use Pterodactyl\Models; | ||||
| use Pterodactyl\Models\Task; | ||||
| use Pterodactyl\Models\User; | ||||
| use Pterodactyl\Models\Server; | ||||
| use Pterodactyl\Models\TaskLog; | ||||
| use Illuminate\Queue\SerializesModels; | ||||
| use Illuminate\Queue\InteractsWithQueue; | ||||
| use Illuminate\Contracts\Queue\ShouldQueue; | ||||
| @ -37,11 +40,6 @@ class SendScheduledTask extends Job implements ShouldQueue | ||||
| { | ||||
|     use InteractsWithQueue, SerializesModels; | ||||
| 
 | ||||
|     /** | ||||
|      * @var \Pterodactyl\Models\Server | ||||
|      */ | ||||
|     protected $server; | ||||
| 
 | ||||
|     /** | ||||
|      * @var \Pterodactyl\Models\Task | ||||
|      */ | ||||
| @ -52,13 +50,12 @@ class SendScheduledTask extends Job implements ShouldQueue | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct(Models\Server $server, Models\Task $task) | ||||
|     public function __construct(Task $task) | ||||
|     { | ||||
|         $this->server = $server; | ||||
|         $this->task = $task; | ||||
| 
 | ||||
|         $task->queued = 1; | ||||
|         $task->save(); | ||||
|         $this->task->queued = true; | ||||
|         $this->task->save(); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -69,7 +66,7 @@ class SendScheduledTask extends Job implements ShouldQueue | ||||
|     public function handle() | ||||
|     { | ||||
|         $time = Carbon::now(); | ||||
|         $log = new Models\TaskLog; | ||||
|         $log = new TaskLog; | ||||
| 
 | ||||
|         if ($this->attempts() >= 1) { | ||||
|             // Just delete the job, we will attempt it again later anyways.
 | ||||
| @ -78,12 +75,15 @@ class SendScheduledTask extends Job implements ShouldQueue | ||||
| 
 | ||||
|         try { | ||||
|             if ($this->task->action === 'command') { | ||||
|                 $repo = new CommandRepository($this->server); | ||||
|                 $repo = new CommandRepository($this->task->server, $this->task->user); | ||||
|                 $response = $repo->send($this->task->data); | ||||
|             } elseif ($this->task->action === 'power') { | ||||
|                 $repo = new PowerRepository($this->server); | ||||
|             } else if ($this->task->action === 'power') { | ||||
|                 $repo = new PowerRepository($this->task->server, $this->task->user); | ||||
|                 $response = $repo->do($this->task->data); | ||||
|             } else { | ||||
|                 throw new \Exception('Task type provided was not valid.'); | ||||
|             } | ||||
| 
 | ||||
|             $log->fill([ | ||||
|                 'task_id' => $this->task->id, | ||||
|                 'run_time' => $time, | ||||
| @ -109,7 +109,7 @@ class SendScheduledTask extends Job implements ShouldQueue | ||||
|             $this->task->fill([ | ||||
|                 'last_run' => $time, | ||||
|                 'next_run' => $cron->getNextRunDate(), | ||||
|                 'queued' => 0, | ||||
|                 'queued' => false, | ||||
|             ]); | ||||
|             $this->task->save(); | ||||
|             $log->save(); | ||||
|  | ||||
| @ -320,7 +320,7 @@ class Server extends Model | ||||
|      */ | ||||
|     public function tasks() | ||||
|     { | ||||
|         return $this->hasMany(Task::class, 'server', 'id'); | ||||
|         return $this->hasMany(Task::class); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|  | ||||
| @ -49,8 +49,10 @@ class Task extends Model | ||||
|      */ | ||||
|     protected $casts = [ | ||||
|         'id' => 'integer', | ||||
|         'server' => 'integer', | ||||
|         'queued' => 'integer', | ||||
|         'user_id' => 'integer', | ||||
|         'server_id' => 'integer', | ||||
|         'queued' => 'boolean', | ||||
|         'active' => 'boolean', | ||||
|     ]; | ||||
| 
 | ||||
|     /** | ||||
| @ -59,4 +61,24 @@ class Task extends Model | ||||
|      * @var array | ||||
|      */ | ||||
|     protected $dates = ['last_run', 'next_run', 'created_at', 'updated_at']; | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the server associated with a task. | ||||
|      * | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function server() | ||||
|     { | ||||
|         return $this->belongsTo(Server::class); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Gets the user associated with a task. | ||||
|      * | ||||
|      * @return \Illuminate\Database\Eloquent\Relations\BelongsTo | ||||
|      */ | ||||
|     public function user() | ||||
|     { | ||||
|         return $this->belongsTo(User::class); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -24,7 +24,8 @@ | ||||
| 
 | ||||
| namespace Pterodactyl\Repositories\Daemon; | ||||
| 
 | ||||
| use Pterodactyl\Models; | ||||
| use Pterodactyl\Models\User; | ||||
| use Pterodactyl\Models\Server; | ||||
| use GuzzleHttp\Exception\ConnectException; | ||||
| use Pterodactyl\Exceptions\DisplayException; | ||||
| 
 | ||||
| @ -37,15 +38,24 @@ class CommandRepository | ||||
|      */ | ||||
|     protected $server; | ||||
| 
 | ||||
|     /** | ||||
|      * The Eloquent Model associated with the user to run the request as. | ||||
|      * | ||||
|      * @var \Pterodactyl\Models\User|null | ||||
|      */ | ||||
|     protected $user; | ||||
| 
 | ||||
|     /** | ||||
|      * Constuctor for repository. | ||||
|      * | ||||
|      * @param  int|\Pterodactyl\Models\Server  $server | ||||
|      * @param  \Pterodactyl\Models\Server  $server | ||||
|      * @param  \Pterodactyl\Models\User|null   $user | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct($server) | ||||
|     public function __construct(Server $server, User $user = null) | ||||
|     { | ||||
|         $this->server = ($server instanceof Models\Server) ? $server : Models\Server::findOrFail($server); | ||||
|         $this->server = $server; | ||||
|         $this->user = $user; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -62,7 +72,7 @@ class CommandRepository | ||||
|         // We don't use the user's specific daemon secret here since we
 | ||||
|         // are assuming that a call to this function has been validated.
 | ||||
|         try { | ||||
|             $response = $this->server->guzzleClient()->request('PUT', '/server/command', [ | ||||
|             $response = $this->server->guzzleClient($this->user)->request('POST', '/server/command', [ | ||||
|                 'http_errors' => false, | ||||
|                 'json' => [ | ||||
|                     'command' => $command, | ||||
|  | ||||
| @ -24,7 +24,8 @@ | ||||
| 
 | ||||
| namespace Pterodactyl\Repositories\Daemon; | ||||
| 
 | ||||
| use Pterodactyl\Models; | ||||
| use Pterodactyl\Models\User; | ||||
| use Pterodactyl\Models\Server; | ||||
| use GuzzleHttp\Exception\ConnectException; | ||||
| use Pterodactyl\Exceptions\DisplayException; | ||||
| 
 | ||||
| @ -37,15 +38,24 @@ class PowerRepository | ||||
|      */ | ||||
|     protected $server; | ||||
| 
 | ||||
|     /** | ||||
|      * The Eloquent Model associated with the user to run the request as. | ||||
|      * | ||||
|      * @var \Pterodactyl\Models\User|null | ||||
|      */ | ||||
|     protected $user; | ||||
| 
 | ||||
|     /** | ||||
|      * Constuctor for repository. | ||||
|      * | ||||
|      * @param  int|\Pterodactyl\Models\Server  $server | ||||
|      * @param  \Pterodactyl\Models\Server  $server | ||||
|      * @param  \Pterodactyl\Models\User|null   $user | ||||
|      * @return void | ||||
|      */ | ||||
|     public function __construct($server) | ||||
|     public function __construct(Server $server, User $user = null) | ||||
|     { | ||||
|         $this->server = ($server instanceof Models\Server) ? $server : Models\Server::findOrFail($server); | ||||
|         $this->server = $server; | ||||
|         $this->user = $user; | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
| @ -59,10 +69,8 @@ class PowerRepository | ||||
|      */ | ||||
|     public function do($action) | ||||
|     { | ||||
|         // We don't use the user's specific daemon secret here since we
 | ||||
|         // are assuming that a call to this function has been validated.
 | ||||
|         try { | ||||
|             $response = $this->server->guzzleClient()->request('PUT', '/server/power', [ | ||||
|             $response = $this->server->guzzleClient($this->user)->request('PUT', '/server/power', [ | ||||
|                 'http_errors' => false, | ||||
|                 'json' => [ | ||||
|                     'action' => $action, | ||||
|  | ||||
| @ -24,9 +24,12 @@ | ||||
| 
 | ||||
| namespace Pterodactyl\Repositories; | ||||
| 
 | ||||
| use DB; | ||||
| use Cron; | ||||
| use Validator; | ||||
| use Pterodactyl\Models; | ||||
| use Pterodactyl\Models\Task; | ||||
| use Pterodactyl\Models\User; | ||||
| use Pterodactyl\Models\Server; | ||||
| use Pterodactyl\Exceptions\DisplayException; | ||||
| use Pterodactyl\Exceptions\DisplayValidationException; | ||||
| 
 | ||||
| @ -64,49 +67,42 @@ class TaskRepository | ||||
|      */ | ||||
|     public function delete($id) | ||||
|     { | ||||
|         $task = Models\Task::findOrFail($id); | ||||
|         try { | ||||
|         $task = Task::findOrFail($id); | ||||
|         $task->delete(); | ||||
| 
 | ||||
|             return true; | ||||
|         } catch (\Exception $ex) { | ||||
|             throw $ex; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Toggles a task active or inactive. | ||||
|      * | ||||
|      * @param  int  $id | ||||
|      * @return int | ||||
|      * @return bool | ||||
|      */ | ||||
|     public function toggle($id) | ||||
|     { | ||||
|         $task = Models\Task::findOrFail($id); | ||||
|         try { | ||||
|             $task->active = ($task->active === 1) ? 0 : 1; | ||||
|             $task->queued = 0; | ||||
|         $task = Task::findOrFail($id); | ||||
| 
 | ||||
|         $task->active = ! $task->active; | ||||
|         $task->queued = false; | ||||
|         $task->save(); | ||||
| 
 | ||||
|         return $task->active; | ||||
|         } catch (\Exception $ex) { | ||||
|             throw $ex; | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Create a new scheduled task for a given server. | ||||
|      * | ||||
|      * @param  int    $id | ||||
|      * @param  int    $server | ||||
|      * @param  int    $user | ||||
|      * @param  array  $data | ||||
|      * @return bool | ||||
|      * @return \Pterodactyl\Models\Task | ||||
|      * | ||||
|      * @throws \Pterodactyl\Exceptions\DisplayException | ||||
|      * @throws \Pterodactyl\Exceptions\DisplayValidationException | ||||
|      */ | ||||
|     public function create($id, $data) | ||||
|     public function create($server, $user, $data) | ||||
|     { | ||||
|         $server = Models\Server::findOrFail($id); | ||||
|         $server = Server::findOrFail($server); | ||||
|         $user = User::findOrFail($user); | ||||
| 
 | ||||
|         $validator = Validator::make($data, [ | ||||
|             'action' => 'string|required', | ||||
| @ -148,9 +144,9 @@ class TaskRepository | ||||
|             throw $ex; | ||||
|         } | ||||
| 
 | ||||
|         $task = new Models\Task; | ||||
|         $task->fill([ | ||||
|             'server' => $server->id, | ||||
|         return Task::create([ | ||||
|             'user_id' => $user->id, | ||||
|             'server_id' => $server->id, | ||||
|             'active' => 1, | ||||
|             'action' => $data['action'], | ||||
|             'data' => $data['data'], | ||||
| @ -164,7 +160,5 @@ class TaskRepository | ||||
|             'last_run' => null, | ||||
|             'next_run' => $buildCron->getNextRunDate(), | ||||
|         ]); | ||||
| 
 | ||||
|         return $task->save(); | ||||
|     } | ||||
| } | ||||
|  | ||||
							
								
								
									
										43
									
								
								database/migrations/2017_04_15_125021_UpgradeTaskSystem.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										43
									
								
								database/migrations/2017_04_15_125021_UpgradeTaskSystem.php
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,43 @@ | ||||
| <?php | ||||
| 
 | ||||
| use Illuminate\Support\Facades\Schema; | ||||
| use Illuminate\Database\Schema\Blueprint; | ||||
| use Illuminate\Database\Migrations\Migration; | ||||
| 
 | ||||
| class UpgradeTaskSystem extends Migration | ||||
| { | ||||
|     /** | ||||
|      * Run the migrations. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function up() | ||||
|     { | ||||
|         Schema::table('tasks', function (Blueprint $table) { | ||||
|             $table->dropForeign(['server']); | ||||
| 
 | ||||
|             $table->renameColumn('server', 'server_id'); | ||||
|             $table->unsignedInteger('user_id')->after('id'); | ||||
| 
 | ||||
|             $table->foreign('server_id')->references('id')->on('servers'); | ||||
|             $table->foreign('user_id')->references('id')->on('users'); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Reverse the migrations. | ||||
|      * | ||||
|      * @return void | ||||
|      */ | ||||
|     public function down() | ||||
|     { | ||||
|         Schema::table('tasks', function (Blueprint $table) { | ||||
|             $table->dropForeign(['server_id', 'user_id']); | ||||
| 
 | ||||
|             $table->renameColumn('server_id', 'server'); | ||||
|             $table->dropColumn('user_id'); | ||||
| 
 | ||||
|             $table->foreign('server')->references('id')->on('servers'); | ||||
|         }); | ||||
|     } | ||||
| } | ||||
| @ -159,7 +159,7 @@ | ||||
|                                     <a href="{{ route('server.tasks', $server->uuidShort)}}"> | ||||
|                                         <i class="fa fa-clock-o"></i> <span>@lang('navigation.server.task_management')</span> | ||||
|                                         <span class="pull-right-container"> | ||||
|                                             <span class="label label-primary pull-right">{{ \Pterodactyl\Models\Task::select('id')->where('server', $server->id)->where('active', 1)->count() }}</span> | ||||
|                                             <span class="label label-primary pull-right">{{ \Pterodactyl\Models\Task::select('id')->where('server_id', $server->id)->where('active', 1)->count() }}</span> | ||||
|                                         </span> | ||||
|                                     </a> | ||||
|                                 </li> | ||||
|  | ||||
| @ -55,7 +55,7 @@ | ||||
|                             <th></th> | ||||
|                         </tr> | ||||
|                         @foreach($tasks as $task) | ||||
|                             <tr @if($task->active === 0)class="muted muted-hover"@endif> | ||||
|                             <tr @if(! $task->active)class="muted muted-hover"@endif> | ||||
|                                 <td class="middle">{{ $actions[$task->action] }}</td> | ||||
|                                 <td class="middle"><code>{{ $task->data }}</code></td> | ||||
|                                 <td class="middle"> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Dane Everitt
						Dane Everitt