Skip to content

Commit f47f0cd

Browse files
committed
More additions to server creation page.
Adds memory/disk/etc. fields as well as selecting the service type and option. Still need to add in the ability to set the variables once an option is selected.
1 parent e77cea6 commit f47f0cd

File tree

6 files changed

+189
-21
lines changed

6 files changed

+189
-21
lines changed

app/Http/Controllers/Admin/AjaxController.php

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use Debugbar;
66
use Pterodactyl\Models\Allocation;
77
use Pterodactyl\Models\Node;
8+
use Pterodactyl\Models\ServiceOptions;
89

910
use Pterodactyl\Http\Controllers\Controller;
1011
use Illuminate\Http\Request;
@@ -24,6 +25,12 @@ public function __construct()
2425

2526
}
2627

28+
/**
29+
* Returns a JSON tree of all avaliable nodes in a given location.
30+
*
31+
* @param \Illuminate\Http\Request $request
32+
* @return \Illuminate\Contracts\View\View
33+
*/
2734
public function postNewServerGetNodes(Request $request)
2835
{
2936

@@ -33,10 +40,16 @@ public function postNewServerGetNodes(Request $request)
3340
], 500);
3441
}
3542

36-
return response(Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get()->toJson());
43+
return response()->json(Node::select('id', 'name', 'public')->where('location', $request->input('location'))->get());
3744

3845
}
3946

47+
/**
48+
* Returns a JSON tree of all avaliable IPs and Ports on a given node.
49+
*
50+
* @param \Illuminate\Http\Request $request
51+
* @return \Illuminate\Contracts\View\View
52+
*/
4053
public function postNewServerGetIps(Request $request)
4154
{
4255

@@ -60,4 +73,23 @@ public function postNewServerGetIps(Request $request)
6073

6174
}
6275

76+
/**
77+
* Returns a JSON tree of all avaliable options for a given service.
78+
*
79+
* @param \Illuminate\Http\Request $request
80+
* @return \Illuminate\Contracts\View\View
81+
*/
82+
public function postNewServerServiceOptions(Request $request)
83+
{
84+
85+
if(!$request->input('service')) {
86+
return response()->json([
87+
'error' => 'Missing service in request.'
88+
], 500);
89+
}
90+
91+
return response()->json(ServiceOptions::select('id', 'name')->where('parent_service', $request->input('service'))->orderBy('name', 'asc')->get());
92+
93+
}
94+
6395
}

app/Http/Controllers/Admin/ServersController.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@
44

55
use Debugbar;
66
use Pterodactyl\Models\Server;
7-
use Pterodactyl\Models\Node;
87
use Pterodactyl\Models\Location;
8+
use Pterodactyl\Models\Service;
99

1010
use Pterodactyl\Http\Controllers\Controller;
1111
use Illuminate\Http\Request;
@@ -38,7 +38,8 @@ public function getIndex(Request $request)
3838
public function getNew(Request $request)
3939
{
4040
return view('admin.servers.new', [
41-
'locations' => Location::all()
41+
'locations' => Location::all(),
42+
'services' => Service::all()
4243
]);
4344
}
4445

app/Http/Routes/AdminRoutes.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ public function map(Router $router) {
2828
$router->group(['prefix' => 'ajax'], function ($server) use ($router) {
2929
$router->post('/new/server/get-nodes', [ 'uses' => 'Admin\AjaxController@postNewServerGetNodes' ]);
3030
$router->post('/new/server/get-ips', [ 'uses' => 'Admin\AjaxController@postNewServerGetIps' ]);
31+
$router->post('/new/server/service-options', [ 'uses' => 'Admin\AjaxController@postNewServerServiceOptions' ]);
3132
});
3233

3334
});

public/css/bootstrap.css

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1205,4 +1205,4 @@ input[type=checkbox],input[type=radio]{margin-top:1px}
12051205
.dropdown-header{padding-left:15px;padding-right:15px;font-size:9px;text-transform:uppercase}
12061206
.popover{color:#fff;font-size:12px;font-weight:300}
12071207
.panel-footer,.panel-heading{border-top-right-radius:0;border-top-left-radius:0}
1208-
.modal .close,.panel-default .close{color:#222}
1208+
.modal .close,.panel-default .close{color:#222}

public/css/pterodactyl.css

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,4 @@ pre{display:block;padding:12px 12px;margin:0;font-size:12px;color:#c7254e;backgr
7373
.close {color:#000;opacity:0.2;font-size:1.6em;}
7474
.close:hover {color:#000;opacity:0.5;}
7575
.filename {outline: none;width:450px;background: transparent;margin-left:-5px;padding:0;border: 0px;font-family: "Open Sans","Helvetica Neue",Helvetica,Arial,sans-serif;font-weight: 250;line-height: 1.1;font-size: 19px;color: #aaa}
76+
form .text-muted {margin: 0 0 -5.5px}

resources/views/admin/servers/new.blade.php

Lines changed: 150 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
@section('content')
88
<div class="col-md-9">
99
<ul class="breadcrumb">
10-
<li><a href="/admin">Admin Control</a></li>
11-
<li><a href="/admin/servers">Servers</a></li>
10+
<li><a href="/admin">Admin Control</a></li>
11+
<li><a href="/admin/servers">Servers</a></li>
1212
<li class="active">Create New Server</li>
13-
</ul>
13+
</ul>
1414
<h3>Create New Server</h3><hr />
1515
<form action="#" method="POST">
1616
<div class="well">
@@ -19,7 +19,7 @@
1919
<label for="server_name" class="control-label">Server Name</label>
2020
<div>
2121
<input type="text" autocomplete="off" name="server_name" class="form-control" />
22-
<p class="text-muted" style="margin: 0 0 -10.5px;"><small><em>Character limits: <code>a-zA-Z0-9_-</code> and <code>[Space]</code> (max 35 characters)</em></small></p>
22+
<p class="text-muted"><small><em>Character limits: <code>a-zA-Z0-9_-</code> and <code>[Space]</code> (max 35 characters)</em></small></p>
2323
</div>
2424
</div>
2525
<div class="form-group col-md-6">
@@ -33,7 +33,7 @@
3333
<div id="load_settings">
3434
<div class="well">
3535
<div class="row">
36-
<div class="ajax_loading_box" style="display:none;"><i class="fa fa-refresh fa-spin" id="position_me"></i></div>
36+
<div class="ajax_loading_box" style="display:none;"><i class="fa fa-refresh fa-spin ajax_loading_position"></i></div>
3737
<div class="form-group col-md-6">
3838
<label for="location" class="control-label">Server Location</label>
3939
<div>
@@ -43,6 +43,7 @@
4343
<option value="{{ $location->id }}">{{ $location->long }} ({{ $location->short }})</option>
4444
@endforeach
4545
</select>
46+
<p class="text-muted"><small>The location in which this server will be deployed.</small></p>
4647
</div>
4748
</div>
4849
<div class="form-group col-md-6 hidden">
@@ -51,6 +52,7 @@
5152
<select name="node" id="getNode" class="form-control">
5253
<option></option>
5354
</select>
55+
<p class="text-muted"><small>The node which this server will be deployed to.</small></p>
5456
</div>
5557
</div>
5658
</div>
@@ -61,12 +63,97 @@
6163
<select name="node" id="getIP" class="form-control">
6264
<option></option>
6365
</select>
66+
<p class="text-muted"><small>Select the main IP that this server will be listening on. You can assign additional open IPs and ports below.</small></p>
6467
</div>
6568
</div>
6669
<div class="form-group col-md-6 hidden">
6770
<label for="location" class="control-label">Server Port</label>
6871
<div>
6972
<select name="node" id="getPort" class="form-control"></select>
73+
<p class="text-muted"><small>Select the main port that this server will be listening on.</small></p>
74+
</div>
75+
</div>
76+
</div>
77+
</div>
78+
</div>
79+
<div class="well">
80+
<div class="row">
81+
<div class="form-group col-md-3 col-xs-6">
82+
<label for="memory" class="control-label">Memory</label>
83+
<div class="input-group">
84+
<input type="text" name="memory" class="form-control" />
85+
<span class="input-group-addon">MB</span>
86+
</div>
87+
</div>
88+
<div class="form-group col-md-3 col-xs-6">
89+
<label for="disk" class="control-label">Disk Space</label>
90+
<div class="input-group">
91+
<input type="text" name="disk" class="form-control" />
92+
<span class="input-group-addon">MB</span>
93+
</div>
94+
</div>
95+
<div class="form-group col-md-3 col-xs-6">
96+
<label for="cpu" class="control-label">CPU Limit</label>
97+
<div class="input-group">
98+
<input type="text" name="cpu" value="0" class="form-control" />
99+
<span class="input-group-addon">%</span>
100+
</div>
101+
</div>
102+
<div class="form-group col-md-3 col-xs-6">
103+
<label for="io" class="control-label">Block I/O</label>
104+
<div class="input-group">
105+
<input type="text" name="io" value="500" class="form-control" />
106+
<span class="input-group-addon">I/O</span>
107+
</div>
108+
</div>
109+
</div>
110+
<div class="row">
111+
<div class="col-md-12">
112+
<p class="text-muted"><small>If you do not want to limit CPU usage set the value to <code>0</code>. To determine a value, take the number <em>physical</em> cores and multiply it by 100. For example, on a quad core system <code>(4 * 100 = 400)</code> there is <code>400%</code> available. To limit a server to using half of a single core, you would set the value to <code>50</code>. To allow a server to use up to two physical cores, set the value to <code>200</code>. BlockIO should be a value between <code>10</code> and <code>1000</code>. Please see <a href="https://docs.docker.com/reference/run/#block-io-bandwidth-blkio-constraint" target="_blank">this documentation</a> for more information about it.</small><p>
113+
</div>
114+
</div>
115+
</div>
116+
<div class="row">
117+
<div class="col-md-6" id="load_services">
118+
<div class="well">
119+
<div class="row">
120+
<div class="ajax_loading_box" style="display:none;"><i class="fa fa-refresh fa-spin ajax_loading_position"></i></div>
121+
<div class="form-group col-md-12">
122+
<label for="service" class="control-label">Service Type</label>
123+
<div>
124+
<select name="node" id="getService" class="form-control">
125+
<option></option>
126+
@foreach($services as $service)
127+
<option value="{{ $service->id }}">{{ $service->name }}</option>
128+
@endforeach
129+
</select>
130+
<p class="text-muted"><small>Select the type of service that this server will be running.</small></p>
131+
</div>
132+
</div>
133+
<div class="form-group col-md-12 hidden">
134+
<label for="service_option" class="control-label">Service Option</label>
135+
<div>
136+
<select name="node" id="getOption" class="form-control">
137+
<option></option>
138+
</select>
139+
<p class="text-muted"><small>Select the type of service that this server will be running.</small></p>
140+
</div>
141+
</div>
142+
</div>
143+
</div>
144+
</div>
145+
<div class="col-md-6">
146+
<div class="well">
147+
<div class="row">
148+
<div class="form-group col-md-12">
149+
<label for="use_custom_image" class="control-label">Use Custom Docker Image</label>
150+
<div class="input-group">
151+
<span class="input-group-addon">
152+
<input type="checkbox" name="use_custom_image" />
153+
</span>
154+
<input type="text" class="form-control" name="custom_image_name" disabled />
155+
</div>
156+
<p class="text-muted"><small>If you would like to use a custom docker image for this server please enter it here. Most users can ignore this option.</small></p>
70157
</div>
71158
</div>
72159
</div>
@@ -76,9 +163,15 @@
76163
</div>
77164
<script>
78165
$(document).ready(function () {
166+
167+
$('input[name="use_custom_image"]').change(function () {
168+
$('input[name="custom_image_name"]').val('').prop('disabled', !($(this).is(':checked')));
169+
});
170+
79171
var nodeData = null;
80172
var currentLocation = null;
81173
var currentNode = null;
174+
var currentService = null;
82175
$('#getLocation').on('change', function (event) {
83176
84177
if ($('#getLocation').val() === '' || $('#getLocation').val() === currentLocation) {
@@ -93,7 +186,7 @@
93186
$('#getIP').html('<option></option>').parent().parent().addClass('hidden');
94187
$('#getPort').html('').parent().parent().addClass('hidden');
95188
96-
handleLoader(true);
189+
handleLoader('#load_settings', true);
97190
98191
$.ajax({
99192
method: 'POST',
@@ -105,17 +198,18 @@
105198
location: $('#getLocation').val()
106199
}
107200
}).done(function (data) {
108-
var data = $.parseJSON(data);
201+
//var data = $.parseJSON(data);
109202
$.each(data, function (i, item) {
110203
var isPublic = (item.public !== 1) ? '(Private Node)' : '';
111204
$('#getNode').append('<option value="' + item.id + '">' + item.name + ' ' + isPublic + '</option>');
112205
});
113206
$('#getNode').parent().parent().removeClass('hidden')
114207
}).fail(function (jqXHR) {
115208
alert('An error occured while attempting to load a list of nodes in this location.');
209+
currentLocation = null;
116210
console.log(jqXHR);
117211
}).always(function () {
118-
handleLoader();
212+
handleLoader('#load_settings');
119213
})
120214
});
121215
$('#getNode').on('change', function (event) {
@@ -130,7 +224,7 @@
130224
$('#getIP').html('<option></option>').parent().parent().addClass('hidden');
131225
$('#getPort').html('').parent().parent().addClass('hidden');
132226
133-
handleLoader(true);
227+
handleLoader('#load_settings', true);
134228
135229
$.ajax({
136230
method: 'POST',
@@ -148,12 +242,15 @@
148242
});
149243
$('#getIP').parent().parent().removeClass('hidden');
150244
}).fail(function (jqXHR) {
245+
alert('An error occured while attempting to get IPs and Ports avaliable on this node.');
246+
currentNode = null;
151247
console.log(jqXHR);
152248
}).always(function () {
153-
handleLoader();
249+
handleLoader('#load_settings');
154250
});
155251
156252
});
253+
157254
$('#getIP').on('change', function (event) {
158255
159256
if ($('#getIP').val() === '') {
@@ -170,27 +267,63 @@
170267
171268
});
172269
270+
$('#getService').on('change', function (event) {
271+
272+
if ($('#getService').val() === '' || $('#getService').val() === currentService) {
273+
return;
274+
}
275+
276+
currentService = $('#getService').val();
277+
handleLoader('#load_services', true);
278+
279+
$.ajax({
280+
method: 'POST',
281+
url: '/admin/ajax/new/server/service-options',
282+
headers: {
283+
'X-CSRF-TOKEN': '{{ csrf_token() }}'
284+
},
285+
data: {
286+
service: $('#getService').val()
287+
}
288+
}).done(function (data) {
289+
$.each(data, function (i, option) {
290+
$('#getOption').append('<option value="' + option.id + '">' + option.name + '</option>');
291+
});
292+
$('#getOption').parent().parent().removeClass('hidden');
293+
}).fail(function (jqXHR) {
294+
alert('An error occured while attempting to list options for this service.');
295+
currentService = null;
296+
console.log(jqXHR);
297+
}).always(function () {
298+
handleLoader('#load_services');
299+
});
300+
301+
});
302+
173303
// Show Loading Animation
174-
function handleLoader (show) {
304+
function handleLoader (element, show) {
305+
306+
var spinner = $(element).find('.ajax_loading_position');
307+
var popover = $(element).find('.ajax_loading_box');
175308
176309
// Show Animation
177-
if (show === true){
178-
var height = $('#load_settings').height();
179-
var width = $('#load_settings').width();
310+
if (typeof show !== 'undefined') {
311+
var height = $(element).height();
312+
var width = $(element).width();
180313
var center_height = (height / 2) - 16;
181314
var center_width = (width / 2) - 16;
182-
$('#position_me').css({
315+
spinner.css({
183316
'top': center_height,
184317
'left': center_width,
185318
'font-size': '32px'
186319
});
187-
$(".ajax_loading_box").css({
320+
popover.css({
188321
'height': height,
189322
'margin': '-20px 0 0 -5px',
190323
'width': width
191324
}).fadeIn();
192325
} else {
193-
$('.ajax_loading_box').fadeOut(100);
326+
popover.hide();
194327
}
195328
196329
}

0 commit comments

Comments
 (0)