Skip to content

Commit 02b29a6

Browse files
committed
Use client API to get resource use for a server
1 parent bcd3b05 commit 02b29a6

File tree

6 files changed

+113
-68
lines changed

6 files changed

+113
-68
lines changed

app/Http/Controllers/Base/DashboardController.php

Lines changed: 0 additions & 54 deletions
This file was deleted.

app/Transformers/Api/Client/StatsTransformer.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Pterodactyl\Transformers\Api\Client;
44

55
use Pterodactyl\Models\Server;
6+
use GuzzleHttp\Exception\RequestException;
7+
use Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException;
68
use Pterodactyl\Contracts\Repository\Daemon\ServerRepositoryInterface;
79

810
class StatsTransformer extends BaseClientTransformer
@@ -36,6 +38,8 @@ public function getResourceName(): string
3638
*
3739
* @param \Pterodactyl\Models\Server $model
3840
* @return array
41+
*
42+
* @throws \Pterodactyl\Exceptions\Http\Connection\DaemonConnectionException
3943
*/
4044
public function transform(Server $model)
4145
{
@@ -61,7 +65,10 @@ public function transform(Server $model)
6165
'disk' => [
6266
'current' => round(object_get($object, 'proc.disk.used', 0)),
6367
'limit' => floatval($model->disk),
68+
'io' => $model->io,
6469
],
70+
'installed' => $model->installed === 1,
71+
'suspended' => (bool) $model->suspended,
6572
];
6673
}
6774

resources/assets/scripts/components/dashboard/Dashboard.vue

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
v-for="(server, index) in servers.models"
2020
v-bind:key="index"
2121
v-bind:server="server"
22-
v-bind:resources="resources[server.uuid]"
2322
/>
2423
</transition-group>
2524
</div>
@@ -39,14 +38,26 @@
3938
loading: true,
4039
search: '',
4140
servers: new ServerCollection,
42-
resources: {},
4341
}
4442
},
4543
46-
mounted: function () {
44+
/**
45+
* Start loading the servers before the DOM $.el is created.
46+
*/
47+
created: function () {
4748
this.loadServers();
4849
},
4950
51+
/**
52+
* Once the page is mounted set a function to run every 5 seconds that will
53+
* iterate through the visible servers and fetch their resource usage.
54+
*/
55+
mounted: function () {
56+
setInterval(() => {
57+
this.servers.each(this.getResourceUse)
58+
}, 10000);
59+
},
60+
5061
methods: {
5162
/**
5263
* Load the user's servers and render them onto the dashboard.
@@ -64,8 +75,9 @@
6475
.then(response => {
6576
this.servers = new ServerCollection;
6677
response.data.data.forEach(obj => {
67-
this.resources[obj.attributes.uuid] = { cpu: 0, memory: 0 };
68-
this.servers.add(obj.attributes);
78+
this.getResourceUse(
79+
this.servers.add(obj.attributes)
80+
);
6981
});
7082
7183
if (this.servers.models.length === 0) {
@@ -93,6 +105,25 @@
93105
onChange: _.debounce(function () {
94106
this.loadServers(this.$data.search);
95107
}, 500),
108+
109+
/**
110+
* Get resource usage for an individual server for rendering purposes.
111+
*
112+
* @param {Server} server
113+
*/
114+
getResourceUse: function (server) {
115+
window.axios.get(this.route('api.client.servers.resources', { server: server.identifier }))
116+
.then(response => {
117+
if (!(response.data instanceof Object)) {
118+
throw new Error('Received an invalid response object back from status endpoint.');
119+
}
120+
121+
window.events.$emit(`server:${server.uuid}::resources`, response.data.attributes);
122+
})
123+
.catch(err => {
124+
console.error(err);
125+
});
126+
},
96127
}
97128
};
98129
</script>

resources/assets/scripts/components/dashboard/ServerBox.vue

Lines changed: 69 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
<div class="server-box animate fadein">
33
<router-link :to="{ name: 'server', params: { id: server.identifier }}" class="content">
44
<div class="float-right">
5-
<div class="indicator"></div>
5+
<div class="indicator" :class="status"></div>
66
</div>
77
<div class="mb-4">
88
<div class="text-black font-bold text-xl">
@@ -19,11 +19,11 @@
1919
</div>
2020
<div class="mb-4 flex text-center">
2121
<div class="inline-block border border-grey-lighter border-l-0 p-4 flex-1">
22-
<span class="font-bold text-xl">{{ resources.cpu > 0 ? resources.cpu : '&mdash;' }}</span>
22+
<span class="font-bold text-xl">{{ cpu > 0 ? cpu : '&mdash;' }}</span>
2323
<span class="font-light text-sm">%</span>
2424
</div>
2525
<div class="inline-block border border-grey-lighter border-l-0 border-r-0 p-4 flex-1">
26-
<span class="font-bold text-xl">{{ resources.memory > 0 ? resources.memory : '&mdash;' }}</span>
26+
<span class="font-bold text-xl">{{ memory > 0 ? memory : '&mdash;' }}</span>
2727
<span class="font-light text-sm">Mb</span>
2828
</div>
2929
</div>
@@ -38,13 +38,76 @@
3838
</template>
3939

4040
<script>
41-
import { Server } from '../../models/server';
41+
import get from 'lodash/get';
4242
4343
export default {
4444
name: 'server-box',
4545
props: {
46-
server: { type: Server, required: true },
47-
resources: { type: Object, required: true },
46+
server: { type: Object, required: true },
47+
},
48+
49+
data: function () {
50+
return {
51+
resources: undefined,
52+
cpu: 0,
53+
memory: 0,
54+
status: '',
55+
};
56+
},
57+
58+
created: function () {
59+
window.events.$on(`server:${this.server.uuid}::resources`, data => {
60+
this.resources = data;
61+
this.status = this.getServerStatus();
62+
63+
this.memory = Number(get(data, 'memory.current', 0)).toFixed(0);
64+
this.cpu = this._calculateCpu(
65+
Number(get(data, 'cpu.current', 0)),
66+
Number(this.server.limits.cpu)
67+
);
68+
});
69+
},
70+
71+
methods: {
72+
/**
73+
* Set the CSS to use for displaying the server's current status.
74+
*/
75+
getServerStatus: function () {
76+
if (!(this.resources instanceof Object)) {
77+
return '';
78+
}
79+
80+
if (!this.resources.installed || this.resources.suspended) {
81+
return '';
82+
}
83+
84+
switch (this.resources.state) {
85+
case 'off':
86+
return 'offline';
87+
case 'on':
88+
case 'starting':
89+
case 'stopping':
90+
return 'online';
91+
default:
92+
return '';
93+
}
94+
},
95+
96+
/**
97+
* Calculate the CPU usage for a given server relative to their set maximum.
98+
*
99+
* @param {Number} current
100+
* @param {Number} max
101+
* @return {Number}
102+
* @private
103+
*/
104+
_calculateCpu: function (current, max) {
105+
if (max === 0) {
106+
return parseFloat(current.toFixed(1));
107+
}
108+
109+
return parseFloat((current / max * 100).toFixed(1));
110+
}
48111
}
49112
};
50113
</script>

routes/api-client.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
Route::group(['prefix' => '/servers/{server}', 'middleware' => [AuthenticateClientAccess::class]], function () {
2424
Route::get('/', 'Servers\ServerController@index')->name('api.client.servers.view');
2525
Route::get('/utilization', 'Servers\ResourceUtilizationController@index')
26-
->middleware(['throttle:15,1'])
26+
->middleware(['throttle:20,1'])
2727
->name('api.client.servers.resources');
2828

2929
Route::post('/command', 'Servers\CommandController@index')->name('api.client.servers.command');

routes/base.php

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@
77
* https://opensource.org/licenses/MIT
88
*/
99
Route::get('/', 'IndexController@index')->name('index');
10-
Route::get('/dashboard/servers', 'DashboardController@servers')->name('dashboard.servers');
11-
Route::get('/status/{server}', 'IndexController@status')->name('index.status');
1210

1311
/*
1412
|--------------------------------------------------------------------------

0 commit comments

Comments
 (0)