Path: blob/1.0-develop/app/Console/Commands/UpgradeCommand.php
7460 views
<?php12namespace Pterodactyl\Console\Commands;34use Illuminate\Console\Command;5use Pterodactyl\Console\Kernel;6use Symfony\Component\Process\Process;7use Symfony\Component\Console\Helper\ProgressBar;89class UpgradeCommand extends Command10{11protected const DEFAULT_URL = 'https://github.com/pterodactyl/panel/releases/%s/panel.tar.gz';1213protected $signature = 'p:upgrade14{--user= : The user that PHP runs under. All files will be owned by this user.}15{--group= : The group that PHP runs under. All files will be owned by this group.}16{--url= : The specific archive to download.}17{--release= : A specific Pterodactyl version to download from GitHub. Leave blank to use latest.}18{--skip-download : If set no archive will be downloaded.}';1920protected $description = 'Downloads a new archive for Pterodactyl from GitHub and then executes the normal upgrade commands.';2122/**23* Executes an upgrade command which will run through all of our standard24* commands for Pterodactyl and enable users to basically just download25* the archive and execute this and be done.26*27* This places the application in maintenance mode as well while the commands28* are being executed.29*30* @throws \Exception31*/32public function handle()33{34$skipDownload = $this->option('skip-download');35if (!$skipDownload) {36$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.');37$this->output->comment('Download Source (set with --url=):');38$this->line($this->getUrl());39}4041if (version_compare(PHP_VERSION, '7.4.0') < 0) {42$this->error('Cannot execute self-upgrade process. The minimum required PHP version required is 7.4.0, you have [' . PHP_VERSION . '].');43}4445$user = 'www-data';46$group = 'www-data';47if ($this->input->isInteractive()) {48if (!$skipDownload) {49$skipDownload = !$this->confirm('Would you like to download and unpack the archive files for the latest version?', true);50}5152if (is_null($this->option('user'))) {53$userDetails = posix_getpwuid(fileowner('public'));54$user = $userDetails['name'] ?? 'www-data';5556if (!$this->confirm("Your webserver user has been detected as <fg=blue>[{$user}]:</> is this correct?", true)) {57$user = $this->anticipate(58'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".',59[60'www-data',61'nginx',62'apache',63]64);65}66}6768if (is_null($this->option('group'))) {69$groupDetails = posix_getgrgid(filegroup('public'));70$group = $groupDetails['name'] ?? 'www-data';7172if (!$this->confirm("Your webserver group has been detected as <fg=blue>[{$group}]:</> is this correct?", true)) {73$group = $this->anticipate(74'Please enter the name of the group running your webserver process. Normally this is the same as your user.',75[76'www-data',77'nginx',78'apache',79]80);81}82}8384if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) {85$this->warn('Upgrade process terminated by user.');8687return;88}89}9091ini_set('output_buffering', '0');92$bar = $this->output->createProgressBar($skipDownload ? 9 : 10);93$bar->start();9495if (!$skipDownload) {96$this->withProgress($bar, function () {97$this->line("\$upgrader> curl -L \"{$this->getUrl()}\" | tar -xzv");98$process = Process::fromShellCommandline("curl -L \"{$this->getUrl()}\" | tar -xzv");99$process->run(function ($type, $buffer) {100$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);101});102});103}104105$this->withProgress($bar, function () {106$this->line('$upgrader> php artisan down');107$this->call('down');108});109110$this->withProgress($bar, function () {111$this->line('$upgrader> chmod -R 755 storage bootstrap/cache');112$process = new Process(['chmod', '-R', '755', 'storage', 'bootstrap/cache']);113$process->run(function ($type, $buffer) {114$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);115});116});117118$this->withProgress($bar, function () {119$command = ['composer', 'install', '--no-ansi'];120if (config('app.env') === 'production' && !config('app.debug')) {121$command[] = '--optimize-autoloader';122$command[] = '--no-dev';123}124125$this->line('$upgrader> ' . implode(' ', $command));126$process = new Process($command);127$process->setTimeout(10 * 60);128$process->run(function ($type, $buffer) {129$this->line($buffer);130});131});132133/** @var \Illuminate\Foundation\Application $app */134$app = require __DIR__ . '/../../../bootstrap/app.php';135/** @var Kernel $kernel */136$kernel = $app->make(Kernel::class);137$kernel->bootstrap();138$this->setLaravel($app);139140$this->withProgress($bar, function () {141$this->line('$upgrader> php artisan view:clear');142$this->call('view:clear');143});144145$this->withProgress($bar, function () {146$this->line('$upgrader> php artisan config:clear');147$this->call('config:clear');148});149150$this->withProgress($bar, function () {151$this->line('$upgrader> php artisan migrate --force --seed');152$this->call('migrate', ['--force' => true, '--seed' => true]);153});154155$this->withProgress($bar, function () use ($user, $group) {156$this->line("\$upgrader> chown -R {$user}:{$group} *");157$process = Process::fromShellCommandline("chown -R {$user}:{$group} *", $this->getLaravel()->basePath());158$process->setTimeout(10 * 60);159$process->run(function ($type, $buffer) {160$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);161});162});163164$this->withProgress($bar, function () {165$this->line('$upgrader> php artisan queue:restart');166$this->call('queue:restart');167});168169$this->withProgress($bar, function () {170$this->line('$upgrader> php artisan up');171$this->call('up');172});173174$this->newLine(2);175$this->info('Panel has been successfully upgraded. Please ensure you also update any Wings instances: https://pterodactyl.io/wings/1.0/upgrading.html');176}177178protected function withProgress(ProgressBar $bar, \Closure $callback)179{180$bar->clear();181$callback();182$bar->advance();183$bar->display();184}185186protected function getUrl(): string187{188if ($this->option('url')) {189return $this->option('url');190}191192return sprintf(self::DEFAULT_URL, $this->option('release') ? 'download/v' . $this->option('release') : 'latest/download');193}194}195196197