]>
Commit | Line | Data |
---|---|---|
10f4cca6 | 1 | <template> |
2 | <Generic :item="item"> | |
3 | <template #content> | |
4 | <p class="title is-4">{{ item.name }}</p> | |
5 | <p class="subtitle is-6"> | |
6 | <template v-if="item.subtitle"> | |
7 | {{ item.subtitle }} | |
8 | </template> | |
9 | <template v-else-if="vms"> | |
13069da1 | 10 | <div v-if="loading"> |
11 | <strong>Loading...</strong> | |
12 | </div> | |
13 | <div v-else-if="error"> | |
14 | <strong class="danger">Error loading info</strong> | |
10f4cca6 | 15 | </div> |
d32f7f64 BW |
16 | <div v-else class="metrics" :class="{'is-size-7-mobile': item.small_font_on_small_screens, 'is-small': item.small_font_on_desktop}"> |
17 | <span v-if="isValueShown('vms')" class="margined">VMs: <span class="is-number"><span class="has-text-weight-bold">{{ vms.running }}</span><span v-if="isValueShown('vms_total')">/{{vms.total}}</span></span></span> | |
18 | <span v-if="isValueShown('lxcs')" class="margined">LXCs: <span class="is-number"><span class="has-text-weight-bold">{{ lxcs.running }}</span><span v-if="isValueShown('lxcs_total')">/{{lxcs.total}}</span></span></span> | |
19 | <span v-if="isValueShown('disk')" class="margined">Disk: <span class="has-text-weight-bold is-number" :class="statusClass(diskUsed)">{{ diskUsed }}%</span></span> | |
20 | <span v-if="isValueShown('mem')" class="margined">Mem: <span class="has-text-weight-bold is-number" :class="statusClass(memoryUsed)">{{ memoryUsed }}%</span></span> | |
21 | <span v-if="isValueShown('cpu')" class="margined">CPU: <span class="has-text-weight-bold is-number" :class="statusClass(cpuUsed)">{{ cpuUsed }}%</span></span> | |
10f4cca6 | 22 | </div> |
23 | </template> | |
24 | </p> | |
25 | </template> | |
13069da1 | 26 | <template #indicator> |
27 | <i v-if="loading" class="fa fa-circle-notch fa-spin fa-2xl"></i> | |
28 | <i v-if="error" class="fa fa-exclamation-circle fa-2xl danger"></i> | |
29 | </template> | |
10f4cca6 | 30 | </Generic> |
31 | </template> | |
32 | ||
33 | <script> | |
34 | import service from "@/mixins/service.js"; | |
35 | import Generic from "./Generic.vue"; | |
36 | ||
37 | export default { | |
38 | name: "Proxmox", | |
39 | mixins: [service], | |
40 | props: { | |
41 | item: Object, | |
42 | }, | |
43 | components: { | |
44 | Generic, | |
45 | }, | |
46 | data: () => ({ | |
47 | vms: { | |
48 | total: 0, | |
49 | running: 0 | |
50 | }, | |
d32f7f64 BW |
51 | lxcs: { |
52 | total: 0, | |
53 | running: 0 | |
54 | }, | |
10f4cca6 | 55 | memoryUsed: 0, |
56 | diskUsed: 0, | |
57 | cpuUsed: 0, | |
d32f7f64 | 58 | hide: [], |
13069da1 | 59 | error: false, |
60 | loading: true | |
10f4cca6 | 61 | }), |
62 | created() { | |
d32f7f64 | 63 | if (this.item.hide) this.hide = this.item.hide; |
10f4cca6 | 64 | this.fetchStatus(); |
65 | }, | |
66 | methods: { | |
67 | statusClass(value) { | |
68 | if (value > this.item.danger_value) return 'danger'; | |
69 | if (value > this.item.warning_value) return 'warning'; | |
70 | return 'healthy' | |
71 | }, | |
72 | fetchStatus: async function () { | |
73 | try { | |
74 | const options = { | |
75 | headers: { | |
76 | "Authorization": this.item.api_token | |
77 | } | |
78 | } | |
79 | const status = await this.fetch(`/api2/json/nodes/${this.item.node}/status`, options); | |
80 | // main metrics: | |
d32f7f64 BW |
81 | const decimalsToShow = this.item.hide_decimals ? 0 : 1; |
82 | this.memoryUsed = ( (status.data.memory.used * 100) / status.data.memory.total ).toFixed(decimalsToShow); | |
83 | this.diskUsed = ( (status.data.rootfs.used * 100) / status.data.rootfs.total ).toFixed(decimalsToShow); | |
84 | this.cpuUsed = (status.data.cpu * 100).toFixed(decimalsToShow); | |
10f4cca6 | 85 | // vms: |
d32f7f64 BW |
86 | if (this.isValueShown('vms')) { |
87 | const vms = await this.fetch(`/api2/json/nodes/${this.item.node}/qemu`, options); | |
88 | this.parseVMsAndLXCs(vms, this.vms); | |
89 | } | |
90 | // lxc containers: | |
91 | if (this.isValueShown('lxcs')) { | |
92 | const lxcs = await this.fetch(`/api2/json/nodes/${this.item.node}/lxc`, options); | |
93 | this.parseVMsAndLXCs(lxcs, this.lxcs); | |
94 | } | |
10f4cca6 | 95 | this.error = false; |
96 | } catch(err) { | |
97 | console.log(err); | |
98 | this.error = true; | |
99 | } | |
4fe179c5 | 100 | this.loading = false; |
10f4cca6 | 101 | }, |
d32f7f64 BW |
102 | parseVMsAndLXCs(items, value) { |
103 | value.total += items.data.length; | |
104 | value.running += items.data.filter( i => i.status === 'running' ).length; | |
105 | // if no vms, hide this value: | |
106 | if (value.total == 0) this.hide.push('lxcs'); | |
107 | }, | |
108 | isValueShown(value) { | |
109 | return this.hide.indexOf(value) == -1; | |
110 | } | |
10f4cca6 | 111 | }, |
112 | }; | |
113 | </script> | |
114 | ||
115 | <style scoped lang="scss"> | |
116 | .is-number { | |
117 | font-family: "Lato" | |
118 | } | |
119 | .healthy { | |
120 | color: green | |
121 | } | |
122 | .warning { | |
123 | color: orange | |
124 | } | |
125 | .danger { | |
126 | color: red | |
127 | } | |
d32f7f64 BW |
128 | .metrics .margined:not(:first-child) { |
129 | margin-left: 0.3rem; | |
130 | } | |
131 | .is-small { | |
132 | font-size: small; | |
10f4cca6 | 133 | } |
134 | </style> | |
135 |