First push before 🥚
This commit is contained in:
parent
0b3c0f6d5a
commit
344c1a9885
11 changed files with 36 additions and 158 deletions
|
@ -34,8 +34,6 @@ class Service extends Model implements CleansAttributes, ValidableContract
|
||||||
protected $fillable = [
|
protected $fillable = [
|
||||||
'name',
|
'name',
|
||||||
'description',
|
'description',
|
||||||
'startup',
|
|
||||||
'index_file',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,8 +43,6 @@ class Service extends Model implements CleansAttributes, ValidableContract
|
||||||
'author' => 'required',
|
'author' => 'required',
|
||||||
'name' => 'required',
|
'name' => 'required',
|
||||||
'description' => 'sometimes',
|
'description' => 'sometimes',
|
||||||
'startup' => 'sometimes',
|
|
||||||
'index_file' => 'required',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -56,8 +52,6 @@ class Service extends Model implements CleansAttributes, ValidableContract
|
||||||
'author' => 'email',
|
'author' => 'email',
|
||||||
'name' => 'string|max:255',
|
'name' => 'string|max:255',
|
||||||
'description' => 'nullable|string',
|
'description' => 'nullable|string',
|
||||||
'startup' => 'nullable|string',
|
|
||||||
'index_file' => 'string',
|
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -107,17 +107,6 @@ class ServiceOption extends Model implements CleansAttributes, ValidableContract
|
||||||
'docker_image' => null,
|
'docker_image' => null,
|
||||||
];
|
];
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the display startup string for the option and will use the parent
|
|
||||||
* service one if the option does not have one defined.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getDisplayStartupAttribute()
|
|
||||||
{
|
|
||||||
return (is_null($this->startup)) ? $this->service->startup : $this->startup;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the install script for the option; if option is copying from another
|
* Returns the install script for the option; if option is copying from another
|
||||||
* it will return the copied script.
|
* it will return the copied script.
|
||||||
|
|
|
@ -58,10 +58,8 @@ class ServiceOptionExporterService
|
||||||
'exported_at' => $this->carbon->now()->toIso8601String(),
|
'exported_at' => $this->carbon->now()->toIso8601String(),
|
||||||
'name' => $option->name,
|
'name' => $option->name,
|
||||||
'author' => array_get(explode(':', $option->tag), 0),
|
'author' => array_get(explode(':', $option->tag), 0),
|
||||||
'tag' => $option->tag,
|
|
||||||
'description' => $option->description,
|
'description' => $option->description,
|
||||||
'image' => $option->docker_image,
|
'image' => $option->docker_image,
|
||||||
'startup' => $option->display_startup,
|
|
||||||
'config' => [
|
'config' => [
|
||||||
'files' => $option->inherit_config_files,
|
'files' => $option->inherit_config_files,
|
||||||
'startup' => $option->inherit_config_startup,
|
'startup' => $option->inherit_config_startup,
|
||||||
|
|
|
@ -91,12 +91,10 @@ $factory->define(Pterodactyl\Models\Node::class, function (Faker\Generator $fake
|
||||||
$factory->define(Pterodactyl\Models\Service::class, function (Faker\Generator $faker) {
|
$factory->define(Pterodactyl\Models\Service::class, function (Faker\Generator $faker) {
|
||||||
return [
|
return [
|
||||||
'id' => $faker->unique()->randomNumber(),
|
'id' => $faker->unique()->randomNumber(),
|
||||||
'author' => $faker->unique()->uuid,
|
'uuid' => $faker->unique()->uuid,
|
||||||
|
'author' => 'testauthor@example.com',
|
||||||
'name' => $faker->word,
|
'name' => $faker->word,
|
||||||
'description' => null,
|
'description' => null,
|
||||||
'folder' => strtolower($faker->unique()->word),
|
|
||||||
'startup' => 'java -jar test.jar',
|
|
||||||
'index_file' => 'indexjs',
|
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -108,7 +106,6 @@ $factory->define(Pterodactyl\Models\ServiceOption::class, function (Faker\Genera
|
||||||
'name' => $faker->name,
|
'name' => $faker->name,
|
||||||
'description' => implode(' ', $faker->sentences(3)),
|
'description' => implode(' ', $faker->sentences(3)),
|
||||||
'startup' => 'java -jar test.jar',
|
'startup' => 'java -jar test.jar',
|
||||||
'tag' => 'test@testfactory.com:' . $faker->unique()->randomNumber(8),
|
|
||||||
];
|
];
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -42,12 +42,16 @@ class RemoveDaemonSecretFromSubusersTable extends Migration
|
||||||
public function down()
|
public function down()
|
||||||
{
|
{
|
||||||
Schema::table('subusers', function (Blueprint $table) {
|
Schema::table('subusers', function (Blueprint $table) {
|
||||||
$table->char('daemonSecret', 36)->after('server_id')->unique();
|
$table->char('daemonSecret', 36)->after('server_id');
|
||||||
});
|
});
|
||||||
|
|
||||||
$subusers = DB::table('subusers')->get();
|
$subusers = DB::table('subusers')->get();
|
||||||
$subusers->each(function ($subuser) {
|
$subusers->each(function ($subuser) {
|
||||||
DB::table('daemon_keys')->where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete();
|
DB::table('daemon_keys')->where('user_id', $subuser->user_id)->where('server_id', $subuser->server_id)->delete();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Schema::table('subusers', function (Blueprint $table) {
|
||||||
|
$table->unique('daemonSecret');
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,8 @@ class ChangeServicesToUseAMoreUniqueIdentifier extends Migration
|
||||||
$table->string('author')->change();
|
$table->string('author')->change();
|
||||||
$table->char('uuid', 36)->after('id');
|
$table->char('uuid', 36)->after('id');
|
||||||
$table->dropColumn('folder');
|
$table->dropColumn('folder');
|
||||||
|
$table->dropColumn('startup');
|
||||||
|
$table->dropColumn('index_file');
|
||||||
});
|
});
|
||||||
|
|
||||||
DB::table('services')->get(['id', 'author', 'uuid'])->each(function ($service) {
|
DB::table('services')->get(['id', 'author', 'uuid'])->each(function ($service) {
|
||||||
|
@ -42,6 +44,8 @@ class ChangeServicesToUseAMoreUniqueIdentifier extends Migration
|
||||||
Schema::table('services', function (Blueprint $table) {
|
Schema::table('services', function (Blueprint $table) {
|
||||||
$table->dropColumn('uuid');
|
$table->dropColumn('uuid');
|
||||||
$table->string('folder')->nullable();
|
$table->string('folder')->nullable();
|
||||||
|
$table->text('startup')->nullable();
|
||||||
|
$table->text('index_file');
|
||||||
$table->string('author', 36)->change();
|
$table->string('author', 36)->change();
|
||||||
|
|
||||||
$table->unique('name');
|
$table->unique('name');
|
||||||
|
|
|
@ -15,19 +15,16 @@ class ChangeToABetterUniqueServiceConfiguration extends Migration
|
||||||
{
|
{
|
||||||
Schema::table('service_options', function (Blueprint $table) {
|
Schema::table('service_options', function (Blueprint $table) {
|
||||||
$table->char('uuid', 36)->after('id');
|
$table->char('uuid', 36)->after('id');
|
||||||
|
$table->dropColumn('tag');
|
||||||
$table->index(['service_id', 'tag']);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
DB::transaction(function () {
|
DB::transaction(function () {
|
||||||
DB::table('service_options')->select([
|
DB::table('service_options')->select([
|
||||||
'service_options.id',
|
'service_options.id',
|
||||||
'service_options.uuid',
|
'service_options.uuid',
|
||||||
'service_options.tag',
|
|
||||||
'services.author AS service_author',
|
'services.author AS service_author',
|
||||||
])->join('services', 'services.id', '=', 'service_options.service_id')->get()->each(function ($option) {
|
])->join('services', 'services.id', '=', 'service_options.service_id')->get()->each(function ($option) {
|
||||||
DB::table('service_options')->where('id', $option->id)->update([
|
DB::table('service_options')->where('id', $option->id)->update([
|
||||||
'tag' => $option->service_author . ':' . $option->tag,
|
|
||||||
'uuid' => Uuid::uuid4()->toString(),
|
'uuid' => Uuid::uuid4()->toString(),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
|
@ -45,13 +42,13 @@ class ChangeToABetterUniqueServiceConfiguration extends Migration
|
||||||
{
|
{
|
||||||
Schema::table('service_options', function (Blueprint $table) {
|
Schema::table('service_options', function (Blueprint $table) {
|
||||||
$table->dropColumn('uuid');
|
$table->dropColumn('uuid');
|
||||||
$table->dropIndex(['service_id', 'tag']);
|
$table->string('tag');
|
||||||
});
|
});
|
||||||
|
|
||||||
DB::transaction(function () {
|
DB::transaction(function () {
|
||||||
DB::table('service_options')->select(['id', 'tag'])->get()->each(function ($option) {
|
DB::table('service_options')->select(['id', 'tag'])->get()->each(function ($option) {
|
||||||
DB::table('service_options')->where('id', $option->id)->update([
|
DB::table('service_options')->where('id', $option->id)->update([
|
||||||
'tag' => array_get(explode(':', $option->tag), 1),
|
'tag' => str_random(10),
|
||||||
]);
|
]);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,73 +0,0 @@
|
||||||
{{-- 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 --}}
|
|
||||||
@extends('layouts.admin')
|
|
||||||
|
|
||||||
@section('title')
|
|
||||||
Service → {{ $service->name }} → Functions
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('content-header')
|
|
||||||
<h1>{{ $service->name }}<small>Extend the default daemon functions using this service file.</small></h1>
|
|
||||||
<ol class="breadcrumb">
|
|
||||||
<li><a href="{{ route('admin.index') }}">Admin</a></li>
|
|
||||||
<li><a href="{{ route('admin.services') }}">Service</a></li>
|
|
||||||
<li><a href="{{ route('admin.services.view', $service->id) }}">{{ $service->name }}</a></li>
|
|
||||||
<li class="active">Functions</li>
|
|
||||||
</ol>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('content')
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="nav-tabs-custom nav-tabs-floating">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li><a href="{{ route('admin.services.view', $service->id) }}">Overview</a></li>
|
|
||||||
<li class="active"><a href="{{ route('admin.services.view.functions', $service->id) }}">Functions</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-header with-border">
|
|
||||||
<h3 class="box-title">Functions Control</h3>
|
|
||||||
</div>
|
|
||||||
<form action="{{ route('admin.services.view.functions', $service->id) }}" method="POST">
|
|
||||||
<div class="box-body no-padding">
|
|
||||||
<div id="editor_index"style="height:500px">{{ $service->index_file }}</div>
|
|
||||||
<textarea name="index_file" class="hidden"></textarea>
|
|
||||||
</div>
|
|
||||||
<div class="box-footer">
|
|
||||||
{!! csrf_field() !!}
|
|
||||||
<button type="submit" name="_method" value="PATCH" class="btn btn-sm btn-success pull-right">Save File</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
@endsection
|
|
||||||
|
|
||||||
@section('footer-scripts')
|
|
||||||
@parent
|
|
||||||
{!! Theme::js('vendor/ace/ace.js') !!}
|
|
||||||
{!! Theme::js('vendor/ace/ext-modelist.js') !!}
|
|
||||||
<script>
|
|
||||||
$(document).ready(function () {
|
|
||||||
const Editor = ace.edit('editor_index');
|
|
||||||
const Modelist = ace.require('ace/ext/modelist')
|
|
||||||
|
|
||||||
Editor.setTheme('ace/theme/chrome');
|
|
||||||
Editor.getSession().setMode('ace/mode/javascript');
|
|
||||||
Editor.getSession().setUseWrapMode(true);
|
|
||||||
Editor.setShowPrintMargin(false);
|
|
||||||
|
|
||||||
$('form').on('submit', function (e) {
|
|
||||||
$('textarea[name="index_file"]').val(Editor.getValue());
|
|
||||||
});
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
@endsection
|
|
|
@ -21,7 +21,7 @@
|
||||||
@section('content')
|
@section('content')
|
||||||
<form action="{{ route('admin.services.new') }}" method="POST">
|
<form action="{{ route('admin.services.new') }}" method="POST">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-12">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-header with-border">
|
<div class="box-header with-border">
|
||||||
<h3 class="box-title">New Service</h3>
|
<h3 class="box-title">New Service</h3>
|
||||||
|
@ -41,19 +41,6 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-6">
|
|
||||||
<div class="box">
|
|
||||||
<div class="box-body">
|
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Default Start Command</label>
|
|
||||||
<div>
|
|
||||||
<textarea name="startup" class="form-control" rows="2">{{ old('startup') }}</textarea>
|
|
||||||
<p class="text-muted"><small>The default start command to use when running options under this service. This command can be modified per-option and should include the executable to be called in the container.</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
{!! csrf_field() !!}
|
{!! csrf_field() !!}
|
||||||
<button type="input" class="btn btn-primary pull-right">Save Service</button>
|
<button type="input" class="btn btn-primary pull-right">Save Service</button>
|
||||||
|
|
|
@ -20,70 +20,53 @@
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
|
||||||
<div class="nav-tabs-custom nav-tabs-floating">
|
|
||||||
<ul class="nav nav-tabs">
|
|
||||||
<li class="active"><a href="{{ route('admin.services.view', $service->id) }}">Overview</a></li>
|
|
||||||
<li><a href="{{ route('admin.services.view.functions', $service->id) }}">Functions</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<form action="{{ route('admin.services.view', $service->id) }}" method="POST">
|
<form action="{{ route('admin.services.view', $service->id) }}" method="POST">
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Name</label>
|
<label class="control-label">Name <span class="field-required"></span></label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" name="name" class="form-control" value="{{ $service->name }}" />
|
<input type="text" name="name" class="form-control" value="{{ $service->name }}" />
|
||||||
<p class="text-muted"><small>This should be a descriptive category name that emcompasses all of the options within the service.</small></p>
|
<p class="text-muted"><small>This should be a descriptive category name that emcompasses all of the options within the service.</small></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Description</label>
|
<label class="control-label">Description <span class="field-required"></span></label>
|
||||||
<div>
|
<div>
|
||||||
<textarea name="description" class="form-control" rows="7">{{ $service->description }}</textarea>
|
<textarea name="description" class="form-control" rows="7">{{ $service->description }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
<div class="box-footer">
|
||||||
|
{!! csrf_field() !!}
|
||||||
|
<button type="submit" name="_method" value="PATCH" class="btn btn-primary btn-sm pull-right">Edit Option</button>
|
||||||
<button id="deleteButton" type="submit" name="_method" value="DELETE" class="btn btn-sm btn-danger muted muted-hover"><i class="fa fa-trash-o"></i></button>
|
<button id="deleteButton" type="submit" name="_method" value="DELETE" class="btn btn-sm btn-danger muted muted-hover"><i class="fa fa-trash-o"></i></button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</form>
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<div class="box">
|
<div class="box">
|
||||||
<div class="box-body">
|
<div class="box-body">
|
||||||
<div class="form-group">
|
|
||||||
<label class="control-label">Default Start Command</label>
|
|
||||||
<div>
|
|
||||||
<textarea name="startup" class="form-control" rows="2">{{ $service->startup }}</textarea>
|
|
||||||
<p class="text-muted"><small>The default start command to use when running options under this service. This command can be modified per-option and should include the executable to be called in the container.</small></p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">Author</label>
|
<label class="control-label">Author</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" readonly class="form-control" value="{{ $service->author }}" />
|
<input type="text" readonly class="form-control" value="{{ $service->author }}" />
|
||||||
|
<p class="text-muted small">The author of this service option. Please direct questions and issues to them unless this is an official option authored by <code>support@pterodactyl.io</code>.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="control-label">UUID</label>
|
<label class="control-label">UUID</label>
|
||||||
<div>
|
<div>
|
||||||
<input type="text" readonly class="form-control" value="{{ $service->uuid }}" />
|
<input type="text" readonly class="form-control" value="{{ $service->uuid }}" />
|
||||||
</div>
|
<p class="text-muted small">A unique identifier that all servers using this option are assigned for identification purposes.</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="box-footer">
|
|
||||||
{!! csrf_field() !!}
|
|
||||||
<button type="submit" name="_method" value="PATCH" class="btn btn-primary btn-sm pull-right">Edit Service</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-xs-12">
|
<div class="col-xs-12">
|
||||||
<div class="box box-primary">
|
<div class="box box-primary">
|
||||||
|
|
|
@ -152,7 +152,6 @@ Route::group(['prefix' => 'services'], function () {
|
||||||
Route::get('/', 'ServiceController@index')->name('admin.services');
|
Route::get('/', 'ServiceController@index')->name('admin.services');
|
||||||
Route::get('/new', 'ServiceController@create')->name('admin.services.new');
|
Route::get('/new', 'ServiceController@create')->name('admin.services.new');
|
||||||
Route::get('/view/{service}', 'ServiceController@view')->name('admin.services.view');
|
Route::get('/view/{service}', 'ServiceController@view')->name('admin.services.view');
|
||||||
Route::get('/view/{service}/functions', 'ServiceController@viewFunctions')->name('admin.services.view.functions');
|
|
||||||
Route::get('/option/new', 'OptionController@create')->name('admin.services.option.new');
|
Route::get('/option/new', 'OptionController@create')->name('admin.services.option.new');
|
||||||
Route::get('/option/{option}', 'OptionController@viewConfiguration')->name('admin.services.option.view');
|
Route::get('/option/{option}', 'OptionController@viewConfiguration')->name('admin.services.option.view');
|
||||||
Route::get('/option/{option}/export', 'Services\Options\OptionShareController@export')->name('admin.services.option.export');
|
Route::get('/option/{option}/export', 'Services\Options\OptionShareController@export')->name('admin.services.option.export');
|
||||||
|
@ -165,7 +164,6 @@ Route::group(['prefix' => 'services'], function () {
|
||||||
Route::post('/option/{option}/variables', 'VariableController@store');
|
Route::post('/option/{option}/variables', 'VariableController@store');
|
||||||
|
|
||||||
Route::patch('/view/{service}', 'ServiceController@update');
|
Route::patch('/view/{service}', 'ServiceController@update');
|
||||||
Route::patch('/view/{service}/functions', 'ServiceController@updateFunctions');
|
|
||||||
Route::patch('/option/{option}', 'OptionController@editConfiguration');
|
Route::patch('/option/{option}', 'OptionController@editConfiguration');
|
||||||
Route::patch('/option/{option}/scripts', 'OptionController@updateScripts');
|
Route::patch('/option/{option}/scripts', 'OptionController@updateScripts');
|
||||||
Route::patch('/option/{option}/variables/{variable}', 'VariableController@update')->name('admin.services.option.variables.edit');
|
Route::patch('/option/{option}/variables/{variable}', 'VariableController@update')->name('admin.services.option.variables.edit');
|
||||||
|
|
Loading…
Reference in a new issue