Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pterodactyl
GitHub Repository: pterodactyl/panel
Path: blob/1.0-develop/app/Console/Commands/Server/BulkPowerActionCommand.php
7461 views
1
<?php
2
3
namespace Pterodactyl\Console\Commands\Server;
4
5
use Pterodactyl\Models\Server;
6
use Illuminate\Console\Command;
7
use Illuminate\Database\Eloquent\Builder;
8
use Illuminate\Validation\ValidationException;
9
use Illuminate\Validation\Factory as ValidatorFactory;
10
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
11
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
12
13
class BulkPowerActionCommand extends Command
14
{
15
protected $signature = 'p:server:bulk-power
16
{action : The action to perform (start, stop, restart, kill)}
17
{--servers= : A comma separated list of servers.}
18
{--nodes= : A comma separated list of nodes.}';
19
20
protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.';
21
22
/**
23
* BulkPowerActionCommand constructor.
24
*/
25
public function __construct(private DaemonPowerRepository $powerRepository, private ValidatorFactory $validator)
26
{
27
parent::__construct();
28
}
29
30
/**
31
* Handle the bulk power request.
32
*
33
* @throws ValidationException
34
*/
35
public function handle()
36
{
37
$action = $this->argument('action');
38
$nodes = empty($this->option('nodes')) ? [] : explode(',', $this->option('nodes'));
39
$servers = empty($this->option('servers')) ? [] : explode(',', $this->option('servers'));
40
41
$validator = $this->validator->make([
42
'action' => $action,
43
'nodes' => $nodes,
44
'servers' => $servers,
45
], [
46
'action' => 'string|in:start,stop,kill,restart',
47
'nodes' => 'array',
48
'nodes.*' => 'integer|min:1',
49
'servers' => 'array',
50
'servers.*' => 'integer|min:1',
51
]);
52
53
if ($validator->fails()) {
54
foreach ($validator->getMessageBag()->all() as $message) {
55
$this->output->error($message);
56
}
57
58
throw new ValidationException($validator);
59
}
60
61
$count = $this->getQueryBuilder($servers, $nodes)->count();
62
if (!$this->confirm(trans('command/messages.server.power.confirm', ['action' => $action, 'count' => $count])) && $this->input->isInteractive()) {
63
return;
64
}
65
66
$bar = $this->output->createProgressBar($count);
67
$powerRepository = $this->powerRepository;
68
$this->getQueryBuilder($servers, $nodes)->each(function (Server $server) use ($action, $powerRepository, &$bar) {
69
$bar->clear();
70
71
try {
72
$powerRepository->setServer($server)->send($action);
73
} catch (DaemonConnectionException $exception) {
74
$this->output->error(trans('command/messages.server.power.action_failed', [
75
'name' => $server->name,
76
'id' => $server->id,
77
'node' => $server->node->name,
78
'message' => $exception->getMessage(),
79
]));
80
}
81
82
$bar->advance();
83
$bar->display();
84
});
85
86
$this->line('');
87
}
88
89
/**
90
* Returns the query builder instance that will return the servers that should be affected.
91
*/
92
protected function getQueryBuilder(array $servers, array $nodes): Builder
93
{
94
$instance = Server::query()->whereNull('status');
95
96
if (!empty($nodes) && !empty($servers)) {
97
$instance->whereIn('id', $servers)->orWhereIn('node_id', $nodes);
98
} elseif (empty($nodes) && !empty($servers)) {
99
$instance->whereIn('id', $servers);
100
} elseif (!empty($nodes) && empty($servers)) {
101
$instance->whereIn('node_id', $nodes);
102
}
103
104
return $instance->with('node');
105
}
106
}
107
108