Skip to content

Commit 50a2108

Browse files
committed
main
1 parent 4b60140 commit 50a2108

File tree

2 files changed

+198
-101
lines changed

2 files changed

+198
-101
lines changed

app/Console/Commands/Update.php

-101
This file was deleted.
+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
<?php
2+
3+
namespace Pterodactyl\Console\Commands;
4+
5+
use Closure;
6+
use Illuminate\Console\Command;
7+
use Pterodactyl\Console\Kernel;
8+
use Symfony\Component\Process\Process;
9+
use Symfony\Component\Console\Helper\ProgressBar;
10+
11+
class UpgradeCommand extends Command
12+
{
13+
protected const DEFAULT_URL = 'https://github.com/pterodactyl/panel/releases/%s/panel.tar.gz';
14+
15+
/** @var string */
16+
protected $signature = 'p:upgrade
17+
{--user= : The user that PHP runs under. All files will be owned by this user.}
18+
{--group= : The group that PHP runs under. All files will be owned by this group.}
19+
{--url= : The specific archive to download.}
20+
{--release= : A specific Pterodactyl version to download from GitHub. Leave blank to use latest.}
21+
{--skip-download : If set no archive will be downloaded.}';
22+
23+
/** @var string */
24+
protected $description = 'Downloads a new archive for Pterodactyl from GitHub and then executes the normal upgrade commands.';
25+
26+
/**
27+
* Executes an upgrade command which will run through all of our standard
28+
* commands for Pterodactyl and enable users to basically just download
29+
* the archive and execute this and be done.
30+
*
31+
* This places the application in maintenance mode as well while the commands
32+
* are being executed.
33+
*
34+
* @throws \Exception
35+
*/
36+
public function handle()
37+
{
38+
$skipDownload = $this->option('skip-download');
39+
if (!$skipDownload) {
40+
$this->output->warning('This command does not verify the integrity of downloaded assets. Please ensure that you trust the download source before continuing. If you do not wish to download an archive, please indicate that using the --skip-download flag, or answering "no" to the question below.');
41+
$this->output->comment('Download Source (set with --url=):');
42+
$this->line($this->getUrl());
43+
}
44+
45+
if (version_compare(PHP_VERSION, '7.4.0') < 0) {
46+
$this->error('Cannot execute self-upgrade process. The minimum required PHP version required is 7.4.0, you have [' . PHP_VERSION . '].');
47+
}
48+
49+
$user = 'www-data';
50+
$group = 'www-data';
51+
if ($this->input->isInteractive()) {
52+
if (!$skipDownload) {
53+
$skipDownload = !$this->confirm('Would you like to download and unpack the archive files for the latest version?', true);
54+
}
55+
56+
if (is_null($this->option('user'))) {
57+
$userDetails = posix_getpwuid(fileowner('public'));
58+
$user = $userDetails['name'] ?? 'www-data';
59+
60+
if (!$this->confirm("Your webserver user has been detected as <fg=blue>[{$user}]:</> is this correct?", true)) {
61+
$user = $this->anticipate(
62+
'Please enter the name of the user running your webserver process. This varies from system to system, but is generally "www-data", "nginx", or "apache".',
63+
[
64+
'www-data',
65+
'nginx',
66+
'apache',
67+
]
68+
);
69+
}
70+
}
71+
72+
if (is_null($this->option('group'))) {
73+
$groupDetails = posix_getgrgid(filegroup('public'));
74+
$group = $groupDetails['name'] ?? 'www-data';
75+
76+
if (!$this->confirm("Your webserver group has been detected as <fg=blue>[{$group}]:</> is this correct?", true)) {
77+
$group = $this->anticipate(
78+
'Please enter the name of the group running your webserver process. Normally this is the same as your user.',
79+
[
80+
'www-data',
81+
'nginx',
82+
'apache',
83+
]
84+
);
85+
}
86+
}
87+
88+
if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) {
89+
$this->warn('Upgrade process terminated by user.');
90+
91+
return;
92+
}
93+
}
94+
95+
ini_set('output_buffering', 0);
96+
$bar = $this->output->createProgressBar($skipDownload ? 9 : 10);
97+
$bar->start();
98+
99+
if (!$skipDownload) {
100+
$this->withProgress($bar, function () {
101+
$this->line("\$upgrader> curl -L \"{$this->getUrl()}\" | tar -xzv");
102+
$process = Process::fromShellCommandline("curl -L \"{$this->getUrl()}\" | tar -xzv");
103+
$process->run(function ($type, $buffer) {
104+
$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);
105+
});
106+
});
107+
}
108+
109+
$this->withProgress($bar, function () {
110+
$this->line('$upgrader> php artisan down');
111+
$this->call('down');
112+
});
113+
114+
$this->withProgress($bar, function () {
115+
$this->line('$upgrader> chmod -R 755 storage bootstrap/cache');
116+
$process = new Process(['chmod', '-R', '755', 'storage', 'bootstrap/cache']);
117+
$process->run(function ($type, $buffer) {
118+
$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);
119+
});
120+
});
121+
122+
$this->withProgress($bar, function () {
123+
$command = ['composer', 'install', '--no-ansi'];
124+
if (config('app.env') === 'production' && !config('app.debug')) {
125+
$command[] = '--optimize-autoloader';
126+
$command[] = '--no-dev';
127+
}
128+
129+
$this->line('$upgrader> ' . implode(' ', $command));
130+
$process = new Process($command);
131+
$process->setTimeout(10 * 60);
132+
$process->run(function ($type, $buffer) {
133+
$this->line($buffer);
134+
});
135+
});
136+
137+
/** @var \Illuminate\Foundation\Application $app */
138+
$app = require __DIR__ . '/../../../bootstrap/app.php';
139+
/** @var \Pterodactyl\Console\Kernel $kernel */
140+
$kernel = $app->make(Kernel::class);
141+
$kernel->bootstrap();
142+
$this->setLaravel($app);
143+
144+
$this->withProgress($bar, function () {
145+
$this->line('$upgrader> php artisan view:clear');
146+
$this->call('view:clear');
147+
});
148+
149+
$this->withProgress($bar, function () {
150+
$this->line('$upgrader> php artisan config:clear');
151+
$this->call('config:clear');
152+
});
153+
154+
$this->withProgress($bar, function () {
155+
$this->line('$upgrader> php artisan migrate --force --seed');
156+
$this->call('migrate', ['--force' => true, '--seed' => true]);
157+
});
158+
159+
$this->withProgress($bar, function () use ($user, $group) {
160+
$this->line("\$upgrader> chown -R {$user}:{$group} *");
161+
$process = Process::fromShellCommandline("chown -R {$user}:{$group} *", $this->getLaravel()->basePath());
162+
$process->setTimeout(10 * 60);
163+
$process->run(function ($type, $buffer) {
164+
$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);
165+
});
166+
});
167+
168+
$this->withProgress($bar, function () {
169+
$this->line('$upgrader> php artisan queue:restart');
170+
$this->call('queue:restart');
171+
});
172+
173+
$this->withProgress($bar, function () {
174+
$this->line('$upgrader> php artisan up');
175+
$this->call('up');
176+
});
177+
178+
$this->newLine(2);
179+
$this->info('Panel has been successfully upgraded. Please ensure you also update any Wings instances: https://pterodactyl.io/wings/1.0/upgrading.html');
180+
}
181+
182+
protected function withProgress(ProgressBar $bar, Closure $callback)
183+
{
184+
$bar->clear();
185+
$callback();
186+
$bar->advance();
187+
$bar->display();
188+
}
189+
190+
protected function getUrl(): string
191+
{
192+
if ($this->option('url')) {
193+
return $this->option('url');
194+
}
195+
196+
return sprintf(self::DEFAULT_URL, $this->option('release') ? 'download/v' . $this->option('release') : 'latest/download');
197+
}
198+
}

0 commit comments

Comments
 (0)