Compare commits
7 Commits
release/v1
...
0.7-develo
Author | SHA1 | Date |
---|---|---|
Dane Everitt | 4028588621 | |
Stepan Fedotov | 1cd08e2f8d | |
Dane Everitt | dcf5cb3cd3 | |
Dane Everitt | 6d69f6ef47 | |
Dane Everitt | 78514f9eb4 | |
Dane Everitt | 7deed07cd1 | |
Anders G. Jørgensen | 597196ad3e |
|
@ -0,0 +1,8 @@
|
||||||
|
{
|
||||||
|
"presets": ["es2015"],
|
||||||
|
"compact": true,
|
||||||
|
"minified": true,
|
||||||
|
"only": "public/themes/pterodactyl/js/frontend/files/src/*.js",
|
||||||
|
"sourceMaps": "inline",
|
||||||
|
"comments": false
|
||||||
|
}
|
|
@ -2,7 +2,7 @@
|
||||||
This is a ready to use docker image for the panel.
|
This is a ready to use docker image for the panel.
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
This docker image requires some additional software to function. The software can either be provided in other containers (see the [docker-compose.yml](https://github.com/pterodactyl/panel/blob/develop/docker-compose.example.yml) as an example) or as existing instances.
|
This docker image requires some additional software to function. The software can either be provided in other containers (see the [docker-compose.yml](docker-compose.yml) as an example) or as existing instances.
|
||||||
|
|
||||||
A mysql database is required. We recommend the stock [MariaDB Image](https://hub.docker.com/_/mariadb/) image if you prefer to run it in a docker container. As a non-containerized option we recommend mariadb.
|
A mysql database is required. We recommend the stock [MariaDB Image](https://hub.docker.com/_/mariadb/) image if you prefer to run it in a docker container. As a non-containerized option we recommend mariadb.
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ You can provide additional settings using a custom `.env` file or by setting the
|
||||||
|
|
||||||
## Setup
|
## Setup
|
||||||
|
|
||||||
Start the docker container and the required dependencies (either provide existing ones or start containers as well, see the [docker-compose.yml](https://github.com/pterodactyl/panel/blob/develop/docker-compose.example.yml) file as an example.
|
Start the docker container and the required dependencies (either provide existing ones or start containers as well, see the [docker-compose.yml](docker-compose.yml) file as an example).
|
||||||
|
|
||||||
After the startup is complete you'll need to create a user.
|
After the startup is complete you'll need to create a user.
|
||||||
If you are running the docker container without docker-compose, use:
|
If you are running the docker container without docker-compose, use:
|
||||||
|
@ -27,13 +27,13 @@ docker-compose exec panel php artisan p:user:make
|
||||||
## Environment Variables
|
## Environment Variables
|
||||||
There are multiple environment variables to configure the panel when not providing your own `.env` file, see the following table for details on each available option.
|
There are multiple environment variables to configure the panel when not providing your own `.env` file, see the following table for details on each available option.
|
||||||
|
|
||||||
Note: If your `APP_URL` starts with `https://` you need to provide an `LE_EMAIL` as well so Certificates can be generated.
|
Note: If your `APP_URL` starts with `https://` you need to provide an `LETSENCRYPT_EMAIL` as well so Certificates can be generated.
|
||||||
|
|
||||||
| Variable | Description | Required |
|
| Variable | Description | Required |
|
||||||
| ------------------- | ------------------------------------------------------------------------------ | -------- |
|
| ------------------- | ------------------------------------------------------------------------------ | -------- |
|
||||||
| `APP_URL` | The URL the panel will be reachable with (including protocol) | yes |
|
| `APP_URL` | The URL the panel will be reachable with (including protocol) | yes |
|
||||||
| `APP_TIMEZONE` | The timezone to use for the panel | yes |
|
| `APP_TIMEZONE` | The timezone to use for the panel | yes |
|
||||||
| `LE_EMAIL` | The email used for letsencrypt certificate generation | yes |
|
| `LETSENCRYPT_EMAIL` | The email used for letsencrypt certificate generation | yes |
|
||||||
| `DB_HOST` | The host of the mysql instance | yes |
|
| `DB_HOST` | The host of the mysql instance | yes |
|
||||||
| `DB_PORT` | The port of the mysql instance | yes |
|
| `DB_PORT` | The port of the mysql instance | yes |
|
||||||
| `DB_DATABASE` | The name of the mysql database | yes |
|
| `DB_DATABASE` | The name of the mysql database | yes |
|
||||||
|
@ -73,4 +73,4 @@ Every driver requires `MAIL_FROM` to be set.
|
||||||
| mandrill | [Mandrill](http://www.mandrill.com/) | `MAIL_USERNAME` |
|
| mandrill | [Mandrill](http://www.mandrill.com/) | `MAIL_USERNAME` |
|
||||||
| postmark | [Postmark](https://postmarkapp.com/) | `MAIL_USERNAME` |
|
| postmark | [Postmark](https://postmarkapp.com/) | `MAIL_USERNAME` |
|
||||||
| mailgun | [Mailgun](https://www.mailgun.com/) | `MAIL_USERNAME`, `MAIL_HOST` |
|
| mailgun | [Mailgun](https://www.mailgun.com/) | `MAIL_USERNAME`, `MAIL_HOST` |
|
||||||
| smtp | Any SMTP server can be configured | `MAIL_USERNAME`, `MAIL_HOST`, `MAIL_PASSWORD`, `MAIL_PORT` |
|
| smtp | Any SMTP server can be configured | `MAIL_USERNAME`, `MAIL_HOST`, `MAIL_PASSWORD`, `MAIL_PORT` |
|
|
@ -31,7 +31,7 @@ server {
|
||||||
location ~ \.php$ {
|
location ~ \.php$ {
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
# the fastcgi_pass path needs to be changed accordingly when using CentOS
|
# the fastcgi_pass path needs to be changed accordingly when using CentOS
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
fastcgi_pass unix:/var/run/php/php-fpm7.2.sock;
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
|
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
|
|
@ -1,4 +1,4 @@
|
||||||
# If using Ubuntu this file should be placed in:
|
# If using Ubuntu this file should be placed in:
|
||||||
# /etc/nginx/sites-available/
|
# /etc/nginx/sites-available/
|
||||||
#
|
#
|
||||||
server {
|
server {
|
||||||
|
@ -49,7 +49,7 @@ server {
|
||||||
|
|
||||||
location ~ \.php$ {
|
location ~ \.php$ {
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
fastcgi_pass unix:/var/run/php/php-fpm7.2.sock;
|
||||||
fastcgi_index index.php;
|
fastcgi_index index.php;
|
||||||
include fastcgi_params;
|
include fastcgi_params;
|
||||||
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
|
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
|
|
@ -0,0 +1,70 @@
|
||||||
|
#!/bin/ash
|
||||||
|
## Ensure we are in /app
|
||||||
|
|
||||||
|
cd /app
|
||||||
|
|
||||||
|
mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php7/ \
|
||||||
|
&& rmdir /app/storage/logs/ \
|
||||||
|
&& chmod 777 /var/log/panel/logs/ \
|
||||||
|
&& ln -s /var/log/panel/logs/ /app/storage/
|
||||||
|
|
||||||
|
## check for .env file and generate app keys if missing
|
||||||
|
if [ -f /app/var/.env ]; then
|
||||||
|
echo "external vars exist."
|
||||||
|
rm /app/.env
|
||||||
|
|
||||||
|
ln -s /app/var/.env /app/
|
||||||
|
else
|
||||||
|
echo "external vars don't exist."
|
||||||
|
rm /app/.env
|
||||||
|
touch /app/var/.env
|
||||||
|
|
||||||
|
## manually generate a key because key generate --force fails
|
||||||
|
echo -e "Generating key."
|
||||||
|
APP_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
||||||
|
echo -e "Generated app key: $APP_KEY"
|
||||||
|
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
|
||||||
|
|
||||||
|
ln -s /app/var/.env /app/
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Checking if https is required."
|
||||||
|
if [ -f /etc/nginx/conf.d/default.conf ]; then
|
||||||
|
echo "Using nginx config already in place."
|
||||||
|
else
|
||||||
|
echo "Checking if letsencrypt email is set."
|
||||||
|
if [ -z $LE_EMAIL ]; then
|
||||||
|
echo "No letsencrypt email is set Failing to http."
|
||||||
|
cp .dev/docker/default.conf /etc/nginx/conf.d/default.conf
|
||||||
|
|
||||||
|
else
|
||||||
|
echo "writing ssl config"
|
||||||
|
cp .dev/docker/default_ssl.conf /etc/nginx/conf.d/default.conf
|
||||||
|
echo "updating ssl config for domain"
|
||||||
|
sed -i "s|<domain>|$(echo $APP_URL | sed 's~http[s]*://~~g')|g" /etc/nginx/conf.d/default.conf
|
||||||
|
echo "generating certs"
|
||||||
|
certbot certonly -d $(echo $APP_URL | sed 's~http[s]*://~~g') --standalone -m $LE_EMAIL --agree-tos -n
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
## check for DB up before starting the panel
|
||||||
|
echo "Checking database status."
|
||||||
|
until nc -z -v -w30 $DB_HOST 3306
|
||||||
|
|
||||||
|
do
|
||||||
|
echo "Waiting for database connection..."
|
||||||
|
# wait for 5 seconds before check again
|
||||||
|
sleep 5
|
||||||
|
done
|
||||||
|
|
||||||
|
## make sure the db is set up
|
||||||
|
echo -e "Migrating and Seeding D.B"
|
||||||
|
php artisan migrate --force
|
||||||
|
php artisan db:seed --force
|
||||||
|
|
||||||
|
## start cronjobs for the queue
|
||||||
|
echo -e "Starting cron jobs."
|
||||||
|
crond -L /var/log/crond -l 5
|
||||||
|
|
||||||
|
echo -e "Starting supervisord."
|
||||||
|
exec "$@"
|
|
@ -20,12 +20,12 @@ supervisor.rpcinterface_factory = supervisor.rpcinterface:make_main_rpcinterface
|
||||||
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
|
serverurl=unix:///tmp/supervisor.sock ; use a unix:// URL for a unix socket
|
||||||
|
|
||||||
[program:php-fpm]
|
[program:php-fpm]
|
||||||
command=/usr/local/sbin/php-fpm -F
|
command=/usr/sbin/php-fpm7 -F
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=true
|
autorestart=true
|
||||||
|
|
||||||
[program:queue-worker]
|
[program:queue-worker]
|
||||||
command=/usr/local/bin/php /app/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
|
command=/usr/bin/php /app/artisan queue:work --queue=high,standard,low --sleep=3 --tries=3
|
||||||
user=nginx
|
user=nginx
|
||||||
autostart=true
|
autostart=true
|
||||||
autorestart=true
|
autorestart=true
|
|
@ -1,9 +1,9 @@
|
||||||
[www]
|
[pterodactyl]
|
||||||
|
|
||||||
user = nginx
|
user = nginx
|
||||||
group = nginx
|
group = nginx
|
||||||
|
|
||||||
listen = 127.0.0.1:9000
|
listen = /var/run/php/php-fpm7.2.sock
|
||||||
listen.owner = nginx
|
listen.owner = nginx
|
||||||
listen.group = nginx
|
listen.group = nginx
|
||||||
listen.mode = 0750
|
listen.mode = 0750
|
|
@ -0,0 +1,39 @@
|
||||||
|
APP_ENV=develop
|
||||||
|
APP_DEBUG=true
|
||||||
|
APP_KEY=SomeRandomString3232RandomString
|
||||||
|
APP_THEME=pterodactyl
|
||||||
|
APP_TIMEZONE=UTC
|
||||||
|
APP_CLEAR_TASKLOG=720
|
||||||
|
APP_DELETE_MINUTES=10
|
||||||
|
APP_URL=http://192.168.50.2/
|
||||||
|
|
||||||
|
DB_HOST=localhost
|
||||||
|
DB_PORT=3306
|
||||||
|
DB_DATABASE=panel
|
||||||
|
DB_USERNAME=pterodactyl
|
||||||
|
DB_PASSWORD=pterodactyl
|
||||||
|
|
||||||
|
CACHE_DRIVER=memcached
|
||||||
|
MEMCACHED_HOST=127.0.0.1
|
||||||
|
SESSION_DRIVER=database
|
||||||
|
|
||||||
|
MAIL_DRIVER=smtp
|
||||||
|
MAIL_HOST=127.0.0.1
|
||||||
|
MAIL_PORT=1025
|
||||||
|
MAIL_USERNAME=
|
||||||
|
MAIL_PASSWORD=
|
||||||
|
MAIL_ENCRYPTION=
|
||||||
|
MAIL_FROM=support@pterodactyl.io
|
||||||
|
|
||||||
|
API_PREFIX=api
|
||||||
|
API_VERSION=v1
|
||||||
|
API_DEBUG=true
|
||||||
|
|
||||||
|
QUEUE_DRIVER=database
|
||||||
|
QUEUE_HIGH=high
|
||||||
|
QUEUE_STANDARD=standard
|
||||||
|
QUEUE_LOW=low
|
||||||
|
|
||||||
|
SQS_KEY=aws-public
|
||||||
|
SQS_SECRET=aws-secret
|
||||||
|
SQS_QUEUE_PREFIX=aws-queue-prefix
|
|
@ -0,0 +1,13 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Mailhog
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# On some systems the user and group might be different.
|
||||||
|
# Some systems use `apache` as the user and group.
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
Restart=on-failure
|
||||||
|
ExecStart=/usr/bin/mailhog
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,189 @@
|
||||||
|
# MariaDB database server configuration file.
|
||||||
|
#
|
||||||
|
# You can copy this file to one of:
|
||||||
|
# - "/etc/mysql/my.cnf" to set global options,
|
||||||
|
# - "~/.my.cnf" to set user-specific options.
|
||||||
|
#
|
||||||
|
# One can use all long options that the program supports.
|
||||||
|
# Run program with --help to get a list of available options and with
|
||||||
|
# --print-defaults to see which it would actually understand and use.
|
||||||
|
#
|
||||||
|
# For explanations see
|
||||||
|
# http://dev.mysql.com/doc/mysql/en/server-system-variables.html
|
||||||
|
|
||||||
|
# This will be passed to all mysql clients
|
||||||
|
# It has been reported that passwords should be enclosed with ticks/quotes
|
||||||
|
# escpecially if they contain "#" chars...
|
||||||
|
# Remember to edit /etc/mysql/debian.cnf when changing the socket location.
|
||||||
|
[client]
|
||||||
|
port = 3306
|
||||||
|
socket = /var/run/mysqld/mysqld.sock
|
||||||
|
|
||||||
|
# Here is entries for some specific programs
|
||||||
|
# The following values assume you have at least 32M ram
|
||||||
|
|
||||||
|
# This was formally known as [safe_mysqld]. Both versions are currently parsed.
|
||||||
|
[mysqld_safe]
|
||||||
|
socket = /var/run/mysqld/mysqld.sock
|
||||||
|
nice = 0
|
||||||
|
|
||||||
|
[mysqld]
|
||||||
|
#
|
||||||
|
# * Basic Settings
|
||||||
|
#
|
||||||
|
user = mysql
|
||||||
|
pid-file = /var/run/mysqld/mysqld.pid
|
||||||
|
socket = /var/run/mysqld/mysqld.sock
|
||||||
|
port = 3306
|
||||||
|
basedir = /usr
|
||||||
|
datadir = /var/lib/mysql
|
||||||
|
tmpdir = /tmp
|
||||||
|
lc_messages_dir = /usr/share/mysql
|
||||||
|
lc_messages = en_US
|
||||||
|
skip-external-locking
|
||||||
|
#
|
||||||
|
# Instead of skip-networking the default is now to listen only on
|
||||||
|
# localhost which is more compatible and is not less secure.
|
||||||
|
bind-address = 0.0.0.0
|
||||||
|
#
|
||||||
|
# * Fine Tuning
|
||||||
|
#
|
||||||
|
max_connections = 100
|
||||||
|
connect_timeout = 5
|
||||||
|
wait_timeout = 600
|
||||||
|
max_allowed_packet = 16M
|
||||||
|
thread_cache_size = 128
|
||||||
|
sort_buffer_size = 4M
|
||||||
|
bulk_insert_buffer_size = 16M
|
||||||
|
tmp_table_size = 32M
|
||||||
|
max_heap_table_size = 32M
|
||||||
|
#
|
||||||
|
# * MyISAM
|
||||||
|
#
|
||||||
|
# This replaces the startup script and checks MyISAM tables if needed
|
||||||
|
# the first time they are touched. On error, make copy and try a repair.
|
||||||
|
myisam_recover_options = BACKUP
|
||||||
|
key_buffer_size = 128M
|
||||||
|
#open-files-limit = 2000
|
||||||
|
table_open_cache = 400
|
||||||
|
myisam_sort_buffer_size = 512M
|
||||||
|
concurrent_insert = 2
|
||||||
|
read_buffer_size = 2M
|
||||||
|
read_rnd_buffer_size = 1M
|
||||||
|
#
|
||||||
|
# * Query Cache Configuration
|
||||||
|
#
|
||||||
|
# Cache only tiny result sets, so we can fit more in the query cache.
|
||||||
|
query_cache_limit = 128K
|
||||||
|
query_cache_size = 64M
|
||||||
|
# for more write intensive setups, set to DEMAND or OFF
|
||||||
|
#query_cache_type = DEMAND
|
||||||
|
#
|
||||||
|
# * Logging and Replication
|
||||||
|
#
|
||||||
|
# Both location gets rotated by the cronjob.
|
||||||
|
# Be aware that this log type is a performance killer.
|
||||||
|
# As of 5.1 you can enable the log at runtime!
|
||||||
|
#general_log_file = /var/log/mysql/mysql.log
|
||||||
|
#general_log = 1
|
||||||
|
#
|
||||||
|
# Error logging goes to syslog due to /etc/mysql/conf.d/mysqld_safe_syslog.cnf.
|
||||||
|
#
|
||||||
|
# we do want to know about network errors and such
|
||||||
|
log_warnings = 2
|
||||||
|
#
|
||||||
|
# Enable the slow query log to see queries with especially long duration
|
||||||
|
#slow_query_log[={0|1}]
|
||||||
|
slow_query_log_file = /var/log/mysql/mariadb-slow.log
|
||||||
|
long_query_time = 10
|
||||||
|
#log_slow_rate_limit = 1000
|
||||||
|
log_slow_verbosity = query_plan
|
||||||
|
|
||||||
|
#log-queries-not-using-indexes
|
||||||
|
#log_slow_admin_statements
|
||||||
|
#
|
||||||
|
# The following can be used as easy to replay backup logs or for replication.
|
||||||
|
# note: if you are setting up a replication slave, see README.Debian about
|
||||||
|
# other settings you may need to change.
|
||||||
|
#server-id = 1
|
||||||
|
#report_host = master1
|
||||||
|
#auto_increment_increment = 2
|
||||||
|
#auto_increment_offset = 1
|
||||||
|
log_bin = /var/log/mysql/mariadb-bin
|
||||||
|
log_bin_index = /var/log/mysql/mariadb-bin.index
|
||||||
|
# not fab for performance, but safer
|
||||||
|
#sync_binlog = 1
|
||||||
|
expire_logs_days = 10
|
||||||
|
max_binlog_size = 100M
|
||||||
|
# slaves
|
||||||
|
#relay_log = /var/log/mysql/relay-bin
|
||||||
|
#relay_log_index = /var/log/mysql/relay-bin.index
|
||||||
|
#relay_log_info_file = /var/log/mysql/relay-bin.info
|
||||||
|
#log_slave_updates
|
||||||
|
#read_only
|
||||||
|
#
|
||||||
|
# If applications support it, this stricter sql_mode prevents some
|
||||||
|
# mistakes like inserting invalid dates etc.
|
||||||
|
#sql_mode = NO_ENGINE_SUBSTITUTION,TRADITIONAL
|
||||||
|
#
|
||||||
|
# * InnoDB
|
||||||
|
#
|
||||||
|
# InnoDB is enabled by default with a 10MB datafile in /var/lib/mysql/.
|
||||||
|
# Read the manual for more InnoDB related options. There are many!
|
||||||
|
default_storage_engine = InnoDB
|
||||||
|
# you can't just change log file size, requires special procedure
|
||||||
|
#innodb_log_file_size = 50M
|
||||||
|
innodb_buffer_pool_size = 256M
|
||||||
|
innodb_log_buffer_size = 8M
|
||||||
|
innodb_file_per_table = 1
|
||||||
|
innodb_open_files = 400
|
||||||
|
innodb_io_capacity = 400
|
||||||
|
innodb_flush_method = O_DIRECT
|
||||||
|
#
|
||||||
|
# * Security Features
|
||||||
|
#
|
||||||
|
# Read the manual, too, if you want chroot!
|
||||||
|
# chroot = /var/lib/mysql/
|
||||||
|
#
|
||||||
|
# For generating SSL certificates I recommend the OpenSSL GUI "tinyca".
|
||||||
|
#
|
||||||
|
# ssl-ca=/etc/mysql/cacert.pem
|
||||||
|
# ssl-cert=/etc/mysql/server-cert.pem
|
||||||
|
# ssl-key=/etc/mysql/server-key.pem
|
||||||
|
|
||||||
|
#
|
||||||
|
# * Galera-related settings
|
||||||
|
#
|
||||||
|
[galera]
|
||||||
|
# Mandatory settings
|
||||||
|
#wsrep_on=ON
|
||||||
|
#wsrep_provider=
|
||||||
|
#wsrep_cluster_address=
|
||||||
|
#binlog_format=row
|
||||||
|
#default_storage_engine=InnoDB
|
||||||
|
#innodb_autoinc_lock_mode=2
|
||||||
|
#
|
||||||
|
# Allow server to accept connections on all interfaces.
|
||||||
|
#
|
||||||
|
#bind-address=0.0.0.0
|
||||||
|
#
|
||||||
|
# Optional setting
|
||||||
|
#wsrep_slave_threads=1
|
||||||
|
#innodb_flush_log_at_trx_commit=0
|
||||||
|
|
||||||
|
[mysqldump]
|
||||||
|
quick
|
||||||
|
quote-names
|
||||||
|
max_allowed_packet = 16M
|
||||||
|
|
||||||
|
[mysql]
|
||||||
|
#no-auto-rehash # faster start of mysql but no tab completion
|
||||||
|
|
||||||
|
[isamchk]
|
||||||
|
key_buffer = 16M
|
||||||
|
|
||||||
|
#
|
||||||
|
# * IMPORTANT: Additional settings that can override those from this file!
|
||||||
|
# The files must end with '.cnf', otherwise they'll be ignored.
|
||||||
|
#
|
||||||
|
!includedir /etc/mysql/conf.d/
|
|
@ -0,0 +1,17 @@
|
||||||
|
#####################################################
|
||||||
|
Pterodactyl Panel Vagrant VM
|
||||||
|
|
||||||
|
Install: /var/www/html/pterodactyl
|
||||||
|
Ports:
|
||||||
|
Panel: 80 (50080 on host)
|
||||||
|
MailHog: 8025 (58025 on host)
|
||||||
|
MySQL: 3306 (53306 on host)
|
||||||
|
|
||||||
|
Default panel users:
|
||||||
|
user: admin passwd: Ptero123 (admin user)
|
||||||
|
user: user passwd: Ptero123 (standard user)
|
||||||
|
|
||||||
|
MySQL is accessible using root/pterodactyl or pterodactyl/pterodactyl
|
||||||
|
|
||||||
|
Service for pteroq and mailhog are running
|
||||||
|
#####################################################
|
|
@ -0,0 +1,84 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
echo "Provisioning development environment for Pterodactyl Panel."
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/motd.txt /etc/motd
|
||||||
|
chmod -x /etc/update-motd.d/10-help-text /etc/update-motd.d/51-cloudguest
|
||||||
|
|
||||||
|
apt-get install -y software-properties-common > /dev/null
|
||||||
|
|
||||||
|
echo "Add the ondrej/php ppa repository"
|
||||||
|
add-apt-repository -y ppa:ondrej/php > /dev/null
|
||||||
|
echo "Add the mariadb repository"
|
||||||
|
curl -sS https://downloads.mariadb.com/MariaDB/mariadb_repo_setup | bash > /dev/null
|
||||||
|
|
||||||
|
apt-get update > /dev/null
|
||||||
|
|
||||||
|
echo "Install the dependencies"
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
# set the mariadb root password because mariadb asks for it
|
||||||
|
debconf-set-selections <<< 'mariadb-server-5.5 mysql-server/root_password password pterodactyl'
|
||||||
|
debconf-set-selections <<< 'mariadb-server-5.5 mysql-server/root_password_again password pterodactyl'
|
||||||
|
# actually install
|
||||||
|
apt-get install -y php7.2 php7.2-cli php7.2-gd php7.2-mysql php7.2-pdo php7.2-mbstring php7.2-tokenizer php7.2-bcmath php7.2-xml php7.2-fpm php7.2-memcached php7.2-curl php7.2-zip php-xdebug mariadb-server nginx curl tar unzip git memcached > /dev/null
|
||||||
|
|
||||||
|
echo "Install composer"
|
||||||
|
curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
|
echo "Install and run mailhog"
|
||||||
|
curl -sL -o /usr/bin/mailhog https://github.com/mailhog/MailHog/releases/download/v1.0.0/MailHog_linux_amd64
|
||||||
|
chmod +x /usr/bin/mailhog
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/mailhog.service /etc/systemd/system/
|
||||||
|
systemctl enable mailhog.service
|
||||||
|
systemctl start mailhog
|
||||||
|
|
||||||
|
echo "Configure xDebug"
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/xdebug.ini /etc/php/7.2/mods-available/
|
||||||
|
systemctl restart php7.2-fpm
|
||||||
|
|
||||||
|
echo "Configure nginx"
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/pterodactyl.conf /etc/nginx/sites-available/
|
||||||
|
rm /etc/nginx/sites-available/default
|
||||||
|
ln -s /etc/nginx/sites-available/pterodactyl.conf /etc/nginx/sites-enabled/pterodactyl.conf
|
||||||
|
systemctl restart nginx
|
||||||
|
|
||||||
|
echo "Setup database"
|
||||||
|
# Replace default config with custom one to bind mysql to 0.0.0.0 to make it accessible from the host
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/mariadb.cnf /etc/mysql/my.cnf
|
||||||
|
systemctl restart mariadb
|
||||||
|
mysql -u root -ppterodactyl << SQL
|
||||||
|
CREATE DATABASE panel;
|
||||||
|
GRANT ALL PRIVILEGES ON panel.* TO 'pterodactyl'@'%' IDENTIFIED BY 'pterodactyl' WITH GRANT OPTION;
|
||||||
|
GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY 'pterodactyl' WITH GRANT OPTION;
|
||||||
|
FLUSH PRIVILEGES;
|
||||||
|
SQL
|
||||||
|
|
||||||
|
echo "Setup pterodactyl queue worker service"
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/pteroq.service /etc/systemd/system/
|
||||||
|
systemctl enable pteroq.service
|
||||||
|
|
||||||
|
|
||||||
|
echo "Setup panel with base settings"
|
||||||
|
cp /var/www/html/pterodactyl/.dev/vagrant/.env.vagrant /var/www/html/pterodactyl/.env
|
||||||
|
cd /var/www/html/pterodactyl
|
||||||
|
chmod -R 755 storage/* bootstrap/cache
|
||||||
|
composer install --no-progress
|
||||||
|
php artisan key:generate --force
|
||||||
|
php artisan migrate
|
||||||
|
php artisan db:seed
|
||||||
|
php artisan p:user:make --name-first Test --name-last Admin --username admin --email testadmin@pterodactyl.io --password Ptero123 --admin 1
|
||||||
|
php artisan p:user:make --name-first Test --name-last User --username user --email testuser@pterodactyl.io --password Ptero123 --admin 0
|
||||||
|
|
||||||
|
echo "Add queue cronjob and start queue worker"
|
||||||
|
(crontab -l 2>/dev/null; echo "* * * * * php /var/www/html/pterodactyl/artisan schedule:run >> /dev/null 2>&1") | crontab -
|
||||||
|
systemctl start pteroq
|
||||||
|
|
||||||
|
echo " ----------------"
|
||||||
|
echo "Provisioning is completed."
|
||||||
|
echo "The panel should be available at http://localhost:50080/"
|
||||||
|
echo "You may use the default admin user to login: admin/Ptero123"
|
||||||
|
echo "A normal user has also been created: user/Ptero123"
|
||||||
|
echo "MailHog is available at http://localhost:58025/"
|
||||||
|
echo "Connect to the database using root/pterodactyl or pterodactyl/pterodactyl on localhost:53306"
|
||||||
|
echo "If you want to access the panel using http://pterodactyl.app you can use the vagrant-dns plugin"
|
||||||
|
echo "Install it with 'vagrant plugin install vagrant-dns', then run 'vagrant dns --install' once"
|
||||||
|
echo "On first use you'll have to manually start vagrant-dns with 'vagrant dns --start'"
|
|
@ -0,0 +1,51 @@
|
||||||
|
# If using Ubuntu this file should be placed in:
|
||||||
|
# /etc/nginx/sites-available/
|
||||||
|
#
|
||||||
|
# If using CentOS this file should be placed in:
|
||||||
|
# /etc/nginx/conf.d/
|
||||||
|
#
|
||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
server_name 0.0.0.0;
|
||||||
|
|
||||||
|
root /var/www/html/pterodactyl/public;
|
||||||
|
index index.html index.htm index.php;
|
||||||
|
charset utf-8;
|
||||||
|
|
||||||
|
location / {
|
||||||
|
try_files $uri $uri/ /index.php?$query_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
location = /favicon.ico { access_log off; log_not_found off; }
|
||||||
|
location = /robots.txt { access_log off; log_not_found off; }
|
||||||
|
|
||||||
|
access_log off;
|
||||||
|
error_log /var/log/nginx/pterodactyl.app-error.log error;
|
||||||
|
|
||||||
|
# allow larger file uploads and longer script runtimes
|
||||||
|
client_max_body_size 100m;
|
||||||
|
client_body_timeout 120s;
|
||||||
|
|
||||||
|
sendfile off;
|
||||||
|
|
||||||
|
location ~ \.php$ {
|
||||||
|
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
||||||
|
# the fastcgi_pass path needs to be changed accordingly when using CentOS
|
||||||
|
fastcgi_pass unix:/var/run/php/php7.2-fpm.sock;
|
||||||
|
fastcgi_index index.php;
|
||||||
|
include fastcgi_params;
|
||||||
|
fastcgi_param PHP_VALUE "upload_max_filesize = 100M \n post_max_size=100M";
|
||||||
|
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
||||||
|
fastcgi_param HTTP_PROXY "";
|
||||||
|
fastcgi_intercept_errors off;
|
||||||
|
fastcgi_buffer_size 16k;
|
||||||
|
fastcgi_buffers 4 16k;
|
||||||
|
fastcgi_connect_timeout 300;
|
||||||
|
fastcgi_send_timeout 300;
|
||||||
|
fastcgi_read_timeout 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
location ~ /\.ht {
|
||||||
|
deny all;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,20 @@
|
||||||
|
# Pterodactyl Queue Worker File
|
||||||
|
# ----------------------------------
|
||||||
|
# File should be placed in:
|
||||||
|
# /etc/systemd/system
|
||||||
|
#
|
||||||
|
# nano /etc/systemd/system/pteroq.service
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Pterodactyl Queue Worker
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
# On some systems the user and group might be different.
|
||||||
|
# Some systems use `apache` as the user and group.
|
||||||
|
User=www-data
|
||||||
|
Group=www-data
|
||||||
|
Restart=on-failure
|
||||||
|
ExecStart=/usr/bin/php /var/www/html/pterodactyl/artisan queue:work database --queue=high,standard,low --sleep=3 --tries=3
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
|
@ -0,0 +1,10 @@
|
||||||
|
zend_extension=xdebug.so
|
||||||
|
|
||||||
|
xdebug.remote_enable=1
|
||||||
|
xdebug.remote_connect_back=1
|
||||||
|
xdebug.remote_port=9000
|
||||||
|
xdebug.scream=0
|
||||||
|
xdebug.show_local_vars=1
|
||||||
|
xdebug.idekey=PHPSTORM
|
||||||
|
|
||||||
|
xdebug.remote_log=/tmp/xdebug.log
|
|
@ -1,17 +1,12 @@
|
||||||
root = true
|
root = true
|
||||||
|
|
||||||
[*]
|
[*]
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
indent_style = space
|
indent_style = space
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
tab_width = 4
|
|
||||||
end_of_line = lf
|
|
||||||
charset = utf-8
|
charset = utf-8
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
insert_final_newline = true
|
|
||||||
|
|
||||||
[*.md]
|
[*.md]
|
||||||
trim_trailing_whitespace = false
|
trim_trailing_whitespace = false
|
||||||
|
|
||||||
[*.{md,nix,yml,yaml}]
|
|
||||||
indent_size = 2
|
|
||||||
tab_width = 2
|
|
||||||
|
|
37
.env.example
37
.env.example
|
@ -2,43 +2,30 @@ APP_ENV=production
|
||||||
APP_DEBUG=false
|
APP_DEBUG=false
|
||||||
APP_KEY=
|
APP_KEY=
|
||||||
APP_THEME=pterodactyl
|
APP_THEME=pterodactyl
|
||||||
APP_TIMEZONE=UTC
|
APP_TIMEZONE=America/New_York
|
||||||
APP_URL=http://panel.example.com
|
APP_CLEAR_TASKLOG=720
|
||||||
APP_LOCALE=en
|
APP_DELETE_MINUTES=10
|
||||||
APP_ENVIRONMENT_ONLY=true
|
APP_ENVIRONMENT_ONLY=true
|
||||||
|
|
||||||
LOG_CHANNEL=daily
|
LOG_CHANNEL=daily
|
||||||
LOG_DEPRECATIONS_CHANNEL=null
|
APP_LOCALE=en
|
||||||
LOG_LEVEL=debug
|
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
|
||||||
DB_HOST=127.0.0.1
|
DB_HOST=127.0.0.1
|
||||||
DB_PORT=3306
|
DB_PORT=3306
|
||||||
DB_DATABASE=panel
|
DB_DATABASE=panel
|
||||||
DB_USERNAME=pterodactyl
|
DB_USERNAME=pterodactyl
|
||||||
DB_PASSWORD=
|
DB_PASSWORD=
|
||||||
|
|
||||||
REDIS_HOST=127.0.0.1
|
|
||||||
REDIS_PASSWORD=null
|
|
||||||
REDIS_PORT=6379
|
|
||||||
|
|
||||||
CACHE_DRIVER=file
|
|
||||||
QUEUE_CONNECTION=redis
|
|
||||||
SESSION_DRIVER=file
|
|
||||||
|
|
||||||
HASHIDS_SALT=
|
HASHIDS_SALT=
|
||||||
HASHIDS_LENGTH=8
|
HASHIDS_LENGTH=8
|
||||||
|
|
||||||
MAIL_MAILER=smtp
|
MAIL_DRIVER=smtp
|
||||||
MAIL_HOST=smtp.example.com
|
MAIL_HOST=mailtrap.io
|
||||||
MAIL_PORT=25
|
MAIL_PORT=2525
|
||||||
MAIL_USERNAME=
|
MAIL_USERNAME=
|
||||||
MAIL_PASSWORD=
|
MAIL_PASSWORD=
|
||||||
MAIL_ENCRYPTION=tls
|
MAIL_ENCRYPTION=tls
|
||||||
MAIL_FROM_ADDRESS=no-reply@example.com
|
MAIL_FROM=no-reply@example.com
|
||||||
MAIL_FROM_NAME="Pterodactyl Panel"
|
|
||||||
# You should set this to your domain to prevent it defaulting to 'localhost', causing
|
QUEUE_HIGH=high
|
||||||
# mail servers such as Gmail to reject your mail.
|
QUEUE_STANDARD=standard
|
||||||
#
|
QUEUE_LOW=low
|
||||||
# @see: https://github.com/pterodactyl/panel/pull/3110
|
|
||||||
# MAIL_EHLO_DOMAIN=panel.example.com
|
|
|
@ -4,13 +4,11 @@ APP_KEY=SomeRandomString3232RandomString
|
||||||
APP_THEME=pterodactyl
|
APP_THEME=pterodactyl
|
||||||
APP_TIMEZONE=UTC
|
APP_TIMEZONE=UTC
|
||||||
APP_URL=http://localhost/
|
APP_URL=http://localhost/
|
||||||
APP_ENVIRONMENT_ONLY=true
|
|
||||||
|
|
||||||
DB_CONNECTION=mysql
|
TESTING_DB_HOST=127.0.0.1
|
||||||
DB_HOST=127.0.0.1
|
TESTING_DB_DATABASE=travis
|
||||||
DB_DATABASE=testing
|
TESTING_DB_USERNAME=root
|
||||||
DB_USERNAME=root
|
TESTING_DB_PASSWORD=""
|
||||||
DB_PASSWORD=
|
|
||||||
|
|
||||||
CACHE_DRIVER=array
|
CACHE_DRIVER=array
|
||||||
SESSION_DRIVER=array
|
SESSION_DRIVER=array
|
||||||
|
@ -18,3 +16,4 @@ MAIL_DRIVER=array
|
||||||
QUEUE_DRIVER=sync
|
QUEUE_DRIVER=sync
|
||||||
|
|
||||||
HASHIDS_SALT=test123
|
HASHIDS_SALT=test123
|
||||||
|
APP_ENVIRONMENT_ONLY=true
|
|
@ -1,6 +0,0 @@
|
||||||
public
|
|
||||||
node_modules
|
|
||||||
resources/views
|
|
||||||
babel.config.js
|
|
||||||
tailwind.config.js
|
|
||||||
webpack.config.js
|
|
51
.eslintrc.js
51
.eslintrc.js
|
@ -1,51 +0,0 @@
|
||||||
/** @type {import('eslint').Linter.Config} */
|
|
||||||
module.exports = {
|
|
||||||
parser: '@typescript-eslint/parser',
|
|
||||||
parserOptions: {
|
|
||||||
ecmaVersion: 6,
|
|
||||||
ecmaFeatures: {
|
|
||||||
jsx: true,
|
|
||||||
},
|
|
||||||
project: './tsconfig.json',
|
|
||||||
tsconfigRootDir: './',
|
|
||||||
},
|
|
||||||
settings: {
|
|
||||||
react: {
|
|
||||||
pragma: 'React',
|
|
||||||
version: 'detect',
|
|
||||||
},
|
|
||||||
linkComponents: [
|
|
||||||
{ name: 'Link', linkAttribute: 'to' },
|
|
||||||
{ name: 'NavLink', linkAttribute: 'to' },
|
|
||||||
],
|
|
||||||
},
|
|
||||||
env: {
|
|
||||||
browser: true,
|
|
||||||
es6: true,
|
|
||||||
},
|
|
||||||
plugins: ['react', 'react-hooks', 'prettier', '@typescript-eslint'],
|
|
||||||
extends: [
|
|
||||||
// 'standard',
|
|
||||||
'eslint:recommended',
|
|
||||||
'plugin:react/recommended',
|
|
||||||
'plugin:@typescript-eslint/recommended',
|
|
||||||
'plugin:jest-dom/recommended',
|
|
||||||
],
|
|
||||||
rules: {
|
|
||||||
eqeqeq: 'error',
|
|
||||||
'prettier/prettier': ['error', {}, { usePrettierrc: true }],
|
|
||||||
// TypeScript can infer this significantly better than eslint ever can.
|
|
||||||
'react/prop-types': 0,
|
|
||||||
'react/display-name': 0,
|
|
||||||
'@typescript-eslint/no-explicit-any': 0,
|
|
||||||
'@typescript-eslint/no-non-null-assertion': 0,
|
|
||||||
// This setup is required to avoid a spam of errors when running eslint about React being
|
|
||||||
// used before it is defined.
|
|
||||||
//
|
|
||||||
// @see https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/no-use-before-define.md#how-to-use
|
|
||||||
'no-use-before-define': 0,
|
|
||||||
'@typescript-eslint/no-use-before-define': 'warn',
|
|
||||||
'@typescript-eslint/no-unused-vars': ['warn', { argsIgnorePattern: '^_', varsIgnorePattern: '^_' }],
|
|
||||||
'@typescript-eslint/ban-ts-comment': ['error', { 'ts-expect-error': 'allow-with-description' }],
|
|
||||||
},
|
|
||||||
};
|
|
|
@ -1 +0,0 @@
|
||||||
github: [matthewpi]
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
---
|
||||||
|
name: "\U0001F41B Bug Report"
|
||||||
|
about: For reporting code or design bugs with the software. DO NOT REPORT APACHE/NGINX/PHP CONFIGURATION ISSUES.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
DO NOT REPORT ISSUES CONFIGURING: SSL, PHP, APACHE, NGINX, YOUR MACHINE, SSH, SFTP, ETC. ON THIS GITHUB TRACKER.
|
||||||
|
|
||||||
|
For assistance installating this software, as well as debugging issues with dependencies, please use our discord server: https://discord.gg/pterodactyl
|
||||||
|
|
||||||
|
You MUST complete all of the below information when reporting a bug, failure to do so will result in closure of your issue. PLEASE stop spamming our tracker with "bugs" that are not related to this project.
|
||||||
|
|
||||||
|
**STOP: READ FIRST, AND THEN DELETE THE ABOVE LINES**
|
||||||
|
|
||||||
|
**Background (please complete the following information):**
|
||||||
|
* Panel or Daemon:
|
||||||
|
* Version of Panel/Daemon:
|
||||||
|
* Server's OS:
|
||||||
|
* Your Computer's OS & Browser:
|
||||||
|
|
||||||
|
**Describe the bug**
|
||||||
|
A clear and concise description of what the bug is.
|
||||||
|
Please provide additional information too, depending on what you have issues with:
|
||||||
|
Panel: `php -v` (the php version in use).
|
||||||
|
Daemon: `uname -a` and `docker info` (your kernel version and information regarding docker)
|
||||||
|
|
||||||
|
**To Reproduce**
|
||||||
|
Steps to reproduce the behavior:
|
||||||
|
1. Go to '...'
|
||||||
|
2. Click on '....'
|
||||||
|
3. Scroll down to '....'
|
||||||
|
4. See error
|
||||||
|
|
||||||
|
**Expected behavior**
|
||||||
|
A clear and concise description of what you expected to happen. If applicable, add screenshots or a recording to help explain your problem.
|
|
@ -0,0 +1,17 @@
|
||||||
|
---
|
||||||
|
name: "\U0001F680 Feature Request"
|
||||||
|
about: Suggest an idea for this project
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Is your feature request related to a problem? Please describe.**
|
||||||
|
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
|
||||||
|
|
||||||
|
**Describe the solution you'd like**
|
||||||
|
A clear and concise description of what you want to happen.
|
||||||
|
|
||||||
|
**Describe alternatives you've considered**
|
||||||
|
A clear and concise description of any alternative solutions or features you've considered.
|
||||||
|
|
||||||
|
**Additional context**
|
||||||
|
Add any other context or screenshots about the feature request here.
|
|
@ -0,0 +1,14 @@
|
||||||
|
---
|
||||||
|
name: "⛔ Installation Help"
|
||||||
|
about: 'Visit our Discord for installation help: https://pterodactyl.io/discord'
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
We use GitHub issues only to discuss about Pterodactyl bugs and new features. For
|
||||||
|
this kind of questions about using Pterodactyl, please visit our Discord for assistance: https://pterodactyl.io/discord
|
||||||
|
|
||||||
|
DO NOT REPORT ISSUES CONFIGURING: SSL, PHP, APACHE, NGINX, YOUR MACHINE, SSH, SFTP, ETC. ON THIS GITHUB TRACKER.
|
||||||
|
|
||||||
|
For assistance installating this software, as well as debugging issues with dependencies, please use our discord server: https://discord.gg/pterodactyl
|
||||||
|
|
||||||
|
PLEASE stop spamming our tracker with "bugs" that are not related to this project.
|
|
@ -1,87 +0,0 @@
|
||||||
name: Bug Report
|
|
||||||
description: Something isn't working quite right in the software.
|
|
||||||
labels: [not confirmed]
|
|
||||||
body:
|
|
||||||
- type: markdown
|
|
||||||
attributes:
|
|
||||||
value: |
|
|
||||||
Bug reports should only be used for reporting issues with how the software works. For assistance installing this software, as well as debugging issues with dependencies, please use our [Discord server](https://discord.gg/pterodactyl).
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Current Behavior
|
|
||||||
description: Please provide a clear & concise description of the issue.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Expected Behavior
|
|
||||||
description: Please describe what you expected to happen.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Steps to Reproduce
|
|
||||||
description: Please be as detailed as possible when providing steps to reproduce, failure to provide steps will result in this issue being closed.
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: panel-version
|
|
||||||
attributes:
|
|
||||||
label: Panel Version
|
|
||||||
description: Version number of your Panel (latest is not a version)
|
|
||||||
placeholder: 1.4.0
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: wings-version
|
|
||||||
attributes:
|
|
||||||
label: Wings Version
|
|
||||||
description: Version number of your Wings (latest is not a version)
|
|
||||||
placeholder: 1.4.2
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: egg-details
|
|
||||||
attributes:
|
|
||||||
label: Games and/or Eggs Affected
|
|
||||||
description: Please include the specific game(s) or egg(s) you are running into this bug with.
|
|
||||||
placeholder: Minecraft (Paper), Minecraft (Forge)
|
|
||||||
|
|
||||||
- type: input
|
|
||||||
id: docker-image
|
|
||||||
attributes:
|
|
||||||
label: Docker Image
|
|
||||||
description: The specific Docker image you are using for the game(s) above.
|
|
||||||
placeholder: ghcr.io/pterodactyl/yolks:java_17
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
id: panel-logs
|
|
||||||
attributes:
|
|
||||||
label: Error Logs
|
|
||||||
description: |
|
|
||||||
Run the following command to collect logs on your system.
|
|
||||||
|
|
||||||
Wings: `sudo wings diagnostics`
|
|
||||||
Panel: `tail -n 150 /var/www/pterodactyl/storage/logs/laravel-$(date +%F).log | nc pteropaste.com 99`
|
|
||||||
placeholder: "https://pteropaste.com/a1h6z"
|
|
||||||
render: bash
|
|
||||||
validations:
|
|
||||||
required: false
|
|
||||||
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Is there an existing issue for this?
|
|
||||||
description: Please [search here](https://github.com/pterodactyl/panel/issues) to see if an issue already exists for your problem.
|
|
||||||
options:
|
|
||||||
- label: I have searched the existing issues before opening this issue.
|
|
||||||
required: true
|
|
||||||
- label: I have provided all relevant details, including the specific game and Docker images I am using if this issue is related to running a server.
|
|
||||||
required: true
|
|
||||||
- label: I have checked in the Discord server and believe this is a bug with the software, and not a configuration issue with my specific system.
|
|
||||||
required: true
|
|
|
@ -1,8 +0,0 @@
|
||||||
blank_issues_enabled: true
|
|
||||||
contact_links:
|
|
||||||
- name: Installation Help
|
|
||||||
url: https://discord.gg/pterodactyl
|
|
||||||
about: Please visit our Discord for help with your installation.
|
|
||||||
- name: General Question
|
|
||||||
url: https://discord.gg/pterodactyl
|
|
||||||
about: Please visit our Discord for general questions about Pterodactyl.
|
|
|
@ -1,32 +0,0 @@
|
||||||
name: Feature Request
|
|
||||||
description: Suggest a new feature or improvement for the software.
|
|
||||||
labels: [feature request]
|
|
||||||
body:
|
|
||||||
- type: checkboxes
|
|
||||||
attributes:
|
|
||||||
label: Is there an existing feature request for this?
|
|
||||||
description: Please [search here](https://github.com/pterodactyl/panel/issues?q=is%3Aissue) to see if someone else has already suggested this.
|
|
||||||
options:
|
|
||||||
- label: I have searched the existing issues before opening this feature request.
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Describe the feature you would like to see.
|
|
||||||
description: "A clear & concise description of the feature you'd like to have added, and what issues it would solve."
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Describe the solution you'd like.
|
|
||||||
description: "You must explain how you'd like to see this feature implemented. Technical implementation details are not necessary, rather an idea of how you'd like to see this feature used."
|
|
||||||
validations:
|
|
||||||
required: true
|
|
||||||
|
|
||||||
- type: textarea
|
|
||||||
attributes:
|
|
||||||
label: Additional context to this request.
|
|
||||||
description: "Add any other context or screenshots about the feature request."
|
|
||||||
validations:
|
|
||||||
required: false
|
|
|
@ -1,81 +0,0 @@
|
||||||
#!/bin/ash -e
|
|
||||||
cd /app
|
|
||||||
|
|
||||||
mkdir -p /var/log/panel/logs/ /var/log/supervisord/ /var/log/nginx/ /var/log/php7/ \
|
|
||||||
&& chmod 777 /var/log/panel/logs/ \
|
|
||||||
&& ln -s /app/storage/logs/ /var/log/panel/
|
|
||||||
|
|
||||||
## check for .env file and generate app keys if missing
|
|
||||||
if [ -f /app/var/.env ]; then
|
|
||||||
echo "external vars exist."
|
|
||||||
rm -rf /app/.env
|
|
||||||
ln -s /app/var/.env /app/
|
|
||||||
else
|
|
||||||
echo "external vars don't exist."
|
|
||||||
rm -rf /app/.env
|
|
||||||
touch /app/var/.env
|
|
||||||
|
|
||||||
## manually generate a key because key generate --force fails
|
|
||||||
if [ -z $APP_KEY ]; then
|
|
||||||
echo -e "Generating key."
|
|
||||||
APP_KEY=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 32 | head -n 1)
|
|
||||||
echo -e "Generated app key: $APP_KEY"
|
|
||||||
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
|
|
||||||
else
|
|
||||||
echo -e "APP_KEY exists in environment, using that."
|
|
||||||
echo -e "APP_KEY=$APP_KEY" > /app/var/.env
|
|
||||||
fi
|
|
||||||
|
|
||||||
ln -s /app/var/.env /app/
|
|
||||||
fi
|
|
||||||
|
|
||||||
echo "Checking if https is required."
|
|
||||||
if [ -f /etc/nginx/http.d/panel.conf ]; then
|
|
||||||
echo "Using nginx config already in place."
|
|
||||||
if [ $LE_EMAIL ]; then
|
|
||||||
echo "Checking for cert update"
|
|
||||||
certbot certonly -d $(echo $APP_URL | sed 's~http[s]*://~~g') --standalone -m $LE_EMAIL --agree-tos -n
|
|
||||||
else
|
|
||||||
echo "No letsencrypt email is set"
|
|
||||||
fi
|
|
||||||
else
|
|
||||||
echo "Checking if letsencrypt email is set."
|
|
||||||
if [ -z $LE_EMAIL ]; then
|
|
||||||
echo "No letsencrypt email is set using http config."
|
|
||||||
cp .github/docker/default.conf /etc/nginx/http.d/panel.conf
|
|
||||||
else
|
|
||||||
echo "writing ssl config"
|
|
||||||
cp .github/docker/default_ssl.conf /etc/nginx/http.d/panel.conf
|
|
||||||
echo "updating ssl config for domain"
|
|
||||||
sed -i "s|<domain>|$(echo $APP_URL | sed 's~http[s]*://~~g')|g" /etc/nginx/http.d/panel.conf
|
|
||||||
echo "generating certs"
|
|
||||||
certbot certonly -d $(echo $APP_URL | sed 's~http[s]*://~~g') --standalone -m $LE_EMAIL --agree-tos -n
|
|
||||||
fi
|
|
||||||
echo "Removing the default nginx config"
|
|
||||||
rm -rf /etc/nginx/http.d/default.conf
|
|
||||||
fi
|
|
||||||
|
|
||||||
if [[ -z $DB_PORT ]]; then
|
|
||||||
echo -e "DB_PORT not specified, defaulting to 3306"
|
|
||||||
DB_PORT=3306
|
|
||||||
fi
|
|
||||||
|
|
||||||
## check for DB up before starting the panel
|
|
||||||
echo "Checking database status."
|
|
||||||
until nc -z -v -w30 $DB_HOST $DB_PORT
|
|
||||||
do
|
|
||||||
echo "Waiting for database connection..."
|
|
||||||
# wait for 1 seconds before check again
|
|
||||||
sleep 1
|
|
||||||
done
|
|
||||||
|
|
||||||
## make sure the db is set up
|
|
||||||
echo -e "Migrating and Seeding D.B"
|
|
||||||
php artisan migrate --seed --force
|
|
||||||
|
|
||||||
## start cronjobs for the queue
|
|
||||||
echo -e "Starting cron jobs."
|
|
||||||
crond -L /var/log/crond -l 5
|
|
||||||
|
|
||||||
echo -e "Starting supervisord."
|
|
||||||
exec "$@"
|
|
|
@ -1,35 +0,0 @@
|
||||||
name: Build
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "develop"
|
|
||||||
- "1.0-develop"
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "develop"
|
|
||||||
- "1.0-develop"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
ui:
|
|
||||||
name: UI
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
node-version: [16]
|
|
||||||
steps:
|
|
||||||
- name: Code Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: ${{ matrix.node-version }}
|
|
||||||
cache: "yarn"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: yarn build:production
|
|
|
@ -1,72 +0,0 @@
|
||||||
name: Tests
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "develop"
|
|
||||||
- "1.0-develop"
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "develop"
|
|
||||||
- "1.0-develop"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
tests:
|
|
||||||
name: Tests
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
php: [8.1, 8.2]
|
|
||||||
database: ["mariadb:10.2", "mysql:8"]
|
|
||||||
services:
|
|
||||||
database:
|
|
||||||
image: ${{ matrix.database }}
|
|
||||||
env:
|
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: yes
|
|
||||||
MYSQL_DATABASE: testing
|
|
||||||
ports:
|
|
||||||
- 3306
|
|
||||||
options: --health-cmd="mysqladmin ping" --health-interval=10s --health-timeout=5s --health-retries=3
|
|
||||||
steps:
|
|
||||||
- name: Code Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Get cache directory
|
|
||||||
id: composer-cache
|
|
||||||
run: |
|
|
||||||
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
|
||||||
|
|
||||||
- name: Cache
|
|
||||||
uses: actions/cache@v3
|
|
||||||
with:
|
|
||||||
path: ${{ steps.composer-cache.outputs.dir }}
|
|
||||||
key: ${{ runner.os }}-composer-${{ matrix.php }}-${{ hashFiles('**/composer.lock') }}
|
|
||||||
restore-keys: |
|
|
||||||
${{ runner.os }}-composer-${{ matrix.php }}-
|
|
||||||
|
|
||||||
- name: Setup PHP
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: ${{ matrix.php }}
|
|
||||||
extensions: bcmath, cli, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
|
|
||||||
tools: composer:v2
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Setup .env
|
|
||||||
run: cp .env.ci .env
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
|
|
||||||
|
|
||||||
- name: Unit tests
|
|
||||||
run: vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit
|
|
||||||
if: ${{ always() }}
|
|
||||||
env:
|
|
||||||
DB_HOST: UNIT_NO_DB
|
|
||||||
|
|
||||||
- name: Integration tests
|
|
||||||
run: vendor/bin/phpunit tests/Integration
|
|
||||||
env:
|
|
||||||
DB_PORT: ${{ job.services.database.ports[3306] }}
|
|
||||||
DB_USERNAME: root
|
|
|
@ -1,69 +0,0 @@
|
||||||
name: Docker
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
- 1.0-develop
|
|
||||||
- release/v1.11.5
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- develop
|
|
||||||
- 1.0-develop
|
|
||||||
release:
|
|
||||||
types:
|
|
||||||
- published
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
push:
|
|
||||||
name: Push
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
if: "!contains(github.ref, 'develop') || (!contains(github.event.head_commit.message, 'skip docker') && !contains(github.event.head_commit.message, 'docker skip'))"
|
|
||||||
steps:
|
|
||||||
- name: Code checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Docker metadata
|
|
||||||
id: docker_meta
|
|
||||||
uses: docker/metadata-action@v4
|
|
||||||
with:
|
|
||||||
images: ghcr.io/nookure/nooktheme
|
|
||||||
flavor: |
|
|
||||||
latest=false
|
|
||||||
tags: |
|
|
||||||
type=raw,value=latest,enable=${{ github.event_name == 'release' && github.event.action == 'published' && github.event.release.prerelease == false }}
|
|
||||||
type=ref,event=tag
|
|
||||||
type=ref,event=branch
|
|
||||||
|
|
||||||
- name: Setup QEMU
|
|
||||||
uses: docker/setup-qemu-action@v2
|
|
||||||
|
|
||||||
- name: Setup Docker buildx
|
|
||||||
uses: docker/setup-buildx-action@v2
|
|
||||||
|
|
||||||
- name: Login to GitHub Container Registry
|
|
||||||
uses: docker/login-action@v2
|
|
||||||
if: "github.event_name != 'pull_request'"
|
|
||||||
with:
|
|
||||||
registry: ghcr.io
|
|
||||||
username: ${{ github.repository_owner }}
|
|
||||||
password: ${{ secrets.REGISTRY_TOKEN }}
|
|
||||||
|
|
||||||
- name: Update version
|
|
||||||
if: "github.event_name == 'release' && github.event.action == 'published'"
|
|
||||||
env:
|
|
||||||
REF: ${{ github.event.release.tag_name }}
|
|
||||||
run: |
|
|
||||||
sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:1}',/" config/app.php
|
|
||||||
|
|
||||||
- name: Build and Push
|
|
||||||
uses: docker/build-push-action@v4
|
|
||||||
with:
|
|
||||||
context: .
|
|
||||||
file: ./Dockerfile
|
|
||||||
push: ${{ github.event_name != 'pull_request' }}
|
|
||||||
platforms: linux/amd64,linux/arm64
|
|
||||||
labels: ${{ steps.docker_meta.outputs.labels }}
|
|
||||||
tags: ${{ steps.docker_meta.outputs.tags }}
|
|
||||||
cache-from: type=gha
|
|
||||||
cache-to: type=gha,mode=max
|
|
|
@ -1,36 +0,0 @@
|
||||||
name: Lint
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- "develop"
|
|
||||||
- "1.0-develop"
|
|
||||||
pull_request:
|
|
||||||
branches:
|
|
||||||
- "develop"
|
|
||||||
- "1.0-develop"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
lint:
|
|
||||||
name: Lint
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Code Checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Setup PHP
|
|
||||||
uses: shivammathur/setup-php@v2
|
|
||||||
with:
|
|
||||||
php-version: "8.1"
|
|
||||||
extensions: bcmath, curl, gd, mbstring, mysql, openssl, pdo, tokenizer, xml, zip
|
|
||||||
tools: composer:v2
|
|
||||||
coverage: none
|
|
||||||
|
|
||||||
- name: Setup .env
|
|
||||||
run: cp .env.ci .env
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: composer install --no-interaction --no-progress --no-suggest --prefer-dist
|
|
||||||
|
|
||||||
- name: PHP CS Fixer
|
|
||||||
run: vendor/bin/php-cs-fixer fix --dry-run --diff
|
|
|
@ -1,89 +0,0 @@
|
||||||
name: Release
|
|
||||||
|
|
||||||
on:
|
|
||||||
push:
|
|
||||||
tags:
|
|
||||||
- "v*"
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
release:
|
|
||||||
name: Release
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Code checkout
|
|
||||||
uses: actions/checkout@v3
|
|
||||||
|
|
||||||
- name: Setup Node
|
|
||||||
uses: actions/setup-node@v3
|
|
||||||
with:
|
|
||||||
node-version: 16
|
|
||||||
cache: "yarn"
|
|
||||||
|
|
||||||
- name: Install dependencies
|
|
||||||
run: yarn install --frozen-lockfile
|
|
||||||
|
|
||||||
- name: Build
|
|
||||||
run: yarn build:production
|
|
||||||
|
|
||||||
- name: Create release branch and bump version
|
|
||||||
env:
|
|
||||||
REF: ${{ github.ref }}
|
|
||||||
run: |
|
|
||||||
BRANCH=release/${REF:10}
|
|
||||||
git config --local user.email "ci@pterodactyl.io"
|
|
||||||
git config --local user.name "Pterodactyl CI"
|
|
||||||
git checkout -b $BRANCH
|
|
||||||
git push -u origin $BRANCH
|
|
||||||
sed -i "s/ 'version' => 'canary',/ 'version' => '${REF:11}',/" config/app.php
|
|
||||||
git add config/app.php
|
|
||||||
git commit -m "ci(release): bump version"
|
|
||||||
git push
|
|
||||||
|
|
||||||
- name: Create release archive
|
|
||||||
run: |
|
|
||||||
rm -rf node_modules tests CODE_OF_CONDUCT.md CONTRIBUTING.md flake.lock flake.nix phpunit.xml shell.nix
|
|
||||||
tar -czf panel.tar.gz * .editorconfig .env.example .eslintignore .eslintrc.js .gitignore .prettierrc.json
|
|
||||||
|
|
||||||
- name: Extract changelog
|
|
||||||
env:
|
|
||||||
REF: ${{ github.ref }}
|
|
||||||
run: |
|
|
||||||
sed -n "/^## ${REF:10}/,/^## /{/^## /b;p}" CHANGELOG.md > ./RELEASE_CHANGELOG
|
|
||||||
|
|
||||||
- name: Create checksum and add to changelog
|
|
||||||
run: |
|
|
||||||
SUM=`sha256sum panel.tar.gz`
|
|
||||||
echo -e "\n#### SHA256 Checksum\n\n\`\`\`\n$SUM\n\`\`\`\n" >> ./RELEASE_CHANGELOG
|
|
||||||
echo $SUM > checksum.txt
|
|
||||||
|
|
||||||
- name: Create release
|
|
||||||
id: create_release
|
|
||||||
uses: softprops/action-gh-release@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
draft: true
|
|
||||||
prerelease: ${{ contains(github.ref, 'rc') || contains(github.ref, 'beta') || contains(github.ref, 'alpha') }}
|
|
||||||
body_path: ./RELEASE_CHANGELOG
|
|
||||||
|
|
||||||
- name: Upload release archive
|
|
||||||
id: upload-release-archive
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: panel.tar.gz
|
|
||||||
asset_name: panel.tar.gz
|
|
||||||
asset_content_type: application/gzip
|
|
||||||
|
|
||||||
- name: Upload release checksum
|
|
||||||
id: upload-release-checksum
|
|
||||||
uses: actions/upload-release-asset@v1
|
|
||||||
env:
|
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
||||||
with:
|
|
||||||
upload_url: ${{ steps.create_release.outputs.upload_url }}
|
|
||||||
asset_path: ./checksum.txt
|
|
||||||
asset_name: checksum.txt
|
|
||||||
asset_content_type: text/plain
|
|
|
@ -1,37 +1,34 @@
|
||||||
/vendor
|
/vendor
|
||||||
*.DS_Store*
|
*.DS_Store*
|
||||||
!.env.ci
|
.env
|
||||||
!.env.example
|
|
||||||
.env*
|
|
||||||
.vagrant/*
|
.vagrant/*
|
||||||
.vscode/*
|
.vscode/*
|
||||||
storage/framework/*
|
storage/framework/*
|
||||||
/.idea
|
/.idea
|
||||||
/nbproject
|
/nbproject
|
||||||
/.direnv
|
|
||||||
|
|
||||||
|
package-lock.json
|
||||||
|
composer.lock
|
||||||
node_modules
|
node_modules
|
||||||
*.log
|
|
||||||
_ide_helper.php
|
|
||||||
_ide_helper_models.php
|
_ide_helper_models.php
|
||||||
.phpstorm.meta.php
|
_ide_helper.php
|
||||||
.yarn
|
|
||||||
public/assets/manifest.json
|
sami.phar
|
||||||
|
/.sami
|
||||||
|
|
||||||
# For local development with docker
|
# For local development with docker
|
||||||
# Remove if we ever put the Dockerfile in the repo
|
# Remove if we ever put the Dockerfile in the repo
|
||||||
.dockerignore
|
.dockerignore
|
||||||
|
#Dockerfile
|
||||||
docker-compose.yml
|
docker-compose.yml
|
||||||
|
|
||||||
# for image related files
|
# for image related files
|
||||||
misc
|
misc
|
||||||
.php-cs-fixer.cache
|
.phpstorm.meta.php
|
||||||
coverage.xml
|
.php_cs.cache
|
||||||
resources/lang/locales.js
|
|
||||||
.phpunit.result.cache
|
|
||||||
|
|
||||||
/public/build
|
coverage.xml
|
||||||
/public/hot
|
|
||||||
result
|
# Vagrant
|
||||||
docker-compose.yaml
|
*.log
|
||||||
release
|
|
||||||
|
|
|
@ -1,52 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
use PhpCsFixer\Config;
|
|
||||||
use PhpCsFixer\Finder;
|
|
||||||
|
|
||||||
$finder = (new Finder())
|
|
||||||
->in(__DIR__)
|
|
||||||
->exclude([
|
|
||||||
'vendor',
|
|
||||||
'node_modules',
|
|
||||||
'storage',
|
|
||||||
'bootstrap/cache',
|
|
||||||
])
|
|
||||||
->notName(['_ide_helper*']);
|
|
||||||
|
|
||||||
return (new Config())
|
|
||||||
->setRiskyAllowed(true)
|
|
||||||
->setFinder($finder)
|
|
||||||
->setRules([
|
|
||||||
'@Symfony' => true,
|
|
||||||
'@PSR1' => true,
|
|
||||||
'@PSR2' => true,
|
|
||||||
'@PSR12' => true,
|
|
||||||
'align_multiline_comment' => ['comment_type' => 'phpdocs_like'],
|
|
||||||
'combine_consecutive_unsets' => true,
|
|
||||||
'concat_space' => ['spacing' => 'one'],
|
|
||||||
'heredoc_to_nowdoc' => true,
|
|
||||||
'no_alias_functions' => true,
|
|
||||||
'no_unreachable_default_argument_value' => true,
|
|
||||||
'no_useless_return' => true,
|
|
||||||
'ordered_imports' => [
|
|
||||||
'sort_algorithm' => 'length',
|
|
||||||
],
|
|
||||||
'phpdoc_align' => [
|
|
||||||
'align' => 'left',
|
|
||||||
'tags' => [
|
|
||||||
'param',
|
|
||||||
'property',
|
|
||||||
'return',
|
|
||||||
'throws',
|
|
||||||
'type',
|
|
||||||
'var',
|
|
||||||
],
|
|
||||||
],
|
|
||||||
'random_api_migration' => true,
|
|
||||||
'ternary_to_null_coalescing' => true,
|
|
||||||
'yoda_style' => [
|
|
||||||
'equal' => false,
|
|
||||||
'identical' => false,
|
|
||||||
'less_and_greater' => false,
|
|
||||||
],
|
|
||||||
]);
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
$finder = PhpCsFixer\Finder::create()
|
||||||
|
->in([
|
||||||
|
'app',
|
||||||
|
'bootstrap',
|
||||||
|
'config',
|
||||||
|
'database',
|
||||||
|
'resources/lang',
|
||||||
|
'routes',
|
||||||
|
'tests',
|
||||||
|
]);
|
||||||
|
|
||||||
|
return PhpCsFixer\Config::create()
|
||||||
|
->setRules([
|
||||||
|
'@Symfony' => true,
|
||||||
|
'@PSR1' => true,
|
||||||
|
'@PSR2' => true,
|
||||||
|
'align_multiline_comment' => ['comment_type' => 'phpdocs_like'],
|
||||||
|
'array_syntax' => ['syntax' => 'short'],
|
||||||
|
'blank_line_before_return' => true,
|
||||||
|
'blank_line_before_statement' => false,
|
||||||
|
'combine_consecutive_unsets' => true,
|
||||||
|
'concat_space' => ['spacing' => 'one'],
|
||||||
|
'declare_equal_normalize' => ['space' => 'single'],
|
||||||
|
'heredoc_to_nowdoc' => true,
|
||||||
|
'increment_style' => ['style' => 'post'],
|
||||||
|
'linebreak_after_opening_tag' => true,
|
||||||
|
'method_argument_space' => [
|
||||||
|
'ensure_fully_multiline' => false,
|
||||||
|
'keep_multiple_spaces_after_comma' => false,
|
||||||
|
],
|
||||||
|
'new_with_braces' => false,
|
||||||
|
'no_alias_functions' => true,
|
||||||
|
'no_multiline_whitespace_before_semicolons' => true,
|
||||||
|
'no_unreachable_default_argument_value' => true,
|
||||||
|
'no_useless_return' => true,
|
||||||
|
'not_operator_with_successor_space' => true,
|
||||||
|
'ordered_imports' => [
|
||||||
|
'sortAlgorithm' => 'length',
|
||||||
|
],
|
||||||
|
'phpdoc_align' => ['tags' => ['param']],
|
||||||
|
'phpdoc_separation' => false,
|
||||||
|
'protected_to_private' => false,
|
||||||
|
'psr0' => ['dir' => 'app'],
|
||||||
|
'psr4' => true,
|
||||||
|
'random_api_migration' => true,
|
||||||
|
'standardize_not_equals' => true,
|
||||||
|
'ternary_to_null_coalescing' => true,
|
||||||
|
'yoda_style' => [
|
||||||
|
'equal' => false,
|
||||||
|
'identical' => false,
|
||||||
|
'less_and_greater' => false,
|
||||||
|
],
|
||||||
|
])->setRiskyAllowed(true)->setFinder($finder);
|
|
@ -1,9 +0,0 @@
|
||||||
{
|
|
||||||
"printWidth": 120,
|
|
||||||
"tabWidth": 4,
|
|
||||||
"useTabs": false,
|
|
||||||
"semi": true,
|
|
||||||
"singleQuote": true,
|
|
||||||
"jsxSingleQuote": true,
|
|
||||||
"endOfLine": "lf"
|
|
||||||
}
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
use Sami\Sami;
|
||||||
|
use Symfony\Component\Finder\Finder;
|
||||||
|
|
||||||
|
$iterator = Finder::create()
|
||||||
|
->files()
|
||||||
|
->name('*.php')
|
||||||
|
->in($dir = __DIR__ . '/app');
|
||||||
|
|
||||||
|
return new Sami($iterator, array(
|
||||||
|
'title' => 'Pterodactyl',
|
||||||
|
'build_dir' => __DIR__ . '/.sami/build',
|
||||||
|
'cache_dir' => __DIR__ . '/.sami/cache',
|
||||||
|
'default_opened_level' => 2,
|
||||||
|
));
|
|
@ -0,0 +1,7 @@
|
||||||
|
preset: laravel
|
||||||
|
risky: false
|
||||||
|
disabled:
|
||||||
|
- concat_without_spaces
|
||||||
|
enabled:
|
||||||
|
- concat_with_spaces
|
||||||
|
- no_unused_imports
|
|
@ -0,0 +1,44 @@
|
||||||
|
language: php
|
||||||
|
dist: trusty
|
||||||
|
git:
|
||||||
|
depth: 3
|
||||||
|
quiet: true
|
||||||
|
matrix:
|
||||||
|
fast_finish: true
|
||||||
|
allow_failures:
|
||||||
|
- env: TEST_SUITE=Coverage
|
||||||
|
env:
|
||||||
|
matrix:
|
||||||
|
- TEST_SUITE=Unit
|
||||||
|
- TEST_SUITE=Coverage
|
||||||
|
- TEST_SUITE=Integration
|
||||||
|
php:
|
||||||
|
- 7.2
|
||||||
|
sudo: false
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- $HOME/.composer/cache
|
||||||
|
services:
|
||||||
|
- mysql
|
||||||
|
before_install:
|
||||||
|
- mysql -e 'CREATE DATABASE IF NOT EXISTS travis;'
|
||||||
|
before_script:
|
||||||
|
- echo 'opcache.enable_cli=1' >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini
|
||||||
|
- cp .env.travis .env
|
||||||
|
- travis_retry composer install --no-interaction --prefer-dist --no-suggest
|
||||||
|
script:
|
||||||
|
- if [ "$TEST_SUITE" = "Unit" ]; then vendor/bin/phpunit --bootstrap vendor/autoload.php tests/Unit; fi;
|
||||||
|
- if [ "$TEST_SUITE" = "Coverage" ]; then vendor/bin/phpunit --bootstrap vendor/autoload.php --coverage-clover coverage.xml tests/Unit; fi;
|
||||||
|
- if [ "$TEST_SUITE" = "Integration" ]; then vendor/bin/phpunit tests/Integration; fi;
|
||||||
|
notifications:
|
||||||
|
email: false
|
||||||
|
webhooks:
|
||||||
|
urls:
|
||||||
|
- https://misc.schrej.net/travistodiscord/pterodev.php
|
||||||
|
on_success: change
|
||||||
|
on_failure: always
|
||||||
|
on_error: always
|
||||||
|
on_cancel: always
|
||||||
|
on_start: never
|
||||||
|
after_success:
|
||||||
|
- bash <(curl -s https://codecov.io/bash)
|
63
BUILDING.md
63
BUILDING.md
|
@ -1,63 +0,0 @@
|
||||||
# Local Development
|
|
||||||
Pterodactyl is now powered by React, Typescript, and Tailwindcss using webpack at its core to generate compiled assets.
|
|
||||||
Release versions of Pterodactyl will include pre-compiled, minified, and hashed assets ready-to-go.
|
|
||||||
|
|
||||||
However, if you are interested in running custom themes or making modifications to the React files you'll need a build
|
|
||||||
system in place to generate these compiled assets. To get your environment setup you'll need at minimum:
|
|
||||||
|
|
||||||
* [Node.js](https://nodejs.org/en/) v14.x.x
|
|
||||||
* [Yarn](https://classic.yarnpkg.com/lang/en/) v1.x.x
|
|
||||||
* [Go](https://golang.org/) 1.17.x
|
|
||||||
|
|
||||||
### Install Dependencies
|
|
||||||
```bash
|
|
||||||
yarn install
|
|
||||||
```
|
|
||||||
|
|
||||||
The command above will download all of the dependencies necessary to get Pterodactyl assets building. After that, its as
|
|
||||||
simple as running the command below to generate assets while you're developing. Until you've run this command at least
|
|
||||||
once you'll likely see a 500 error on your Panel about a missing `manifest.json` file. This is generated by the commands
|
|
||||||
below.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# Build the compiled set of assets for development.
|
|
||||||
yarn run build
|
|
||||||
|
|
||||||
# Build the assets automatically as they are changed. This allows you to refresh
|
|
||||||
# the page and see the changes immediately.
|
|
||||||
yarn run watch
|
|
||||||
```
|
|
||||||
|
|
||||||
### Hot Module Reloading
|
|
||||||
For more advanced users, we also support 'Hot Module Reloading', allowing you to quickly see changes you're making
|
|
||||||
to the Vue template files without having to reload the page you're on. To Get started with this, you just need
|
|
||||||
to run the command below.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
PUBLIC_PATH=http://192.168.1.1:8080 yarn run serve --host 192.168.1.1
|
|
||||||
```
|
|
||||||
|
|
||||||
There are two _very important_ parts of this command to take note of and change for your specific environment. The first
|
|
||||||
is the `--host` flag, which is required and should point to the machine where the `webpack-serve` server will be running.
|
|
||||||
The second is the `PUBLIC_PATH` environment variable which is the URL pointing to the HMR server and is appended to all of
|
|
||||||
the asset URLs used in Pterodactyl.
|
|
||||||
|
|
||||||
#### Development Environment
|
|
||||||
If you're using the [`pterodactyl/development`](https://github.com/pterodactyl/development) environments, which are
|
|
||||||
highly recommended, you can just run `yarn run serve` to run the HMR server, no additional configuration is necessary.
|
|
||||||
|
|
||||||
### Building for Production
|
|
||||||
Once you have your files squared away and ready for the live server, you'll be needing to generate compiled, minified,
|
|
||||||
and hashed assets to push live. To do so, run the command below:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
yarn run build:production
|
|
||||||
```
|
|
||||||
|
|
||||||
This will generate a production JS bundle and associated assets, all located in `public/assets/` which will need to
|
|
||||||
be uploaded to your server or CDN for clients to use.
|
|
||||||
|
|
||||||
### Running Wings
|
|
||||||
To run `wings` in development all you need to do is set up the configuration file as normal when adding a new node, and
|
|
||||||
then you can build and run a local version of Wings by executing `make debug` in the Wings code directory. This must
|
|
||||||
be run on a Linux VM of some sort, you cannot run this locally on macOS or Windows.
|
|
687
CHANGELOG.md
687
CHANGELOG.md
|
@ -3,693 +3,6 @@ This file is a running track of new features and fixes to each version of the pa
|
||||||
|
|
||||||
This project follows [Semantic Versioning](http://semver.org) guidelines.
|
This project follows [Semantic Versioning](http://semver.org) guidelines.
|
||||||
|
|
||||||
## v1.11.7
|
|
||||||
|
|
||||||
### Added
|
|
||||||
|
|
||||||
* Java 21 to Minecraft eggs
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Updated Minecraft EULA link
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Fixed backups not ever being marked as completed (#5088)
|
|
||||||
* Fixed `.7z` files not being detected as a compressed file (#5016)
|
|
||||||
|
|
||||||
## v1.11.6
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
|
|
||||||
* Better node ownership checks for internal backup endpoints
|
|
||||||
* Improved validation rules on `docker_image` fields to prevent invalid inputs
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
|
|
||||||
* Multiple XSS vulnerabilities in the admin area ([GHSA-384w-wffr-x63q](https://github.com/pterodactyl/panel/security/advisories/GHSA-384w-wffr-x63q))
|
|
||||||
|
|
||||||
## v1.11.5
|
|
||||||
### Fixed
|
|
||||||
* Rust egg using the wrong Docker image, breaking Rust modding frameworks.
|
|
||||||
|
|
||||||
## v1.11.4
|
|
||||||
### Added
|
|
||||||
* Added support for the `server.queryport` option on the Rust egg.
|
|
||||||
* Added support for the Carbon modding framework to the Rust egg.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Upgraded to Laravel 10.
|
|
||||||
* Sensitive data is no longer shown in the CopyOnClick toast notification.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Allow SVGs to be edited in the server's file manager.
|
|
||||||
* Properly validate the request body when creating a backup.
|
|
||||||
* Fixed issue with schedules running at the wrong time when the panel utilized a timezone with non-hour offsets (such as `Australia/Darwin`).
|
|
||||||
* Fixes the log directory when running the Panel in a container.
|
|
||||||
* Fixes the permission name used to check if a user has permission to read files/folders.
|
|
||||||
* Fixes the ability to unset a server's description through the client API.
|
|
||||||
* Fixed the MassActionBar on the server's file manager blocking elements below it, preventing them from being interacted with.
|
|
||||||
|
|
||||||
## v1.11.3
|
|
||||||
### Changed
|
|
||||||
* When updating a server's description through the client API, if no value is specified, the description will now remain unchanged.
|
|
||||||
* When installing the Panel for the first time, the queue driver will now all default to `redis` instead of `sync`.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* `php artisan p:environment:mail` not correctly setting the right variable for `MAIL_FROM_ADDRESS`.
|
|
||||||
* Fixed the conflict state rendering on the UI for a server showing `reinstall_failed` as `restoring_backup`.
|
|
||||||
* Fixed the unknown column `uuid` error when jobs fail, causing them not to get stored correctly.
|
|
||||||
* Fixed the server task endpoints in the client API not allowing `sequence_id` and `continue_on_failure` to be set.
|
|
||||||
|
|
||||||
## v1.11.2
|
|
||||||
### Changed
|
|
||||||
* Telemetry no longer sends a map of Egg and Nest UUIDs to the number of servers using them.
|
|
||||||
* Increased the timeout for the decompress files endpoint in the client API from 15 seconds to 15 minutes.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixed Panel Docker image having a `v` prefix in the version displayed in the admin area.
|
|
||||||
* Fixed emails using the wrong queue name, causing them to not be sent.
|
|
||||||
* Fixed the settings keys used for configuring SMTP settings, causing settings to not save properly.
|
|
||||||
* Fixed the `MAIL_EHLO_DOMAIN` environment variable not being properly backwards compatible with the old `SERVER_NAME` variable.
|
|
||||||
|
|
||||||
## v1.11.1
|
|
||||||
### Fixed
|
|
||||||
* Fixed Panel Docker image showing `canary` as it's version.
|
|
||||||
|
|
||||||
## v1.11.0
|
|
||||||
### Changed (since 1.10.4)
|
|
||||||
* Changed minimum PHP version requirement from `7.4` to `8.0`.
|
|
||||||
* Upgraded from Laravel 8 to Laravel 9.
|
|
||||||
* This release requires Wings v1.11.x in order for Server Transfers to work.
|
|
||||||
* `MB` byte suffixes are now displayed as `MiB` to more accurately reflect the actual value.
|
|
||||||
* Server re-installation failures are tracked independently of the initial installation process.
|
|
||||||
|
|
||||||
### Fixed (since 1.10.4)
|
|
||||||
* Node maintenance mode now properly blocks access to servers.
|
|
||||||
* Fixed the length validation on the Minecraft Forge egg.
|
|
||||||
* Fixed the password in the JDBC string not being properly URL encoded.
|
|
||||||
* Fixed an issue where Wings would throw a validation error while attempting to upload activity logs.
|
|
||||||
* Properly handle a missing `Content-Length` header in the response from the daemon.
|
|
||||||
* Ensure activity log properties are always returned as an object instead of an empty array.
|
|
||||||
|
|
||||||
### Added (since 1.10.4)
|
|
||||||
* Added the `server:settings.description` activity log event for when a server description is changed.
|
|
||||||
* Added the ability to cancel file uploads in the file manager for a server.
|
|
||||||
* Added a telemetry service to collect anonymous metrics from the panel, this feature is *enabled* by default and can be toggled using the `PTERODACTYL_TELEMETRY_ENABLED` environment variable.
|
|
||||||
|
|
||||||
## v1.11.0-rc.2
|
|
||||||
### Changed
|
|
||||||
* `MB` byte suffixes are now displayed as `MiB` to more accurately reflect the actual value.
|
|
||||||
* Server re-installation failures are tracked independently of the initial installation process.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Properly handle a missing `Content-Length` header in the response from the daemon.
|
|
||||||
* Ensure activity log properties are always returned as an object instead of an empty array.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Added the `server:settings.description` activity log event for when a server description is changed.
|
|
||||||
* Added the ability to cancel file uploads in the file manager for a server.
|
|
||||||
* Added a telemetry service to collect anonymous metrics from the panel, this feature is disabled by default and can be toggled using the `PTERODACTYL_TELEMETRY_ENABLED` environment variable.
|
|
||||||
|
|
||||||
## v1.11.0-rc.1
|
|
||||||
### Changed
|
|
||||||
* Changed minimum PHP version requirement from `7.4` to `8.0`.
|
|
||||||
* Upgraded from Laravel 8 to Laravel 9.
|
|
||||||
* This release requires Wings v1.11.x in order for Server Transfers to work.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Node maintenance mode now properly blocks access to servers.
|
|
||||||
* Fixed the length validation on the Minecraft Forge egg.
|
|
||||||
* Fixed the password in the JDBC string not being properly URL encoded.
|
|
||||||
* Fixed an issue where Wings would throw a validation error while attempting to upload activity logs.
|
|
||||||
|
|
||||||
## v1.10.4
|
|
||||||
### Fixed
|
|
||||||
* Fixed an issue where subusers could be given permissions that are not actually registered or used.
|
|
||||||
* Fixed an issue where node FQDNs could not just be IP addresses.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Change maximum number of API keys per user from `10` to `25`.
|
|
||||||
* Change byte unit prefix from `B` to `iB` to better reflect our usage of base 2 (multiples of 1024).
|
|
||||||
|
|
||||||
## v1.10.3
|
|
||||||
### Fixed
|
|
||||||
* S3 Backup driver now supports Cloudflare R2.
|
|
||||||
* Node FQDNs can now be used with AAAA records with no A records present.
|
|
||||||
* Server transfers can no longer be initiated if the server is being installed, transferred, or restoring a backup.
|
|
||||||
* Fixed an issue relating to the use of arrays in the `config_files` field with eggs.
|
|
||||||
* Fixed `oom_disabled` not being mapped in the Application API when creating a new server.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* File manager now supports selecting multiple files for upload (when using the upload button).
|
|
||||||
* Added a configuration option for specifying the S3 storage class for backups.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Servers will now show the current uptime when the server is starting rather than only showing when the server is marked as online.
|
|
||||||
|
|
||||||
## v1.10.2
|
|
||||||
### Fixed
|
|
||||||
* Fixes a rendering issue with egg descriptions in the admin area
|
|
||||||
* Fixes the page title on the SSH Keys page
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Additional validation rules will now show a toggle switch rather than an input when editing server variables
|
|
||||||
* The eggs endpoint will now always return an empty JSON object for the `config_files` field, even if the field is completely empty
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds a `Force Outgoing IP` option for eggs that can be used to ensure servers making outgoing connections use their allocation IP rather than the node's primary ip
|
|
||||||
* Adds options to configure sending of email (re)install notifications
|
|
||||||
* Add an option to configure the part size for backups uploaded to S3
|
|
||||||
|
|
||||||
## v1.10.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes a surprise `clock()` function that was used for debugging and should not have made it into the release. This was causing activity events to not properly sync between the Panel and Wings.
|
|
||||||
|
|
||||||
## v1.10.0
|
|
||||||
### Fixed
|
|
||||||
* Fixes improper cache key naming on the frontend causing server activity logs to be duplicated across server page views.
|
|
||||||
* Fixes overflow issues on dialogs when the internal content is too long.
|
|
||||||
* Fixes spinner overlay on console improperly taking up the entire page making it impossible to use navigation controls.
|
|
||||||
* Fixes 2FA QR code background being too dark for some phones to properly scan.
|
|
||||||
* File manager now properly displays an error message if a user attempts to upload a folder rather than files.
|
|
||||||
* Fixes the "Create Directory" dialog persisting the previously entered value when it is re-opened.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* IP addresses in activity logs are now always displayed to administrators, regardless of if they own the server or not.
|
|
||||||
* Scroll down indicator on the console has been changed to a down arrow to be clearer.
|
|
||||||
* Docker builds have been updated to use `PHP 8.1`.
|
|
||||||
* Recaptcha validation domain is now configurable using the `RECAPTCHA_DOMAIN` environment variable.
|
|
||||||
* Drag and drop overlay on the file manager has been tweaked to be slightly more consistent with the frontend style and be a little easier to read.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds support for the `user_uuid` claim on all generated JWTs which allows Wings to properly identify the user performing each action.
|
|
||||||
* Adds support for recieving external activity log events from Wings instances (power state, commands, SFTP, and uploads).
|
|
||||||
* Adds support for tracking failed password-based SFTP logins.
|
|
||||||
* Server name and description are now passed along to Wings making them available in egg variables for parsing and including.
|
|
||||||
* Adds support for displaying all active file uploads in the file manager.
|
|
||||||
|
|
||||||
## v1.9.2
|
|
||||||
### Fixed
|
|
||||||
* Fixes rouding in sidebar of CPU usage graph that was causing an excessive number of zeros to be rendered.
|
|
||||||
* Fixes the Java Version selector modal having the wrong default value selected initially.
|
|
||||||
* Fixes console rendering in Safari that was causing the console to resize excessively and graphs to overlay content.
|
|
||||||
* Fixes missing "Starting"/"Stopping" status display in the server uptime block.
|
|
||||||
* Fixes incorrect formatting of activity log when viewing certain file actions.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updated the UI for the two-step authorization setup on accounts to use new Dialog UI and provide better clarity to new users.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Added missing `<DOCTYPE html>` tag to template output to avoid entering quirks mode in browsers.
|
|
||||||
* Added password requirement when enabling TOTP on an account.
|
|
||||||
|
|
||||||
## v1.9.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes missing "Click to Copy" for server address on the console data blocks.
|
|
||||||
* Fixes data points on the graphs not being properly rounded to two decimal places.
|
|
||||||
* Returns byte formatting logic to use `1024` as the base value, rather than `1000`.
|
|
||||||
* Fixes permission error occurring when a server is marked as installing and an admin navigates to the console screen.
|
|
||||||
* Fixes improper display of install/transfer warning on the server console page.
|
|
||||||
* Fixes permission matching for the server settings page to correctly allow access when a user has _any_ of the needed permissions.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Moves the server data blocks to the right-hand side of the console, rather than the left.
|
|
||||||
* Rather than defaulting graph values at `0` when resetting or refreshing the page, their values are now hidden entirely.
|
|
||||||
* **[security]** Hides IP addresses from all activity log entries that are not directly associated with the currently signed in user.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds the current resource limits for a server next to each data block on the console screen.
|
|
||||||
|
|
||||||
## v1.9.0
|
|
||||||
### Added
|
|
||||||
* Added support for using Tailwind classes inside components using `className={}` rather than having to use `twin.macro` with the `css={}` prop.
|
|
||||||
* Added HeadlessUI and Heroicons packages.
|
|
||||||
* Added new `Tooltip.tsx` component to support displaying tooltips within the Panel.
|
|
||||||
* Adds a new activity log view for both user accounts and individual servers. This builds upon data collected in previous releases.
|
|
||||||
* Added a new column `api_key_id` to the `activity_logs` table to indicate if the user performed the action while using an API key.
|
|
||||||
* Adds initial support for language translations on the front-end. The underlying implementation details are working, however work has not yet begun on actually translating all of the strings yet. Expect this to continue in future releases.
|
|
||||||
* Improved accessibility for navigation icons by adding a tooltip on hover to indicate what each one does.
|
|
||||||
* Adds logging for API keys that are blocked from performing an API action due to IP address limiting.
|
|
||||||
* Adds support for `?filter[description]=foo` when querying servers on both the client and application API.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updated how release assets are generated to perform more logical bundle splitting. This should help reduce the amount of data users have to download at once in order to render the UI.
|
|
||||||
* Upgraded From TailwindCSS 2 to 3 — for most people this should have minimal if any impact.
|
|
||||||
* Chart.js updated from v2 to v3.
|
|
||||||
* Reduced the number of custom colors in use — by default we now use Tailwind's default color pallet, with the exception of a custom gray scheme.
|
|
||||||
* **[deprecated]** The use of `neutral` and `primary` have been deprecated in class names, prefer `gray` and `blue` respectively.
|
|
||||||
* Begins the process of dropping the use of Gravatars for user avatars and replaces them with dynamically generated SVG images.
|
|
||||||
* Improved front-end route definitions to make it easier for external modifications to inject their routes and components into the codebase without having to modify as many core files.
|
|
||||||
* Redesigned the server console screen to better display data users might be looking for, and increase the height of the console itself.
|
|
||||||
* Merged the two network data graphs into a single dual-line graph to better display incoming and outgoing data volumes.
|
|
||||||
* Updated all byte formatting logic to use `1000` as the divisor rather than `1024` to be more consistent with what users most likely expect.
|
|
||||||
* Changed the underlying `eslint` rules applied to the front-end codebase to simplify them dramatically. We now utilize `prettier` in combination with some basic default rulesets to make it easier to understand the expected formatting.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixes a bug causing a 404 error when attempting to delete a database from a server in the admin control panel.
|
|
||||||
* Fixes console input auto-capitalizing and auto-correcting when entering text on some mobile devices.
|
|
||||||
* Fixes SES service configuration using a hard-coded `us-east-1` region.
|
|
||||||
* Fixes a bug causing a 404 error when attempting to delete an SSH key from your account when the SHA256 hash includes a slash.
|
|
||||||
* Fixes mobile keyboards automatically attempting to capitalize and spellcheck typing on the server console.
|
|
||||||
* Fixes improper support for IP address CIDR ranges when creating API keys for the client area.
|
|
||||||
* Fixes a bug preventing additional included details from being returned from the application API when utilizing a client API key as an administrator.
|
|
||||||
|
|
||||||
## v1.8.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes a bug causing mounts to return a 404 error when adding them to a server.
|
|
||||||
* Fixes a bug causing the Egg Image dropdown to not display properly when creating a new server.
|
|
||||||
* Fixes a bug causing an error when attemping to create a new server via the API.
|
|
||||||
|
|
||||||
## v1.8.0
|
|
||||||
**Important:** this version updates the `version` field on generated Eggs to be `PTDL_v2` due to formatting changes. This
|
|
||||||
should be completely seamless for most installations as the Panel is able to convert between the two. Custom solutions
|
|
||||||
using these eggs should be updated to account for the new format.
|
|
||||||
|
|
||||||
This release also changes API key behavior — "client" keys belonging to admin users can now be used to access
|
|
||||||
the `/api/application` endpoints in their entirety. Existing "application" keys generated in the admin area should
|
|
||||||
be considered deprecated, but will continue to work. Application keys _will not_ work with the client API.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Schedules are no longer run when a server is suspended or marked as installing.
|
|
||||||
* The remote field when creating a database is no longer limited to an IP address and `%` wildcard — all expected MySQL remote host values are allowed.
|
|
||||||
* Allocations cannot be deleted from a server by a user if the server is configured with an `allocation_limit` set to `0`.
|
|
||||||
* The Java Version modal no longer shows a dropdown and update option to users that do not have permission to make those changes.
|
|
||||||
* The Java Version modal now correctly returns only the images available to the server's selected Egg.
|
|
||||||
* Fixes leading and trailing spaces being removed from variable values on file manager endpoints, causing errors when trying to perform actions against certain files and folders.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Forces HTTPS on URLs when the `APP_URL` value is set and includes `https://` within the URL. This addresses proxy misconfiguration issues that would cause URLs to be generated incorrectly.
|
|
||||||
* Lowers the default timeout values for requests to Wings instances from 10 seconds to 5 seconds.
|
|
||||||
* Additional permissions (`CREATE TEMPORARY TABLES`, `CREATE VIEW`, `SHOW VIEW`, `EVENT`, and `TRIGGER`) are granted to users when creating new databases for servers.
|
|
||||||
* development: removed Laravel Debugbar in favor of Clockwork for debugging.
|
|
||||||
* The 2FA input field when logging in is now correctly identified as `one-time-password` to help browser autofill capabilities.
|
|
||||||
* Changed API authentication mechanisms to make use of Laravel Sanctum to significantly clean up our internal handling of sessions.
|
|
||||||
* API keys generated by the system now set a prefix to identify them as Pterodactyl API keys, and if they are client or application keys. This prefix looks like `ptlc_` for client keys, and `ptla_` for application keys. Existing API keys are unaffected by this change.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Added support for PHP 8.1 in addition to PHP 8.0 and 7.4.
|
|
||||||
* Adds more support for catching potential PID exhaustion errors in different games.
|
|
||||||
* It is now possible to create a new node on the Panel using an artisan command.
|
|
||||||
* A new cron cheatsheet has been added which appears when creating a schedule.
|
|
||||||
* Adds support for filtering the `/api/application/nodes/:id/allocations` endpoint using `?filter[server_id]=0` to only return allocations that are not currently assigned to a server on that node.
|
|
||||||
* Adds support for naming docker image values in an Egg to improve front-end display capabilities.
|
|
||||||
* Adds command to return the configuration for a specific node in both YAML and JSON format (`php artisan p:node:configuration`).
|
|
||||||
* Adds command to return a list of all nodes available on the Panel in both table and JSON format (`php artisan p:node:list`).
|
|
||||||
* Adds server network (inbound/outbound) usage graphs to the console screen.
|
|
||||||
* Adds support for configuring CORS on the API by setting the `APP_CORS_ALLOWED_ORIGINS=example.com,dashboard.example.com` environment variable. By default all instances are configured with this set to `*` which allows any origin.
|
|
||||||
* Adds proper activity logging for the following areas of the Panel: authentication, user account modifications, server modification. This is an initial test implementation before further roll-out in the software. Events are logged into the database but are not currently exposed in the UI — they will be displayed in a future update.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
* Removes Google Analytics from the front end code.
|
|
||||||
* Removes multiple middleware that were previously used for configuring API access and controlling model fetching. This has all been replaced with Laravel Sanctum and standard Laravel API tooling. This should make codebase discovery significantly more simple.
|
|
||||||
* **DEPRECATED**: The use of `Pterodactyl\Models\AuditLog` is deprecated and all references to this model have been removed from the codebase. In the next major release this model and table will be fully dropped.
|
|
||||||
|
|
||||||
## v1.7.0
|
|
||||||
### Fixed
|
|
||||||
* Fixes typo in message shown to user when deleting a database.
|
|
||||||
* Fixes formatting of IPv6 addresses when displaying allocations to users.
|
|
||||||
* Fixes an exception thrown while trying to return error messages from API endpoints that inproperly masked the true underlying error.
|
|
||||||
* Fixes SSL certificate path generation for Let's Encrypt by ensuring they are always transformed to lowercase.
|
|
||||||
* Removes duplicate entries when creating a nested folder in the file manager.
|
|
||||||
* Fixes missing validation of Egg Author email addresses during the setup process that could cause unexpected failures later on.
|
|
||||||
* Fixes font rendering issues of the console on Firefox due to an outdated version of xterm.js being used.
|
|
||||||
* Fixes display overlap issues of the two-factor configuration form in a user's settings.
|
|
||||||
* **[security]** When authenticating using an API key a user session is now only persisted for the duration of the request before being destroyed.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* CPU graph changed to show the maximum amount of CPU available to a server to better match how the memory graph is displayed.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds support for `DB_PORT` environment variable in the Docker enterpoint for the Panel image.
|
|
||||||
* Adds suport for ARM environments in the Docker image.
|
|
||||||
* Adds a new warning modal for Steam servers shown when an invalid Game Server Login Token (GSL Token) is detected.
|
|
||||||
* Adds a new warning modal for Steam servers shown when the installation process runs out of available disk space.
|
|
||||||
* Adds a new warning modal for Minecraft servers shown when a server exceeds the maximum number of child processes.
|
|
||||||
* Adds support for displaying certain server variable fields as a checkbox when they're detected as using `boolean` or `in:0,1` validation rules.
|
|
||||||
* Adds support for Pug and Jade in the file editor.
|
|
||||||
* Adds an entry to the `robots.txt` file to correctly disallow all bot indexing.
|
|
||||||
|
|
||||||
|
|
||||||
## v1.6.6
|
|
||||||
### Fixed
|
|
||||||
* **[security]** Fixes a CSRF vulnerability for both the administrative test email endpoint and node auto-deployment token generation endpoint. [GHSA-wwgq-9jhf-qgw6](https://github.com/pterodactyl/panel/security/advisories/GHSA-wwgq-9jhf-qgw6)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updates Minecraft eggs to include latest Java 17 yolk by default.
|
|
||||||
|
|
||||||
## v1.6.5
|
|
||||||
### Fixed
|
|
||||||
* Fixes broken application API endpoints due to changes introduced with session management in 1.6.4.
|
|
||||||
|
|
||||||
## v1.6.4
|
|
||||||
_This release should not be used, please use `1.6.5`. It has been pulled from our releases._
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixes a session management bug that would cause a user who signs out of one browser to be unintentionally logged out of other browser sessions when using the client API.
|
|
||||||
|
|
||||||
## v1.6.3
|
|
||||||
### Fixed
|
|
||||||
* **[Security]** Changes logout endpoint to be a POST request with CSRF-token validation to prevent a malicious actor from triggering a user logout.
|
|
||||||
* Fixes Wings receiving the wrong server suspension state when syncing servers.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds additional throttling to login and password reset endpoints.
|
|
||||||
* Adds server uptime display when viewing a server console.
|
|
||||||
|
|
||||||
## v1.6.2
|
|
||||||
### Fixed
|
|
||||||
* **[Security]** Fixes an authentication bypass vulerability that could allow a malicious actor to login as another user in the Panel without knowing that user's email or password.
|
|
||||||
|
|
||||||
## v1.6.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes server build modifications not being properly persisted to the database when edited.
|
|
||||||
* Correctly exposes the `oom_disabled` field in the `build` limits block for a server build so that Wings can pick it up.
|
|
||||||
*
|
|
||||||
## v1.6.0
|
|
||||||
### Fixed
|
|
||||||
* Fixes array merging logic for server transfers that would cause a 500 error to occur in some scenarios.
|
|
||||||
* Fixes user password updates not correctly logging the user out and returning a failure message even upon successful update.
|
|
||||||
* Fixes the count of used backups when browsing a paginated backup list for a server.
|
|
||||||
* Fixes an error being triggered when API endpoints are called with no `User-Agent` header and an audit log is generated for the action.
|
|
||||||
* Fixes state management on the frontend not properly resetting the loading indicator when adding subusers to a server.
|
|
||||||
* Fixes extraneous API calls being made to Wings for the server file listing when not on a file manager screen.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds foreign key relationship on the `mount_node`, `mount_server` and `egg_mount` tables.
|
|
||||||
* Adds environment variable `PER_SCHEDULE_TASK_LIMIT` to allow manual overrides for the number of tasks that can exist on a single schedule. This is currently defaulted to `10`.
|
|
||||||
* OOM killer can now be configured at the time of server creation.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Server updates are not dependent on a successful call to Wings occurring — if the API call fails internally the error will be logged but the server update will still be persisted.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
* Removed `WingsServerRepository::update()` function — if you were previously using this to modify server elements on Wings please replace calls to it with `::sync()` after updating Wings.
|
|
||||||
|
|
||||||
## v1.5.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes Docker image 404ing instead of being able to access the Panel.
|
|
||||||
* Fixes Java version feature being only loaded when the `eula` feature is specified.
|
|
||||||
* Fixes `php artisan p:upgrade` not forcing and seeding while running migrations.
|
|
||||||
* Fixes spinner overlays overlapping on the server console page.
|
|
||||||
* Fixes Wings being unable to update backup statuses.
|
|
||||||
|
|
||||||
## v1.5.0
|
|
||||||
### Fixed
|
|
||||||
* Fixes deleting a locked backup that has also been marked as failed to allow deletion rather than returning an error about being locked.
|
|
||||||
* Fixes server creation process not correctly sending `start_on_completion` to Wings instance.
|
|
||||||
* Fixes `z-index` on file mass delete modal so it is displayed on top of all elements, rather than hidden under some.
|
|
||||||
* Supports re-sending requests to the Panel API for backups that are currently marked as failed, allowing a previously failed backup to be marked as successful.
|
|
||||||
* Minor updates to multiple default eggs for improved error handling and more accurate field-level validation.
|
|
||||||
|
|
||||||
### Updated
|
|
||||||
* Updates help text for CPU limiting when creating a new server to properly indicate virtual threads are included, rather than only physical threads.
|
|
||||||
* Updates all of the default eggs shipped with the Panel to reference new [`ghcr.io` yolks repository](https://github.com/pterodactyl/yolks).
|
|
||||||
* When adding 2FA to an account the key used to generate the token is now displayed to the user allowing them to manually input into their app if necessary.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds SSL/TLS options for MySQL and Redis in line with most recent Laravel updates.
|
|
||||||
* New users created for server MySQL instances will now have the correct permissions for creating foreign keys on tables.
|
|
||||||
* Adds new automatic popup feature to allow users to quickly update their Minecraft servers to the latest Java® eggs as necessary if unsupported versions are detected.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
* Removes legacy `userInteraction` key from eggs which was unused.
|
|
||||||
|
|
||||||
## v1.4.2
|
|
||||||
### Fixed
|
|
||||||
* Fixes logic to disallow creating a backup schedule if the server's backup limit is set to 0.
|
|
||||||
* Fixes bug preventing a database host from being updated if the linked node is set to "none".
|
|
||||||
* Fixes files and menus under the "Mass Actions Bar" being unclickable when it is visible.
|
|
||||||
* Fixes issues with the Teamspeak and Mumble eggs causing installs to fail.
|
|
||||||
* Fixes automated query to avoid pruning backups that are still running unintentionally.
|
|
||||||
* Fixes "Delete Server" confirmation modal on the admin screen to actually show up when deleting rather than immediately deleting the server.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds support for locking individual server backups to prevent deletion by users or automated backup processes.
|
|
||||||
* List of files to be deleted is now shown on the delete file confirmation modal.
|
|
||||||
* Adds support for using `IF` statements in database queries when a database user is created through the Panel.
|
|
||||||
* Adds support for using a custom mailgun API endpoint rather than only the US based endpoint.
|
|
||||||
* Adds CPU limit display next to the current CPU usage to match disk and memory usage reporting.
|
|
||||||
* Adds a "Scroll to Bottom" helper element to the server console when not scrolled to the bottom currently.
|
|
||||||
* Adds support for querying the API for servers by using the `uuidShort` field rather than only the `uuid` field.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updates codebase to use TypeScript 4.
|
|
||||||
* **[security]**: removes the external dependency for loading QRCode images. They're now generated directly on the frontend using JavaScript.
|
|
||||||
|
|
||||||
## v1.4.1
|
|
||||||
### Added
|
|
||||||
* Adds support for only running a schedule if the server is currently in an online state.
|
|
||||||
* Adds support for ignoring errors during task execution and continuing on to the next item in the sequence. For example, continuing to a server restart even if sending a command beforehand failed.
|
|
||||||
* Adds the ability to specify the group to use for file permissions when using the `p:upgrade` command.
|
|
||||||
* Adds the ability to manually run a schedule even if it is currently disabled.
|
|
||||||
|
|
||||||
## v1.4.0
|
|
||||||
### Fixed
|
|
||||||
* Removes the use of tagging when storing server resource usage in the cache. This addresses errors encountered when using the `file` driver.
|
|
||||||
* Fixes Wings response handling if Wings returns an error response with a 200-level status code that would improperly be passed back to the client as a successful request.
|
|
||||||
* Fixes use of JSON specific functions in SQL queries to better support MariaDB users.
|
|
||||||
* Fixes a migration that could fail on some MySQL/MariaDB setups when trying to encrypt node token values.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Increases the maximum length allowed for a server name using the Rust egg.
|
|
||||||
* Updated server resource utilization API call to Wings to use new API response format used by `Wings@1.4.0`.
|
|
||||||
|
|
||||||
## v1.3.2
|
|
||||||
### Fixed
|
|
||||||
* Fixes self-upgrade incorrectly executing the command to un-tar downloaded archives.
|
|
||||||
* Fixes the checkbox to delete all files when restoring a backup not actually passing that along in the API call. Files will now properly be deleted when restoring if selected.
|
|
||||||
* Fixes some keybindings not working correctly in the server console on Windows machines.
|
|
||||||
* Fixes mobile UI incorrectly squishing the Docker image selector on the server settings page.
|
|
||||||
* Fixes recovery tokens not having a `created_at` value set on them properly when they are created.
|
|
||||||
* Fixes flawed migration that would not correctly set the month value into schedule crons.
|
|
||||||
* Fixes incorrect mounting for Docker compose file that would cause error logs to be missing.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Server resource lookups are now cached on the Panel for 20 seconds at a time to reduce the load from multiple clients requesting the same server's stats.
|
|
||||||
* Bungeecord egg no longer force-enables the query listener.
|
|
||||||
* Adds page to the dashboard URL to allow easy loading of a specific pagination page rather than resetting back to the first page when refreshing.
|
|
||||||
* All application API endpoints now correctly support the `?per_page=N` query parameter to specify how many resources to return at once.
|
|
||||||
|
|
||||||
## v1.3.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes the Rust egg not properly seeding during the upgrade & installation process.
|
|
||||||
* Fixes backups not being downloadable via the frontend.
|
|
||||||
* Fixes backup listing showing the wrong number of existing backups based on the current page you're on.
|
|
||||||
|
|
||||||
## v1.3.0
|
|
||||||
### Fixed
|
|
||||||
* Fixes administrator "Other Servers" toggle being persisted wrongly when signing out and signing into a non-administrator account on the server dashboard.
|
|
||||||
* Fixes composer failing to run properly in local environments where there is no database connection available once configured.
|
|
||||||
* Fixes SQL exception caused by the Panel attempting to store null values in the database.
|
|
||||||
* Fixes validation errors caused by improper defaults when trying to edit system settings in the admin area.
|
|
||||||
* Fixes console overflow when using smaller-than-default font sizes in Firefox.
|
|
||||||
* Fixes console text input field having a white background when manually building new assets from the release build due to a missing `babel-macros` definition file.
|
|
||||||
* Fixes database improperly using a signed `smallint` field rather than an unsigned field which restricted SFTP ports to 32767 or less.
|
|
||||||
* Fixes server console resize handler to no longer encounter an exception at random that breaks the entire UI.
|
|
||||||
* Fixes unhandled error caused by entering an invalid IP address or FQDN when creating a new node allocation.
|
|
||||||
* Fixes unhandled error when Wings would fetch a server configuration from the Panel that uses an Egg with invalid JSON data for the configuration fields.
|
|
||||||
* Fixes email not being sent to a user when their server is done installing.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds support for automatically copying SFTP connection details when clicking into the text field.
|
|
||||||
* Messaging about a node not having any allocations available for deployment has been adjusted to be more understandable by users.
|
|
||||||
* Adds automated self-upgrade process for Pterodactyl Panel once this version is installed on servers. This allows users to update by using a single command.
|
|
||||||
* Adds support for specifying a month when creating or modifying a server schedule.
|
|
||||||
* Adds support for restoring backups (including those in S3 buckets) to a server and optionally deleting all existing files when doing so.
|
|
||||||
* Adds underlying support for audit logging on servers. Currently this is only used by some internal functionality but will be slowly expanded as time permits to allow more robust logging.
|
|
||||||
* Adds logic to automatically reset failed server states when Wings is rebooted. This will kick servers out of "installing" and "restoring from backup" states automatically.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updated to `Laravel 8` and bumped minimum PHP version from `7.3` to `7.4` with PHP `8.0` being the recommended.
|
|
||||||
* Server state is now stored in a single `status` column within the database rather than multiple different `tinyint` columns.
|
|
||||||
|
|
||||||
## v1.2.2
|
|
||||||
### Fixed
|
|
||||||
* **[security]** Fixes authentication bypass allowing a user to take control of specific server actions such as executing schedules, rotating database passwords, and viewing or deleting a backup.
|
|
||||||
|
|
||||||
## v1.2.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes URL-encoding of filenames when working in the filemanager to fix issues when moving, renaming, or deleting files.
|
|
||||||
* Fixes URL-encoding of email addresses when requesting a password reset.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds the ability for users to select a base Java Docker image for most Minecraft specific eggs shipped as defaults.
|
|
||||||
|
|
||||||
## v1.2.0
|
|
||||||
### Fixed
|
|
||||||
* Fixes newest backup being deleted when creating a new one using the schedule tasks, rather than the oldest backup.
|
|
||||||
* Fixes multiple encoding issues when handling file names in the manager.
|
|
||||||
* Fixes database password not properly being copied to the clipboard when clicked.
|
|
||||||
* Fixes failed transfers unintentionally locking a server into a failed state and not properly releasing allocations that were reserved.
|
|
||||||
* Fixes error box on server pages having an oval refresh button rather than a perfect circle.
|
|
||||||
* Fixes a bunch of errors and usage issues relating to backups especially when uploading to S3-based systems.
|
|
||||||
* Fixes HMR breaking navigation in development modes on the frontend.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updated Paper egg to default to Java 11 as the base docker image.
|
|
||||||
* Removes the file mode display from the File Manager row listing.
|
|
||||||
* Updated input UI elements to have thicker borders and more consistent highlighting when active.
|
|
||||||
* Changed searchbar toggle from `"k"` to `Cmd/Ctrl + "/"` to avoid accidental toggles and be more consistent with other sites.
|
|
||||||
* Upgrades TailwindCSS to `v2`.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds support for eggs to define multiple Docker images that can be selected by users (e.g. Java 8 & 11 images for a single egg).
|
|
||||||
* Adds support for configuring the default interval for failed backups to be pruned from the system to avoid long running backups being incorrectly cleared.
|
|
||||||
* Adds server transfer output logging to the server console allowing admins to see how a transfer is progressing directly in the UI.
|
|
||||||
* Adds client API endpoint to download a file from a remote souce. This functionality is not currently expressed in the UI.
|
|
||||||
|
|
||||||
## v1.1.3
|
|
||||||
### Fixed
|
|
||||||
* Server bulk power actions command will no longer attempt to run commands against installing or suspended servers.
|
|
||||||
* Fixes the application API throwing an error when attempting to return variables for a server.
|
|
||||||
* Fixes an error when attempting to install Panel dependencies without specifying an `.env` file due to an unset default timezone.
|
|
||||||
* Fixes a null value flip in the database migrations.
|
|
||||||
* Fixes password change endpoint for users allowing a blank value to be provided (even if nothing actually happened).
|
|
||||||
* Fixes database IP addresses not allowing a `0` in the first octet field.
|
|
||||||
* Fixes node information being impossible to update if there was a network error during the process. Any errors encountered communicating with Wings are now reported but will not block the actual saving of the changes.
|
|
||||||
* **[Security]** When 2FA is required on an account the client API endpoints will now properly return an error and the UI will redirect the user to setup 2FA.
|
|
||||||
* **[Security]** When changing the owner of a server the old owner's JWT is now properly invalidated on Wings.
|
|
||||||
* Fixes a server error when requesting database information for a server as a subuser and the account is not granted `view_password` permissions.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds support for basic backup rotation on a server when creating scheduled backup tasks.
|
|
||||||
* Makes URLs present in the console clickable.
|
|
||||||
* Adds `chmod` support to the file manager so that users can manually make modifications to file permissions as they need.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* UI will no longer show a delete button to users when they're editing themselves.
|
|
||||||
* Updated logic for bulk power actions to no longer run actions against suspended or installing servers.
|
|
||||||
|
|
||||||
## v1.1.2
|
|
||||||
### Fixed
|
|
||||||
* Fixes an exception thrown while trying to validate IP access for the client API.
|
|
||||||
* Fixes command history scrolling not putting the cursor at the end of the line.
|
|
||||||
* Fixes file manager rows triggering a 404 when middle-clicked to open in a new tab.
|
|
||||||
|
|
||||||
## v1.1.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes allocation permissions checking on the frontend checking the wrong permission therefore leading to the item never showing up.
|
|
||||||
* Fixes allocations not updating correctly when added or deleted and switching between pages.
|
|
||||||
|
|
||||||
## v1.1.0
|
|
||||||
This release **requires** `Wings@1.1.0` in order to work properly due to breaking internal API changes.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixes subuser creation/edit modal not submitting correctly when attemping to make modifications.
|
|
||||||
* Fixes a few remaining issues with multiple egg install scripts.
|
|
||||||
* Removes the ability for a schedule to have a null name and replaces any existing null names with a randomly generated name.
|
|
||||||
* Fixes schedules aborting the entire run process if a single schedule encountered an exception. This resolves batches of schedules never running correctly if they occur after a broken schedule.
|
|
||||||
* Fixes schedules not properly resetting themselves if an exception was encountered during the run.
|
|
||||||
* Fixes numerous N+1 query run-aways when loading multiple servers via the API.
|
|
||||||
* Fixes numerous issues with displaying directory and file names in the file manager if they included special characters that could not be decoded properly.
|
|
||||||
* Fixes CPU pinning not being properly passed along to Wings when updated (this also fixes memory/CPU/disk not passing along correctly as well).
|
|
||||||
* Fixes spinner not displaying properly when displayed over a modal.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds ability for users to generate their own additional server allocations via the frontend if enabled.
|
|
||||||
* Adds the ability for a user to remove un-needed allocations from their server (as long as it is not the primary allocation).
|
|
||||||
* Adds support for tracking the last 32 sent console commands for a server. Access the history by using the arrow keys when the command field is active.
|
|
||||||
* Adds S3 specific environment variables allowing for backups to use any S3 compatiable system, not just AWS.
|
|
||||||
* Adds support for copying a server allocation address to the clipboard when clicked.
|
|
||||||
* Adds information about the next schedule run time when viewing an individual schedule.
|
|
||||||
* Adds link to view a server in the admin control panel to the frontend server view when logged in as a root admin.
|
|
||||||
* Adds support for egg-specific frontend/backend functionality. This is a beta feature meant for internal features at this time.
|
|
||||||
* Adds back the EULA warning popup when starting a Minecraft server without an accepted EULA.
|
|
||||||
* Adds missing descriptions for some user permissions on the frontend UI.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Adds Save/Invite button to top of subuser edit/creation modal to reduce the need for scrolling.
|
|
||||||
* Updated language for server transfers and mounts to be less confusing.
|
|
||||||
* Wings API endpoint for fetching all servers on a node is now properly paginated to reduce system load when returning hundreds or thousands of servers at once.
|
|
||||||
* Removes unnecessary Wings API calls when adding/editing/deleting mounts.
|
|
||||||
* Primary allocation for a server is now always returned, even if the subuser does not have permission to view all of the server allocations.
|
|
||||||
* Google Analytics frontend code is now only loaded when a valid key is provided.
|
|
||||||
|
|
||||||
## v1.0.3
|
|
||||||
### Fixed
|
|
||||||
* Fixes bug causing subusers to not be creatable or editable via the frontend for servers.
|
|
||||||
* Fixes system timezone not being passed along properly to the MySQL connection causing scheduled tasks to run every minute when the MySQL instance and Panel timezone did not line up.
|
|
||||||
* Fixes listing servers owned by a user in the admin area to actually list their servers.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Adds SameSite `lax` attribute for cookies generated by the Panel.
|
|
||||||
* Adds better filtering for searching servers in the admin area to better key off name, uuid, or owner username/email.
|
|
||||||
|
|
||||||
## v1.0.2
|
|
||||||
### Added
|
|
||||||
* Adds support for searching inside the file editor.
|
|
||||||
* Adds support for manually executing a schedule regardless of if it is currently queued or not.
|
|
||||||
* Adds an indicator to the schedule UI to show when a schedule is currently processing.
|
|
||||||
* Adds support for setting the `backup_limit` of a server via the API.
|
|
||||||
* **[Security]** Adds login throttling to the 2FA verification endpoint.
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
* Fixes subuser page title missing server name.
|
|
||||||
* Fixes schedule task `sequence_id` not properly being reset when a schedule's task is deleted.
|
|
||||||
* Fixes misc. UI bugs throughout the frontend when long text overflows its bounds.
|
|
||||||
* Fixes user deletion command to properly handle email & ID searching.
|
|
||||||
* Fixes color issues in the terminal causing certain text & background combinations to be illegible.
|
|
||||||
* Fixes reCAPTCHA not properly resetting on login failure.
|
|
||||||
* Fixes error messages not properly resetting between login screens.
|
|
||||||
* Fixes a UI crash when attempting to create or view a directory or file that contained the `%` somewhere in the name.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Updated the search modal to close itself when the ESC key is pressed.
|
|
||||||
* Updates the schedule view and editing UI to better display information to users.
|
|
||||||
* Changed logic powering server searching on the frontend to return more accurate results and return all servers when executing the query as an admin.
|
|
||||||
* Admin CP link no longer opens in a new tab.
|
|
||||||
* Mounts will no longer allow a user to mount certain directory combinations. This blocks mounting one server's files into another server, and blocks using the server data directory as a mount destination.
|
|
||||||
* Cleaned up assorted server build modification code.
|
|
||||||
* Updates default eggs to have improved install scripts and more consistent container usage.
|
|
||||||
|
|
||||||
## v1.0.1
|
|
||||||
### Fixed
|
|
||||||
* Fixes 500 error when mounting a mount to a server, and other related errors when handling mounts.
|
|
||||||
* Ensures that `server_transfers` database is deleted if it already exists to avoid unnecessary error.
|
|
||||||
* Fixes servers getting marked as "not installed" when modifying their startup arguments.
|
|
||||||
* Fixes filemanager breadcrumbs being set incorrectly when navigating between files and folders.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* Change the requests per minute from 240 to 720 for the client API to avoid unecessarily displaying
|
|
||||||
"Too Many Requests" errors.
|
|
||||||
* Added error output to certain commands that will output and terminate the command execution if the database
|
|
||||||
migrations have not been run correctly for the instance.
|
|
||||||
|
|
||||||
## v1.0.0
|
|
||||||
Pterodactyl 1.0 represents the culmination of over two years of work, almost 2,000 commits, endless bug and feature requests, and a dream that
|
|
||||||
has been in the making since 2013. 🎉
|
|
||||||
|
|
||||||
Due to the sheer size and timeline of this release I've massively truncated the listing below. There are numerous smaller
|
|
||||||
bug fixes and changes that would simply be too difficult to keep track of here. Please feel free to browse through the releases
|
|
||||||
tab for this repository to see more specific changes that have been made.
|
|
||||||
|
|
||||||
### Added
|
|
||||||
* Adds a new client-facing API allowing a user to control all aspects of their individual servers, or servers
|
|
||||||
which they have been granted access to as a subuser.
|
|
||||||
* Adds the ability for backups to be created for a server both manually and via a scheduled task.
|
|
||||||
* Adds the ability for users to modify their server allocations on the fly and include notes for each allocation.
|
|
||||||
* Adds the ability for users to generate recovery tokens for 2FA protected logins which can be used in place of
|
|
||||||
a code should their device be inaccessible.
|
|
||||||
* Adds support for transfering servers between Nodes via the Panel.
|
|
||||||
* Adds the ability to assign specific CPU cores to a server (CPU Pinning) process.
|
|
||||||
* Server owners can now reinstall their assigned server egg automatically with a button on the frontend.
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
* The entire user frontend has been replaced with a responsive, React backed design implemented using Tailwind CSS.
|
|
||||||
* Replaces a large amount of complex daemon authentication logic by funneling most API calls through the Panel, and using
|
|
||||||
JSON Web Tokens where necessary to handle one-time direct authentication with Wings.
|
|
||||||
* Frontend server listing now includes a toggle to show or hide servers which an administrator has access to, rather
|
|
||||||
than always showing all servers on the system when logged into an admin account.
|
|
||||||
* We've replaced Ace Editor on the frontend with a better solution to allow lighter builds and more end-user functionality.
|
|
||||||
* Server permissions have been overhauled to be both easier to understand in the codebase, and allows plugins to better
|
|
||||||
hook into the permission system.
|
|
||||||
|
|
||||||
### Removed
|
|
||||||
* Removes large swaths of code complexity and confusing interface designs that caused a lot of pain to new developers
|
|
||||||
trying to jump into the codebase. We've simplified this to stick to more established Laravel design standards to make
|
|
||||||
it easy to parse through the project and make contributions.
|
|
||||||
|
|
||||||
## v0.7.19 (Derelict Dermodactylus)
|
## v0.7.19 (Derelict Dermodactylus)
|
||||||
### Fixed
|
### Fixed
|
||||||
* **[Security]** Fixes XSS in the admin area's server owner selection.
|
* **[Security]** Fixes XSS in the admin area's server owner selection.
|
||||||
|
|
|
@ -1,31 +1,44 @@
|
||||||
# Contributing
|
# Contributing
|
||||||
|
We're glad you want to help us out and make this panel the best that it can be! We have a few simple things to follow when making changes to files and adding new features.
|
||||||
|
|
||||||
Pterodactyl does not accept Pull Requests (PRs) _for new functionality_ from users that are not currently part of the
|
### Project Branches
|
||||||
core project team. It has become overwhelming to try and give the proper time and attention that such complicated PRs
|
This section mainly applies to those with read/write access to our repositories, but can be helpful for others.
|
||||||
tend to require — and deserve. As a result, it is in the project's best interest to limit the scope of work on
|
|
||||||
new functionality to work done within the core project team.
|
|
||||||
|
|
||||||
PRs that address existing _bugs_ with a corresponding issue opened in our issue tracker will continue to be accepted
|
The `develop` branch should always be in a runnable state, and not contain any major breaking features. For the most part, this means you will need to create `feature/` branches in order to add new functionality or change how things work. When making a feature branch, if it is referencing something in the issue tracker, please title the branch `feature/PTDL-###` where `###` is the issue number.
|
||||||
and reviewed. Their scope is often significantly more targeted, and simply improving upon existing and well defined
|
|
||||||
logic.
|
Moving forward all commits from contributors should be in the form of a PR, unless it is something we have previously discussed as being able to be pushed right into `develop`.
|
||||||
|
|
||||||
|
All new code should contain unit tests at a minimum (where applicable). There is a lot of uncovered code currently, so as you are doing things please be looking for places that you can write tests.
|
||||||
|
|
||||||
|
### Update the CHANGELOG
|
||||||
|
When adding something that is new, fixed, changed, or security-related for the next release you should be adding a note to the CHANGELOG. If something is changing within the same version (i.e. fixing a bug introduced but not released) it should _not_ go into the CHANGELOG.
|
||||||
|
|
||||||
|
### Code Guidelines
|
||||||
|
We are a `PSR-4` and `PSR-0` compliant project, so please follow those guidelines at a minimum. In addition, StyleCI runs on all of our code to ensure the formatting is standardized across everything. When a PR is made StyleCI will analyze your code and make a pull to that branch if necessary to fix any formatting issues. This project also ships with a PHP-CS configuration file and you are welcome to configure your local environment to make use of that.
|
||||||
|
|
||||||
|
All class variable declarations should be in alphabetical order, and constructor arguments should be in alphabetical order based on the classname. See the example below for how this should look, or check out any of the `app/Service` files for examples.
|
||||||
|
|
||||||
|
```php
|
||||||
|
class ProcessScheduleService
|
||||||
|
{
|
||||||
|
protected $repository;
|
||||||
|
protected $runnerService;
|
||||||
|
|
||||||
|
public function __construct(RunTaskService $runnerService, ScheduleRepositoryInterface $repository)
|
||||||
|
{
|
||||||
|
$this->repository = $repository;
|
||||||
|
$this->runnerService = $runnerService;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
### Responsible Disclosure
|
### Responsible Disclosure
|
||||||
|
This is a fairly in-depth project and makes use of a lot of parts. We strive to keep everything as secure as possible and welcome you to take a look at the code provided in this project yourself. We do ask that you be considerate of others who are using the software and not publicly disclose security issues without contacting us first by email.
|
||||||
|
|
||||||
This is a fairly in-depth project and makes use of a lot of parts. We strive to keep everything as secure as possible
|
We'll make a deal with you: if you contact us by email and we fail to respond to you within a week you are welcome to publicly disclose whatever issue you have found. We understand how frustrating it is when you find something big and no one will respond to you. This holds us to a standard of providing prompt attention to any issues that arise and keeping this community safe.
|
||||||
and welcome you to take a look at the code provided in this project yourself. We do ask that you be considerate of
|
|
||||||
others who are using the software and not publicly disclose security issues without contacting us first by email.
|
|
||||||
|
|
||||||
We'll make a deal with you: if you contact us by email, and we fail to respond to you within a week you are welcome to
|
If you've found what you believe is a security issue please email us at `support@pterodactyl.io`.
|
||||||
publicly disclose whatever issue you have found. We understand how frustrating it is when you find something big and
|
|
||||||
no one will respond to you. This holds us to a standard of providing prompt attention to any issues that arise and
|
|
||||||
keeping this community safe.
|
|
||||||
|
|
||||||
If you've found what you believe is a security issue please email `matthew@pterodactyl.io`. Please check
|
### Where to find Us
|
||||||
[SECURITY.md](/SECURITY.md) for additional details.
|
You can find us in a couple places online. First and foremost, we're active right here on Github. If you encounter a bug or other problems, open an issue on here for us to take a look at it. We also accept feature requests here as well.
|
||||||
|
|
||||||
### Contact Us
|
You can also find us on [Discord](https://pterodactyl.io/discord). In the event that you need to get in contact with us privately feel free to contact us at `support@pterodactyl.io`. Try not to email us with requests for support regarding the panel, we'll probably just direct you to our Discord.
|
||||||
|
|
||||||
You can find us in a couple places online. First and foremost, we're active right here on GitHub. If you encounter a
|
|
||||||
bug or other problems, open an issue on here for us to take a look at it. We also accept feature requests here as well.
|
|
||||||
|
|
||||||
You can also find us on [Discord](https://discord.gg/pterodactyl).
|
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
# Pterodactyl Panel Contributors
|
||||||
|
This panel would not be possible without the support of our wonderful community of
|
||||||
|
developers who provide code enhancements, new features, and bug fixes to make this panel
|
||||||
|
the best that is can be. You can view a full listing of contributors [here](https://github.com/Pterodactyl/Panel/graphs/contributors).
|
||||||
|
|
||||||
|
Dane Everitt [@DaneEveritt](https://github.com/Pterodactyl/Panel/commits?author=DaneEveritt)
|
||||||
|
|
||||||
|
Dylan Seidt [@DDynamic](https://github.com/Pterodactyl/Panel/commits?author=DDynamic)
|
||||||
|
|
||||||
|
[@nikkiii](https://github.com/Pterodactyl/Panel/commits?author=nikkiii)
|
||||||
|
|
||||||
|
# Get Involved
|
||||||
|
See our `CONTRIBUTING.md` document for information on how to get started. Once you've submitted some code feel free to
|
||||||
|
modify this file and add your name to the list. Please follow the format above for your name and linking to your contributions.
|
55
Dockerfile
55
Dockerfile
|
@ -1,41 +1,26 @@
|
||||||
# Stage 0:
|
FROM alpine:3.8
|
||||||
# Build the assets that are needed for the frontend. This build stage is then discarded
|
|
||||||
# since we won't need NodeJS anymore in the future. This Docker image ships a final production
|
|
||||||
# level distribution of Pterodactyl.
|
|
||||||
FROM --platform=$TARGETOS/$TARGETARCH mhart/alpine-node:14
|
|
||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
|
|
||||||
|
RUN apk add --no-cache --update ca-certificates certbot nginx dcron curl tini php7 php7-bcmath php7-common php7-dom php7-fpm php7-gd php7-mbstring php7-openssl php7-zip php7-pdo php7-phar php7-json php7-pdo_mysql php7-session php7-ctype php7-tokenizer php7-zlib php7-simplexml php7-fileinfo supervisor \
|
||||||
|
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer
|
||||||
|
|
||||||
COPY . ./
|
COPY . ./
|
||||||
RUN yarn install --frozen-lockfile \
|
|
||||||
&& yarn run build:production
|
|
||||||
|
|
||||||
# Stage 1:
|
RUN cp .env.example .env \
|
||||||
# Build the actual container with all of the needed PHP dependencies that will run the application.
|
&& composer install --no-dev --optimize-autoloader \
|
||||||
FROM --platform=$TARGETOS/$TARGETARCH php:8.1-fpm-alpine
|
&& rm .env \
|
||||||
WORKDIR /app
|
&& chown -R nginx:nginx . && chmod -R 777 storage/* bootstrap/cache
|
||||||
COPY . ./
|
|
||||||
COPY --from=0 /app/public/assets ./public/assets
|
|
||||||
RUN apk add --no-cache --update ca-certificates dcron curl git supervisor tar unzip nginx libpng-dev libxml2-dev libzip-dev certbot certbot-nginx \
|
|
||||||
&& docker-php-ext-configure zip \
|
|
||||||
&& docker-php-ext-install bcmath gd pdo_mysql zip \
|
|
||||||
&& curl -sS https://getcomposer.org/installer | php -- --install-dir=/usr/local/bin --filename=composer \
|
|
||||||
&& cp .env.example .env \
|
|
||||||
&& mkdir -p bootstrap/cache/ storage/logs storage/framework/sessions storage/framework/views storage/framework/cache \
|
|
||||||
&& chmod 777 -R bootstrap storage \
|
|
||||||
&& composer install --no-dev --optimize-autoloader \
|
|
||||||
&& rm -rf .env bootstrap/cache/*.php \
|
|
||||||
&& mkdir -p /app/storage/logs/ \
|
|
||||||
&& chown -R nginx:nginx .
|
|
||||||
|
|
||||||
RUN rm /usr/local/etc/php-fpm.conf \
|
RUN cp .dev/docker/default.conf /etc/nginx/conf.d/default.conf \
|
||||||
&& echo "* * * * * /usr/local/bin/php /app/artisan schedule:run >> /dev/null 2>&1" >> /var/spool/cron/crontabs/root \
|
&& cp .dev/docker/www.conf /etc/php7/php-fpm.d/www.conf \
|
||||||
&& echo "0 23 * * * certbot renew --nginx --quiet" >> /var/spool/cron/crontabs/root \
|
&& cat .dev/docker/supervisord.conf > /etc/supervisord.conf \
|
||||||
&& sed -i s/ssl_session_cache/#ssl_session_cache/g /etc/nginx/nginx.conf \
|
&& echo "* * * * * /usr/bin/php /app/artisan schedule:run >> /dev/null 2>&1" >> /var/spool/cron/crontabs/root \
|
||||||
&& mkdir -p /var/run/php /var/run/nginx
|
&& sed -i s/ssl_session_cache/#ssl_session_cache/g /etc/nginx/nginx.conf \
|
||||||
|
&& mkdir -p /var/run/php /var/run/nginx
|
||||||
COPY .github/docker/default.conf /etc/nginx/http.d/default.conf
|
|
||||||
COPY .github/docker/www.conf /usr/local/etc/php-fpm.conf
|
|
||||||
COPY .github/docker/supervisord.conf /etc/supervisord.conf
|
|
||||||
|
|
||||||
EXPOSE 80 443
|
EXPOSE 80 443
|
||||||
ENTRYPOINT [ "/bin/ash", ".github/docker/entrypoint.sh" ]
|
|
||||||
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]
|
ENTRYPOINT ["/bin/ash", ".dev/docker/entrypoint.sh"]
|
||||||
|
|
||||||
|
CMD [ "supervisord", "-n", "-c", "/etc/supervisord.conf" ]
|
|
@ -1,8 +1,7 @@
|
||||||
# The MIT License (MIT)
|
# The MIT License (MIT)
|
||||||
|
|
||||||
```
|
```
|
||||||
Pterodactyl®
|
Copyright (c) 2015 - 2020 Dane Everitt <dane@daneeveritt.com>
|
||||||
Copyright © Dane Everitt <dane@daneeveritt.com> and contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
674
NookLicense.md
674
NookLicense.md
|
@ -1,674 +0,0 @@
|
||||||
GNU GENERAL PUBLIC LICENSE
|
|
||||||
Version 3, 29 June 2007
|
|
||||||
|
|
||||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
|
||||||
of this license document, but changing it is not allowed.
|
|
||||||
|
|
||||||
Preamble
|
|
||||||
|
|
||||||
The GNU General Public License is a free, copyleft license for
|
|
||||||
software and other kinds of works.
|
|
||||||
|
|
||||||
The licenses for most software and other practical works are designed
|
|
||||||
to take away your freedom to share and change the works. By contrast,
|
|
||||||
the GNU General Public License is intended to guarantee your freedom to
|
|
||||||
share and change all versions of a program--to make sure it remains free
|
|
||||||
software for all its users. We, the Free Software Foundation, use the
|
|
||||||
GNU General Public License for most of our software; it applies also to
|
|
||||||
any other work released this way by its authors. You can apply it to
|
|
||||||
your programs, too.
|
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
|
||||||
price. Our General Public Licenses are designed to make sure that you
|
|
||||||
have the freedom to distribute copies of free software (and charge for
|
|
||||||
them if you wish), that you receive source code or can get it if you
|
|
||||||
want it, that you can change the software or use pieces of it in new
|
|
||||||
free programs, and that you know you can do these things.
|
|
||||||
|
|
||||||
To protect your rights, we need to prevent others from denying you
|
|
||||||
these rights or asking you to surrender the rights. Therefore, you have
|
|
||||||
certain responsibilities if you distribute copies of the software, or if
|
|
||||||
you modify it: responsibilities to respect the freedom of others.
|
|
||||||
|
|
||||||
For example, if you distribute copies of such a program, whether
|
|
||||||
gratis or for a fee, you must pass on to the recipients the same
|
|
||||||
freedoms that you received. You must make sure that they, too, receive
|
|
||||||
or can get the source code. And you must show them these terms so they
|
|
||||||
know their rights.
|
|
||||||
|
|
||||||
Developers that use the GNU GPL protect your rights with two steps:
|
|
||||||
(1) assert copyright on the software, and (2) offer you this License
|
|
||||||
giving you legal permission to copy, distribute and/or modify it.
|
|
||||||
|
|
||||||
For the developers' and authors' protection, the GPL clearly explains
|
|
||||||
that there is no warranty for this free software. For both users' and
|
|
||||||
authors' sake, the GPL requires that modified versions be marked as
|
|
||||||
changed, so that their problems will not be attributed erroneously to
|
|
||||||
authors of previous versions.
|
|
||||||
|
|
||||||
Some devices are designed to deny users access to install or run
|
|
||||||
modified versions of the software inside them, although the manufacturer
|
|
||||||
can do so. This is fundamentally incompatible with the aim of
|
|
||||||
protecting users' freedom to change the software. The systematic
|
|
||||||
pattern of such abuse occurs in the area of products for individuals to
|
|
||||||
use, which is precisely where it is most unacceptable. Therefore, we
|
|
||||||
have designed this version of the GPL to prohibit the practice for those
|
|
||||||
products. If such problems arise substantially in other domains, we
|
|
||||||
stand ready to extend this provision to those domains in future versions
|
|
||||||
of the GPL, as needed to protect the freedom of users.
|
|
||||||
|
|
||||||
Finally, every program is threatened constantly by software patents.
|
|
||||||
States should not allow patents to restrict development and use of
|
|
||||||
software on general-purpose computers, but in those that do, we wish to
|
|
||||||
avoid the special danger that patents applied to a free program could
|
|
||||||
make it effectively proprietary. To prevent this, the GPL assures that
|
|
||||||
patents cannot be used to render the program non-free.
|
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
|
||||||
modification follow.
|
|
||||||
|
|
||||||
TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
0. Definitions.
|
|
||||||
|
|
||||||
"This License" refers to version 3 of the GNU General Public License.
|
|
||||||
|
|
||||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
|
||||||
works, such as semiconductor masks.
|
|
||||||
|
|
||||||
"The Program" refers to any copyrightable work licensed under this
|
|
||||||
License. Each licensee is addressed as "you". "Licensees" and
|
|
||||||
"recipients" may be individuals or organizations.
|
|
||||||
|
|
||||||
To "modify" a work means to copy from or adapt all or part of the work
|
|
||||||
in a fashion requiring copyright permission, other than the making of an
|
|
||||||
exact copy. The resulting work is called a "modified version" of the
|
|
||||||
earlier work or a work "based on" the earlier work.
|
|
||||||
|
|
||||||
A "covered work" means either the unmodified Program or a work based
|
|
||||||
on the Program.
|
|
||||||
|
|
||||||
To "propagate" a work means to do anything with it that, without
|
|
||||||
permission, would make you directly or secondarily liable for
|
|
||||||
infringement under applicable copyright law, except executing it on a
|
|
||||||
computer or modifying a private copy. Propagation includes copying,
|
|
||||||
distribution (with or without modification), making available to the
|
|
||||||
public, and in some countries other activities as well.
|
|
||||||
|
|
||||||
To "convey" a work means any kind of propagation that enables other
|
|
||||||
parties to make or receive copies. Mere interaction with a user through
|
|
||||||
a computer network, with no transfer of a copy, is not conveying.
|
|
||||||
|
|
||||||
An interactive user interface displays "Appropriate Legal Notices"
|
|
||||||
to the extent that it includes a convenient and prominently visible
|
|
||||||
feature that (1) displays an appropriate copyright notice, and (2)
|
|
||||||
tells the user that there is no warranty for the work (except to the
|
|
||||||
extent that warranties are provided), that licensees may convey the
|
|
||||||
work under this License, and how to view a copy of this License. If
|
|
||||||
the interface presents a list of user commands or options, such as a
|
|
||||||
menu, a prominent item in the list meets this criterion.
|
|
||||||
|
|
||||||
1. Source Code.
|
|
||||||
|
|
||||||
The "source code" for a work means the preferred form of the work
|
|
||||||
for making modifications to it. "Object code" means any non-source
|
|
||||||
form of a work.
|
|
||||||
|
|
||||||
A "Standard Interface" means an interface that either is an official
|
|
||||||
standard defined by a recognized standards body, or, in the case of
|
|
||||||
interfaces specified for a particular programming language, one that
|
|
||||||
is widely used among developers working in that language.
|
|
||||||
|
|
||||||
The "System Libraries" of an executable work include anything, other
|
|
||||||
than the work as a whole, that (a) is included in the normal form of
|
|
||||||
packaging a Major Component, but which is not part of that Major
|
|
||||||
Component, and (b) serves only to enable use of the work with that
|
|
||||||
Major Component, or to implement a Standard Interface for which an
|
|
||||||
implementation is available to the public in source code form. A
|
|
||||||
"Major Component", in this context, means a major essential component
|
|
||||||
(kernel, window system, and so on) of the specific operating system
|
|
||||||
(if any) on which the executable work runs, or a compiler used to
|
|
||||||
produce the work, or an object code interpreter used to run it.
|
|
||||||
|
|
||||||
The "Corresponding Source" for a work in object code form means all
|
|
||||||
the source code needed to generate, install, and (for an executable
|
|
||||||
work) run the object code and to modify the work, including scripts to
|
|
||||||
control those activities. However, it does not include the work's
|
|
||||||
System Libraries, or general-purpose tools or generally available free
|
|
||||||
programs which are used unmodified in performing those activities but
|
|
||||||
which are not part of the work. For example, Corresponding Source
|
|
||||||
includes interface definition files associated with source files for
|
|
||||||
the work, and the source code for shared libraries and dynamically
|
|
||||||
linked subprograms that the work is specifically designed to require,
|
|
||||||
such as by intimate data communication or control flow between those
|
|
||||||
subprograms and other parts of the work.
|
|
||||||
|
|
||||||
The Corresponding Source need not include anything that users
|
|
||||||
can regenerate automatically from other parts of the Corresponding
|
|
||||||
Source.
|
|
||||||
|
|
||||||
The Corresponding Source for a work in source code form is that
|
|
||||||
same work.
|
|
||||||
|
|
||||||
2. Basic Permissions.
|
|
||||||
|
|
||||||
All rights granted under this License are granted for the term of
|
|
||||||
copyright on the Program, and are irrevocable provided the stated
|
|
||||||
conditions are met. This License explicitly affirms your unlimited
|
|
||||||
permission to run the unmodified Program. The output from running a
|
|
||||||
covered work is covered by this License only if the output, given its
|
|
||||||
content, constitutes a covered work. This License acknowledges your
|
|
||||||
rights of fair use or other equivalent, as provided by copyright law.
|
|
||||||
|
|
||||||
You may make, run and propagate covered works that you do not
|
|
||||||
convey, without conditions so long as your license otherwise remains
|
|
||||||
in force. You may convey covered works to others for the sole purpose
|
|
||||||
of having them make modifications exclusively for you, or provide you
|
|
||||||
with facilities for running those works, provided that you comply with
|
|
||||||
the terms of this License in conveying all material for which you do
|
|
||||||
not control copyright. Those thus making or running the covered works
|
|
||||||
for you must do so exclusively on your behalf, under your direction
|
|
||||||
and control, on terms that prohibit them from making any copies of
|
|
||||||
your copyrighted material outside their relationship with you.
|
|
||||||
|
|
||||||
Conveying under any other circumstances is permitted solely under
|
|
||||||
the conditions stated below. Sublicensing is not allowed; section 10
|
|
||||||
makes it unnecessary.
|
|
||||||
|
|
||||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
|
||||||
|
|
||||||
No covered work shall be deemed part of an effective technological
|
|
||||||
measure under any applicable law fulfilling obligations under article
|
|
||||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
|
||||||
similar laws prohibiting or restricting circumvention of such
|
|
||||||
measures.
|
|
||||||
|
|
||||||
When you convey a covered work, you waive any legal power to forbid
|
|
||||||
circumvention of technological measures to the extent such circumvention
|
|
||||||
is effected by exercising rights under this License with respect to
|
|
||||||
the covered work, and you disclaim any intention to limit operation or
|
|
||||||
modification of the work as a means of enforcing, against the work's
|
|
||||||
users, your or third parties' legal rights to forbid circumvention of
|
|
||||||
technological measures.
|
|
||||||
|
|
||||||
4. Conveying Verbatim Copies.
|
|
||||||
|
|
||||||
You may convey verbatim copies of the Program's source code as you
|
|
||||||
receive it, in any medium, provided that you conspicuously and
|
|
||||||
appropriately publish on each copy an appropriate copyright notice;
|
|
||||||
keep intact all notices stating that this License and any
|
|
||||||
non-permissive terms added in accord with section 7 apply to the code;
|
|
||||||
keep intact all notices of the absence of any warranty; and give all
|
|
||||||
recipients a copy of this License along with the Program.
|
|
||||||
|
|
||||||
You may charge any price or no price for each copy that you convey,
|
|
||||||
and you may offer support or warranty protection for a fee.
|
|
||||||
|
|
||||||
5. Conveying Modified Source Versions.
|
|
||||||
|
|
||||||
You may convey a work based on the Program, or the modifications to
|
|
||||||
produce it from the Program, in the form of source code under the
|
|
||||||
terms of section 4, provided that you also meet all of these conditions:
|
|
||||||
|
|
||||||
a) The work must carry prominent notices stating that you modified
|
|
||||||
it, and giving a relevant date.
|
|
||||||
|
|
||||||
b) The work must carry prominent notices stating that it is
|
|
||||||
released under this License and any conditions added under section
|
|
||||||
7. This requirement modifies the requirement in section 4 to
|
|
||||||
"keep intact all notices".
|
|
||||||
|
|
||||||
c) You must license the entire work, as a whole, under this
|
|
||||||
License to anyone who comes into possession of a copy. This
|
|
||||||
License will therefore apply, along with any applicable section 7
|
|
||||||
additional terms, to the whole of the work, and all its parts,
|
|
||||||
regardless of how they are packaged. This License gives no
|
|
||||||
permission to license the work in any other way, but it does not
|
|
||||||
invalidate such permission if you have separately received it.
|
|
||||||
|
|
||||||
d) If the work has interactive user interfaces, each must display
|
|
||||||
Appropriate Legal Notices; however, if the Program has interactive
|
|
||||||
interfaces that do not display Appropriate Legal Notices, your
|
|
||||||
work need not make them do so.
|
|
||||||
|
|
||||||
A compilation of a covered work with other separate and independent
|
|
||||||
works, which are not by their nature extensions of the covered work,
|
|
||||||
and which are not combined with it such as to form a larger program,
|
|
||||||
in or on a volume of a storage or distribution medium, is called an
|
|
||||||
"aggregate" if the compilation and its resulting copyright are not
|
|
||||||
used to limit the access or legal rights of the compilation's users
|
|
||||||
beyond what the individual works permit. Inclusion of a covered work
|
|
||||||
in an aggregate does not cause this License to apply to the other
|
|
||||||
parts of the aggregate.
|
|
||||||
|
|
||||||
6. Conveying Non-Source Forms.
|
|
||||||
|
|
||||||
You may convey a covered work in object code form under the terms
|
|
||||||
of sections 4 and 5, provided that you also convey the
|
|
||||||
machine-readable Corresponding Source under the terms of this License,
|
|
||||||
in one of these ways:
|
|
||||||
|
|
||||||
a) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by the
|
|
||||||
Corresponding Source fixed on a durable physical medium
|
|
||||||
customarily used for software interchange.
|
|
||||||
|
|
||||||
b) Convey the object code in, or embodied in, a physical product
|
|
||||||
(including a physical distribution medium), accompanied by a
|
|
||||||
written offer, valid for at least three years and valid for as
|
|
||||||
long as you offer spare parts or customer support for that product
|
|
||||||
model, to give anyone who possesses the object code either (1) a
|
|
||||||
copy of the Corresponding Source for all the software in the
|
|
||||||
product that is covered by this License, on a durable physical
|
|
||||||
medium customarily used for software interchange, for a price no
|
|
||||||
more than your reasonable cost of physically performing this
|
|
||||||
conveying of source, or (2) access to copy the
|
|
||||||
Corresponding Source from a network server at no charge.
|
|
||||||
|
|
||||||
c) Convey individual copies of the object code with a copy of the
|
|
||||||
written offer to provide the Corresponding Source. This
|
|
||||||
alternative is allowed only occasionally and noncommercially, and
|
|
||||||
only if you received the object code with such an offer, in accord
|
|
||||||
with subsection 6b.
|
|
||||||
|
|
||||||
d) Convey the object code by offering access from a designated
|
|
||||||
place (gratis or for a charge), and offer equivalent access to the
|
|
||||||
Corresponding Source in the same way through the same place at no
|
|
||||||
further charge. You need not require recipients to copy the
|
|
||||||
Corresponding Source along with the object code. If the place to
|
|
||||||
copy the object code is a network server, the Corresponding Source
|
|
||||||
may be on a different server (operated by you or a third party)
|
|
||||||
that supports equivalent copying facilities, provided you maintain
|
|
||||||
clear directions next to the object code saying where to find the
|
|
||||||
Corresponding Source. Regardless of what server hosts the
|
|
||||||
Corresponding Source, you remain obligated to ensure that it is
|
|
||||||
available for as long as needed to satisfy these requirements.
|
|
||||||
|
|
||||||
e) Convey the object code using peer-to-peer transmission, provided
|
|
||||||
you inform other peers where the object code and Corresponding
|
|
||||||
Source of the work are being offered to the general public at no
|
|
||||||
charge under subsection 6d.
|
|
||||||
|
|
||||||
A separable portion of the object code, whose source code is excluded
|
|
||||||
from the Corresponding Source as a System Library, need not be
|
|
||||||
included in conveying the object code work.
|
|
||||||
|
|
||||||
A "User Product" is either (1) a "consumer product", which means any
|
|
||||||
tangible personal property which is normally used for personal, family,
|
|
||||||
or household purposes, or (2) anything designed or sold for incorporation
|
|
||||||
into a dwelling. In determining whether a product is a consumer product,
|
|
||||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
|
||||||
product received by a particular user, "normally used" refers to a
|
|
||||||
typical or common use of that class of product, regardless of the status
|
|
||||||
of the particular user or of the way in which the particular user
|
|
||||||
actually uses, or expects or is expected to use, the product. A product
|
|
||||||
is a consumer product regardless of whether the product has substantial
|
|
||||||
commercial, industrial or non-consumer uses, unless such uses represent
|
|
||||||
the only significant mode of use of the product.
|
|
||||||
|
|
||||||
"Installation Information" for a User Product means any methods,
|
|
||||||
procedures, authorization keys, or other information required to install
|
|
||||||
and execute modified versions of a covered work in that User Product from
|
|
||||||
a modified version of its Corresponding Source. The information must
|
|
||||||
suffice to ensure that the continued functioning of the modified object
|
|
||||||
code is in no case prevented or interfered with solely because
|
|
||||||
modification has been made.
|
|
||||||
|
|
||||||
If you convey an object code work under this section in, or with, or
|
|
||||||
specifically for use in, a User Product, and the conveying occurs as
|
|
||||||
part of a transaction in which the right of possession and use of the
|
|
||||||
User Product is transferred to the recipient in perpetuity or for a
|
|
||||||
fixed term (regardless of how the transaction is characterized), the
|
|
||||||
Corresponding Source conveyed under this section must be accompanied
|
|
||||||
by the Installation Information. But this requirement does not apply
|
|
||||||
if neither you nor any third party retains the ability to install
|
|
||||||
modified object code on the User Product (for example, the work has
|
|
||||||
been installed in ROM).
|
|
||||||
|
|
||||||
The requirement to provide Installation Information does not include a
|
|
||||||
requirement to continue to provide support service, warranty, or updates
|
|
||||||
for a work that has been modified or installed by the recipient, or for
|
|
||||||
the User Product in which it has been modified or installed. Access to a
|
|
||||||
network may be denied when the modification itself materially and
|
|
||||||
adversely affects the operation of the network or violates the rules and
|
|
||||||
protocols for communication across the network.
|
|
||||||
|
|
||||||
Corresponding Source conveyed, and Installation Information provided,
|
|
||||||
in accord with this section must be in a format that is publicly
|
|
||||||
documented (and with an implementation available to the public in
|
|
||||||
source code form), and must require no special password or key for
|
|
||||||
unpacking, reading or copying.
|
|
||||||
|
|
||||||
7. Additional Terms.
|
|
||||||
|
|
||||||
"Additional permissions" are terms that supplement the terms of this
|
|
||||||
License by making exceptions from one or more of its conditions.
|
|
||||||
Additional permissions that are applicable to the entire Program shall
|
|
||||||
be treated as though they were included in this License, to the extent
|
|
||||||
that they are valid under applicable law. If additional permissions
|
|
||||||
apply only to part of the Program, that part may be used separately
|
|
||||||
under those permissions, but the entire Program remains governed by
|
|
||||||
this License without regard to the additional permissions.
|
|
||||||
|
|
||||||
When you convey a copy of a covered work, you may at your option
|
|
||||||
remove any additional permissions from that copy, or from any part of
|
|
||||||
it. (Additional permissions may be written to require their own
|
|
||||||
removal in certain cases when you modify the work.) You may place
|
|
||||||
additional permissions on material, added by you to a covered work,
|
|
||||||
for which you have or can give appropriate copyright permission.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, for material you
|
|
||||||
add to a covered work, you may (if authorized by the copyright holders of
|
|
||||||
that material) supplement the terms of this License with terms:
|
|
||||||
|
|
||||||
a) Disclaiming warranty or limiting liability differently from the
|
|
||||||
terms of sections 15 and 16 of this License; or
|
|
||||||
|
|
||||||
b) Requiring preservation of specified reasonable legal notices or
|
|
||||||
author attributions in that material or in the Appropriate Legal
|
|
||||||
Notices displayed by works containing it; or
|
|
||||||
|
|
||||||
c) Prohibiting misrepresentation of the origin of that material, or
|
|
||||||
requiring that modified versions of such material be marked in
|
|
||||||
reasonable ways as different from the original version; or
|
|
||||||
|
|
||||||
d) Limiting the use for publicity purposes of names of licensors or
|
|
||||||
authors of the material; or
|
|
||||||
|
|
||||||
e) Declining to grant rights under trademark law for use of some
|
|
||||||
trade names, trademarks, or service marks; or
|
|
||||||
|
|
||||||
f) Requiring indemnification of licensors and authors of that
|
|
||||||
material by anyone who conveys the material (or modified versions of
|
|
||||||
it) with contractual assumptions of liability to the recipient, for
|
|
||||||
any liability that these contractual assumptions directly impose on
|
|
||||||
those licensors and authors.
|
|
||||||
|
|
||||||
All other non-permissive additional terms are considered "further
|
|
||||||
restrictions" within the meaning of section 10. If the Program as you
|
|
||||||
received it, or any part of it, contains a notice stating that it is
|
|
||||||
governed by this License along with a term that is a further
|
|
||||||
restriction, you may remove that term. If a license document contains
|
|
||||||
a further restriction but permits relicensing or conveying under this
|
|
||||||
License, you may add to a covered work material governed by the terms
|
|
||||||
of that license document, provided that the further restriction does
|
|
||||||
not survive such relicensing or conveying.
|
|
||||||
|
|
||||||
If you add terms to a covered work in accord with this section, you
|
|
||||||
must place, in the relevant source files, a statement of the
|
|
||||||
additional terms that apply to those files, or a notice indicating
|
|
||||||
where to find the applicable terms.
|
|
||||||
|
|
||||||
Additional terms, permissive or non-permissive, may be stated in the
|
|
||||||
form of a separately written license, or stated as exceptions;
|
|
||||||
the above requirements apply either way.
|
|
||||||
|
|
||||||
8. Termination.
|
|
||||||
|
|
||||||
You may not propagate or modify a covered work except as expressly
|
|
||||||
provided under this License. Any attempt otherwise to propagate or
|
|
||||||
modify it is void, and will automatically terminate your rights under
|
|
||||||
this License (including any patent licenses granted under the third
|
|
||||||
paragraph of section 11).
|
|
||||||
|
|
||||||
However, if you cease all violation of this License, then your
|
|
||||||
license from a particular copyright holder is reinstated (a)
|
|
||||||
provisionally, unless and until the copyright holder explicitly and
|
|
||||||
finally terminates your license, and (b) permanently, if the copyright
|
|
||||||
holder fails to notify you of the violation by some reasonable means
|
|
||||||
prior to 60 days after the cessation.
|
|
||||||
|
|
||||||
Moreover, your license from a particular copyright holder is
|
|
||||||
reinstated permanently if the copyright holder notifies you of the
|
|
||||||
violation by some reasonable means, this is the first time you have
|
|
||||||
received notice of violation of this License (for any work) from that
|
|
||||||
copyright holder, and you cure the violation prior to 30 days after
|
|
||||||
your receipt of the notice.
|
|
||||||
|
|
||||||
Termination of your rights under this section does not terminate the
|
|
||||||
licenses of parties who have received copies or rights from you under
|
|
||||||
this License. If your rights have been terminated and not permanently
|
|
||||||
reinstated, you do not qualify to receive new licenses for the same
|
|
||||||
material under section 10.
|
|
||||||
|
|
||||||
9. Acceptance Not Required for Having Copies.
|
|
||||||
|
|
||||||
You are not required to accept this License in order to receive or
|
|
||||||
run a copy of the Program. Ancillary propagation of a covered work
|
|
||||||
occurring solely as a consequence of using peer-to-peer transmission
|
|
||||||
to receive a copy likewise does not require acceptance. However,
|
|
||||||
nothing other than this License grants you permission to propagate or
|
|
||||||
modify any covered work. These actions infringe copyright if you do
|
|
||||||
not accept this License. Therefore, by modifying or propagating a
|
|
||||||
covered work, you indicate your acceptance of this License to do so.
|
|
||||||
|
|
||||||
10. Automatic Licensing of Downstream Recipients.
|
|
||||||
|
|
||||||
Each time you convey a covered work, the recipient automatically
|
|
||||||
receives a license from the original licensors, to run, modify and
|
|
||||||
propagate that work, subject to this License. You are not responsible
|
|
||||||
for enforcing compliance by third parties with this License.
|
|
||||||
|
|
||||||
An "entity transaction" is a transaction transferring control of an
|
|
||||||
organization, or substantially all assets of one, or subdividing an
|
|
||||||
organization, or merging organizations. If propagation of a covered
|
|
||||||
work results from an entity transaction, each party to that
|
|
||||||
transaction who receives a copy of the work also receives whatever
|
|
||||||
licenses to the work the party's predecessor in interest had or could
|
|
||||||
give under the previous paragraph, plus a right to possession of the
|
|
||||||
Corresponding Source of the work from the predecessor in interest, if
|
|
||||||
the predecessor has it or can get it with reasonable efforts.
|
|
||||||
|
|
||||||
You may not impose any further restrictions on the exercise of the
|
|
||||||
rights granted or affirmed under this License. For example, you may
|
|
||||||
not impose a license fee, royalty, or other charge for exercise of
|
|
||||||
rights granted under this License, and you may not initiate litigation
|
|
||||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
|
||||||
any patent claim is infringed by making, using, selling, offering for
|
|
||||||
sale, or importing the Program or any portion of it.
|
|
||||||
|
|
||||||
11. Patents.
|
|
||||||
|
|
||||||
A "contributor" is a copyright holder who authorizes use under this
|
|
||||||
License of the Program or a work on which the Program is based. The
|
|
||||||
work thus licensed is called the contributor's "contributor version".
|
|
||||||
|
|
||||||
A contributor's "essential patent claims" are all patent claims
|
|
||||||
owned or controlled by the contributor, whether already acquired or
|
|
||||||
hereafter acquired, that would be infringed by some manner, permitted
|
|
||||||
by this License, of making, using, or selling its contributor version,
|
|
||||||
but do not include claims that would be infringed only as a
|
|
||||||
consequence of further modification of the contributor version. For
|
|
||||||
purposes of this definition, "control" includes the right to grant
|
|
||||||
patent sublicenses in a manner consistent with the requirements of
|
|
||||||
this License.
|
|
||||||
|
|
||||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
|
||||||
patent license under the contributor's essential patent claims, to
|
|
||||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
|
||||||
propagate the contents of its contributor version.
|
|
||||||
|
|
||||||
In the following three paragraphs, a "patent license" is any express
|
|
||||||
agreement or commitment, however denominated, not to enforce a patent
|
|
||||||
(such as an express permission to practice a patent or covenant not to
|
|
||||||
sue for patent infringement). To "grant" such a patent license to a
|
|
||||||
party means to make such an agreement or commitment not to enforce a
|
|
||||||
patent against the party.
|
|
||||||
|
|
||||||
If you convey a covered work, knowingly relying on a patent license,
|
|
||||||
and the Corresponding Source of the work is not available for anyone
|
|
||||||
to copy, free of charge and under the terms of this License, through a
|
|
||||||
publicly available network server or other readily accessible means,
|
|
||||||
then you must either (1) cause the Corresponding Source to be so
|
|
||||||
available, or (2) arrange to deprive yourself of the benefit of the
|
|
||||||
patent license for this particular work, or (3) arrange, in a manner
|
|
||||||
consistent with the requirements of this License, to extend the patent
|
|
||||||
license to downstream recipients. "Knowingly relying" means you have
|
|
||||||
actual knowledge that, but for the patent license, your conveying the
|
|
||||||
covered work in a country, or your recipient's use of the covered work
|
|
||||||
in a country, would infringe one or more identifiable patents in that
|
|
||||||
country that you have reason to believe are valid.
|
|
||||||
|
|
||||||
If, pursuant to or in connection with a single transaction or
|
|
||||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
|
||||||
covered work, and grant a patent license to some of the parties
|
|
||||||
receiving the covered work authorizing them to use, propagate, modify
|
|
||||||
or convey a specific copy of the covered work, then the patent license
|
|
||||||
you grant is automatically extended to all recipients of the covered
|
|
||||||
work and works based on it.
|
|
||||||
|
|
||||||
A patent license is "discriminatory" if it does not include within
|
|
||||||
the scope of its coverage, prohibits the exercise of, or is
|
|
||||||
conditioned on the non-exercise of one or more of the rights that are
|
|
||||||
specifically granted under this License. You may not convey a covered
|
|
||||||
work if you are a party to an arrangement with a third party that is
|
|
||||||
in the business of distributing software, under which you make payment
|
|
||||||
to the third party based on the extent of your activity of conveying
|
|
||||||
the work, and under which the third party grants, to any of the
|
|
||||||
parties who would receive the covered work from you, a discriminatory
|
|
||||||
patent license (a) in connection with copies of the covered work
|
|
||||||
conveyed by you (or copies made from those copies), or (b) primarily
|
|
||||||
for and in connection with specific products or compilations that
|
|
||||||
contain the covered work, unless you entered into that arrangement,
|
|
||||||
or that patent license was granted, prior to 28 March 2007.
|
|
||||||
|
|
||||||
Nothing in this License shall be construed as excluding or limiting
|
|
||||||
any implied license or other defenses to infringement that may
|
|
||||||
otherwise be available to you under applicable patent law.
|
|
||||||
|
|
||||||
12. No Surrender of Others' Freedom.
|
|
||||||
|
|
||||||
If conditions are imposed on you (whether by court order, agreement or
|
|
||||||
otherwise) that contradict the conditions of this License, they do not
|
|
||||||
excuse you from the conditions of this License. If you cannot convey a
|
|
||||||
covered work so as to satisfy simultaneously your obligations under this
|
|
||||||
License and any other pertinent obligations, then as a consequence you may
|
|
||||||
not convey it at all. For example, if you agree to terms that obligate you
|
|
||||||
to collect a royalty for further conveying from those to whom you convey
|
|
||||||
the Program, the only way you could satisfy both those terms and this
|
|
||||||
License would be to refrain entirely from conveying the Program.
|
|
||||||
|
|
||||||
13. Use with the GNU Affero General Public License.
|
|
||||||
|
|
||||||
Notwithstanding any other provision of this License, you have
|
|
||||||
permission to link or combine any covered work with a work licensed
|
|
||||||
under version 3 of the GNU Affero General Public License into a single
|
|
||||||
combined work, and to convey the resulting work. The terms of this
|
|
||||||
License will continue to apply to the part which is the covered work,
|
|
||||||
but the special requirements of the GNU Affero General Public License,
|
|
||||||
section 13, concerning interaction through a network will apply to the
|
|
||||||
combination as such.
|
|
||||||
|
|
||||||
14. Revised Versions of this License.
|
|
||||||
|
|
||||||
The Free Software Foundation may publish revised and/or new versions of
|
|
||||||
the GNU General Public License from time to time. Such new versions will
|
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
|
||||||
address new problems or concerns.
|
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the
|
|
||||||
Program specifies that a certain numbered version of the GNU General
|
|
||||||
Public License "or any later version" applies to it, you have the
|
|
||||||
option of following the terms and conditions either of that numbered
|
|
||||||
version or of any later version published by the Free Software
|
|
||||||
Foundation. If the Program does not specify a version number of the
|
|
||||||
GNU General Public License, you may choose any version ever published
|
|
||||||
by the Free Software Foundation.
|
|
||||||
|
|
||||||
If the Program specifies that a proxy can decide which future
|
|
||||||
versions of the GNU General Public License can be used, that proxy's
|
|
||||||
public statement of acceptance of a version permanently authorizes you
|
|
||||||
to choose that version for the Program.
|
|
||||||
|
|
||||||
Later license versions may give you additional or different
|
|
||||||
permissions. However, no additional obligations are imposed on any
|
|
||||||
author or copyright holder as a result of your choosing to follow a
|
|
||||||
later version.
|
|
||||||
|
|
||||||
15. Disclaimer of Warranty.
|
|
||||||
|
|
||||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
|
||||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
|
||||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
|
||||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
|
||||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
||||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
|
||||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
|
||||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
|
||||||
|
|
||||||
16. Limitation of Liability.
|
|
||||||
|
|
||||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
|
||||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
|
||||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
|
||||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
|
||||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
|
||||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
|
||||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
|
||||||
SUCH DAMAGES.
|
|
||||||
|
|
||||||
17. Interpretation of Sections 15 and 16.
|
|
||||||
|
|
||||||
If the disclaimer of warranty and limitation of liability provided
|
|
||||||
above cannot be given local legal effect according to their terms,
|
|
||||||
reviewing courts shall apply local law that most closely approximates
|
|
||||||
an absolute waiver of all civil liability in connection with the
|
|
||||||
Program, unless a warranty or assumption of liability accompanies a
|
|
||||||
copy of the Program in return for a fee.
|
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
|
||||||
|
|
||||||
How to Apply These Terms to Your New Programs
|
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
|
||||||
possible use to the public, the best way to achieve this is to make it
|
|
||||||
free software which everyone can redistribute and change under these terms.
|
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest
|
|
||||||
to attach them to the start of each source file to most effectively
|
|
||||||
state the exclusion of warranty; and each file should have at least
|
|
||||||
the "copyright" line and a pointer to where the full notice is found.
|
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
|
||||||
Copyright (C) <year> <name of author>
|
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
|
||||||
|
|
||||||
If the program does terminal interaction, make it output a short
|
|
||||||
notice like this when it starts in an interactive mode:
|
|
||||||
|
|
||||||
<program> Copyright (C) <year> <name of author>
|
|
||||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
|
||||||
This is free software, and you are welcome to redistribute it
|
|
||||||
under certain conditions; type `show c' for details.
|
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
|
||||||
parts of the General Public License. Of course, your program's commands
|
|
||||||
might be different; for a GUI interface, you would use an "about box".
|
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or school,
|
|
||||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
|
||||||
For more information on this, and how to apply and follow the GNU GPL, see
|
|
||||||
<https://www.gnu.org/licenses/>.
|
|
||||||
|
|
||||||
The GNU General Public License does not permit incorporating your program
|
|
||||||
into proprietary programs. If your program is a subroutine library, you
|
|
||||||
may consider it more useful to permit linking proprietary applications with
|
|
||||||
the library. If this is what you want to do, use the GNU Lesser General
|
|
||||||
Public License instead of this License. But first, please read
|
|
||||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
174
README.md
174
README.md
|
@ -1,135 +1,75 @@
|
||||||
# Nook Theme
|
[![Logo Image](https://cdn.pterodactyl.io/logos/new/pterodactyl_logo.png)](https://pterodactyl.io)
|
||||||
NookTheme is a free and open source [Pterodactyl theme](https://pterodactyl.io) designed to be simple, clean, and modern.
|
|
||||||
|
|
||||||
![Image](https://i.imgur.com/AFjHGBr.png)
|
[![Build status](https://img.shields.io/travis/pterodactyl/panel/develop.svg?style=flat-square)](https://travis-ci.org/pterodactyl/panel)
|
||||||
|
[![StyleCI](https://styleci.io/repos/47508644/shield?branch=develop)](https://styleci.io/repos/47508644)
|
||||||
|
[![Codecov](https://img.shields.io/codecov/c/github/pterodactyl/panel/develop.svg?style=flat-square)](https://codecov.io/gh/Pterodactyl/Panel)
|
||||||
|
[![Discord](https://img.shields.io/discord/122900397965705216.svg?style=flat-square&label=Discord)](https://pterodactyl.io/discord)
|
||||||
|
|
||||||
<details>
|
# Pterodactyl Panel
|
||||||
<summary>View Screnshots</summary>
|
|
||||||
|
|
||||||
![Image](https://i.imgur.com/CNxF3iT.png)
|
Pterodactyl is the open-source game server management panel built with PHP7, Nodejs, and Go. Designed with security in mind, Pterodactyl runs all game servers in isolated Docker containers while exposing a beautiful and intuitive UI to administrators and users.
|
||||||
![Image](https://i.imgur.com/IflRtEX.png)
|
What more are you waiting for? Make game servers a first class citizen on your platform today.
|
||||||
![Image](https://i.imgur.com/vNLK5jP.png)
|
|
||||||
![Image](https://i.imgur.com/dnxV2CS.png)
|
|
||||||
</details>
|
|
||||||
|
|
||||||
## Installation
|
![Image](https://cdn.pterodactyl.io/site-assets/mockup-macbook-grey.png)
|
||||||
|
|
||||||
This will update your panel to the latest version of NookTheme panel is based. <br>
|
## Support & Documentation
|
||||||
You can see the version in the current branch name.
|
Support for using Pterodactyl can be found on our [Documentation Website](https://pterodactyl.io/project/introduction.html), [Guides Website](https://guides.pterodactyl.io), or via our [Discord Chat](https://discord.gg/QRDZvVm).
|
||||||
### Enter Maintenance Mode
|
|
||||||
|
|
||||||
Whenever you are performing an update you should be sure to place your Panel into maintenance mode. This will prevent
|
### Supported Games
|
||||||
users from encountering unexpected errors and ensure everything can be updated before users encounter
|
We support a huge variety of games by utilizing Docker containers to isolate each instance, giving you the power to host your games across the world without having to bloat each physical machine with additional dependencies.
|
||||||
potentially new features.
|
|
||||||
|
|
||||||
```bash
|
Some of our core supported games include:
|
||||||
cd /var/www/pterodactyl
|
|
||||||
|
|
||||||
php artisan down
|
* Minecraft — including Spigot, Sponge, Bungeecord, Waterfall, and more
|
||||||
```
|
* Rust
|
||||||
|
* Terraria
|
||||||
|
* Teamspeak
|
||||||
|
* Mumble
|
||||||
|
* Team Fortress 2
|
||||||
|
* Counter Strike: Global Offensive
|
||||||
|
* Garry's Mod
|
||||||
|
* ARK: Survival Evolved
|
||||||
|
|
||||||
### Download the theme
|
In addition to our standard nest of supported games, our community is constantly pushing the limits of this software and there are plenty more games available provided by the community. Some of these games include:
|
||||||
|
|
||||||
The first step in the update process is to download the new panel files from GitHub. The command below will download
|
* Factorio
|
||||||
the release archive for the most recent version of Pterodactyl, save it in the current directory and will automatically
|
* San Andreas: MP
|
||||||
unpack the archive into your current folder.
|
* Pocketmine MP
|
||||||
|
* Squad
|
||||||
|
* FiveM
|
||||||
|
* Xonotic
|
||||||
|
* Discord ATLBot
|
||||||
|
|
||||||
```bash
|
## Credits
|
||||||
curl -L https://github.com/Nookure/NookTheme/releases/latest/download/panel.tar.gz | tar -xzv
|
This software would not be possible without the work of other open-source authors who provide tools such as:
|
||||||
```
|
|
||||||
|
|
||||||
Once all of the files are downloaded we need to set the correct permissions on the cache and storage directories to avoid
|
[Ace Editor](https://ace.c9.io), [AdminLTE](https://almsaeedstudio.com), [Animate.css](http://daneden.github.io/animate.css/), [AnsiUp](https://github.com/drudru/ansi_up), [Async.js](https://github.com/caolan/async),
|
||||||
any webserver related errors.
|
[Bootstrap](http://getbootstrap.com), [Bootstrap Notify](http://bootstrap-notify.remabledesigns.com), [Chart.js](http://www.chartjs.org), [FontAwesome](http://fontawesome.io),
|
||||||
|
[FontAwesome Animations](https://github.com/l-lin/font-awesome-animation), [jQuery](http://jquery.com), [Laravel](https://laravel.com), [Lodash](https://lodash.com),
|
||||||
|
[Select2](https://select2.github.io), [Socket.io](http://socket.io), [Socket.io File Upload](https://github.com/vote539/socketio-file-upload), [SweetAlert](http://t4t5.github.io/sweetalert),
|
||||||
|
[Typeahead](https://github.com/bassjobsen/Bootstrap-3-Typeahead), and [Particles.js](http://vincentgarreau.com/particles.js).
|
||||||
|
|
||||||
```bash
|
Some Javascript and CSS used within the panel is licensed under a `MIT` or `Apache 2.0` license. Please check their respective header files for more information.
|
||||||
chmod -R 755 storage/* bootstrap/cache
|
|
||||||
```
|
|
||||||
|
|
||||||
### Update Dependencies
|
|
||||||
|
|
||||||
After you've downloaded all of the new files you will need to upgrade the core components of the panel. To do this,
|
|
||||||
simply run the commands below and follow any prompts.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
composer install --no-dev --optimize-autoloader
|
|
||||||
```
|
|
||||||
|
|
||||||
### Clear Compiled Template Cache
|
|
||||||
|
|
||||||
You'll also want to clear the compiled template cache to ensure that new and modified templates show up correctly for
|
|
||||||
users.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
php artisan view:clear
|
|
||||||
php artisan config:clear
|
|
||||||
```
|
|
||||||
|
|
||||||
### Database Updates
|
|
||||||
|
|
||||||
You'll also need to update your database schema for the newest version of Pterodactyl. Running the command below
|
|
||||||
will update the schema and ensure the default eggs we ship are up to date (and add any new ones we might have). Just
|
|
||||||
remember, _never edit core eggs we ship_! They will be overwritten by this update process.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
php artisan migrate --seed --force
|
|
||||||
```
|
|
||||||
|
|
||||||
### Set Permissions
|
|
||||||
|
|
||||||
The last step is to set the proper owner of the files to be the user that runs your webserver. In most cases this
|
|
||||||
is `www-data` but can vary from system to system — sometimes being `nginx`, `caddy`, `apache`, or even `nobody`.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
# If using NGINX or Apache (not on CentOS):
|
|
||||||
chown -R www-data:www-data /var/www/pterodactyl/*
|
|
||||||
|
|
||||||
# If using NGINX on CentOS:
|
|
||||||
chown -R nginx:nginx /var/www/pterodactyl/*
|
|
||||||
|
|
||||||
# If using Apache on CentOS
|
|
||||||
chown -R apache:apache /var/www/pterodactyl/*
|
|
||||||
```
|
|
||||||
|
|
||||||
### Restarting Queue Workers
|
|
||||||
|
|
||||||
After _every_ update you should restart the queue worker to ensure that the new code is loaded in and used.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
php artisan queue:restart
|
|
||||||
```
|
|
||||||
|
|
||||||
### Exit Maintenance Mode
|
|
||||||
|
|
||||||
Now that everything has been updated you need to exit maintenance mode so that the Panel can resume accepting
|
|
||||||
connections.
|
|
||||||
|
|
||||||
```bash
|
|
||||||
php artisan up
|
|
||||||
```
|
|
||||||
|
|
||||||
## Documentation
|
|
||||||
|
|
||||||
* [Panel Documentation](https://pterodactyl.io/panel/1.0/getting_started.html)
|
|
||||||
* [Wings Documentation](https://pterodactyl.io/wings/1.0/installing.html)
|
|
||||||
* [Community Guides](https://pterodactyl.io/community/about.html)
|
|
||||||
* Or, get additional help [via Discord](https://discord.nookure.com/)
|
|
||||||
|
|
||||||
## Star History
|
|
||||||
|
|
||||||
<a href="https://star-history.com/#Nookure/NookTheme&Timeline">
|
|
||||||
<picture>
|
|
||||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=Nookure/NookTheme&type=Timeline&theme=dark" />
|
|
||||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=Nookure/NookTheme&type=Timeline" />
|
|
||||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=Nookure/NookTheme&type=Timeline" />
|
|
||||||
</picture>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
|
```
|
||||||
|
Copyright (c) 2015 - 2018 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
|
||||||
Pterodactyl® Copyright © 2015 - 2023 Dane Everitt and contributors.
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
> Nookure is not affiliated with Pterodactyl® Panel or its contributors.
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
Pterodactyl code released under the [MIT License](./LICENSE.md).
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
NookTheme code edits released under the [GNU GPLv3 License](./NookLicense.md).
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
|
```
|
||||||
|
|
19
SECURITY.md
19
SECURITY.md
|
@ -1,19 +0,0 @@
|
||||||
# Security Policy
|
|
||||||
|
|
||||||
## Supported Versions
|
|
||||||
|
|
||||||
The following versions of Pterodactyl are receiving active support and maintenance. Any security vulnerabilities discovered must be reproducible in supported versions.
|
|
||||||
|
|
||||||
| Panel | Daemon | Supported |
|
|
||||||
|--------|--------------|--------------------|
|
|
||||||
| 1.11.x | wings@1.11.x | :white_check_mark: |
|
|
||||||
| 0.7.x | daemon@0.6.x | :x: |
|
|
||||||
|
|
||||||
|
|
||||||
## Reporting a Vulnerability
|
|
||||||
|
|
||||||
Please reach out directly to any project team member on Discord when reporting a security vulnerability, or you can email `matthew@pterodactyl.io`.
|
|
||||||
|
|
||||||
We make every effort to respond as soon as possible, although it may take a day or two for us to sync internally and determine the severity of the report and its impact. Please, _do not_ use a public facing channel or GitHub issues to report sensitive security issues.
|
|
||||||
|
|
||||||
As part of our process, we will create a security advisory for the affected versions and disclose it publicly, usually two to four weeks after a releasing a version that addresses it.
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
Vagrant.configure("2") do |config|
|
||||||
|
config.vm.box = "bento/ubuntu-16.04"
|
||||||
|
|
||||||
|
config.vm.synced_folder "./", "/var/www/html/pterodactyl",
|
||||||
|
owner: "www-data", group: "www-data"
|
||||||
|
|
||||||
|
config.vm.provision :shell, path: ".dev/vagrant/provision.sh"
|
||||||
|
|
||||||
|
config.vm.network :private_network, ip: "192.168.50.2"
|
||||||
|
config.vm.network :forwarded_port, guest: 80, host: 50080
|
||||||
|
config.vm.network :forwarded_port, guest: 8025, host: 58025
|
||||||
|
config.vm.network :forwarded_port, guest: 3306, host: 53306
|
||||||
|
|
||||||
|
# Config for the vagrant-dns plugin (https://github.com/BerlinVagrant/vagrant-dns)
|
||||||
|
config.dns.tld = "test"
|
||||||
|
config.dns.patterns = [/^pterodactyl.test$/]
|
||||||
|
end
|
|
@ -1,22 +1,31 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Environment;
|
namespace Pterodactyl\Console\Commands\Environment;
|
||||||
|
|
||||||
|
use DateTimeZone;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Console\Kernel;
|
use Illuminate\Contracts\Console\Kernel;
|
||||||
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
||||||
|
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||||
|
|
||||||
class AppSettingsCommand extends Command
|
class AppSettingsCommand extends Command
|
||||||
{
|
{
|
||||||
use EnvironmentWriterTrait;
|
use EnvironmentWriterTrait;
|
||||||
|
|
||||||
public const CACHE_DRIVERS = [
|
const ALLOWED_CACHE_DRIVERS = [
|
||||||
'redis' => 'Redis (recommended)',
|
'redis' => 'Redis (recommended)',
|
||||||
'memcached' => 'Memcached',
|
'memcached' => 'Memcached',
|
||||||
'file' => 'Filesystem',
|
'file' => 'Filesystem',
|
||||||
];
|
];
|
||||||
|
|
||||||
public const SESSION_DRIVERS = [
|
const ALLOWED_SESSION_DRIVERS = [
|
||||||
'redis' => 'Redis (recommended)',
|
'redis' => 'Redis (recommended)',
|
||||||
'memcached' => 'Memcached',
|
'memcached' => 'Memcached',
|
||||||
'database' => 'MySQL Database',
|
'database' => 'MySQL Database',
|
||||||
|
@ -24,14 +33,30 @@ class AppSettingsCommand extends Command
|
||||||
'cookie' => 'Cookie',
|
'cookie' => 'Cookie',
|
||||||
];
|
];
|
||||||
|
|
||||||
public const QUEUE_DRIVERS = [
|
const ALLOWED_QUEUE_DRIVERS = [
|
||||||
'redis' => 'Redis (recommended)',
|
'redis' => 'Redis (recommended)',
|
||||||
'database' => 'MySQL Database',
|
'database' => 'MySQL Database',
|
||||||
'sync' => 'Sync',
|
'sync' => 'Sync',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Console\Kernel
|
||||||
|
*/
|
||||||
|
protected $command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Config\Repository
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Configure basic environment settings for the Panel.';
|
protected $description = 'Configure basic environment settings for the Panel.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:environment:setup
|
protected $signature = 'p:environment:setup
|
||||||
{--new-salt : Whether or not to generate a new salt for Hashids.}
|
{--new-salt : Whether or not to generate a new salt for Hashids.}
|
||||||
{--author= : The email that services created on this instance should be linked to.}
|
{--author= : The email that services created on this instance should be linked to.}
|
||||||
|
@ -43,17 +68,25 @@ class AppSettingsCommand extends Command
|
||||||
{--redis-host= : Redis host to use for connections.}
|
{--redis-host= : Redis host to use for connections.}
|
||||||
{--redis-pass= : Password used to connect to redis.}
|
{--redis-pass= : Password used to connect to redis.}
|
||||||
{--redis-port= : Port to connect to redis over.}
|
{--redis-port= : Port to connect to redis over.}
|
||||||
{--settings-ui= : Enable or disable the settings UI.}
|
{--disable-settings-ui}';
|
||||||
{--telemetry= : Enable or disable anonymous telemetry.}';
|
|
||||||
|
|
||||||
protected array $variables = [];
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $variables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AppSettingsCommand constructor.
|
* AppSettingsCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Config\Repository $config
|
||||||
|
* @param \Illuminate\Contracts\Console\Kernel $command
|
||||||
*/
|
*/
|
||||||
public function __construct(private Kernel $console)
|
public function __construct(ConfigRepository $config, Kernel $command)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->command = $command;
|
||||||
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -61,81 +94,60 @@ class AppSettingsCommand extends Command
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\PterodactylException
|
* @throws \Pterodactyl\Exceptions\PterodactylException
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle()
|
||||||
{
|
{
|
||||||
if (empty(config('hashids.salt')) || $this->option('new-salt')) {
|
if (empty($this->config->get('hashids.salt')) || $this->option('new-salt')) {
|
||||||
$this->variables['HASHIDS_SALT'] = str_random(20);
|
$this->variables['HASHIDS_SALT'] = str_random(20);
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->output->comment('Provide the email address that eggs exported by this Panel should be from. This should be a valid email address.');
|
$this->output->comment(trans('command/messages.environment.app.author_help'));
|
||||||
$this->variables['APP_SERVICE_AUTHOR'] = $this->option('author') ?? $this->ask(
|
$this->variables['APP_SERVICE_AUTHOR'] = $this->option('author') ?? $this->ask(
|
||||||
'Egg Author Email',
|
trans('command/messages.environment.app.author'), $this->config->get('pterodactyl.service.author', 'unknown@unknown.com')
|
||||||
config('pterodactyl.service.author', 'unknown@unknown.com')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!filter_var($this->variables['APP_SERVICE_AUTHOR'], FILTER_VALIDATE_EMAIL)) {
|
$this->output->comment(trans('command/messages.environment.app.app_url_help'));
|
||||||
$this->output->error('The service author email provided is invalid.');
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->output->comment('The application URL MUST begin with https:// or http:// depending on if you are using SSL or not. If you do not include the scheme your emails and other content will link to the wrong location.');
|
|
||||||
$this->variables['APP_URL'] = $this->option('url') ?? $this->ask(
|
$this->variables['APP_URL'] = $this->option('url') ?? $this->ask(
|
||||||
'Application URL',
|
trans('command/messages.environment.app.app_url'), $this->config->get('app.url', 'http://example.org')
|
||||||
config('app.url', 'https://example.com')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->output->comment('The timezone should match one of PHP\'s supported timezones. If you are unsure, please reference https://php.net/manual/en/timezones.php.');
|
$this->output->comment(trans('command/messages.environment.app.timezone_help'));
|
||||||
$this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->anticipate(
|
$this->variables['APP_TIMEZONE'] = $this->option('timezone') ?? $this->anticipate(
|
||||||
'Application Timezone',
|
trans('command/messages.environment.app.timezone'),
|
||||||
\DateTimeZone::listIdentifiers(),
|
DateTimeZone::listIdentifiers(DateTimeZone::ALL),
|
||||||
config('app.timezone')
|
$this->config->get('app.timezone')
|
||||||
);
|
);
|
||||||
|
|
||||||
$selected = config('cache.default', 'redis');
|
$selected = $this->config->get('cache.default', 'redis');
|
||||||
$this->variables['CACHE_DRIVER'] = $this->option('cache') ?? $this->choice(
|
$this->variables['CACHE_DRIVER'] = $this->option('cache') ?? $this->choice(
|
||||||
'Cache Driver',
|
trans('command/messages.environment.app.cache_driver'),
|
||||||
self::CACHE_DRIVERS,
|
self::ALLOWED_CACHE_DRIVERS,
|
||||||
array_key_exists($selected, self::CACHE_DRIVERS) ? $selected : null
|
array_key_exists($selected, self::ALLOWED_CACHE_DRIVERS) ? $selected : null
|
||||||
);
|
);
|
||||||
|
|
||||||
$selected = config('session.driver', 'redis');
|
$selected = $this->config->get('session.driver', 'redis');
|
||||||
$this->variables['SESSION_DRIVER'] = $this->option('session') ?? $this->choice(
|
$this->variables['SESSION_DRIVER'] = $this->option('session') ?? $this->choice(
|
||||||
'Session Driver',
|
trans('command/messages.environment.app.session_driver'),
|
||||||
self::SESSION_DRIVERS,
|
self::ALLOWED_SESSION_DRIVERS,
|
||||||
array_key_exists($selected, self::SESSION_DRIVERS) ? $selected : null
|
array_key_exists($selected, self::ALLOWED_SESSION_DRIVERS) ? $selected : null
|
||||||
);
|
);
|
||||||
|
|
||||||
$selected = config('queue.default', 'redis');
|
$selected = $this->config->get('queue.default', 'redis');
|
||||||
$this->variables['QUEUE_CONNECTION'] = $this->option('queue') ?? $this->choice(
|
$this->variables['QUEUE_CONNECTION'] = $this->option('queue') ?? $this->choice(
|
||||||
'Queue Driver',
|
trans('command/messages.environment.app.queue_driver'),
|
||||||
self::QUEUE_DRIVERS,
|
self::ALLOWED_QUEUE_DRIVERS,
|
||||||
array_key_exists($selected, self::QUEUE_DRIVERS) ? $selected : null
|
array_key_exists($selected, self::ALLOWED_QUEUE_DRIVERS) ? $selected : null
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!is_null($this->option('settings-ui'))) {
|
if ($this->option('disable-settings-ui')) {
|
||||||
$this->variables['APP_ENVIRONMENT_ONLY'] = $this->option('settings-ui') == 'true' ? 'false' : 'true';
|
$this->variables['APP_ENVIRONMENT_ONLY'] = 'true';
|
||||||
} else {
|
} else {
|
||||||
$this->variables['APP_ENVIRONMENT_ONLY'] = $this->confirm('Enable UI based settings editor?', true) ? 'false' : 'true';
|
$this->variables['APP_ENVIRONMENT_ONLY'] = $this->confirm(trans('command/messages.environment.app.settings'), true) ? 'false' : 'true';
|
||||||
}
|
|
||||||
|
|
||||||
$this->output->comment('Please reference https://pterodactyl.io/panel/1.0/additional_configuration.html#telemetry for more detailed information regarding telemetry data and collection.');
|
|
||||||
$this->variables['PTERODACTYL_TELEMETRY_ENABLED'] = $this->option('telemetry') ?? $this->confirm(
|
|
||||||
'Enable sending anonymous telemetry data?',
|
|
||||||
config('pterodactyl.telemetry.enabled', true)
|
|
||||||
) ? 'true' : 'false';
|
|
||||||
|
|
||||||
// Make sure session cookies are set as "secure" when using HTTPS
|
|
||||||
if (str_starts_with($this->variables['APP_URL'], 'https://')) {
|
|
||||||
$this->variables['SESSION_SECURE_COOKIE'] = 'true';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->checkForRedis();
|
$this->checkForRedis();
|
||||||
$this->writeToEnvironment($this->variables);
|
$this->writeToEnvironment($this->variables);
|
||||||
|
|
||||||
$this->info($this->console->output());
|
$this->info($this->command->output());
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -152,22 +164,21 @@ class AppSettingsCommand extends Command
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->output->note('You\'ve selected the Redis driver for one or more options, please provide valid connection information below. In most cases you can use the defaults provided unless you have modified your setup.');
|
$this->output->note(trans('command/messages.environment.app.using_redis'));
|
||||||
$this->variables['REDIS_HOST'] = $this->option('redis-host') ?? $this->ask(
|
$this->variables['REDIS_HOST'] = $this->option('redis-host') ?? $this->ask(
|
||||||
'Redis Host',
|
trans('command/messages.environment.app.redis_host'), $this->config->get('database.redis.default.host')
|
||||||
config('database.redis.default.host')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$askForRedisPassword = true;
|
$askForRedisPassword = true;
|
||||||
if (!empty(config('database.redis.default.password'))) {
|
if (! empty($this->config->get('database.redis.default.password'))) {
|
||||||
$this->variables['REDIS_PASSWORD'] = config('database.redis.default.password');
|
$this->variables['REDIS_PASSWORD'] = $this->config->get('database.redis.default.password');
|
||||||
$askForRedisPassword = $this->confirm('It seems a password is already defined for Redis, would you like to change it?');
|
$askForRedisPassword = $this->confirm(trans('command/messages.environment.app.redis_pass_defined'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($askForRedisPassword) {
|
if ($askForRedisPassword) {
|
||||||
$this->output->comment('By default a Redis server instance has no password as it is running locally and inaccessible to the outside world. If this is the case, simply hit enter without entering a value.');
|
$this->output->comment(trans('command/messages.environment.app.redis_pass_help'));
|
||||||
$this->variables['REDIS_PASSWORD'] = $this->option('redis-pass') ?? $this->output->askHidden(
|
$this->variables['REDIS_PASSWORD'] = $this->option('redis-pass') ?? $this->output->askHidden(
|
||||||
'Redis Password'
|
trans('command/messages.environment.app.redis_password')
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,8 +187,7 @@ class AppSettingsCommand extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->variables['REDIS_PORT'] = $this->option('redis-port') ?? $this->ask(
|
$this->variables['REDIS_PORT'] = $this->option('redis-port') ?? $this->ask(
|
||||||
'Redis Port',
|
trans('command/messages.environment.app.redis_port'), $this->config->get('database.redis.default.port')
|
||||||
config('database.redis.default.port')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,48 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Environment;
|
namespace Pterodactyl\Console\Commands\Environment;
|
||||||
|
|
||||||
|
use PDOException;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Console\Kernel;
|
use Illuminate\Contracts\Console\Kernel;
|
||||||
use Illuminate\Database\DatabaseManager;
|
use Illuminate\Database\DatabaseManager;
|
||||||
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
use Pterodactyl\Traits\Commands\EnvironmentWriterTrait;
|
||||||
|
use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||||
|
|
||||||
class DatabaseSettingsCommand extends Command
|
class DatabaseSettingsCommand extends Command
|
||||||
{
|
{
|
||||||
use EnvironmentWriterTrait;
|
use EnvironmentWriterTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Config\Repository
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Console\Kernel
|
||||||
|
*/
|
||||||
|
protected $console;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Database\DatabaseManager
|
||||||
|
*/
|
||||||
|
protected $database;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Configure database settings for the Panel.';
|
protected $description = 'Configure database settings for the Panel.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:environment:database
|
protected $signature = 'p:environment:database
|
||||||
{--host= : The connection address for the MySQL server.}
|
{--host= : The connection address for the MySQL server.}
|
||||||
{--port= : The connection port for the MySQL server.}
|
{--port= : The connection port for the MySQL server.}
|
||||||
|
@ -20,62 +50,71 @@ class DatabaseSettingsCommand extends Command
|
||||||
{--username= : Username to use when connecting.}
|
{--username= : Username to use when connecting.}
|
||||||
{--password= : Password to use for this database.}';
|
{--password= : Password to use for this database.}';
|
||||||
|
|
||||||
protected array $variables = [];
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $variables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DatabaseSettingsCommand constructor.
|
* DatabaseSettingsCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Config\Repository $config
|
||||||
|
* @param \Illuminate\Database\DatabaseManager $database
|
||||||
|
* @param \Illuminate\Contracts\Console\Kernel $console
|
||||||
*/
|
*/
|
||||||
public function __construct(private DatabaseManager $database, private Kernel $console)
|
public function __construct(ConfigRepository $config, DatabaseManager $database, Kernel $console)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->config = $config;
|
||||||
|
$this->console = $console;
|
||||||
|
$this->database = $database;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle command execution.
|
* Handle command execution.
|
||||||
*
|
*
|
||||||
|
* @return int
|
||||||
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\PterodactylException
|
* @throws \Pterodactyl\Exceptions\PterodactylException
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle()
|
||||||
{
|
{
|
||||||
$this->output->note('It is highly recommended to not use "localhost" as your database host as we have seen frequent socket connection issues. If you want to use a local connection you should be using "127.0.0.1".');
|
$this->output->note(trans('command/messages.environment.database.host_warning'));
|
||||||
$this->variables['DB_HOST'] = $this->option('host') ?? $this->ask(
|
$this->variables['DB_HOST'] = $this->option('host') ?? $this->ask(
|
||||||
'Database Host',
|
trans('command/messages.environment.database.host'), $this->config->get('database.connections.mysql.host', '127.0.0.1')
|
||||||
config('database.connections.mysql.host', '127.0.0.1')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['DB_PORT'] = $this->option('port') ?? $this->ask(
|
$this->variables['DB_PORT'] = $this->option('port') ?? $this->ask(
|
||||||
'Database Port',
|
trans('command/messages.environment.database.port'), $this->config->get('database.connections.mysql.port', 3306)
|
||||||
config('database.connections.mysql.port', 3306)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['DB_DATABASE'] = $this->option('database') ?? $this->ask(
|
$this->variables['DB_DATABASE'] = $this->option('database') ?? $this->ask(
|
||||||
'Database Name',
|
trans('command/messages.environment.database.database'), $this->config->get('database.connections.mysql.database', 'panel')
|
||||||
config('database.connections.mysql.database', 'panel')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->output->note('Using the "root" account for MySQL connections is not only highly frowned upon, it is also not allowed by this application. You\'ll need to have created a MySQL user for this software.');
|
$this->output->note(trans('command/messages.environment.database.username_warning'));
|
||||||
$this->variables['DB_USERNAME'] = $this->option('username') ?? $this->ask(
|
$this->variables['DB_USERNAME'] = $this->option('username') ?? $this->ask(
|
||||||
'Database Username',
|
trans('command/messages.environment.database.username'), $this->config->get('database.connections.mysql.username', 'pterodactyl')
|
||||||
config('database.connections.mysql.username', 'pterodactyl')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$askForMySQLPassword = true;
|
$askForMySQLPassword = true;
|
||||||
if (!empty(config('database.connections.mysql.password')) && $this->input->isInteractive()) {
|
if (! empty($this->config->get('database.connections.mysql.password')) && $this->input->isInteractive()) {
|
||||||
$this->variables['DB_PASSWORD'] = config('database.connections.mysql.password');
|
$this->variables['DB_PASSWORD'] = $this->config->get('database.connections.mysql.password');
|
||||||
$askForMySQLPassword = $this->confirm('It appears you already have a MySQL connection password defined, would you like to change it?');
|
$askForMySQLPassword = $this->confirm(trans('command/messages.environment.database.password_defined'));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($askForMySQLPassword) {
|
if ($askForMySQLPassword) {
|
||||||
$this->variables['DB_PASSWORD'] = $this->option('password') ?? $this->secret('Database Password');
|
$this->variables['DB_PASSWORD'] = $this->option('password') ?? $this->secret(trans('command/messages.environment.database.password'));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$this->testMySQLConnection();
|
$this->testMySQLConnection();
|
||||||
} catch (\PDOException $exception) {
|
} catch (PDOException $exception) {
|
||||||
$this->output->error(sprintf('Unable to connect to the MySQL server using the provided credentials. The error returned was "%s".', $exception->getMessage()));
|
$this->output->error(trans('command/messages.environment.database.connection_error', ['error' => $exception->getMessage()]));
|
||||||
$this->output->error('Your connection credentials have NOT been saved. You will need to provide valid connection information before proceeding.');
|
$this->output->error(trans('command/messages.environment.database.creds_not_saved'));
|
||||||
|
|
||||||
if ($this->confirm('Go back and try again?')) {
|
if ($this->confirm(trans('command/messages.environment.database.try_again'))) {
|
||||||
$this->database->disconnect('_pterodactyl_command_test');
|
$this->database->disconnect('_pterodactyl_command_test');
|
||||||
|
|
||||||
return $this->handle();
|
return $this->handle();
|
||||||
|
@ -96,16 +135,16 @@ class DatabaseSettingsCommand extends Command
|
||||||
*/
|
*/
|
||||||
private function testMySQLConnection()
|
private function testMySQLConnection()
|
||||||
{
|
{
|
||||||
config()->set('database.connections._pterodactyl_command_test', [
|
$this->config->set('database.connections._pterodactyl_command_test', [
|
||||||
'driver' => 'mysql',
|
'driver' => 'mysql',
|
||||||
'host' => $this->variables['DB_HOST'],
|
'host' => $this->variables['DB_HOST'],
|
||||||
'port' => $this->variables['DB_PORT'],
|
'port' => $this->variables['DB_PORT'],
|
||||||
'database' => $this->variables['DB_DATABASE'],
|
'database' => $this->variables['DB_DATABASE'],
|
||||||
'username' => $this->variables['DB_USERNAME'],
|
'username' => $this->variables['DB_USERNAME'],
|
||||||
'password' => $this->variables['DB_PASSWORD'],
|
'password' => $this->variables['DB_PASSWORD'],
|
||||||
'charset' => 'utf8mb4',
|
'charset' => 'utf8mb4',
|
||||||
'collation' => 'utf8mb4_unicode_ci',
|
'collation' => 'utf8mb4_unicode_ci',
|
||||||
'strict' => true,
|
'strict' => true,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
$this->database->connection('_pterodactyl_command_test')->getPdo();
|
$this->database->connection('_pterodactyl_command_test')->getPdo();
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Environment;
|
namespace Pterodactyl\Console\Commands\Environment;
|
||||||
|
|
||||||
|
@ -10,8 +17,19 @@ class EmailSettingsCommand extends Command
|
||||||
{
|
{
|
||||||
use EnvironmentWriterTrait;
|
use EnvironmentWriterTrait;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Config\Repository
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Set or update the email sending configuration for the Panel.';
|
protected $description = 'Set or update the email sending configuration for the Panel.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:environment:mail
|
protected $signature = 'p:environment:mail
|
||||||
{--driver= : The mail driver to use.}
|
{--driver= : The mail driver to use.}
|
||||||
{--email= : Email address that messages from the Panel will originate from.}
|
{--email= : Email address that messages from the Panel will originate from.}
|
||||||
|
@ -19,37 +37,40 @@ class EmailSettingsCommand extends Command
|
||||||
{--encryption=}
|
{--encryption=}
|
||||||
{--host=}
|
{--host=}
|
||||||
{--port=}
|
{--port=}
|
||||||
{--endpoint=}
|
|
||||||
{--username=}
|
{--username=}
|
||||||
{--password=}';
|
{--password=}';
|
||||||
|
|
||||||
protected array $variables = [];
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $variables = [];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* EmailSettingsCommand constructor.
|
* EmailSettingsCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Config\Repository $config
|
||||||
*/
|
*/
|
||||||
public function __construct(private ConfigRepository $config)
|
public function __construct(ConfigRepository $config)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->config = $config;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle command execution.
|
* Handle command execution.
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\PterodactylException
|
* @throws \Pterodactyl\Exceptions\PterodactylException
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
$this->variables['MAIL_DRIVER'] = $this->option('driver') ?? $this->choice(
|
$this->variables['MAIL_DRIVER'] = $this->option('driver') ?? $this->choice(
|
||||||
trans('command/messages.environment.mail.ask_driver'),
|
trans('command/messages.environment.mail.ask_driver'), [
|
||||||
[
|
|
||||||
'smtp' => 'SMTP Server',
|
'smtp' => 'SMTP Server',
|
||||||
'sendmail' => 'sendmail Binary',
|
'mail' => 'PHP\'s Internal Mail Function',
|
||||||
'mailgun' => 'Mailgun Transactional Email',
|
'mailgun' => 'Mailgun Transactional Email',
|
||||||
'mandrill' => 'Mandrill Transactional Email',
|
'mandrill' => 'Mandrill Transactional Email',
|
||||||
'postmark' => 'Postmark Transactional Email',
|
'postmark' => 'Postmarkapp Transactional Email',
|
||||||
],
|
], $this->config->get('mail.driver', 'smtp')
|
||||||
$this->config->get('mail.default', 'smtp')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$method = 'setup' . studly_case($this->variables['MAIL_DRIVER']) . 'DriverVariables';
|
$method = 'setup' . studly_case($this->variables['MAIL_DRIVER']) . 'DriverVariables';
|
||||||
|
@ -57,14 +78,16 @@ class EmailSettingsCommand extends Command
|
||||||
$this->{$method}();
|
$this->{$method}();
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->variables['MAIL_FROM_ADDRESS'] = $this->option('email') ?? $this->ask(
|
$this->variables['MAIL_FROM'] = $this->option('email') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_mail_from'),
|
trans('command/messages.environment.mail.ask_mail_from'), $this->config->get('mail.from.address')
|
||||||
$this->config->get('mail.from.address')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['MAIL_FROM_NAME'] = $this->option('from') ?? $this->ask(
|
$this->variables['MAIL_FROM_NAME'] = $this->option('from') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_mail_name'),
|
trans('command/messages.environment.mail.ask_mail_name'), $this->config->get('mail.from.name')
|
||||||
$this->config->get('mail.from.name')
|
);
|
||||||
|
|
||||||
|
$this->variables['MAIL_ENCRYPTION'] = $this->option('encryption') ?? $this->choice(
|
||||||
|
trans('command/messages.environment.mail.ask_encryption'), ['tls' => 'TLS', 'ssl' => 'SSL', '' => 'None'], $this->config->get('mail.encryption', 'tls')
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->writeToEnvironment($this->variables);
|
$this->writeToEnvironment($this->variables);
|
||||||
|
@ -79,29 +102,20 @@ class EmailSettingsCommand extends Command
|
||||||
private function setupSmtpDriverVariables()
|
private function setupSmtpDriverVariables()
|
||||||
{
|
{
|
||||||
$this->variables['MAIL_HOST'] = $this->option('host') ?? $this->ask(
|
$this->variables['MAIL_HOST'] = $this->option('host') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_smtp_host'),
|
trans('command/messages.environment.mail.ask_smtp_host'), $this->config->get('mail.host')
|
||||||
$this->config->get('mail.mailers.smtp.host')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['MAIL_PORT'] = $this->option('port') ?? $this->ask(
|
$this->variables['MAIL_PORT'] = $this->option('port') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_smtp_port'),
|
trans('command/messages.environment.mail.ask_smtp_port'), $this->config->get('mail.port')
|
||||||
$this->config->get('mail.mailers.smtp.port')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['MAIL_USERNAME'] = $this->option('username') ?? $this->ask(
|
$this->variables['MAIL_USERNAME'] = $this->option('username') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_smtp_username'),
|
trans('command/messages.environment.mail.ask_smtp_username'), $this->config->get('mail.username')
|
||||||
$this->config->get('mail.mailers.smtp.username')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['MAIL_PASSWORD'] = $this->option('password') ?? $this->secret(
|
$this->variables['MAIL_PASSWORD'] = $this->option('password') ?? $this->secret(
|
||||||
trans('command/messages.environment.mail.ask_smtp_password')
|
trans('command/messages.environment.mail.ask_smtp_password')
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['MAIL_ENCRYPTION'] = $this->option('encryption') ?? $this->choice(
|
|
||||||
trans('command/messages.environment.mail.ask_encryption'),
|
|
||||||
['tls' => 'TLS', 'ssl' => 'SSL', '' => 'None'],
|
|
||||||
$this->config->get('mail.mailers.smtp.encryption', 'tls')
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -110,18 +124,11 @@ class EmailSettingsCommand extends Command
|
||||||
private function setupMailgunDriverVariables()
|
private function setupMailgunDriverVariables()
|
||||||
{
|
{
|
||||||
$this->variables['MAILGUN_DOMAIN'] = $this->option('host') ?? $this->ask(
|
$this->variables['MAILGUN_DOMAIN'] = $this->option('host') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_mailgun_domain'),
|
trans('command/messages.environment.mail.ask_mailgun_domain'), $this->config->get('services.mailgun.domain')
|
||||||
$this->config->get('services.mailgun.domain')
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->variables['MAILGUN_SECRET'] = $this->option('password') ?? $this->ask(
|
$this->variables['MAILGUN_SECRET'] = $this->option('password') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_mailgun_secret'),
|
trans('command/messages.environment.mail.ask_mailgun_secret'), $this->config->get('services.mailgun.secret')
|
||||||
$this->config->get('services.mailgun.secret')
|
|
||||||
);
|
|
||||||
|
|
||||||
$this->variables['MAILGUN_ENDPOINT'] = $this->option('endpoint') ?? $this->ask(
|
|
||||||
trans('command/messages.environment.mail.ask_mailgun_endpoint'),
|
|
||||||
$this->config->get('services.mailgun.endpoint')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,8 +138,7 @@ class EmailSettingsCommand extends Command
|
||||||
private function setupMandrillDriverVariables()
|
private function setupMandrillDriverVariables()
|
||||||
{
|
{
|
||||||
$this->variables['MANDRILL_SECRET'] = $this->option('password') ?? $this->ask(
|
$this->variables['MANDRILL_SECRET'] = $this->option('password') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_mandrill_secret'),
|
trans('command/messages.environment.mail.ask_mandrill_secret'), $this->config->get('services.mandrill.secret')
|
||||||
$this->config->get('services.mandrill.secret')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,8 +151,7 @@ class EmailSettingsCommand extends Command
|
||||||
$this->variables['MAIL_HOST'] = 'smtp.postmarkapp.com';
|
$this->variables['MAIL_HOST'] = 'smtp.postmarkapp.com';
|
||||||
$this->variables['MAIL_PORT'] = 587;
|
$this->variables['MAIL_PORT'] = 587;
|
||||||
$this->variables['MAIL_USERNAME'] = $this->variables['MAIL_PASSWORD'] = $this->option('username') ?? $this->ask(
|
$this->variables['MAIL_USERNAME'] = $this->variables['MAIL_PASSWORD'] = $this->option('username') ?? $this->ask(
|
||||||
trans('command/messages.environment.mail.ask_postmark_username'),
|
trans('command/messages.environment.mail.ask_postmark_username'), $this->config->get('mail.username')
|
||||||
$this->config->get('mail.username')
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands;
|
namespace Pterodactyl\Console\Commands;
|
||||||
|
|
||||||
|
@ -8,16 +15,38 @@ use Illuminate\Contracts\Config\Repository as ConfigRepository;
|
||||||
|
|
||||||
class InfoCommand extends Command
|
class InfoCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Displays the application, database, and email configurations along with the panel version.';
|
protected $description = 'Displays the application, database, and email configurations along with the panel version.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Config\Repository
|
||||||
|
*/
|
||||||
|
protected $config;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:info';
|
protected $signature = 'p:info';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VersionCommand constructor.
|
* @var \Pterodactyl\Services\Helpers\SoftwareVersionService
|
||||||
*/
|
*/
|
||||||
public function __construct(private ConfigRepository $config, private SoftwareVersionService $versionService)
|
protected $versionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* VersionCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Config\Repository $config
|
||||||
|
* @param \Pterodactyl\Services\Helpers\SoftwareVersionService $versionService
|
||||||
|
*/
|
||||||
|
public function __construct(ConfigRepository $config, SoftwareVersionService $versionService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->config = $config;
|
||||||
|
$this->versionService = $versionService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -36,7 +65,7 @@ class InfoCommand extends Command
|
||||||
$this->output->title('Application Configuration');
|
$this->output->title('Application Configuration');
|
||||||
$this->table([], [
|
$this->table([], [
|
||||||
['Environment', $this->formatText($this->config->get('app.env'), $this->config->get('app.env') === 'production' ?: 'bg=red')],
|
['Environment', $this->formatText($this->config->get('app.env'), $this->config->get('app.env') === 'production' ?: 'bg=red')],
|
||||||
['Debug Mode', $this->formatText($this->config->get('app.debug') ? 'Yes' : 'No', !$this->config->get('app.debug') ?: 'bg=red')],
|
['Debug Mode', $this->formatText($this->config->get('app.debug') ? 'Yes' : 'No', ! $this->config->get('app.debug') ?: 'bg=red')],
|
||||||
['Installation URL', $this->config->get('app.url')],
|
['Installation URL', $this->config->get('app.url')],
|
||||||
['Installation Directory', base_path()],
|
['Installation Directory', base_path()],
|
||||||
['Timezone', $this->config->get('app.timezone')],
|
['Timezone', $this->config->get('app.timezone')],
|
||||||
|
@ -52,29 +81,32 @@ class InfoCommand extends Command
|
||||||
$driver = $this->config->get('database.default');
|
$driver = $this->config->get('database.default');
|
||||||
$this->table([], [
|
$this->table([], [
|
||||||
['Driver', $driver],
|
['Driver', $driver],
|
||||||
['Host', $this->config->get("database.connections.$driver.host")],
|
['Host', $this->config->get("database.connections.{$driver}.host")],
|
||||||
['Port', $this->config->get("database.connections.$driver.port")],
|
['Port', $this->config->get("database.connections.{$driver}.port")],
|
||||||
['Database', $this->config->get("database.connections.$driver.database")],
|
['Database', $this->config->get("database.connections.{$driver}.database")],
|
||||||
['Username', $this->config->get("database.connections.$driver.username")],
|
['Username', $this->config->get("database.connections.{$driver}.username")],
|
||||||
], 'compact');
|
], 'compact');
|
||||||
|
|
||||||
// TODO: Update this to handle other mail drivers
|
|
||||||
$this->output->title('Email Configuration');
|
$this->output->title('Email Configuration');
|
||||||
$this->table([], [
|
$this->table([], [
|
||||||
['Driver', $this->config->get('mail.default')],
|
['Driver', $this->config->get('mail.driver')],
|
||||||
['Host', $this->config->get('mail.mailers.smtp.host')],
|
['Host', $this->config->get('mail.host')],
|
||||||
['Port', $this->config->get('mail.mailers.smtp.port')],
|
['Port', $this->config->get('mail.port')],
|
||||||
['Username', $this->config->get('mail.mailers.smtp.username')],
|
['Username', $this->config->get('mail.username')],
|
||||||
['From Address', $this->config->get('mail.from.address')],
|
['From Address', $this->config->get('mail.from.address')],
|
||||||
['From Name', $this->config->get('mail.from.name')],
|
['From Name', $this->config->get('mail.from.name')],
|
||||||
['Encryption', $this->config->get('mail.mailers.smtp.encryption')],
|
['Encryption', $this->config->get('mail.encryption')],
|
||||||
], 'compact');
|
], 'compact');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format output in a Name: Value manner.
|
* Format output in a Name: Value manner.
|
||||||
|
*
|
||||||
|
* @param string $value
|
||||||
|
* @param string $opts
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function formatText(string $value, string $opts = ''): string
|
private function formatText($value, $opts = '')
|
||||||
{
|
{
|
||||||
return sprintf('<%s>%s</>', $opts, $value);
|
return sprintf('<%s>%s</>', $opts, $value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,28 +1,59 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Location;
|
namespace Pterodactyl\Console\Commands\Location;
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Support\Collection;
|
|
||||||
use Pterodactyl\Services\Locations\LocationDeletionService;
|
use Pterodactyl\Services\Locations\LocationDeletionService;
|
||||||
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
use Pterodactyl\Contracts\Repository\LocationRepositoryInterface;
|
||||||
|
|
||||||
class DeleteLocationCommand extends Command
|
class DeleteLocationCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Locations\LocationDeletionService
|
||||||
|
*/
|
||||||
|
protected $deletionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Deletes a location from the Panel.';
|
protected $description = 'Deletes a location from the Panel.';
|
||||||
|
|
||||||
protected $signature = 'p:location:delete {--short= : The short code of the location to delete.}';
|
/**
|
||||||
|
* @var \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
protected $locations;
|
||||||
|
|
||||||
protected Collection $locations;
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\LocationRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'p:location:delete {--short= : The short code of the location to delete.}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeleteLocationCommand constructor.
|
* DeleteLocationCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\LocationRepositoryInterface $repository
|
||||||
|
* @param \Pterodactyl\Services\Locations\LocationDeletionService $deletionService
|
||||||
*/
|
*/
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private LocationDeletionService $deletionService,
|
LocationDeletionService $deletionService,
|
||||||
private LocationRepositoryInterface $repository
|
LocationRepositoryInterface $repository
|
||||||
) {
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->deletionService = $deletionService;
|
||||||
|
$this->repository = $repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -35,8 +66,7 @@ class DeleteLocationCommand extends Command
|
||||||
{
|
{
|
||||||
$this->locations = $this->locations ?? $this->repository->all();
|
$this->locations = $this->locations ?? $this->repository->all();
|
||||||
$short = $this->option('short') ?? $this->anticipate(
|
$short = $this->option('short') ?? $this->anticipate(
|
||||||
trans('command/messages.location.ask_short'),
|
trans('command/messages.location.ask_short'), $this->locations->pluck('short')->toArray()
|
||||||
$this->locations->pluck('short')->toArray()
|
|
||||||
);
|
);
|
||||||
|
|
||||||
$location = $this->locations->where('short', $short)->first();
|
$location = $this->locations->where('short', $short)->first();
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Location;
|
namespace Pterodactyl\Console\Commands\Location;
|
||||||
|
|
||||||
|
@ -7,18 +14,33 @@ use Pterodactyl\Services\Locations\LocationCreationService;
|
||||||
|
|
||||||
class MakeLocationCommand extends Command
|
class MakeLocationCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Locations\LocationCreationService
|
||||||
|
*/
|
||||||
|
protected $creationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:location:make
|
protected $signature = 'p:location:make
|
||||||
{--short= : The shortcode name of this location (ex. us1).}
|
{--short= : The shortcode name of this location (ex. us1).}
|
||||||
{--long= : A longer description of this location.}';
|
{--long= : A longer description of this location.}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Creates a new location on the system via the CLI.';
|
protected $description = 'Creates a new location on the system via the CLI.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new command instance.
|
* Create a new command instance.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Services\Locations\LocationCreationService $creationService
|
||||||
*/
|
*/
|
||||||
public function __construct(private LocationCreationService $creationService)
|
public function __construct(LocationCreationService $creationService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->creationService = $creationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -2,23 +2,34 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Maintenance;
|
namespace Pterodactyl\Console\Commands\Maintenance;
|
||||||
|
|
||||||
|
use SplFileInfo;
|
||||||
use Carbon\Carbon;
|
use Carbon\Carbon;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Contracts\Filesystem\Filesystem;
|
|
||||||
use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
|
use Illuminate\Contracts\Filesystem\Factory as FilesystemFactory;
|
||||||
|
|
||||||
class CleanServiceBackupFilesCommand extends Command
|
class CleanServiceBackupFilesCommand extends Command
|
||||||
{
|
{
|
||||||
public const BACKUP_THRESHOLD_MINUTES = 5;
|
const BACKUP_THRESHOLD_MINUTES = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Clean orphaned .bak files created when modifying services.';
|
protected $description = 'Clean orphaned .bak files created when modifying services.';
|
||||||
|
|
||||||
protected $signature = 'p:maintenance:clean-service-backups';
|
/**
|
||||||
|
* @var \Illuminate\Contracts\Filesystem\Filesystem
|
||||||
|
*/
|
||||||
|
protected $disk;
|
||||||
|
|
||||||
protected Filesystem $disk;
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'p:maintenance:clean-service-backups';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CleanServiceBackupFilesCommand constructor.
|
* CleanServiceBackupFilesCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Contracts\Filesystem\Factory $filesystem
|
||||||
*/
|
*/
|
||||||
public function __construct(FilesystemFactory $filesystem)
|
public function __construct(FilesystemFactory $filesystem)
|
||||||
{
|
{
|
||||||
|
@ -34,7 +45,7 @@ class CleanServiceBackupFilesCommand extends Command
|
||||||
{
|
{
|
||||||
$files = $this->disk->files('services/.bak');
|
$files = $this->disk->files('services/.bak');
|
||||||
|
|
||||||
collect($files)->each(function (\SplFileInfo $file) {
|
collect($files)->each(function (SplFileInfo $file) {
|
||||||
$lastModified = Carbon::createFromTimestamp($this->disk->lastModified($file->getPath()));
|
$lastModified = Carbon::createFromTimestamp($this->disk->lastModified($file->getPath()));
|
||||||
if ($lastModified->diffInMinutes(Carbon::now()) > self::BACKUP_THRESHOLD_MINUTES) {
|
if ($lastModified->diffInMinutes(Carbon::now()) > self::BACKUP_THRESHOLD_MINUTES) {
|
||||||
$this->disk->delete($file->getPath());
|
$this->disk->delete($file->getPath());
|
||||||
|
|
|
@ -1,49 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Maintenance;
|
|
||||||
|
|
||||||
use Carbon\CarbonImmutable;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\BackupRepository;
|
|
||||||
|
|
||||||
class PruneOrphanedBackupsCommand extends Command
|
|
||||||
{
|
|
||||||
protected $signature = 'p:maintenance:prune-backups {--prune-age=}';
|
|
||||||
|
|
||||||
protected $description = 'Marks all backups older than "n" minutes that have not yet completed as being failed.';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* PruneOrphanedBackupsCommand constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private BackupRepository $backupRepository)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$since = $this->option('prune-age') ?? config('backups.prune_age', 360);
|
|
||||||
if (!$since || !is_digit($since)) {
|
|
||||||
throw new \InvalidArgumentException('The "--prune-age" argument must be a value greater than 0.');
|
|
||||||
}
|
|
||||||
|
|
||||||
$query = $this->backupRepository->getBuilder()
|
|
||||||
->whereNull('completed_at')
|
|
||||||
->where('created_at', '<=', CarbonImmutable::now()->subMinutes($since)->toDateTimeString());
|
|
||||||
|
|
||||||
$count = $query->count();
|
|
||||||
if (!$count) {
|
|
||||||
$this->info('There are no orphaned backups to be marked as failed.');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->warn("Marking $count uncompleted backups that are older than $since minutes as failed.");
|
|
||||||
|
|
||||||
$query->update([
|
|
||||||
'is_successful' => false,
|
|
||||||
'completed_at' => CarbonImmutable::now(),
|
|
||||||
'updated_at' => CarbonImmutable::now(),
|
|
||||||
]);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -0,0 +1,58 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Console\Commands\Migration;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\ApiKey;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface;
|
||||||
|
|
||||||
|
class CleanOrphanedApiKeysCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'p:migration:clean-orphaned-keys';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Cleans API keys from the database that are not assigned a specific role.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* CleanOrphanedApiKeysCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\ApiKeyRepositoryInterface $repository
|
||||||
|
*/
|
||||||
|
public function __construct(ApiKeyRepositoryInterface $repository)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete all orphaned API keys from the database when upgrading from 0.6 to 0.7.
|
||||||
|
*
|
||||||
|
* @return null|void
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$count = $this->repository->findCountWhere([['key_type', '=', ApiKey::TYPE_NONE]]);
|
||||||
|
$continue = $this->confirm(
|
||||||
|
'This action will remove ' . $count . ' keys from the database. Are you sure you wish to continue?', false
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! $continue) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->info('Deleting keys...');
|
||||||
|
$this->repository->deleteWhere([['key_type', '=', ApiKey::TYPE_NONE]]);
|
||||||
|
$this->info('Keys were successfully deleted.');
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,69 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Node;
|
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Pterodactyl\Services\Nodes\NodeCreationService;
|
|
||||||
|
|
||||||
class MakeNodeCommand extends Command
|
|
||||||
{
|
|
||||||
protected $signature = 'p:node:make
|
|
||||||
{--name= : A name to identify the node.}
|
|
||||||
{--description= : A description to identify the node.}
|
|
||||||
{--locationId= : A valid locationId.}
|
|
||||||
{--fqdn= : The domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node.}
|
|
||||||
{--public= : Should the node be public or private? (public=1 / private=0).}
|
|
||||||
{--scheme= : Which scheme should be used? (Enable SSL=https / Disable SSL=http).}
|
|
||||||
{--proxy= : Is the daemon behind a proxy? (Yes=1 / No=0).}
|
|
||||||
{--maintenance= : Should maintenance mode be enabled? (Enable Maintenance mode=1 / Disable Maintenance mode=0).}
|
|
||||||
{--maxMemory= : Set the max memory amount.}
|
|
||||||
{--overallocateMemory= : Enter the amount of ram to overallocate (% or -1 to overallocate the maximum).}
|
|
||||||
{--maxDisk= : Set the max disk amount.}
|
|
||||||
{--overallocateDisk= : Enter the amount of disk to overallocate (% or -1 to overallocate the maximum).}
|
|
||||||
{--uploadSize= : Enter the maximum upload filesize.}
|
|
||||||
{--daemonListeningPort= : Enter the wings listening port.}
|
|
||||||
{--daemonSFTPPort= : Enter the wings SFTP listening port.}
|
|
||||||
{--daemonBase= : Enter the base folder.}';
|
|
||||||
|
|
||||||
protected $description = 'Creates a new node on the system via the CLI.';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* MakeNodeCommand constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private NodeCreationService $creationService)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle the command execution process.
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$data['name'] = $this->option('name') ?? $this->ask('Enter a short identifier used to distinguish this node from others');
|
|
||||||
$data['description'] = $this->option('description') ?? $this->ask('Enter a description to identify the node');
|
|
||||||
$data['location_id'] = $this->option('locationId') ?? $this->ask('Enter a valid location id');
|
|
||||||
$data['scheme'] = $this->option('scheme') ?? $this->anticipate(
|
|
||||||
'Please either enter https for SSL or http for a non-ssl connection',
|
|
||||||
['https', 'http'],
|
|
||||||
'https'
|
|
||||||
);
|
|
||||||
$data['fqdn'] = $this->option('fqdn') ?? $this->ask('Enter a domain name (e.g node.example.com) to be used for connecting to the daemon. An IP address may only be used if you are not using SSL for this node');
|
|
||||||
$data['public'] = $this->option('public') ?? $this->confirm('Should this node be public? As a note, setting a node to private you will be denying the ability to auto-deploy to this node.', true);
|
|
||||||
$data['behind_proxy'] = $this->option('proxy') ?? $this->confirm('Is your FQDN behind a proxy?');
|
|
||||||
$data['maintenance_mode'] = $this->option('maintenance') ?? $this->confirm('Should maintenance mode be enabled?');
|
|
||||||
$data['memory'] = $this->option('maxMemory') ?? $this->ask('Enter the maximum amount of memory');
|
|
||||||
$data['memory_overallocate'] = $this->option('overallocateMemory') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new servers');
|
|
||||||
$data['disk'] = $this->option('maxDisk') ?? $this->ask('Enter the maximum amount of disk space');
|
|
||||||
$data['disk_overallocate'] = $this->option('overallocateDisk') ?? $this->ask('Enter the amount of memory to over allocate by, -1 will disable checking and 0 will prevent creating new server');
|
|
||||||
$data['upload_size'] = $this->option('uploadSize') ?? $this->ask('Enter the maximum filesize upload', '100');
|
|
||||||
$data['daemonListen'] = $this->option('daemonListeningPort') ?? $this->ask('Enter the wings listening port', '8080');
|
|
||||||
$data['daemonSFTP'] = $this->option('daemonSFTPPort') ?? $this->ask('Enter the wings SFTP listening port', '2022');
|
|
||||||
$data['daemonBase'] = $this->option('daemonBase') ?? $this->ask('Enter the base folder', '/var/lib/pterodactyl/volumes');
|
|
||||||
|
|
||||||
$node = $this->creationService->handle($data);
|
|
||||||
$this->line('Successfully created a new node on the location ' . $data['location_id'] . ' with the name ' . $data['name'] . ' and has an id of ' . $node->id . '.');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Node;
|
|
||||||
|
|
||||||
use Pterodactyl\Models\Node;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
|
|
||||||
class NodeConfigurationCommand extends Command
|
|
||||||
{
|
|
||||||
protected $signature = 'p:node:configuration
|
|
||||||
{node : The ID or UUID of the node to return the configuration for.}
|
|
||||||
{--format=yaml : The output format. Options are "yaml" and "json".}';
|
|
||||||
|
|
||||||
protected $description = 'Displays the configuration for the specified node.';
|
|
||||||
|
|
||||||
public function handle(): int
|
|
||||||
{
|
|
||||||
$column = ctype_digit((string) $this->argument('node')) ? 'id' : 'uuid';
|
|
||||||
|
|
||||||
/** @var \Pterodactyl\Models\Node $node */
|
|
||||||
$node = Node::query()->where($column, $this->argument('node'))->firstOr(function () {
|
|
||||||
$this->error('The selected node does not exist.');
|
|
||||||
|
|
||||||
exit(1);
|
|
||||||
});
|
|
||||||
|
|
||||||
$format = $this->option('format');
|
|
||||||
if (!in_array($format, ['yaml', 'yml', 'json'])) {
|
|
||||||
$this->error('Invalid format specified. Valid options are "yaml" and "json".');
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($format === 'json') {
|
|
||||||
$this->output->write($node->getJsonConfiguration(true));
|
|
||||||
} else {
|
|
||||||
$this->output->write($node->getYamlConfiguration());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->output->newLine();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,34 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Node;
|
|
||||||
|
|
||||||
use Pterodactyl\Models\Node;
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
|
|
||||||
class NodeListCommand extends Command
|
|
||||||
{
|
|
||||||
protected $signature = 'p:node:list {--format=text : The output format: "text" or "json". }';
|
|
||||||
|
|
||||||
public function handle(): int
|
|
||||||
{
|
|
||||||
$nodes = Node::query()->with('location')->get()->map(function (Node $node) {
|
|
||||||
return [
|
|
||||||
'id' => $node->id,
|
|
||||||
'uuid' => $node->uuid,
|
|
||||||
'name' => $node->name,
|
|
||||||
'location' => $node->location->short,
|
|
||||||
'host' => $node->getConnectionAddress(),
|
|
||||||
];
|
|
||||||
});
|
|
||||||
|
|
||||||
if ($this->option('format') === 'json') {
|
|
||||||
$this->output->write($nodes->toJson(JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES));
|
|
||||||
} else {
|
|
||||||
$this->table(['ID', 'UUID', 'Name', 'Location', 'Host'], $nodes->toArray());
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->output->newLine();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -12,13 +12,13 @@ class KeyGenerateCommand extends BaseKeyGenerateCommand
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
if (!empty(config('app.key')) && $this->input->isInteractive()) {
|
if (! empty(config('app.key')) && $this->input->isInteractive()) {
|
||||||
$this->output->warning('It appears you have already configured an application encryption key. Continuing with this process with overwrite that key and cause data corruption for any existing encrypted data. DO NOT CONTINUE UNLESS YOU KNOW WHAT YOU ARE DOING.');
|
$this->output->warning(trans('command/messages.key.warning'));
|
||||||
if (!$this->confirm('I understand the consequences of performing this command and accept all responsibility for the loss of encrypted data.')) {
|
if (! $this->confirm(trans('command/messages.key.confirm'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$this->confirm('Are you sure you wish to continue? Changing the application encryption key WILL CAUSE DATA LOSS.')) {
|
if (! $this->confirm(trans('command/messages.key.final_confirm'))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Overrides;
|
|
||||||
|
|
||||||
use Pterodactyl\Console\RequiresDatabaseMigrations;
|
|
||||||
use Illuminate\Database\Console\Seeds\SeedCommand as BaseSeedCommand;
|
|
||||||
|
|
||||||
class SeedCommand extends BaseSeedCommand
|
|
||||||
{
|
|
||||||
use RequiresDatabaseMigrations;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Block someone from running this seed command if they have not completed
|
|
||||||
* the migration process.
|
|
||||||
*/
|
|
||||||
public function handle(): int
|
|
||||||
{
|
|
||||||
if (!$this->hasCompletedMigrations()) {
|
|
||||||
$this->showMigrationWarning();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::handle();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,26 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Overrides;
|
|
||||||
|
|
||||||
use Pterodactyl\Console\RequiresDatabaseMigrations;
|
|
||||||
use Illuminate\Foundation\Console\UpCommand as BaseUpCommand;
|
|
||||||
|
|
||||||
class UpCommand extends BaseUpCommand
|
|
||||||
{
|
|
||||||
use RequiresDatabaseMigrations;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Block someone from running this up command if they have not completed
|
|
||||||
* the migration process.
|
|
||||||
*/
|
|
||||||
public function handle(): int
|
|
||||||
{
|
|
||||||
if (!$this->hasCompletedMigrations()) {
|
|
||||||
$this->showMigrationWarning();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return parent::handle() ?? 0;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,76 +1,86 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Schedule;
|
namespace Pterodactyl\Console\Commands\Schedule;
|
||||||
|
|
||||||
use Exception;
|
use Cake\Chronos\Chronos;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Pterodactyl\Models\Schedule;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Support\Facades\Log;
|
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
|
||||||
use Pterodactyl\Services\Schedules\ProcessScheduleService;
|
use Pterodactyl\Services\Schedules\ProcessScheduleService;
|
||||||
|
use Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface;
|
||||||
|
|
||||||
class ProcessRunnableCommand extends Command
|
class ProcessRunnableCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Process schedules in the database and determine which are ready to run.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Schedules\ProcessScheduleService
|
||||||
|
*/
|
||||||
|
protected $processScheduleService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:schedule:process';
|
protected $signature = 'p:schedule:process';
|
||||||
|
|
||||||
protected $description = 'Process schedules in the database and determine which are ready to run.';
|
/**
|
||||||
|
* ProcessRunnableCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Services\Schedules\ProcessScheduleService $processScheduleService
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\ScheduleRepositoryInterface $repository
|
||||||
|
*/
|
||||||
|
public function __construct(ProcessScheduleService $processScheduleService, ScheduleRepositoryInterface $repository)
|
||||||
|
{
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->processScheduleService = $processScheduleService;
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle command execution.
|
* Handle command execution.
|
||||||
*/
|
*/
|
||||||
public function handle(): int
|
public function handle()
|
||||||
{
|
{
|
||||||
$schedules = Schedule::query()
|
$schedules = $this->repository->getSchedulesToProcess(Chronos::now()->toAtomString());
|
||||||
->with('tasks')
|
|
||||||
->whereRelation('server', fn (Builder $builder) => $builder->whereNull('status'))
|
|
||||||
->where('is_active', true)
|
|
||||||
->where('is_processing', false)
|
|
||||||
->whereRaw('next_run_at <= NOW()')
|
|
||||||
->get();
|
|
||||||
|
|
||||||
if ($schedules->count() < 1) {
|
if ($schedules->count() < 1) {
|
||||||
$this->line('There are no scheduled tasks for servers that need to be run.');
|
$this->line('There are no scheduled tasks for servers that need to be run.');
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$bar = $this->output->createProgressBar(count($schedules));
|
|
||||||
foreach ($schedules as $schedule) {
|
|
||||||
$bar->clear();
|
|
||||||
$this->processSchedule($schedule);
|
|
||||||
$bar->advance();
|
|
||||||
$bar->display();
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->line('');
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes a given schedule and logs and errors encountered the console output. This should
|
|
||||||
* never throw an exception out, otherwise you'll end up killing the entire run group causing
|
|
||||||
* any other schedules to not process correctly.
|
|
||||||
*
|
|
||||||
* @see https://github.com/pterodactyl/panel/issues/2609
|
|
||||||
*/
|
|
||||||
protected function processSchedule(Schedule $schedule)
|
|
||||||
{
|
|
||||||
if ($schedule->tasks->isEmpty()) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
$bar = $this->output->createProgressBar(count($schedules));
|
||||||
$this->getLaravel()->make(ProcessScheduleService::class)->handle($schedule);
|
$schedules->each(function ($schedule) use ($bar) {
|
||||||
|
if ($schedule->tasks instanceof Collection && count($schedule->tasks) > 0) {
|
||||||
|
$this->processScheduleService->handle($schedule);
|
||||||
|
|
||||||
$this->line(trans('command/messages.schedule.output_line', [
|
if ($this->input->isInteractive()) {
|
||||||
'schedule' => $schedule->name,
|
$bar->clear();
|
||||||
'hash' => $schedule->hashid,
|
$this->line(trans('command/messages.schedule.output_line', [
|
||||||
]));
|
'schedule' => $schedule->name,
|
||||||
} catch (\Throwable|\Exception $exception) {
|
'hash' => $schedule->hashid,
|
||||||
Log::error($exception, ['schedule_id' => $schedule->id]);
|
]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$this->error("An error was encountered while processing Schedule #$schedule->id: " . $exception->getMessage());
|
$bar->advance();
|
||||||
}
|
$bar->display();
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,35 +2,67 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\Server;
|
namespace Pterodactyl\Console\Commands\Server;
|
||||||
|
|
||||||
use Pterodactyl\Models\Server;
|
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Illuminate\Database\Eloquent\Builder;
|
use GuzzleHttp\Exception\RequestException;
|
||||||
use Illuminate\Validation\ValidationException;
|
use Illuminate\Validation\ValidationException;
|
||||||
use Illuminate\Validation\Factory as ValidatorFactory;
|
use Illuminate\Validation\Factory as ValidatorFactory;
|
||||||
use Pterodactyl\Repositories\Wings\DaemonPowerRepository;
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
|
use Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface;
|
||||||
|
|
||||||
class BulkPowerActionCommand extends Command
|
class BulkPowerActionCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface
|
||||||
|
*/
|
||||||
|
private $powerRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||||
|
*/
|
||||||
|
private $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Illuminate\Validation\Factory
|
||||||
|
*/
|
||||||
|
private $validator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:server:bulk-power
|
protected $signature = 'p:server:bulk-power
|
||||||
{action : The action to perform (start, stop, restart, kill)}
|
{action : The action to perform (start, stop, restart, kill)}
|
||||||
{--servers= : A comma separated list of servers.}
|
{--servers= : A comma separated list of servers.}
|
||||||
{--nodes= : A comma separated list of nodes.}';
|
{--nodes= : A comma separated list of nodes.}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.';
|
protected $description = 'Perform bulk power management on large groupings of servers or nodes at once.';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* BulkPowerActionCommand constructor.
|
* BulkPowerActionCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\Daemon\PowerRepositoryInterface $powerRepository
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
||||||
|
* @param \Illuminate\Validation\Factory $validator
|
||||||
*/
|
*/
|
||||||
public function __construct(private DaemonPowerRepository $powerRepository, private ValidatorFactory $validator)
|
public function __construct(
|
||||||
{
|
PowerRepositoryInterface $powerRepository,
|
||||||
|
ServerRepositoryInterface $repository,
|
||||||
|
ValidatorFactory $validator
|
||||||
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->powerRepository = $powerRepository;
|
||||||
|
$this->repository = $repository;
|
||||||
|
$this->validator = $validator;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle the bulk power request.
|
* Handle the bulk power request.
|
||||||
*
|
*
|
||||||
* @throws \Illuminate\Validation\ValidationException
|
* @throws \Illuminate\Validation\ValidationException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\Daemon\InvalidPowerSignalException
|
||||||
*/
|
*/
|
||||||
public function handle()
|
public function handle()
|
||||||
{
|
{
|
||||||
|
@ -58,19 +90,23 @@ class BulkPowerActionCommand extends Command
|
||||||
throw new ValidationException($validator);
|
throw new ValidationException($validator);
|
||||||
}
|
}
|
||||||
|
|
||||||
$count = $this->getQueryBuilder($servers, $nodes)->count();
|
$count = $this->repository->getServersForPowerActionCount($servers, $nodes);
|
||||||
if (!$this->confirm(trans('command/messages.server.power.confirm', ['action' => $action, 'count' => $count])) && $this->input->isInteractive()) {
|
if (! $this->confirm(trans('command/messages.server.power.confirm', ['action' => $action, 'count' => $count]))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$bar = $this->output->createProgressBar($count);
|
$bar = $this->output->createProgressBar($count);
|
||||||
$powerRepository = $this->powerRepository;
|
$servers = $this->repository->getServersForPowerAction($servers, $nodes);
|
||||||
$this->getQueryBuilder($servers, $nodes)->each(function (Server $server) use ($action, $powerRepository, &$bar) {
|
|
||||||
|
foreach ($servers as $server) {
|
||||||
$bar->clear();
|
$bar->clear();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$powerRepository->setServer($server)->send($action);
|
$this->powerRepository
|
||||||
} catch (DaemonConnectionException $exception) {
|
->setNode($server->node)
|
||||||
|
->setServer($server)
|
||||||
|
->sendSignal($action);
|
||||||
|
} catch (RequestException $exception) {
|
||||||
$this->output->error(trans('command/messages.server.power.action_failed', [
|
$this->output->error(trans('command/messages.server.power.action_failed', [
|
||||||
'name' => $server->name,
|
'name' => $server->name,
|
||||||
'id' => $server->id,
|
'id' => $server->id,
|
||||||
|
@ -81,26 +117,8 @@ class BulkPowerActionCommand extends Command
|
||||||
|
|
||||||
$bar->advance();
|
$bar->advance();
|
||||||
$bar->display();
|
$bar->display();
|
||||||
});
|
}
|
||||||
|
|
||||||
$this->line('');
|
$this->line('');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the query builder instance that will return the servers that should be affected.
|
|
||||||
*/
|
|
||||||
protected function getQueryBuilder(array $servers, array $nodes): Builder
|
|
||||||
{
|
|
||||||
$instance = Server::query()->whereNull('status');
|
|
||||||
|
|
||||||
if (!empty($nodes) && !empty($servers)) {
|
|
||||||
$instance->whereIn('id', $servers)->orWhereIn('node_id', $nodes);
|
|
||||||
} elseif (empty($nodes) && !empty($servers)) {
|
|
||||||
$instance->whereIn('id', $servers);
|
|
||||||
} elseif (!empty($nodes) && empty($servers)) {
|
|
||||||
$instance->whereIn('node_id', $nodes);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $instance->with('node');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Pterodactyl\Console\Commands\Server;
|
||||||
|
|
||||||
|
use Webmozart\Assert\Assert;
|
||||||
|
use Illuminate\Console\Command;
|
||||||
|
use GuzzleHttp\Exception\RequestException;
|
||||||
|
use Pterodactyl\Contracts\Repository\ServerRepositoryInterface;
|
||||||
|
use Pterodactyl\Services\Servers\ServerConfigurationStructureService;
|
||||||
|
use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface as DaemonServerRepositoryInterface;
|
||||||
|
|
||||||
|
class RebuildServerCommand extends Command
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Servers\ServerConfigurationStructureService
|
||||||
|
*/
|
||||||
|
protected $configurationStructureService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $daemonRepository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $description = 'Rebuild a single server, all servers on a node, or all servers on the panel.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\ServerRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $signature = 'p:server:rebuild
|
||||||
|
{server? : The ID of the server to rebuild.}
|
||||||
|
{--node= : ID of the node to rebuild all servers on. Ignored if server is passed.}';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* RebuildServerCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface $daemonRepository
|
||||||
|
* @param \Pterodactyl\Services\Servers\ServerConfigurationStructureService $configurationStructureService
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\ServerRepositoryInterface $repository
|
||||||
|
*/
|
||||||
|
public function __construct(
|
||||||
|
DaemonServerRepositoryInterface $daemonRepository,
|
||||||
|
ServerConfigurationStructureService $configurationStructureService,
|
||||||
|
ServerRepositoryInterface $repository
|
||||||
|
) {
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->configurationStructureService = $configurationStructureService;
|
||||||
|
$this->daemonRepository = $daemonRepository;
|
||||||
|
$this->repository = $repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle command execution.
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
|
{
|
||||||
|
$servers = $this->getServersToProcess();
|
||||||
|
$bar = $this->output->createProgressBar(count($servers));
|
||||||
|
|
||||||
|
$servers->each(function ($server) use ($bar) {
|
||||||
|
$bar->clear();
|
||||||
|
$json = array_merge($this->configurationStructureService->handle($server), ['rebuild' => true]);
|
||||||
|
|
||||||
|
try {
|
||||||
|
$this->daemonRepository->setServer($server)->update($json);
|
||||||
|
} catch (RequestException $exception) {
|
||||||
|
$this->output->error(trans('command/messages.server.rebuild_failed', [
|
||||||
|
'name' => $server->name,
|
||||||
|
'id' => $server->id,
|
||||||
|
'node' => $server->node->name,
|
||||||
|
'message' => $exception->getMessage(),
|
||||||
|
]));
|
||||||
|
}
|
||||||
|
|
||||||
|
$bar->advance();
|
||||||
|
$bar->display();
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->line('');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the servers to be rebuilt.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Collection
|
||||||
|
*/
|
||||||
|
private function getServersToProcess()
|
||||||
|
{
|
||||||
|
Assert::nullOrIntegerish($this->argument('server'), 'Value passed in server argument must be null or an integer, received %s.');
|
||||||
|
Assert::nullOrIntegerish($this->option('node'), 'Value passed in node option must be null or integer, received %s.');
|
||||||
|
|
||||||
|
return $this->repository->getDataForRebuild($this->argument('server'), $this->option('node'));
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,34 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands;
|
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Symfony\Component\VarDumper\VarDumper;
|
|
||||||
use Pterodactyl\Services\Telemetry\TelemetryCollectionService;
|
|
||||||
|
|
||||||
class TelemetryCommand extends Command
|
|
||||||
{
|
|
||||||
protected $description = 'Displays all the data that would be sent to the Pterodactyl Telemetry Service if telemetry collection is enabled.';
|
|
||||||
|
|
||||||
protected $signature = 'p:telemetry';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TelemetryCommand constructor.
|
|
||||||
*/
|
|
||||||
public function __construct(private TelemetryCollectionService $telemetryCollectionService)
|
|
||||||
{
|
|
||||||
parent::__construct();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handle execution of command.
|
|
||||||
*
|
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
|
||||||
*/
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$this->output->info('Collecting telemetry data, this may take a while...');
|
|
||||||
|
|
||||||
VarDumper::dump($this->telemetryCollectionService->collect());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,195 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands;
|
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
use Pterodactyl\Console\Kernel;
|
|
||||||
use Symfony\Component\Process\Process;
|
|
||||||
use Symfony\Component\Console\Helper\ProgressBar;
|
|
||||||
|
|
||||||
class UpgradeCommand extends Command
|
|
||||||
{
|
|
||||||
protected const DEFAULT_URL = 'https://github.com/pterodactyl/panel/releases/%s/panel.tar.gz';
|
|
||||||
|
|
||||||
protected $signature = 'p:upgrade
|
|
||||||
{--user= : The user that PHP runs under. All files will be owned by this user.}
|
|
||||||
{--group= : The group that PHP runs under. All files will be owned by this group.}
|
|
||||||
{--url= : The specific archive to download.}
|
|
||||||
{--release= : A specific Pterodactyl version to download from GitHub. Leave blank to use latest.}
|
|
||||||
{--skip-download : If set no archive will be downloaded.}';
|
|
||||||
|
|
||||||
protected $description = 'Downloads a new archive for Pterodactyl from GitHub and then executes the normal upgrade commands.';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Executes an upgrade command which will run through all of our standard
|
|
||||||
* commands for Pterodactyl and enable users to basically just download
|
|
||||||
* the archive and execute this and be done.
|
|
||||||
*
|
|
||||||
* This places the application in maintenance mode as well while the commands
|
|
||||||
* are being executed.
|
|
||||||
*
|
|
||||||
* @throws \Exception
|
|
||||||
*/
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$skipDownload = $this->option('skip-download');
|
|
||||||
if (!$skipDownload) {
|
|
||||||
$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.');
|
|
||||||
$this->output->comment('Download Source (set with --url=):');
|
|
||||||
$this->line($this->getUrl());
|
|
||||||
}
|
|
||||||
|
|
||||||
if (version_compare(PHP_VERSION, '7.4.0') < 0) {
|
|
||||||
$this->error('Cannot execute self-upgrade process. The minimum required PHP version required is 7.4.0, you have [' . PHP_VERSION . '].');
|
|
||||||
}
|
|
||||||
|
|
||||||
$user = 'www-data';
|
|
||||||
$group = 'www-data';
|
|
||||||
if ($this->input->isInteractive()) {
|
|
||||||
if (!$skipDownload) {
|
|
||||||
$skipDownload = !$this->confirm('Would you like to download and unpack the archive files for the latest version?', true);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_null($this->option('user'))) {
|
|
||||||
$userDetails = posix_getpwuid(fileowner('public'));
|
|
||||||
$user = $userDetails['name'] ?? 'www-data';
|
|
||||||
|
|
||||||
if (!$this->confirm("Your webserver user has been detected as <fg=blue>[{$user}]:</> is this correct?", true)) {
|
|
||||||
$user = $this->anticipate(
|
|
||||||
'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".',
|
|
||||||
[
|
|
||||||
'www-data',
|
|
||||||
'nginx',
|
|
||||||
'apache',
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_null($this->option('group'))) {
|
|
||||||
$groupDetails = posix_getgrgid(filegroup('public'));
|
|
||||||
$group = $groupDetails['name'] ?? 'www-data';
|
|
||||||
|
|
||||||
if (!$this->confirm("Your webserver group has been detected as <fg=blue>[{$group}]:</> is this correct?", true)) {
|
|
||||||
$group = $this->anticipate(
|
|
||||||
'Please enter the name of the group running your webserver process. Normally this is the same as your user.',
|
|
||||||
[
|
|
||||||
'www-data',
|
|
||||||
'nginx',
|
|
||||||
'apache',
|
|
||||||
]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!$this->confirm('Are you sure you want to run the upgrade process for your Panel?')) {
|
|
||||||
$this->warn('Upgrade process terminated by user.');
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ini_set('output_buffering', '0');
|
|
||||||
$bar = $this->output->createProgressBar($skipDownload ? 9 : 10);
|
|
||||||
$bar->start();
|
|
||||||
|
|
||||||
if (!$skipDownload) {
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line("\$upgrader> curl -L \"{$this->getUrl()}\" | tar -xzv");
|
|
||||||
$process = Process::fromShellCommandline("curl -L \"{$this->getUrl()}\" | tar -xzv");
|
|
||||||
$process->run(function ($type, $buffer) {
|
|
||||||
$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> php artisan down');
|
|
||||||
$this->call('down');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> chmod -R 755 storage bootstrap/cache');
|
|
||||||
$process = new Process(['chmod', '-R', '755', 'storage', 'bootstrap/cache']);
|
|
||||||
$process->run(function ($type, $buffer) {
|
|
||||||
$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$command = ['composer', 'install', '--no-ansi'];
|
|
||||||
if (config('app.env') === 'production' && !config('app.debug')) {
|
|
||||||
$command[] = '--optimize-autoloader';
|
|
||||||
$command[] = '--no-dev';
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->line('$upgrader> ' . implode(' ', $command));
|
|
||||||
$process = new Process($command);
|
|
||||||
$process->setTimeout(10 * 60);
|
|
||||||
$process->run(function ($type, $buffer) {
|
|
||||||
$this->line($buffer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
/** @var \Illuminate\Foundation\Application $app */
|
|
||||||
$app = require __DIR__ . '/../../../bootstrap/app.php';
|
|
||||||
/** @var \Pterodactyl\Console\Kernel $kernel */
|
|
||||||
$kernel = $app->make(Kernel::class);
|
|
||||||
$kernel->bootstrap();
|
|
||||||
$this->setLaravel($app);
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> php artisan view:clear');
|
|
||||||
$this->call('view:clear');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> php artisan config:clear');
|
|
||||||
$this->call('config:clear');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> php artisan migrate --force --seed');
|
|
||||||
$this->call('migrate', ['--force' => true, '--seed' => true]);
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () use ($user, $group) {
|
|
||||||
$this->line("\$upgrader> chown -R {$user}:{$group} *");
|
|
||||||
$process = Process::fromShellCommandline("chown -R {$user}:{$group} *", $this->getLaravel()->basePath());
|
|
||||||
$process->setTimeout(10 * 60);
|
|
||||||
$process->run(function ($type, $buffer) {
|
|
||||||
$this->{$type === Process::ERR ? 'error' : 'line'}($buffer);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> php artisan queue:restart');
|
|
||||||
$this->call('queue:restart');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->withProgress($bar, function () {
|
|
||||||
$this->line('$upgrader> php artisan up');
|
|
||||||
$this->call('up');
|
|
||||||
});
|
|
||||||
|
|
||||||
$this->newLine(2);
|
|
||||||
$this->info('Panel has been successfully upgraded. Please ensure you also update any Wings instances: https://pterodactyl.io/wings/1.0/upgrading.html');
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function withProgress(ProgressBar $bar, \Closure $callback)
|
|
||||||
{
|
|
||||||
$bar->clear();
|
|
||||||
$callback();
|
|
||||||
$bar->advance();
|
|
||||||
$bar->display();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected function getUrl(): string
|
|
||||||
{
|
|
||||||
if ($this->option('url')) {
|
|
||||||
return $this->option('url');
|
|
||||||
}
|
|
||||||
|
|
||||||
return sprintf(self::DEFAULT_URL, $this->option('release') ? 'download/v' . $this->option('release') : 'latest/download');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,44 +1,74 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\User;
|
namespace Pterodactyl\Console\Commands\User;
|
||||||
|
|
||||||
use Pterodactyl\Models\User;
|
|
||||||
use Webmozart\Assert\Assert;
|
use Webmozart\Assert\Assert;
|
||||||
use Illuminate\Console\Command;
|
use Illuminate\Console\Command;
|
||||||
use Pterodactyl\Services\Users\UserDeletionService;
|
use Pterodactyl\Services\Users\UserDeletionService;
|
||||||
|
use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||||
|
|
||||||
class DeleteUserCommand extends Command
|
class DeleteUserCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Users\UserDeletionService
|
||||||
|
*/
|
||||||
|
protected $deletionService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Deletes a user from the Panel if no servers are attached to their account.';
|
protected $description = 'Deletes a user from the Panel if no servers are attached to their account.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:user:delete {--user=}';
|
protected $signature = 'p:user:delete {--user=}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DeleteUserCommand constructor.
|
* DeleteUserCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Services\Users\UserDeletionService $deletionService
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository
|
||||||
*/
|
*/
|
||||||
public function __construct(private UserDeletionService $deletionService)
|
public function __construct(
|
||||||
{
|
UserDeletionService $deletionService,
|
||||||
|
UserRepositoryInterface $repository
|
||||||
|
) {
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->deletionService = $deletionService;
|
||||||
|
$this->repository = $repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handle(): int
|
/**
|
||||||
|
* @return bool
|
||||||
|
* @throws \Pterodactyl\Exceptions\DisplayException
|
||||||
|
*/
|
||||||
|
public function handle()
|
||||||
{
|
{
|
||||||
$search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users'));
|
$search = $this->option('user') ?? $this->ask(trans('command/messages.user.search_users'));
|
||||||
Assert::notEmpty($search, 'Search term should be an email address, got: %s.');
|
Assert::notEmpty($search, 'Search term must be a non-null value, received %s.');
|
||||||
|
|
||||||
$results = User::query()
|
|
||||||
->where('id', 'LIKE', "$search%")
|
|
||||||
->orWhere('username', 'LIKE', "$search%")
|
|
||||||
->orWhere('email', 'LIKE', "$search%")
|
|
||||||
->get();
|
|
||||||
|
|
||||||
|
$results = $this->repository->setSearchTerm($search)->all();
|
||||||
if (count($results) < 1) {
|
if (count($results) < 1) {
|
||||||
$this->error(trans('command/messages.user.no_users_found'));
|
$this->error(trans('command/messages.user.no_users_found'));
|
||||||
if ($this->input->isInteractive()) {
|
if ($this->input->isInteractive()) {
|
||||||
return $this->handle();
|
return $this->handle();
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->input->isInteractive()) {
|
if ($this->input->isInteractive()) {
|
||||||
|
@ -48,24 +78,22 @@ class DeleteUserCommand extends Command
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->table(['User ID', 'Email', 'Name'], $tableValues);
|
$this->table(['User ID', 'Email', 'Name'], $tableValues);
|
||||||
if (!$deleteUser = $this->ask(trans('command/messages.user.select_search_user'))) {
|
if (! $deleteUser = $this->ask(trans('command/messages.user.select_search_user'))) {
|
||||||
return $this->handle();
|
return $this->handle();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (count($results) > 1) {
|
if (count($results) > 1) {
|
||||||
$this->error(trans('command/messages.user.multiple_found'));
|
$this->error(trans('command/messages.user.multiple_found'));
|
||||||
|
|
||||||
return 1;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
$deleteUser = $results->first();
|
$deleteUser = $results->first();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->confirm(trans('command/messages.user.confirm_delete')) || !$this->input->isInteractive()) {
|
if ($this->confirm(trans('command/messages.user.confirm_delete')) || ! $this->input->isInteractive()) {
|
||||||
$this->deletionService->handle($deleteUser);
|
$this->deletionService->handle($deleteUser);
|
||||||
$this->info(trans('command/messages.user.deleted'));
|
$this->info(trans('command/messages.user.deleted'));
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\User;
|
namespace Pterodactyl\Console\Commands\User;
|
||||||
|
|
||||||
|
@ -7,16 +14,31 @@ use Pterodactyl\Contracts\Repository\UserRepositoryInterface;
|
||||||
|
|
||||||
class DisableTwoFactorCommand extends Command
|
class DisableTwoFactorCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Disable two-factor authentication for a specific user in the Panel.';
|
protected $description = 'Disable two-factor authentication for a specific user in the Panel.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Contracts\Repository\UserRepositoryInterface
|
||||||
|
*/
|
||||||
|
protected $repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:user:disable2fa {--email= : The email of the user to disable 2-Factor for.}';
|
protected $signature = 'p:user:disable2fa {--email= : The email of the user to disable 2-Factor for.}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* DisableTwoFactorCommand constructor.
|
* DisableTwoFactorCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Contracts\Repository\UserRepositoryInterface $repository
|
||||||
*/
|
*/
|
||||||
public function __construct(private UserRepositoryInterface $repository)
|
public function __construct(UserRepositoryInterface $repository)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->repository = $repository;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands\User;
|
namespace Pterodactyl\Console\Commands\User;
|
||||||
|
|
||||||
|
@ -7,16 +14,31 @@ use Pterodactyl\Services\Users\UserCreationService;
|
||||||
|
|
||||||
class MakeUserCommand extends Command
|
class MakeUserCommand extends Command
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var \Pterodactyl\Services\Users\UserCreationService
|
||||||
|
*/
|
||||||
|
protected $creationService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $description = 'Creates a user on the system via the CLI.';
|
protected $description = 'Creates a user on the system via the CLI.';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
protected $signature = 'p:user:make {--email=} {--username=} {--name-first=} {--name-last=} {--password=} {--admin=} {--no-password}';
|
protected $signature = 'p:user:make {--email=} {--username=} {--name-first=} {--name-last=} {--password=} {--admin=} {--no-password}';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MakeUserCommand constructor.
|
* MakeUserCommand constructor.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Services\Users\UserCreationService $creationService
|
||||||
*/
|
*/
|
||||||
public function __construct(private UserCreationService $creationService)
|
public function __construct(UserCreationService $creationService)
|
||||||
{
|
{
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->creationService = $creationService;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -33,7 +55,7 @@ class MakeUserCommand extends Command
|
||||||
$name_first = $this->option('name-first') ?? $this->ask(trans('command/messages.user.ask_name_first'));
|
$name_first = $this->option('name-first') ?? $this->ask(trans('command/messages.user.ask_name_first'));
|
||||||
$name_last = $this->option('name-last') ?? $this->ask(trans('command/messages.user.ask_name_last'));
|
$name_last = $this->option('name-last') ?? $this->ask(trans('command/messages.user.ask_name_last'));
|
||||||
|
|
||||||
if (is_null($password = $this->option('password')) && !$this->option('no-password')) {
|
if (is_null($password = $this->option('password')) && ! $this->option('no-password')) {
|
||||||
$this->warn(trans('command/messages.user.ask_password_help'));
|
$this->warn(trans('command/messages.user.ask_password_help'));
|
||||||
$this->line(trans('command/messages.user.ask_password_tip'));
|
$this->line(trans('command/messages.user.ask_password_tip'));
|
||||||
$password = $this->secret(trans('command/messages.user.ask_password'));
|
$password = $this->secret(trans('command/messages.user.ask_password'));
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console\Commands;
|
|
||||||
|
|
||||||
use Illuminate\Console\Command;
|
|
||||||
|
|
||||||
class Love extends Command
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* The name and signature of the console command.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $signature = 'n:love';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The console command description.
|
|
||||||
*
|
|
||||||
* @var string
|
|
||||||
*/
|
|
||||||
protected $description = '<3';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Execute the console command.
|
|
||||||
*
|
|
||||||
* @return int
|
|
||||||
*/
|
|
||||||
public function handle()
|
|
||||||
{
|
|
||||||
$this->info('Ari <3');
|
|
||||||
return Command::SUCCESS;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -2,75 +2,27 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Console;
|
namespace Pterodactyl\Console;
|
||||||
|
|
||||||
use Ramsey\Uuid\Uuid;
|
|
||||||
use Pterodactyl\Models\ActivityLog;
|
|
||||||
use Illuminate\Console\Scheduling\Schedule;
|
use Illuminate\Console\Scheduling\Schedule;
|
||||||
use Illuminate\Database\Console\PruneCommand;
|
|
||||||
use Pterodactyl\Repositories\Eloquent\SettingsRepository;
|
|
||||||
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
|
||||||
use Pterodactyl\Services\Telemetry\TelemetryCollectionService;
|
|
||||||
use Pterodactyl\Console\Commands\Schedule\ProcessRunnableCommand;
|
|
||||||
use Pterodactyl\Console\Commands\Maintenance\PruneOrphanedBackupsCommand;
|
|
||||||
use Pterodactyl\Console\Commands\Maintenance\CleanServiceBackupFilesCommand;
|
|
||||||
|
|
||||||
class Kernel extends ConsoleKernel
|
class Kernel extends ConsoleKernel
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Register the commands for the application.
|
* Register the commands for the application.
|
||||||
*/
|
*/
|
||||||
protected function commands(): void
|
protected function commands()
|
||||||
{
|
{
|
||||||
$this->load(__DIR__ . '/Commands');
|
$this->load(__DIR__ . '/Commands');
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define the application's command schedule.
|
* Define the application's command schedule.
|
||||||
*/
|
|
||||||
protected function schedule(Schedule $schedule): void
|
|
||||||
{
|
|
||||||
// https://laravel.com/docs/10.x/upgrade#redis-cache-tags
|
|
||||||
$schedule->command('cache:prune-stale-tags')->hourly();
|
|
||||||
|
|
||||||
// Execute scheduled commands for servers every minute, as if there was a normal cron running.
|
|
||||||
$schedule->command(ProcessRunnableCommand::class)->everyMinute()->withoutOverlapping();
|
|
||||||
$schedule->command(CleanServiceBackupFilesCommand::class)->daily();
|
|
||||||
|
|
||||||
if (config('backups.prune_age')) {
|
|
||||||
// Every 30 minutes, run the backup pruning command so that any abandoned backups can be deleted.
|
|
||||||
$schedule->command(PruneOrphanedBackupsCommand::class)->everyThirtyMinutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config('activity.prune_days')) {
|
|
||||||
$schedule->command(PruneCommand::class, ['--model' => [ActivityLog::class]])->daily();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config('pterodactyl.telemetry.enabled')) {
|
|
||||||
$this->registerTelemetry($schedule);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* I wonder what this does.
|
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
* @param \Illuminate\Console\Scheduling\Schedule $schedule
|
||||||
* @throws \Illuminate\Contracts\Container\BindingResolutionException
|
|
||||||
*/
|
*/
|
||||||
private function registerTelemetry(Schedule $schedule): void
|
protected function schedule(Schedule $schedule)
|
||||||
{
|
{
|
||||||
$settingsRepository = app()->make(SettingsRepository::class);
|
$schedule->command('p:schedule:process')->everyMinute()->withoutOverlapping();
|
||||||
|
$schedule->command('p:maintenance:clean-service-backups')->daily();
|
||||||
$uuid = $settingsRepository->get('app:telemetry:uuid');
|
|
||||||
if (is_null($uuid)) {
|
|
||||||
$uuid = Uuid::uuid4()->toString();
|
|
||||||
$settingsRepository->set('app:telemetry:uuid', $uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculate a fixed time to run the data push at, this will be the same time every day.
|
|
||||||
$time = hexdec(str_replace('-', '', substr($uuid, 27))) % 1440;
|
|
||||||
$hour = floor($time / 60);
|
|
||||||
$minute = $time % 60;
|
|
||||||
|
|
||||||
// Run the telemetry collector.
|
|
||||||
$schedule->call(app()->make(TelemetryCollectionService::class))->description('Collect Telemetry')->dailyAt("$hour:$minute");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,55 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Console;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @mixin \Illuminate\Console\Command
|
|
||||||
*/
|
|
||||||
trait RequiresDatabaseMigrations
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Checks if the migrations have finished running by comparing the last migration file.
|
|
||||||
*/
|
|
||||||
protected function hasCompletedMigrations(): bool
|
|
||||||
{
|
|
||||||
/** @var \Illuminate\Database\Migrations\Migrator $migrator */
|
|
||||||
$migrator = $this->getLaravel()->make('migrator');
|
|
||||||
|
|
||||||
$files = $migrator->getMigrationFiles(database_path('migrations'));
|
|
||||||
|
|
||||||
if (!$migrator->repositoryExists()) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (array_diff(array_keys($files), $migrator->getRepository()->getRan())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Throw a massive error into the console to hopefully catch the users attention and get
|
|
||||||
* them to properly run the migrations rather than ignoring all of the other previous
|
|
||||||
* errors...
|
|
||||||
*/
|
|
||||||
protected function showMigrationWarning(): void
|
|
||||||
{
|
|
||||||
$this->getOutput()->writeln('<options=bold>
|
|
||||||
| @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |
|
|
||||||
| |
|
|
||||||
| Your database has not been properly migrated! |
|
|
||||||
| |
|
|
||||||
| @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ |</>
|
|
||||||
|
|
||||||
You must run the following command to finish migrating your database:
|
|
||||||
|
|
||||||
<fg=green;options=bold>php artisan migrate --step --force</>
|
|
||||||
|
|
||||||
You will not be able to use Pterodactyl Panel as expected without fixing your
|
|
||||||
database state by running the command above.
|
|
||||||
');
|
|
||||||
|
|
||||||
$this->getOutput()->error('You must correct the error above before continuing.');
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -8,6 +8,8 @@ interface ReceivesEvents
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Handles receiving an event from the application.
|
* Handles receiving an event from the application.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Events\Event $notification
|
||||||
*/
|
*/
|
||||||
public function handle(Event $notification): void;
|
public function handle(Event $notification): void;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,24 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Criteria;
|
namespace Pterodactyl\Contracts\Criteria;
|
||||||
|
|
||||||
use Illuminate\Database\Eloquent\Model;
|
|
||||||
use Pterodactyl\Repositories\Repository;
|
use Pterodactyl\Repositories\Repository;
|
||||||
|
|
||||||
interface CriteriaInterface
|
interface CriteriaInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Apply selected criteria to a repository call.
|
* Apply selected criteria to a repository call.
|
||||||
|
*
|
||||||
|
* @param \Illuminate\Database\Eloquent\Model $model
|
||||||
|
* @param \Pterodactyl\Repositories\Repository $repository
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function apply(Model $model, Repository $repository): mixed;
|
public function apply($model, Repository $repository);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Extensions;
|
namespace Pterodactyl\Contracts\Extensions;
|
||||||
|
|
||||||
|
@ -9,7 +16,11 @@ interface HashidsInterface extends VendorHashidsInterface
|
||||||
/**
|
/**
|
||||||
* Decode an encoded hashid and return the first result.
|
* Decode an encoded hashid and return the first result.
|
||||||
*
|
*
|
||||||
|
* @param string $encoded
|
||||||
|
* @param null $default
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws \InvalidArgumentException
|
* @throws \InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
public function decodeFirst(string $encoded, string $default = null): mixed;
|
public function decodeFirst($encoded, $default = null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Http;
|
|
||||||
|
|
||||||
interface ClientPermissionsRequest
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* Returns the permissions string indicating which permission should be used to
|
|
||||||
* validate that the authenticated user has permission to perform this action against
|
|
||||||
* the given resource (server).
|
|
||||||
*/
|
|
||||||
public function permission(): string;
|
|
||||||
}
|
|
|
@ -2,18 +2,82 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
use Pterodactyl\Models\Allocation;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
interface AllocationRepositoryInterface extends RepositoryInterface
|
interface AllocationRepositoryInterface extends RepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return all the allocations that exist for a node that are not currently
|
* Set an array of allocation IDs to be assigned to a specific server.
|
||||||
|
*
|
||||||
|
* @param int|null $server
|
||||||
|
* @param array $ids
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function assignAllocationsToServer(int $server = null, array $ids): int;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all of the allocations for a specific node.
|
||||||
|
*
|
||||||
|
* @param int $node
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function getAllocationsForNode(int $node): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all of the allocations for a node in a paginated format.
|
||||||
|
*
|
||||||
|
* @param int $node
|
||||||
|
* @param int $perPage
|
||||||
|
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||||
|
*/
|
||||||
|
public function getPaginatedAllocationsForNode(int $node, int $perPage = 100): LengthAwarePaginator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all of the unique IPs that exist for a given node.
|
||||||
|
*
|
||||||
|
* @param int $node
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function getUniqueAllocationIpsForNode(int $node): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all of the allocations that exist for a node that are not currently
|
||||||
* allocated.
|
* allocated.
|
||||||
|
*
|
||||||
|
* @param int $node
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getUnassignedAllocationIds(int $node): array;
|
public function getUnassignedAllocationIds(int $node): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a single allocation from those meeting the requirements.
|
* Get an array of all allocations that are currently assigned to a given server.
|
||||||
|
*
|
||||||
|
* @param int $server
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false): ?Allocation;
|
public function getAssignedAllocationIds(int $server): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a concatenated result set of node ips that already have at least one
|
||||||
|
* server assigned to that IP. This allows for filtering out sets for
|
||||||
|
* dedicated allocation IPs.
|
||||||
|
*
|
||||||
|
* If an array of nodes is passed the results will be limited to allocations
|
||||||
|
* in those nodes.
|
||||||
|
*
|
||||||
|
* @param array $nodes
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function getDiscardableDedicatedAllocations(array $nodes = []): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a single allocation from those meeting the requirements.
|
||||||
|
*
|
||||||
|
* @param array $nodes
|
||||||
|
* @param array $ports
|
||||||
|
* @param bool $dedicated
|
||||||
|
* @return \Pterodactyl\Models\Allocation|null
|
||||||
|
*/
|
||||||
|
public function getRandomAllocation(array $nodes, array $ports, bool $dedicated = false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,22 +8,36 @@ use Illuminate\Support\Collection;
|
||||||
interface ApiKeyRepositoryInterface extends RepositoryInterface
|
interface ApiKeyRepositoryInterface extends RepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Get all the account API keys that exist for a specific user.
|
* Get all of the account API keys that exist for a specific user.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\User $user
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getAccountKeys(User $user): Collection;
|
public function getAccountKeys(User $user): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the application API keys that exist for a specific user.
|
* Get all of the application API keys that exist for a specific user.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\User $user
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getApplicationKeys(User $user): Collection;
|
public function getApplicationKeys(User $user): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an account API key from the panel for a specific user.
|
* Delete an account API key from the panel for a specific user.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\User $user
|
||||||
|
* @param string $identifier
|
||||||
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function deleteAccountKey(User $user, string $identifier): int;
|
public function deleteAccountKey(User $user, string $identifier): int;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete an application API key from the panel for a specific user.
|
* Delete an application API key from the panel for a specific user.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\User $user
|
||||||
|
* @param string $identifier
|
||||||
|
* @return int
|
||||||
*/
|
*/
|
||||||
public function deleteApplicationKey(User $user, string $identifier): int;
|
public function deleteApplicationKey(User $user, string $identifier): int;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Attributes;
|
||||||
|
|
||||||
|
interface SearchableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the search term.
|
||||||
|
*
|
||||||
|
* @param string|null $term
|
||||||
|
* @return $this
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
public function search($term);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the search term to use when requesting all records from
|
||||||
|
* the model.
|
||||||
|
*
|
||||||
|
* @param string|null $term
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setSearchTerm(string $term = null);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if a valid search term is set on this repository.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasSearchTerm(): bool;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the search term.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getSearchTerm();
|
||||||
|
}
|
|
@ -0,0 +1,65 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Daemon;
|
||||||
|
|
||||||
|
use GuzzleHttp\Client;
|
||||||
|
use Pterodactyl\Models\Node;
|
||||||
|
use Pterodactyl\Models\Server;
|
||||||
|
|
||||||
|
interface BaseRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Set the node model to be used for this daemon connection.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setNode(Node $node);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the node model being used.
|
||||||
|
*
|
||||||
|
* @return \Pterodactyl\Models\Node|null
|
||||||
|
*/
|
||||||
|
public function getNode();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the Server model to use when requesting information from the Daemon.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Server $server
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setServer(Server $server);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Server model.
|
||||||
|
*
|
||||||
|
* @return \Pterodactyl\Models\Server|null
|
||||||
|
*/
|
||||||
|
public function getServer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the token to be used in the X-Access-Token header for requests to the daemon.
|
||||||
|
*
|
||||||
|
* @param string $token
|
||||||
|
* @return $this
|
||||||
|
*/
|
||||||
|
public function setToken(string $token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the access token being used for requests.
|
||||||
|
*
|
||||||
|
* @return string|null
|
||||||
|
*/
|
||||||
|
public function getToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return an instance of the Guzzle HTTP Client to be used for requests.
|
||||||
|
*
|
||||||
|
* @param array $headers
|
||||||
|
* @return \GuzzleHttp\Client
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
*/
|
||||||
|
public function getHttpClient(array $headers = []): Client;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Daemon;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
interface CommandRepositoryInterface extends BaseRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Send a command to a server.
|
||||||
|
*
|
||||||
|
* @param string $command
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function send(string $command): ResponseInterface;
|
||||||
|
}
|
|
@ -0,0 +1,16 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Daemon;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
interface ConfigurationRepositoryInterface extends BaseRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Update the configuration details for the specified node using data from the database.
|
||||||
|
*
|
||||||
|
* @param array $overrides
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function update(array $overrides = []): ResponseInterface;
|
||||||
|
}
|
|
@ -0,0 +1,50 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Daemon;
|
||||||
|
|
||||||
|
use stdClass;
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
interface FileRepositoryInterface extends BaseRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return stat information for a given file.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return \stdClass
|
||||||
|
*
|
||||||
|
* @throws \GuzzleHttp\Exception\RequestException
|
||||||
|
*/
|
||||||
|
public function getFileStat(string $path): stdClass;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the contents of a given file if it can be edited in the Panel.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return string
|
||||||
|
*
|
||||||
|
* @throws \GuzzleHttp\Exception\RequestException
|
||||||
|
*/
|
||||||
|
public function getContent(string $path): string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save new contents to a given file.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @param string $content
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*
|
||||||
|
* @throws \GuzzleHttp\Exception\RequestException
|
||||||
|
*/
|
||||||
|
public function putContent(string $path, string $content): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a directory listing for a given path.
|
||||||
|
*
|
||||||
|
* @param string $path
|
||||||
|
* @return array
|
||||||
|
*
|
||||||
|
* @throws \GuzzleHttp\Exception\RequestException
|
||||||
|
*/
|
||||||
|
public function getDirectory(string $path): array;
|
||||||
|
}
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Daemon;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
interface PowerRepositoryInterface extends BaseRepositoryInterface
|
||||||
|
{
|
||||||
|
const SIGNAL_START = 'start';
|
||||||
|
const SIGNAL_STOP = 'stop';
|
||||||
|
const SIGNAL_RESTART = 'restart';
|
||||||
|
const SIGNAL_KILL = 'kill';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a power signal to a server.
|
||||||
|
*
|
||||||
|
* @param string $signal
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\Daemon\InvalidPowerSignalException
|
||||||
|
*/
|
||||||
|
public function sendSignal(string $signal): ResponseInterface;
|
||||||
|
}
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository\Daemon;
|
||||||
|
|
||||||
|
use Psr\Http\Message\ResponseInterface;
|
||||||
|
|
||||||
|
interface ServerRepositoryInterface extends BaseRepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Create a new server on the daemon for the panel.
|
||||||
|
*
|
||||||
|
* @param array $structure
|
||||||
|
* @param array $overrides
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*
|
||||||
|
* @throws \GuzzleHttp\Exception\RequestException
|
||||||
|
*/
|
||||||
|
public function create(array $structure, array $overrides = []): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update server details on the daemon.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function update(array $data): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a server to be reinstalled on the system.
|
||||||
|
*
|
||||||
|
* @param array|null $data
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function reinstall(array $data = null): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark a server as needing a container rebuild the next time the server is booted.
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function rebuild(): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suspend a server on the daemon.
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function suspend(): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Un-suspend a server on the daemon.
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function unsuspend(): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete a server on the daemon.
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function delete(): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return details on a specific server.
|
||||||
|
*
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*/
|
||||||
|
public function details(): ResponseInterface;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Revoke an access key on the daemon before the time is expired.
|
||||||
|
*
|
||||||
|
* @param string|array $key
|
||||||
|
* @return \Psr\Http\Message\ResponseInterface
|
||||||
|
*
|
||||||
|
* @throws \GuzzleHttp\Exception\RequestException
|
||||||
|
*/
|
||||||
|
public function revokeAccessKey($key): ResponseInterface;
|
||||||
|
}
|
|
@ -0,0 +1,52 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\User;
|
||||||
|
use Pterodactyl\Models\DaemonKey;
|
||||||
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
|
interface DaemonKeyRepositoryInterface extends RepositoryInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* String prepended to keys to identify that they are managed internally and not part of the user API.
|
||||||
|
*/
|
||||||
|
const INTERNAL_KEY_IDENTIFIER = 'i_';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load the server and user relations onto a key model.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\DaemonKey $key
|
||||||
|
* @param bool $refresh
|
||||||
|
* @return \Pterodactyl\Models\DaemonKey
|
||||||
|
*/
|
||||||
|
public function loadServerAndUserRelations(DaemonKey $key, bool $refresh = false): DaemonKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a daemon key with the associated server relation attached.
|
||||||
|
*
|
||||||
|
* @param string $key
|
||||||
|
* @return \Pterodactyl\Models\DaemonKey
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
|
*/
|
||||||
|
public function getKeyWithServer(string $key): DaemonKey;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all of the keys for a specific user including the information needed
|
||||||
|
* from their server relation for revocation on the daemon.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\User $user
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
|
*/
|
||||||
|
public function getKeysForRevocation(User $user): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Delete an array of daemon keys from the database. Used primarily in
|
||||||
|
* conjunction with getKeysForRevocation.
|
||||||
|
*
|
||||||
|
* @param array $ids
|
||||||
|
* @return bool|int
|
||||||
|
*/
|
||||||
|
public function deleteKeys(array $ids);
|
||||||
|
}
|
|
@ -9,6 +9,8 @@ interface DatabaseHostRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return database hosts with a count of databases and the node
|
* Return database hosts with a count of databases and the node
|
||||||
* information for which it is attached.
|
* information for which it is attached.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getWithViewDetails(): Collection;
|
public function getWithViewDetails(): Collection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,60 +2,107 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Database;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
|
||||||
interface DatabaseRepositoryInterface extends RepositoryInterface
|
interface DatabaseRepositoryInterface extends RepositoryInterface
|
||||||
{
|
{
|
||||||
public const DEFAULT_CONNECTION_NAME = 'dynamic';
|
const DEFAULT_CONNECTION_NAME = 'dynamic';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the connection name to execute statements against.
|
* Set the connection name to execute statements against.
|
||||||
|
*
|
||||||
|
* @param string $connection
|
||||||
|
* @return $this
|
||||||
*/
|
*/
|
||||||
public function setConnection(string $connection): self;
|
public function setConnection(string $connection);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the connection to execute statements against.
|
* Return the connection to execute statements against.
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getConnection(): string;
|
public function getConnection(): string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the databases belonging to a server.
|
* Return all of the databases belonging to a server.
|
||||||
|
*
|
||||||
|
* @param int $server
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getDatabasesForServer(int $server): Collection;
|
public function getDatabasesForServer(int $server): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the databases for a given host with the server relationship loaded.
|
* Return all of the databases for a given host with the server relationship loaded.
|
||||||
|
*
|
||||||
|
* @param int $host
|
||||||
|
* @param int $count
|
||||||
|
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||||
*/
|
*/
|
||||||
public function getDatabasesForHost(int $host, int $count = 25): LengthAwarePaginator;
|
public function getDatabasesForHost(int $host, int $count = 25): LengthAwarePaginator;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new database if it does not already exist on the host with
|
||||||
|
* the provided details.
|
||||||
|
*
|
||||||
|
* @param array $data
|
||||||
|
* @return \Pterodactyl\Models\Database
|
||||||
|
*
|
||||||
|
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
|
||||||
|
* @throws \Pterodactyl\Exceptions\Repository\DuplicateDatabaseNameException
|
||||||
|
*/
|
||||||
|
public function createIfNotExists(array $data): Database;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new database on a given connection.
|
* Create a new database on a given connection.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createDatabase(string $database): bool;
|
public function createDatabase(string $database): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new database user on a given connection.
|
* Create a new database user on a given connection.
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param string $remote
|
||||||
|
* @param string $password
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function createUser(string $username, string $remote, string $password, ?int $max_connections): bool;
|
public function createUser(string $username, string $remote, string $password): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Give a specific user access to a given database.
|
* Give a specific user access to a given database.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @param string $username
|
||||||
|
* @param string $remote
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function assignUserToDatabase(string $database, string $username, string $remote): bool;
|
public function assignUserToDatabase(string $database, string $username, string $remote): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flush the privileges for a given connection.
|
* Flush the privileges for a given connection.
|
||||||
|
*
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function flush(): bool;
|
public function flush(): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop a given database on a specific connection.
|
* Drop a given database on a specific connection.
|
||||||
|
*
|
||||||
|
* @param string $database
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function dropDatabase(string $database): bool;
|
public function dropDatabase(string $database): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drop a given user on a specific connection.
|
* Drop a given user on a specific connection.
|
||||||
|
*
|
||||||
|
* @param string $username
|
||||||
|
* @param string $remote
|
||||||
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function dropUser(string $username, string $remote): bool;
|
public function dropUser(string $username, string $remote): bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
@ -10,22 +17,34 @@ interface EggRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return an egg with the variables relation attached.
|
* Return an egg with the variables relation attached.
|
||||||
*
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Pterodactyl\Models\Egg
|
||||||
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithVariables(int $id): Egg;
|
public function getWithVariables(int $id): Egg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all eggs and their relations to be used in the daemon API.
|
* Return all eggs and their relations to be used in the daemon API.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Database\Eloquent\Collection
|
||||||
*/
|
*/
|
||||||
public function getAllWithCopyAttributes(): Collection;
|
public function getAllWithCopyAttributes(): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return an egg with the scriptFrom and configFrom relations loaded onto the model.
|
* Return an egg with the scriptFrom and configFrom relations loaded onto the model.
|
||||||
|
*
|
||||||
|
* @param int|string $value
|
||||||
|
* @param string $column
|
||||||
|
* @return \Pterodactyl\Models\Egg
|
||||||
*/
|
*/
|
||||||
public function getWithCopyAttributes(int|string $value, string $column = 'id'): Egg;
|
public function getWithCopyAttributes($value, string $column = 'id'): Egg;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the data needed to export a service.
|
* Return all of the data needed to export a service.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Pterodactyl\Models\Egg
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
|
@ -33,6 +52,10 @@ interface EggRepositoryInterface extends RepositoryInterface
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Confirm a copy script belongs to the same nest as the item trying to use it.
|
* Confirm a copy script belongs to the same nest as the item trying to use it.
|
||||||
|
*
|
||||||
|
* @param int $copyFromId
|
||||||
|
* @param int $service
|
||||||
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function isCopyableScript(int $copyFromId, int $service): bool;
|
public function isCopyableScript(int $copyFromId, int $service): bool;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
@ -9,6 +16,9 @@ interface EggVariableRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return editable variables for a given egg. Editable variables must be set to
|
* Return editable variables for a given egg. Editable variables must be set to
|
||||||
* user viewable in order to be picked up by this function.
|
* user viewable in order to be picked up by this function.
|
||||||
|
*
|
||||||
|
* @param int $egg
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getEditableVariables(int $egg): Collection;
|
public function getEditableVariables(int $egg): Collection;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,21 +4,29 @@ namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
use Pterodactyl\Models\Location;
|
use Pterodactyl\Models\Location;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface;
|
||||||
|
|
||||||
interface LocationRepositoryInterface extends RepositoryInterface
|
interface LocationRepositoryInterface extends RepositoryInterface, SearchableInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return locations with a count of nodes and servers attached to it.
|
* Return locations with a count of nodes and servers attached to it.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getAllWithDetails(): Collection;
|
public function getAllWithDetails(): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the available locations with the nodes as a relationship.
|
* Return all of the available locations with the nodes as a relationship.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getAllWithNodes(): Collection;
|
public function getAllWithNodes(): Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return all the nodes and their respective count of servers for a location.
|
* Return all of the nodes and their respective count of servers for a location.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return mixed
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
|
@ -27,6 +35,9 @@ interface LocationRepositoryInterface extends RepositoryInterface
|
||||||
/**
|
/**
|
||||||
* Return a location and the count of nodes in that location.
|
* Return a location and the count of nodes in that location.
|
||||||
*
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return mixed
|
||||||
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithNodeCount(int $id): Location;
|
public function getWithNodeCount(int $id): Location;
|
||||||
|
|
|
@ -1,29 +1,44 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
use Pterodactyl\Models\Nest;
|
use Pterodactyl\Models\Nest;
|
||||||
use Illuminate\Database\Eloquent\Collection;
|
|
||||||
|
|
||||||
interface NestRepositoryInterface extends RepositoryInterface
|
interface NestRepositoryInterface extends RepositoryInterface
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Return a nest or all nests with their associated eggs and variables.
|
* Return a nest or all nests with their associated eggs, variables, and packs.
|
||||||
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Illuminate\Database\Eloquent\Collection|\Pterodactyl\Models\Nest
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithEggs(int $id = null): Collection|Nest;
|
public function getWithEggs(int $id = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a nest or all nests and the count of eggs and servers for that nest.
|
* Return a nest or all nests and the count of eggs, packs, and servers for that nest.
|
||||||
|
*
|
||||||
|
* @param int|null $id
|
||||||
|
* @return \Pterodactyl\Models\Nest|\Illuminate\Database\Eloquent\Collection
|
||||||
*
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithCounts(int $id = null): Collection|Nest;
|
public function getWithCounts(int $id = null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a nest along with its associated eggs and the servers relation on those eggs.
|
* Return a nest along with its associated eggs and the servers relation on those eggs.
|
||||||
*
|
*
|
||||||
|
* @param int $id
|
||||||
|
* @return \Pterodactyl\Models\Nest
|
||||||
|
*
|
||||||
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
|
||||||
*/
|
*/
|
||||||
public function getWithEggServers(int $id): Nest;
|
public function getWithEggServers(int $id): Nest;
|
||||||
|
|
|
@ -2,37 +2,74 @@
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
use Generator;
|
||||||
use Pterodactyl\Models\Node;
|
use Pterodactyl\Models\Node;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface;
|
||||||
|
|
||||||
interface NodeRepositoryInterface extends RepositoryInterface
|
interface NodeRepositoryInterface extends RepositoryInterface, SearchableInterface
|
||||||
{
|
{
|
||||||
public const THRESHOLD_PERCENTAGE_LOW = 75;
|
const THRESHOLD_PERCENTAGE_LOW = 75;
|
||||||
public const THRESHOLD_PERCENTAGE_MEDIUM = 90;
|
const THRESHOLD_PERCENTAGE_MEDIUM = 90;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the usage stats for a single node.
|
* Return the usage stats for a single node.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getUsageStats(Node $node): array;
|
public function getUsageStats(Node $node): array;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the usage stats for a single node.
|
* Return the usage stats for a single node.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getUsageStatsRaw(Node $node): array;
|
public function getUsageStatsRaw(Node $node): array;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return all available nodes with a searchable interface.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||||
|
*/
|
||||||
|
public function getNodeListingData(): LengthAwarePaginator;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a single node with location and server information.
|
* Return a single node with location and server information.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @param bool $refresh
|
||||||
|
* @return \Pterodactyl\Models\Node
|
||||||
*/
|
*/
|
||||||
public function loadLocationAndServerCount(Node $node, bool $refresh = false): Node;
|
public function loadLocationAndServerCount(Node $node, bool $refresh = false): Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attach a paginated set of allocations to a node mode including
|
* Attach a paginated set of allocations to a node mode including
|
||||||
* any servers that are also attached to those allocations.
|
* any servers that are also attached to those allocations.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Node $node
|
||||||
|
* @param bool $refresh
|
||||||
|
* @return \Pterodactyl\Models\Node
|
||||||
*/
|
*/
|
||||||
public function loadNodeAllocations(Node $node, bool $refresh = false): Node;
|
public function loadNodeAllocations(Node $node, bool $refresh = false): Node;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a collection of nodes for all locations to use in server creation UI.
|
* Return a collection of nodes for all locations to use in server creation UI.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Support\Collection
|
||||||
*/
|
*/
|
||||||
public function getNodesForServerCreation(): Collection;
|
public function getNodesForServerCreation(): Collection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the IDs of all nodes that exist in the provided locations and have the space
|
||||||
|
* available to support the additional disk and memory provided.
|
||||||
|
*
|
||||||
|
* @param array $locations
|
||||||
|
* @param int $disk
|
||||||
|
* @param int $memory
|
||||||
|
* @return \Generator
|
||||||
|
*/
|
||||||
|
public function getNodesWithResourceUse(array $locations, int $disk, int $memory): Generator;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
use Pterodactyl\Models\Pack;
|
||||||
|
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
|
||||||
|
use Pterodactyl\Contracts\Repository\Attributes\SearchableInterface;
|
||||||
|
|
||||||
|
interface PackRepositoryInterface extends RepositoryInterface, SearchableInterface
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Return a pack with the associated server models attached to it.
|
||||||
|
*
|
||||||
|
* @param \Pterodactyl\Models\Pack $pack
|
||||||
|
* @param bool $refresh
|
||||||
|
* @return \Pterodactyl\Models\Pack
|
||||||
|
*/
|
||||||
|
public function loadServerData(Pack $pack, bool $refresh = false): Pack;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a paginated listing of packs with their associated egg and server count.
|
||||||
|
*
|
||||||
|
* @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
|
||||||
|
*/
|
||||||
|
public function paginateWithEggAndServerCount(): LengthAwarePaginator;
|
||||||
|
}
|
|
@ -1,4 +1,11 @@
|
||||||
<?php
|
<?php
|
||||||
|
/**
|
||||||
|
* Pterodactyl - Panel
|
||||||
|
* Copyright (c) 2015 - 2017 Dane Everitt <dane@daneeveritt.com>.
|
||||||
|
*
|
||||||
|
* This software is licensed under the terms of the MIT license.
|
||||||
|
* https://opensource.org/licenses/MIT
|
||||||
|
*/
|
||||||
|
|
||||||
namespace Pterodactyl\Contracts\Repository;
|
namespace Pterodactyl\Contracts\Repository;
|
||||||
|
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue