Skip to content

Commit 26eeffd

Browse files
committed
Fix bug preventing changing of the server startup on first save attempt.
1 parent 1800d1c commit 26eeffd

File tree

9 files changed

+69
-83
lines changed

9 files changed

+69
-83
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ This project follows [Semantic Versioning](http://semver.org) guidelines.
1313
* `[beta.1]` — Fixes bug causing inability to create new servers on the Panel.
1414
* `[beta.1]` — Fixes bug causing inability to delete an allocation due to misconfigured JS.
1515
* `[beta.1]` — Fixes bug causing inability to set the IP alias for an allocation to an empty value.
16+
* `[beta.1]` — Fixes bug that caused startup changes to not propigate to the server correctly on the first save.
17+
18+
### Changed
19+
* Moved Docker image setting to be on the startup management page for a server rather than the details page. This value changes based on the Nest and Egg that are selected.
1620

1721
## v0.7.0-beta.1 (Derelict Dermodactylus)
1822
### Added

app/Contracts/Repository/ServerRepositoryInterface.php

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,15 @@ public function getDataForCreation(Server $server, bool $refresh = false): Serve
9595
public function getWithDatabases($id);
9696

9797
/**
98-
* Return data about the daemon service in a consumable format.
98+
* Get data for use when updating a server on the Daemon. Returns an array of
99+
* the egg and pack UUID which are used for build and rebuild. Only loads relations
100+
* if they are missing, or refresh is set to true.
99101
*
100-
* @param int $id
102+
* @param \Pterodactyl\Models\Server $server
103+
* @param bool $refresh
101104
* @return array
102-
*
103-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
104105
*/
105-
public function getDaemonServiceData($id);
106+
public function getDaemonServiceData(Server $server, bool $refresh = false): array;
106107

107108
/**
108109
* Return an array of server IDs that a given user can access based on owner and subuser permissions.

app/Http/Controllers/Admin/ServersController.php

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -410,25 +410,6 @@ public function setDetails(Request $request, Server $server)
410410
return redirect()->route('admin.servers.view.details', $server->id);
411411
}
412412

413-
/**
414-
* Set the new docker container for a server.
415-
*
416-
* @param \Illuminate\Http\Request $request
417-
* @param \Pterodactyl\Models\Server $server
418-
* @return \Illuminate\Http\RedirectResponse
419-
*
420-
* @throws \Pterodactyl\Exceptions\DisplayException
421-
* @throws \Pterodactyl\Exceptions\Model\DataValidationException
422-
* @throws \Pterodactyl\Exceptions\Repository\RecordNotFoundException
423-
*/
424-
public function setContainer(Request $request, Server $server)
425-
{
426-
$this->detailsModificationService->setDockerImage($server, $request->input('docker_image'));
427-
$this->alert->success(trans('admin/server.alerts.docker_image_updated'))->flash();
428-
429-
return redirect()->route('admin.servers.view.details', $server->id);
430-
}
431-
432413
/**
433414
* Toggles the install status for a server.
434415
*

app/Repositories/Eloquent/ServerRepository.php

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -187,21 +187,27 @@ public function getWithDatabases($id)
187187
}
188188

189189
/**
190-
* {@inheritdoc}
190+
* Get data for use when updating a server on the Daemon. Returns an array of
191+
* the egg and pack UUID which are used for build and rebuild. Only loads relations
192+
* if they are missing, or refresh is set to true.
193+
*
194+
* @param \Pterodactyl\Models\Server $server
195+
* @param bool $refresh
196+
* @return array
191197
*/
192-
public function getDaemonServiceData($id)
198+
public function getDaemonServiceData(Server $server, bool $refresh = false): array
193199
{
194-
Assert::integerish($id, 'First argument passed to getDaemonServiceData must be integer, received %s.');
200+
if (! $server->relationLoaded('egg') || $refresh) {
201+
$server->load('egg');
202+
}
195203

196-
$instance = $this->getBuilder()->with('egg.nest', 'pack')->find($id, $this->getColumns());
197-
if (! $instance) {
198-
throw new RecordNotFoundException();
204+
if (! $server->relationLoaded('pack') || $refresh) {
205+
$server->load('pack');
199206
}
200207

201208
return [
202-
'type' => $instance->egg->nest->folder,
203-
'option' => $instance->egg->tag,
204-
'pack' => (! is_null($instance->pack_id)) ? $instance->pack->uuid : null,
209+
'egg' => $server->getRelation('egg')->uuid,
210+
'pack' => is_null($server->getRelation('pack')) ? null : $server->getRelation('pack')->uuid,
205211
];
206212
}
207213

app/Services/Servers/StartupModificationService.php

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -99,14 +99,17 @@ public function handle(Server $server, array $data)
9999
});
100100
}
101101

102-
$daemonData = ['build' => [
103-
'env|overwrite' => $this->environmentService->handle($server),
104-
]];
105-
102+
$daemonData = [];
106103
if ($this->isUserLevel(User::USER_LEVEL_ADMIN)) {
107104
$this->updateAdministrativeSettings($data, $server, $daemonData);
108105
}
109106

107+
$daemonData = array_merge_recursive($daemonData, [
108+
'build' => [
109+
'env|overwrite' => $this->environmentService->handle($server),
110+
],
111+
]);
112+
110113
try {
111114
$this->daemonServerRepository->setNode($server->node_id)->setAccessServer($server->uuid)->update($daemonData);
112115
} catch (RequestException $exception) {
@@ -136,17 +139,15 @@ private function updateAdministrativeSettings(array $data, Server &$server, arra
136139
'egg_id' => array_get($data, 'egg_id', $server->egg_id),
137140
'pack_id' => array_get($data, 'pack_id', $server->pack_id) > 0 ? array_get($data, 'pack_id', $server->pack_id) : null,
138141
'skip_scripts' => isset($data['skip_scripts']),
142+
'image' => array_get($data, 'docker_image', $server->image),
139143
]);
140144

141-
if (
142-
$server->nest_id != array_get($data, 'nest_id', $server->nest_id) ||
143-
$server->egg_id != array_get($data, 'egg_id', $server->egg_id) ||
144-
$server->pack_id != array_get($data, 'pack_id', $server->pack_id)
145-
) {
146-
$daemonData['service'] = array_merge(
147-
$this->repository->withColumns(['id', 'egg_id', 'pack_id'])->getDaemonServiceData($server->id),
145+
$daemonData = array_merge($daemonData, [
146+
'build' => ['image' => $server->image],
147+
'service' => array_merge(
148+
$this->repository->getDaemonServiceData($server, true),
148149
['skip_scripts' => isset($data['skip_scripts'])]
149-
);
150-
}
150+
),
151+
]);
151152
}
152153
}

resources/themes/pterodactyl/admin/servers/view/details.blade.php

Lines changed: 1 addition & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@
3939
</div>
4040
</div>
4141
<div class="row">
42-
<div class="col-sm-6">
42+
<div class="col-xs-12">
4343
<div class="box box-primary">
4444
<div class="box-header with-border">
4545
<h3 class="box-title">Base Information</h3>
@@ -63,15 +63,6 @@
6363
<textarea name="description" rows="3" class="form-control">{{ old('description', $server->description) }}</textarea>
6464
<p class="text-muted small">A brief description of this server.</p>
6565
</div>
66-
<div class="form-group">
67-
<label for="name" class="control-label">Daemon Secret Token</label>
68-
<input type="text" disabled value="{{ $server->daemonSecret }}" class="form-control" />
69-
<p class="text-muted small">This token should not be shared with anyone as it has full control over this server.</p>
70-
</div>
71-
<div class="form-group">
72-
<input type="checkbox" name="reset_token" id="pResetToken"/> <label for="pResetToken">Reset Daemon Token</label>
73-
<p class="text-muted small">Resetting this token will cause any requests using the old token to fail.</p>
74-
</div>
7566
</div>
7667
<div class="box-footer">
7768
{!! csrf_field() !!}
@@ -81,27 +72,6 @@
8172
</form>
8273
</div>
8374
</div>
84-
<div class="col-sm-6">
85-
<div class="box box-success">
86-
<div class="box-header with-border">
87-
<h3 class="box-title">Container Setup</h3>
88-
</div>
89-
<form action="{{ route('admin.servers.view.details.container', $server->id) }}" method="POST">
90-
<div class="box-body">
91-
<div class="form-group">
92-
<label for="name" class="control-label">Docker Image</label>
93-
<input type="text" name="docker_image" value="{{ $server->image }}" class="form-control" />
94-
<p class="text-muted small">The docker image to use for this server. The default image for this service and option combination is <code>{{ $server->egg->docker_image }}</code>.</p>
95-
</div>
96-
</div>
97-
<div class="box-footer">
98-
{!! csrf_field() !!}
99-
{!! method_field('PATCH') !!}
100-
<input type="submit" class="btn btn-sm btn-primary" value="Update Docker Container" />
101-
</div>
102-
</form>
103-
</div>
104-
</div>
10575
</div>
10676
@endsection
10777

resources/themes/pterodactyl/admin/servers/view/startup.blade.php

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@
109109
</div>
110110
</div>
111111
</div>
112+
<div class="box">
113+
<div class="box-header with-border">
114+
<h3 class="box-title">Docker Container Configuration</h3>
115+
</div>
116+
<div class="box-body">
117+
<div class="form-group">
118+
<label for="pDockerImage" class="control-label">Image</label>
119+
<input type="text" name="docker_image" id="pDockerImage" value="{{ $server->image }}" class="form-control" />
120+
<p class="text-muted small">The Docker image to use for this server. The default image for the selected egg is <code id="setDefaultImage"></code>.</p>
121+
</div>
122+
</div>
123+
</div>
112124
</div>
113125
<div class="col-md-6">
114126
<div class="row" id="appendVariablesTo"></div>
@@ -143,7 +155,11 @@
143155
var parentChain = _.get(Pterodactyl.nests, $('#pNestId').val(), null);
144156
var objectChain = _.get(parentChain, 'eggs.' + $(this).val(), null);
145157
146-
$('#pDefaultContainer').val(_.get(objectChain, 'docker_image', 'not defined!'));
158+
$('#setDefaultImage').html(_.get(objectChain, 'docker_image', 'undefined'));
159+
$('#pDockerImage').val(_.get(objectChain, 'docker_image', 'undefined'));
160+
if (objectChain.id === parseInt('{{ $server->egg_id }}')) {
161+
$('#pDockerImage').val('{{ $server->image }}');
162+
}
147163
148164
if (!_.get(objectChain, 'startup', false)) {
149165
$('#pDefaultStartupCommand').val(_.get(parentChain, 'startup', 'ERROR: Startup Not Defined!'));

routes/admin.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,6 @@
105105
Route::post('/view/{server}/delete', 'ServersController@delete');
106106

107107
Route::patch('/view/{server}/details', 'ServersController@setDetails');
108-
Route::patch('/view/{server}/details/container', 'ServersController@setContainer')->name('admin.servers.view.details.container');
109108
Route::patch('/view/{server}/database', 'ServersController@resetDatabasePassword');
110109

111110
Route::delete('/view/{server}/database/{database}/delete', 'ServersController@deleteDatabase')->name('admin.servers.view.database.delete');

tests/Unit/Services/Servers/StartupModificationServiceTest.php

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ public function testStartupModificationAsAdminUser()
107107
{
108108
$model = factory(Server::class)->make([
109109
'egg_id' => 123,
110+
'image' => 'docker:image',
110111
]);
111112

112113
$this->connection->shouldReceive('beginTransaction')->withNoArgs()->once()->andReturnNull();
@@ -121,22 +122,29 @@ public function testStartupModificationAsAdminUser()
121122
'variable_id' => 1,
122123
], ['variable_value' => 'stored-value'])->once()->andReturnNull();
123124

124-
$this->environmentService->shouldReceive('handle')->with($model)->once()->andReturn(['env']);
125-
126125
$this->repository->shouldReceive('update')->with($model->id, m::subset([
127126
'installed' => 0,
128127
'egg_id' => 456,
129128
'pack_id' => 789,
129+
'image' => 'docker:image',
130130
]))->once()->andReturn($model);
131-
$this->repository->shouldReceive('withColumns->getDaemonServiceData')->with($model->id)->once()->andReturn([]);
131+
$this->repository->shouldReceive('getDaemonServiceData')->with($model, true)->once()->andReturn([
132+
'egg' => 'abcd1234',
133+
'pack' => 'xyz987',
134+
]);
135+
136+
$this->environmentService->shouldReceive('handle')->with($model)->once()->andReturn(['env']);
132137

133138
$this->daemonServerRepository->shouldReceive('setNode')->with($model->node_id)->once()->andReturnSelf();
134139
$this->daemonServerRepository->shouldReceive('setAccessServer')->with($model->uuid)->once()->andReturnSelf();
135140
$this->daemonServerRepository->shouldReceive('update')->with([
136141
'build' => [
137142
'env|overwrite' => ['env'],
143+
'image' => $model->image,
138144
],
139145
'service' => [
146+
'egg' => 'abcd1234',
147+
'pack' => 'xyz987',
140148
'skip_scripts' => false,
141149
],
142150
])->once()->andReturnSelf();
@@ -145,7 +153,7 @@ public function testStartupModificationAsAdminUser()
145153

146154
$service = $this->getService();
147155
$service->setUserLevel(User::USER_LEVEL_ADMIN);
148-
$service->handle($model, ['egg_id' => 456, 'pack_id' => 789, 'environment' => ['test' => 'abcd1234']]);
156+
$service->handle($model, ['docker_image' => 'docker:image', 'egg_id' => 456, 'pack_id' => 789, 'environment' => ['test' => 'abcd1234']]);
149157
$this->assertTrue(true);
150158
}
151159

0 commit comments

Comments
 (0)