@fastybird/smart-panel-backend 0.2.0-alpha.1 → 0.3.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -29,5 +29,26 @@ export declare abstract class Platform {
29
29
  softTempLimit: boolean;
30
30
  };
31
31
  protected readThrottleFromSysfs(): Promise<ThrottleStatusDto | null>;
32
+ protected readContainerMemory(): Promise<{
33
+ total: number;
34
+ used: number;
35
+ free: number;
36
+ } | null>;
37
+ protected readContainerCpuCount(): Promise<number>;
38
+ protected readContainerCpuLoad(): Promise<number | null>;
39
+ protected filterContainerStorage(fsList: Array<{
40
+ fs: string;
41
+ type: string;
42
+ mount: string;
43
+ size: number;
44
+ used: number;
45
+ available: number;
46
+ }>): Array<{
47
+ fs: string;
48
+ used: number;
49
+ size: number;
50
+ available: number;
51
+ }>;
52
+ protected getContainerSystemInfo(): Promise<SystemInfoDto>;
32
53
  protected validateDto<T extends object>(dtoClass: new () => T, rawData: unknown): Promise<T>;
33
54
  }
@@ -6,8 +6,11 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.Platform = void 0;
7
7
  const class_validator_1 = require("class-validator");
8
8
  const promises_1 = __importDefault(require("fs/promises"));
9
+ const os_1 = __importDefault(require("os"));
10
+ const systeminformation_1 = __importDefault(require("systeminformation"));
9
11
  const logger_1 = require("../../../common/logger");
10
12
  const transform_utils_1 = require("../../../common/utils/transform.utils");
13
+ const system_info_dto_1 = require("../dto/system-info.dto");
11
14
  const throttle_status_dto_1 = require("../dto/throttle-status.dto");
12
15
  const platform_constants_1 = require("../platform.constants");
13
16
  const platform_exceptions_1 = require("../platform.exceptions");
@@ -35,6 +38,181 @@ class Platform {
35
38
  }
36
39
  return null;
37
40
  }
41
+ async readContainerMemory() {
42
+ try {
43
+ const [maxRaw, currentRaw] = await Promise.all([
44
+ promises_1.default.readFile('/sys/fs/cgroup/memory.max', 'utf-8'),
45
+ promises_1.default.readFile('/sys/fs/cgroup/memory.current', 'utf-8'),
46
+ ]);
47
+ const max = maxRaw.trim();
48
+ const current = parseInt(currentRaw.trim(), 10);
49
+ if (max !== 'max' && !isNaN(current)) {
50
+ const total = parseInt(max, 10);
51
+ if (!isNaN(total) && total > 0) {
52
+ return { total, used: current, free: Math.max(0, total - current) };
53
+ }
54
+ }
55
+ }
56
+ catch {
57
+ }
58
+ try {
59
+ const [limitRaw, usageRaw] = await Promise.all([
60
+ promises_1.default.readFile('/sys/fs/cgroup/memory/memory.limit_in_bytes', 'utf-8'),
61
+ promises_1.default.readFile('/sys/fs/cgroup/memory/memory.usage_in_bytes', 'utf-8'),
62
+ ]);
63
+ const limit = parseInt(limitRaw.trim(), 10);
64
+ const usage = parseInt(usageRaw.trim(), 10);
65
+ if (!isNaN(limit) && !isNaN(usage) && limit < 2 ** 62) {
66
+ return { total: limit, used: usage, free: Math.max(0, limit - usage) };
67
+ }
68
+ }
69
+ catch {
70
+ }
71
+ return null;
72
+ }
73
+ async readContainerCpuCount() {
74
+ try {
75
+ const raw = await promises_1.default.readFile('/sys/fs/cgroup/cpu.max', 'utf-8');
76
+ const [quotaStr, periodStr] = raw.trim().split(/\s+/);
77
+ if (quotaStr !== 'max') {
78
+ const quota = parseInt(quotaStr, 10);
79
+ const period = parseInt(periodStr, 10);
80
+ if (!isNaN(quota) && quota > 0 && !isNaN(period) && period > 0) {
81
+ return quota / period;
82
+ }
83
+ }
84
+ }
85
+ catch {
86
+ }
87
+ try {
88
+ const [quotaRaw, periodRaw] = await Promise.all([
89
+ promises_1.default.readFile('/sys/fs/cgroup/cpu/cpu.cfs_quota_us', 'utf-8'),
90
+ promises_1.default.readFile('/sys/fs/cgroup/cpu/cpu.cfs_period_us', 'utf-8'),
91
+ ]);
92
+ const quota = parseInt(quotaRaw.trim(), 10);
93
+ const period = parseInt(periodRaw.trim(), 10);
94
+ if (!isNaN(quota) && quota > 0 && !isNaN(period) && period > 0) {
95
+ return quota / period;
96
+ }
97
+ }
98
+ catch {
99
+ }
100
+ return os_1.default.cpus().length || 1;
101
+ }
102
+ async readContainerCpuLoad() {
103
+ const cpuCount = await this.readContainerCpuCount();
104
+ try {
105
+ const readV2 = async () => {
106
+ const stat = await promises_1.default.readFile('/sys/fs/cgroup/cpu.stat', 'utf-8');
107
+ const match = stat.match(/usage_usec\s+(\d+)/);
108
+ if (!match) {
109
+ throw new Error('usage_usec not found');
110
+ }
111
+ return parseInt(match[1], 10);
112
+ };
113
+ const t1 = Date.now();
114
+ const u1 = await readV2();
115
+ await new Promise((r) => setTimeout(r, 200));
116
+ const t2 = Date.now();
117
+ const u2 = await readV2();
118
+ const elapsedUs = (t2 - t1) * 1000;
119
+ const cpuUs = u2 - u1;
120
+ if (elapsedUs > 0) {
121
+ return Math.min(100, (cpuUs / (elapsedUs * cpuCount)) * 100);
122
+ }
123
+ }
124
+ catch {
125
+ }
126
+ try {
127
+ const readV1 = async () => {
128
+ const raw = await promises_1.default.readFile('/sys/fs/cgroup/cpuacct/cpuacct.usage', 'utf-8');
129
+ return parseInt(raw.trim(), 10);
130
+ };
131
+ const t1 = Date.now();
132
+ const u1 = await readV1();
133
+ await new Promise((r) => setTimeout(r, 200));
134
+ const t2 = Date.now();
135
+ const u2 = await readV1();
136
+ const elapsedNs = (t2 - t1) * 1_000_000;
137
+ const cpuNs = u2 - u1;
138
+ if (elapsedNs > 0) {
139
+ return Math.min(100, (cpuNs / (elapsedNs * cpuCount)) * 100);
140
+ }
141
+ }
142
+ catch {
143
+ }
144
+ return null;
145
+ }
146
+ filterContainerStorage(fsList) {
147
+ const PSEUDO_FS = new Set(['tmpfs', 'devtmpfs', 'squashfs', 'proc', 'sysfs', 'ramfs']);
148
+ return fsList
149
+ .filter((d) => d.size > 0 && !PSEUDO_FS.has(d.type) && !d.type.startsWith('cgroup'))
150
+ .map((d) => ({ fs: d.fs, used: d.used, size: d.size, available: d.available }));
151
+ }
152
+ async getContainerSystemInfo() {
153
+ const [hostCpu, hostMemory, storage, osInfo, temp, network, graphics, networkInterface, containerMemory, containerCpu,] = await Promise.all([
154
+ systeminformation_1.default.currentLoad(),
155
+ systeminformation_1.default.mem(),
156
+ systeminformation_1.default.fsSize(),
157
+ systeminformation_1.default.osInfo(),
158
+ systeminformation_1.default.cpuTemperature(),
159
+ systeminformation_1.default.networkStats(),
160
+ systeminformation_1.default.graphics(),
161
+ systeminformation_1.default.networkInterfaces('default'),
162
+ this.readContainerMemory(),
163
+ this.readContainerCpuLoad(),
164
+ ]);
165
+ const time = systeminformation_1.default.time();
166
+ const memory = containerMemory ?? {
167
+ total: hostMemory.total,
168
+ used: hostMemory.used,
169
+ free: hostMemory.free,
170
+ };
171
+ const cpuLoad = containerCpu ?? hostCpu.currentLoad;
172
+ const containerStorage = this.filterContainerStorage(storage);
173
+ const defaultNetworkInterface = Array.isArray(networkInterface) ? networkInterface[0] : networkInterface;
174
+ const rawData = {
175
+ cpuLoad,
176
+ memory,
177
+ storage: containerStorage,
178
+ primaryStorage: containerStorage[0] ?? { fs: '', used: 0, size: 0, available: 0 },
179
+ os: {
180
+ platform: osInfo.platform,
181
+ distro: osInfo.distro,
182
+ release: osInfo.release,
183
+ uptime: Math.floor(process.uptime()),
184
+ node: process.version.replace(/^v/, ''),
185
+ npm: null,
186
+ timezone: time.timezone,
187
+ },
188
+ temperature: {
189
+ cpu: temp.main,
190
+ },
191
+ network: network.map((row) => ({
192
+ interface: row.iface,
193
+ rxBytes: row.rx_bytes,
194
+ txBytes: row.tx_bytes,
195
+ })),
196
+ defaultNetwork: {
197
+ interface: defaultNetworkInterface?.iface ?? '',
198
+ ip4: defaultNetworkInterface?.ip4 ?? '',
199
+ ip6: defaultNetworkInterface?.ip6 ?? '',
200
+ mac: defaultNetworkInterface?.mac ?? '',
201
+ hostname: osInfo.hostname,
202
+ },
203
+ display: {
204
+ resolutionX: graphics.displays[0]?.resolutionX || 0,
205
+ resolutionY: graphics.displays[0]?.resolutionY || 0,
206
+ currentResX: graphics.displays[0]?.currentResX || 0,
207
+ currentResY: graphics.displays[0]?.currentResY || 0,
208
+ },
209
+ process: {
210
+ pid: process.pid,
211
+ uptime: Math.floor(process.uptime()),
212
+ },
213
+ };
214
+ return this.validateDto(system_info_dto_1.SystemInfoDto, rawData);
215
+ }
38
216
  async validateDto(dtoClass, rawData) {
39
217
  const instance = (0, transform_utils_1.toInstance)(dtoClass, rawData);
40
218
  const errors = await (0, class_validator_1.validate)(instance, { whitelist: true });
@@ -1 +1 @@
1
- {"version":3,"file":"abstract.platform.js","sourceRoot":"","sources":["../../../../src/modules/platform/platforms/abstract.platform.ts"],"names":[],"mappings":";;;;;;AAAA,qDAA2C;AAC3C,2DAA6B;AAE7B,mDAA+D;AAC/D,2EAAmE;AAInE,oEAA+D;AAE/D,8DAA6D;AAC7D,gEAA2D;AAE3D,MAAsB,QAAQ;IAA9B;QACW,WAAM,GAAG,IAAA,8BAAqB,EAAC,yCAAoB,EAAE,UAAU,CAAC,CAAC;IAqE5E,CAAC;IA7CU,kBAAkB,CAAC,MAAc;QAC1C,OAAO;YACN,YAAY,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;YAC9B,gBAAgB,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;YAClC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;YAC5B,aAAa,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;SAC/B,CAAC;IACH,CAAC;IAMS,KAAK,CAAC,qBAAqB;QACpC,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAEzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpB,OAAO,IAAI,CAAC,WAAW,CAAC,uCAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAES,KAAK,CAAC,WAAW,CAAmB,QAAqB,EAAE,OAAgB;QACpF,MAAM,QAAQ,GAAG,IAAA,4BAAU,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAQ,EAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,QAAQ,CAAC,IAAI,EAAE,EAAE;gBAChE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;aAC/C,CAAC,CAAC;YAEH,MAAM,IAAI,uCAAiB,CAAC,sDAAsD,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAE7D,OAAO,QAAQ,CAAC;IACjB,CAAC;;AArEF,4BAsEC;AAlD0B,4BAAmB,GAAG,sDAAsD,AAAzD,CAA0D"}
1
+ {"version":3,"file":"abstract.platform.js","sourceRoot":"","sources":["../../../../src/modules/platform/platforms/abstract.platform.ts"],"names":[],"mappings":";;;;;;AAAA,qDAA2C;AAC3C,2DAA6B;AAC7B,4CAAoB;AACpB,0EAA0D;AAE1D,mDAA+D;AAC/D,2EAAmE;AAEnE,4DAAmE;AAEnE,oEAA+D;AAE/D,8DAA6D;AAC7D,gEAA2D;AAE3D,MAAsB,QAAQ;IAA9B;QACW,WAAM,GAAG,IAAA,8BAAqB,EAAC,yCAAoB,EAAE,UAAU,CAAC,CAAC;IAmV5E,CAAC;IA3TU,kBAAkB,CAAC,MAAc;QAC1C,OAAO;YACN,YAAY,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;YAC9B,gBAAgB,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;YAClC,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;YAC5B,aAAa,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,GAAG,CAAC;SAC/B,CAAC;IACH,CAAC;IAMS,KAAK,CAAC,qBAAqB;QACpC,IAAI,CAAC;YACJ,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;YACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAEzC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC;gBACpB,OAAO,IAAI,CAAC,WAAW,CAAC,uCAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAC,CAAC;YAC7E,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAUS,KAAK,CAAC,mBAAmB;QAElC,IAAI,CAAC;YACJ,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC9C,kBAAE,CAAC,QAAQ,CAAC,2BAA2B,EAAE,OAAO,CAAC;gBACjD,kBAAE,CAAC,QAAQ,CAAC,+BAA+B,EAAE,OAAO,CAAC;aACrD,CAAC,CAAC;YAEH,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAGhD,IAAI,GAAG,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;gBACtC,MAAM,KAAK,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAEhC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;oBAChC,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC,EAAE,CAAC;gBACrE,CAAC;YACF,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAGD,IAAI,CAAC;YACJ,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC9C,kBAAE,CAAC,QAAQ,CAAC,6CAA6C,EAAE,OAAO,CAAC;gBACnE,kBAAE,CAAC,QAAQ,CAAC,6CAA6C,EAAE,OAAO,CAAC;aACnE,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAC5C,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAG5C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvD,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC,EAAE,CAAC;YACxE,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAMS,KAAK,CAAC,qBAAqB;QAEpC,IAAI,CAAC;YACJ,MAAM,GAAG,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,wBAAwB,EAAE,OAAO,CAAC,CAAC;YACjE,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YAEtD,IAAI,QAAQ,KAAK,KAAK,EAAE,CAAC;gBACxB,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBACrC,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;gBAEvC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;oBAChE,OAAO,KAAK,GAAG,MAAM,CAAC;gBACvB,CAAC;YACF,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAGD,IAAI,CAAC;YACJ,MAAM,CAAC,QAAQ,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;gBAC/C,kBAAE,CAAC,QAAQ,CAAC,qCAAqC,EAAE,OAAO,CAAC;gBAC3D,kBAAE,CAAC,QAAQ,CAAC,sCAAsC,EAAE,OAAO,CAAC;aAC5D,CAAC,CAAC;YAEH,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAC5C,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YAE9C,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,MAAM,GAAG,CAAC,EAAE,CAAC;gBAChE,OAAO,KAAK,GAAG,MAAM,CAAC;YACvB,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,YAAE,CAAC,IAAI,EAAE,CAAC,MAAM,IAAI,CAAC,CAAC;IAC9B,CAAC;IAQS,KAAK,CAAC,oBAAoB;QACnC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAGpD,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,KAAK,IAAqB,EAAE;gBAC1C,MAAM,IAAI,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,yBAAyB,EAAE,OAAO,CAAC,CAAC;gBACnE,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,oBAAoB,CAAC,CAAC;gBAE/C,IAAI,CAAC,KAAK,EAAE,CAAC;oBACZ,MAAM,IAAI,KAAK,CAAC,sBAAsB,CAAC,CAAC;gBACzC,CAAC;gBAED,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YAC/B,CAAC,CAAC;YAEF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;YAE1B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAE7C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;YAE1B,MAAM,SAAS,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,IAAI,CAAC;YACnC,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,CAAC;YAEtB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBACnB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9D,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAGD,IAAI,CAAC;YACJ,MAAM,MAAM,GAAG,KAAK,IAAqB,EAAE;gBAC1C,MAAM,GAAG,GAAG,MAAM,kBAAE,CAAC,QAAQ,CAAC,sCAAsC,EAAE,OAAO,CAAC,CAAC;gBAE/E,OAAO,QAAQ,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;YACjC,CAAC,CAAC;YAEF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;YAE1B,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;YAE7C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;YACtB,MAAM,EAAE,GAAG,MAAM,MAAM,EAAE,CAAC;YAE1B,MAAM,SAAS,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,GAAG,SAAS,CAAC;YACxC,MAAM,KAAK,GAAG,EAAE,GAAG,EAAE,CAAC;YAEtB,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;gBACnB,OAAO,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,KAAK,GAAG,CAAC,SAAS,GAAG,QAAQ,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9D,CAAC;QACF,CAAC;QAAC,MAAM,CAAC;QAET,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAMS,sBAAsB,CAC/B,MAAyG;QAEzG,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;QAEvF,OAAO,MAAM;aACX,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;aACnF,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,SAAS,EAAE,CAAC,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC;IAOS,KAAK,CAAC,sBAAsB;QAGrC,MAAM,CACL,OAAO,EACP,UAAU,EACV,OAAO,EACP,MAAM,EACN,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,gBAAgB,EAChB,eAAe,EACf,YAAY,EACZ,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YACrB,2BAAE,CAAC,WAAW,EAAE;YAChB,2BAAE,CAAC,GAAG,EAAE;YACR,2BAAE,CAAC,MAAM,EAAE;YACX,2BAAE,CAAC,MAAM,EAAE;YACX,2BAAE,CAAC,cAAc,EAAE;YACnB,2BAAE,CAAC,YAAY,EAAE;YACjB,2BAAE,CAAC,QAAQ,EAAE;YACb,2BAAE,CAAC,iBAAiB,CAAC,SAAS,CAE7B;YACD,IAAI,CAAC,mBAAmB,EAAE;YAC1B,IAAI,CAAC,oBAAoB,EAAE;SAC3B,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,2BAAE,CAAC,IAAI,EAAE,CAAC;QAEvB,MAAM,MAAM,GAAG,eAAe,IAAI;YACjC,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,IAAI,EAAE,UAAU,CAAC,IAAI;SACrB,CAAC;QAEF,MAAM,OAAO,GAAG,YAAY,IAAI,OAAO,CAAC,WAAW,CAAC;QAGpD,MAAM,gBAAgB,GAAG,IAAI,CAAC,sBAAsB,CAAC,OAAO,CAAC,CAAC;QAE9D,MAAM,uBAAuB,GAAG,KAAK,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAEzG,MAAM,OAAO,GAAG;YACf,OAAO;YACP,MAAM;YACN,OAAO,EAAE,gBAAgB;YACzB,cAAc,EAAE,gBAAgB,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE;YACjF,EAAE,EAAE;gBACH,QAAQ,EAAE,MAAM,CAAC,QAAQ;gBACzB,MAAM,EAAE,MAAM,CAAC,MAAM;gBACrB,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;gBACpC,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC;gBACvC,GAAG,EAAE,IAAI;gBACT,QAAQ,EAAE,IAAI,CAAC,QAAQ;aACvB;YACD,WAAW,EAAE;gBACZ,GAAG,EAAE,IAAI,CAAC,IAAI;aACd;YACD,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;gBAC9B,SAAS,EAAE,GAAG,CAAC,KAAK;gBACpB,OAAO,EAAE,GAAG,CAAC,QAAQ;gBACrB,OAAO,EAAE,GAAG,CAAC,QAAQ;aACrB,CAAC,CAAC;YACH,cAAc,EAAE;gBACf,SAAS,EAAE,uBAAuB,EAAE,KAAK,IAAI,EAAE;gBAC/C,GAAG,EAAE,uBAAuB,EAAE,GAAG,IAAI,EAAE;gBACvC,GAAG,EAAE,uBAAuB,EAAE,GAAG,IAAI,EAAE;gBACvC,GAAG,EAAE,uBAAuB,EAAE,GAAG,IAAI,EAAE;gBACvC,QAAQ,EAAE,MAAM,CAAC,QAAQ;aACzB;YACD,OAAO,EAAE;gBACR,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC;gBACnD,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC;gBACnD,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC;gBACnD,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,WAAW,IAAI,CAAC;aACnD;YACD,OAAO,EAAE;gBACR,GAAG,EAAE,OAAO,CAAC,GAAG;gBAChB,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC;aACpC;SACD,CAAC;QAEF,OAAO,IAAI,CAAC,WAAW,CAAC,+BAAa,EAAE,OAAO,CAAC,CAAC;IACjD,CAAC;IAES,KAAK,CAAC,WAAW,CAAmB,QAAqB,EAAE,OAAgB;QACpF,MAAM,QAAQ,GAAG,IAAA,4BAAU,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAE/C,MAAM,MAAM,GAAG,MAAM,IAAA,0BAAQ,EAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAE7D,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,8BAA8B,QAAQ,CAAC,IAAI,EAAE,EAAE;gBAChE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;aAC/C,CAAC,CAAC;YAEH,MAAM,IAAI,uCAAiB,CAAC,sDAAsD,CAAC,CAAC;QACrF,CAAC;QAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,0BAA0B,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;QAE7D,OAAO,QAAQ,CAAC;IACjB,CAAC;;AAnVF,4BAoVC;AAhU0B,4BAAmB,GAAG,sDAAsD,AAAzD,CAA0D"}
@@ -1,5 +1,7 @@
1
+ import { SystemInfoDto } from '../dto/system-info.dto';
1
2
  import { GenericPlatform } from './generic.platform';
2
3
  export declare class DockerPlatform extends GenericPlatform {
4
+ getSystemInfo(): Promise<SystemInfoDto>;
3
5
  rebootDevice(): Promise<void>;
4
6
  powerOffDevice(): Promise<void>;
5
7
  private getContainerId;
@@ -11,6 +11,9 @@ const util_1 = require("util");
11
11
  const generic_platform_1 = require("./generic.platform");
12
12
  const execFileAsync = (0, util_1.promisify)(child_process_1.execFile);
13
13
  class DockerPlatform extends generic_platform_1.GenericPlatform {
14
+ async getSystemInfo() {
15
+ return this.getContainerSystemInfo();
16
+ }
14
17
  async rebootDevice() {
15
18
  this.logger.log('[SYSTEM] Restarting container via Docker API...');
16
19
  const containerId = await this.getContainerId();
@@ -1 +1 @@
1
- {"version":3,"file":"docker.platform.js","sourceRoot":"","sources":["../../../../src/modules/platform/platforms/docker.platform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"docker.platform.js","sourceRoot":"","sources":["../../../../src/modules/platform/platforms/docker.platform.ts"],"names":[],"mappings":"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"}
@@ -1,9 +1,11 @@
1
+ import { SystemInfoDto } from '../dto/system-info.dto';
1
2
  import { ThrottleStatusDto } from '../dto/throttle-status.dto';
2
3
  import { GenericPlatform } from './generic.platform';
3
4
  export declare class HomeAssistantPlatform extends GenericPlatform {
4
5
  private readonly supervisorToken;
5
6
  private readonly supervisorUrl;
6
7
  constructor();
8
+ getSystemInfo(): Promise<SystemInfoDto>;
7
9
  getThrottleStatus(): Promise<ThrottleStatusDto>;
8
10
  rebootDevice(): Promise<void>;
9
11
  powerOffDevice(): Promise<void>;
@@ -10,6 +10,9 @@ class HomeAssistantPlatform extends generic_platform_1.GenericPlatform {
10
10
  this.supervisorToken = process.env.SUPERVISOR_TOKEN ?? null;
11
11
  this.supervisorUrl = process.env.SUPERVISOR_URL ?? 'http://supervisor';
12
12
  }
13
+ async getSystemInfo() {
14
+ return this.getContainerSystemInfo();
15
+ }
13
16
  async getThrottleStatus() {
14
17
  const result = await this.readThrottleFromSysfs();
15
18
  if (result) {
@@ -1 +1 @@
1
- {"version":3,"file":"home-assistant.platform.js","sourceRoot":"","sources":["../../../../src/modules/platform/platforms/home-assistant.platform.ts"],"names":[],"mappings":";;;AAAA,oEAA+D;AAC/D,gEAA2D;AAE3D,yDAAqD;AAErD,MAAa,qBAAsB,SAAQ,kCAAe;IAIzD;QACC,KAAK,EAAE,CAAC;QAER,IAAI,CAAC,eAAe,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,IAAI,CAAC;QAC5D,IAAI,CAAC,aAAa,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,mBAAmB,CAAC;IACxE,CAAC;IAQD,KAAK,CAAC,iBAAiB;QACtB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAElD,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,MAAM,CAAC;QACf,CAAC;QAED,OAAO,IAAI,CAAC,WAAW,CAAC,uCAAiB,EAAE,IAAI,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,YAAY;QACjB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,qDAAqD,CAAC,CAAC;QAEvE,MAAM,IAAI,CAAC,iBAAiB,CAAC,sBAAsB,EAAE,MAAM,CAAC,CAAC;IAC9D,CAAC;IAED,KAAK,CAAC,cAAc;QACnB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QAErE,MAAM,IAAI,CAAC,iBAAiB,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;IAC3D,CAAC;IAEO,KAAK,CAAC,iBAAiB,CAAC,QAAgB,EAAE,MAAc;QAC/D,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;YAC3B,MAAM,IAAI,uCAAiB,CAC1B,gGAAgG,CAChG,CAAC;QACH,CAAC;QAED,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,QAAQ,EAAE,CAAC;QAC/C,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,MAAM,CAAC,CAAC;QAE/D,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBACjC,MAAM;gBACN,OAAO,EAAE;oBACR,aAAa,EAAE,UAAU,IAAI,CAAC,eAAe,EAAE;oBAC/C,cAAc,EAAE,kBAAkB;iBAClC;gBACD,MAAM,EAAE,UAAU,CAAC,MAAM;aACzB,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBAClB,MAAM,IAAI,KAAK,CAAC,QAAQ,QAAQ,CAAC,MAAM,KAAK,QAAQ,CAAC,UAAU,EAAE,CAAC,CAAC;YACpE,CAAC;YAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC9B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,MAAM,GAAG,GAAG,KAAc,CAAC;YAE3B,IAAI,GAAG,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;gBAC/B,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kCAAkC,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC;gBAE1E,MAAM,IAAI,uCAAiB,CAAC,iDAAiD,MAAM,IAAI,QAAQ,EAAE,CAAC,CAAC;YACpG,CAAC;YAED,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,+BAA+B,MAAM,IAAI,QAAQ,MAAM,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;YAExF,MAAM,IAAI,uCAAiB,CAAC,8CAA8C,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QAC1F,CAAC;gBAAS,CAAC;YACV,YAAY,CAAC,SAAS,CAAC,CAAC;QACzB,CAAC;IACF,CAAC;CACD;AAjFD,sDAiFC"}
1
+ {"version":3,"file":"home-assistant.platform.js","sourceRoot":"","sources":["../../../../src/modules/platform/platforms/home-assistant.platform.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,294 @@
1
+ #!/bin/bash
2
+ set -e
3
+
4
+ VERSION="${1:-${UPDATE_VERSION:-latest}}"
5
+ STATUS_FILE="${STATUS_FILE:-/var/lib/smart-panel/update-status.json}"
6
+ INSTALL_TYPE="${INSTALL_TYPE:-npm}"
7
+ IMAGE_BASE_DIR="${IMAGE_BASE_DIR:-/opt/smart-panel}"
8
+ DOWNLOAD_URL="${DOWNLOAD_URL:-}"
9
+
10
+ # Capture once — used for all status writes so timeout detection works correctly
11
+ STARTED_AT="$(date -Iseconds)"
12
+
13
+ update_status() {
14
+ local status="$1"
15
+ local phase="$2"
16
+ local error="${3:-}"
17
+ local completed_at=""
18
+
19
+ if [ "$status" = "complete" ] || [ "$status" = "failed" ]; then
20
+ completed_at=$(date -Iseconds)
21
+ fi
22
+
23
+ local tmp_file="${STATUS_FILE}.tmp"
24
+
25
+ # Use printf with %s to prevent injection in JSON values.
26
+ # Escape double-quotes and backslashes in the error message.
27
+ local safe_error=""
28
+ if [ -n "$error" ]; then
29
+ safe_error=$(printf '%s' "$error" | sed 's/\\/\\\\/g; s/"/\\"/g')
30
+ fi
31
+
32
+ printf '{\n\t"status": "%s",\n\t"phase": "%s",\n\t"targetVersion": "%s",\n\t"startedAt": "%s"' \
33
+ "$status" "$phase" "$VERSION" "$STARTED_AT" > "$tmp_file"
34
+
35
+ if [ -n "$completed_at" ]; then
36
+ printf ',\n\t"completedAt": "%s"' "$completed_at" >> "$tmp_file"
37
+ fi
38
+
39
+ printf ',\n\t"error": "%s"' "$safe_error" >> "$tmp_file"
40
+ printf '\n}\n' >> "$tmp_file"
41
+
42
+ mv "$tmp_file" "$STATUS_FILE"
43
+ }
44
+
45
+ cleanup() {
46
+ local exit_code=$?
47
+
48
+ if [ $exit_code -ne 0 ]; then
49
+ # Only write a generic failure if a specific error wasn't already recorded
50
+ if [ -f "$STATUS_FILE" ] && grep -q '"status": "failed"' "$STATUS_FILE" 2>/dev/null; then
51
+ return
52
+ fi
53
+ update_status "failed" "failed" "Update process exited with code $exit_code"
54
+ fi
55
+ }
56
+
57
+ trap cleanup EXIT
58
+
59
+ # ──────────────────────────────────────────────────────────────
60
+ # Image-based update (Raspbian image installs)
61
+ # ──────────────────────────────────────────────────────────────
62
+ if [ "$INSTALL_TYPE" = "image" ]; then
63
+ # Verify passwordless sudo is available (required for systemctl, chown, ln)
64
+ if ! sudo -n true 2>/dev/null; then
65
+ update_status "failed" "failed" "Passwordless sudo is not available for this user"
66
+ exit 1
67
+ fi
68
+ # Strip leading 'v' prefix if present to avoid double-prefixed dirs like vv1.0.0
69
+ CLEAN_VERSION="${VERSION#v}"
70
+ NEW_VERSION_DIR="${IMAGE_BASE_DIR}/v${CLEAN_VERSION}"
71
+ CURRENT_LINK="${IMAGE_BASE_DIR}/current"
72
+ PREVIOUS_TARGET=""
73
+
74
+ # Save the current version for rollback
75
+ if [ -L "$CURRENT_LINK" ]; then
76
+ PREVIOUS_TARGET=$(readlink "$CURRENT_LINK")
77
+ fi
78
+
79
+ # Guard: refuse to overwrite the currently running version
80
+ # Resolve relative to IMAGE_BASE_DIR since PREVIOUS_TARGET may be relative
81
+ RESOLVED_PREV=$(cd "$IMAGE_BASE_DIR" && realpath "$PREVIOUS_TARGET" 2>/dev/null || true)
82
+ RESOLVED_NEW=$(cd "$IMAGE_BASE_DIR" && realpath "$NEW_VERSION_DIR" 2>/dev/null || true)
83
+
84
+ if [ -n "$PREVIOUS_TARGET" ] && [ -n "$RESOLVED_PREV" ] && [ -n "$RESOLVED_NEW" ] && [ "$RESOLVED_PREV" = "$RESOLVED_NEW" ]; then
85
+ update_status "failed" "failed" "Target version v${CLEAN_VERSION} is already the active version"
86
+ exit 1
87
+ fi
88
+
89
+ # ── Download ──
90
+ update_status "downloading" "downloading"
91
+
92
+ if [ -z "$DOWNLOAD_URL" ]; then
93
+ update_status "failed" "failed" "No download URL provided for image update"
94
+ exit 1
95
+ fi
96
+
97
+ TMP_TARBALL="/tmp/smart-panel-backend-v${CLEAN_VERSION}.tar.gz"
98
+
99
+ curl -fSL -o "$TMP_TARBALL" "$DOWNLOAD_URL" 2>&1 || {
100
+ update_status "failed" "failed" "Download failed from ${DOWNLOAD_URL}"
101
+ exit 1
102
+ }
103
+
104
+ # ── Extract ──
105
+ update_status "installing" "installing"
106
+
107
+ mkdir -p "$NEW_VERSION_DIR"
108
+
109
+ tar -xzf "$TMP_TARBALL" -C "$NEW_VERSION_DIR" 2>&1 || {
110
+ rm -rf "$NEW_VERSION_DIR"
111
+ rm -f "$TMP_TARBALL"
112
+ update_status "failed" "failed" "Failed to extract update archive"
113
+ exit 1
114
+ }
115
+
116
+ rm -f "$TMP_TARBALL"
117
+
118
+ # Create the image-install marker in the new version
119
+ touch "${NEW_VERSION_DIR}/.image-install" || {
120
+ rm -rf "$NEW_VERSION_DIR"
121
+ update_status "failed" "failed" "Failed to create image-install marker"
122
+ exit 1
123
+ }
124
+
125
+ # ── Install dependencies ──
126
+ cd "$NEW_VERSION_DIR"
127
+
128
+ pnpm install --prod --ignore-scripts 2>&1 || {
129
+ rm -rf "$NEW_VERSION_DIR"
130
+ update_status "failed" "failed" "pnpm install failed"
131
+ exit 1
132
+ }
133
+
134
+ # ── Rebuild native modules ──
135
+ if [ -x "${IMAGE_BASE_DIR}/rebuild-native.sh" ]; then
136
+ "${IMAGE_BASE_DIR}/rebuild-native.sh" "${NEW_VERSION_DIR}" 2>&1 || {
137
+ rm -rf "$NEW_VERSION_DIR"
138
+ update_status "failed" "failed" "Native module rebuild failed"
139
+ exit 1
140
+ }
141
+ fi
142
+
143
+ # Set ownership
144
+ sudo chown -R smart-panel:smart-panel "$NEW_VERSION_DIR" || {
145
+ rm -rf "$NEW_VERSION_DIR"
146
+ update_status "failed" "failed" "Failed to set ownership on ${NEW_VERSION_DIR}"
147
+ exit 1
148
+ }
149
+
150
+ # ── Stop service ──
151
+ update_status "stopping" "stopping"
152
+ sudo systemctl stop smart-panel 2>/dev/null || true
153
+
154
+ # ── Switch symlink (atomic on same filesystem) ──
155
+ sudo ln -sfn "$NEW_VERSION_DIR" "$CURRENT_LINK" || {
156
+ # Revert on failure
157
+ if [ -n "$PREVIOUS_TARGET" ]; then
158
+ sudo ln -sfn "$PREVIOUS_TARGET" "$CURRENT_LINK"
159
+ fi
160
+ sudo systemctl start smart-panel 2>/dev/null || true
161
+ update_status "failed" "failed" "Failed to switch version symlink"
162
+ exit 1
163
+ }
164
+
165
+ # ── Run database migrations ──
166
+ update_status "migrating" "migrating"
167
+
168
+ ENV_FILE="/etc/smart-panel/environment"
169
+
170
+ if [ -f "${NEW_VERSION_DIR}/dist/dataSource.js" ]; then
171
+ (
172
+ set -a
173
+ # shellcheck source=/dev/null
174
+ [ -f "$ENV_FILE" ] && . "$ENV_FILE"
175
+ set +a
176
+ cd "$NEW_VERSION_DIR"
177
+ node node_modules/typeorm/cli.js migration:run -d dist/dataSource.js
178
+ ) 2>&1 || {
179
+ # Migration failed — revert symlink if possible
180
+ update_status "stopping" "stopping"
181
+ sudo systemctl stop smart-panel 2>/dev/null || true
182
+
183
+ if [ -n "$PREVIOUS_TARGET" ]; then
184
+ if sudo ln -sfn "$PREVIOUS_TARGET" "$CURRENT_LINK"; then
185
+ rm -rf "$NEW_VERSION_DIR"
186
+ update_status "failed" "failed" "Database migration failed — reverted to previous version"
187
+ else
188
+ # Symlink revert failed — keep new version so system stays bootable
189
+ update_status "failed" "failed" "Database migration failed — symlink revert also failed"
190
+ fi
191
+ else
192
+ # No previous version — keep current in place so system stays bootable
193
+ update_status "failed" "failed" "Database migration failed — no previous version to revert to"
194
+ fi
195
+
196
+ sudo systemctl start smart-panel 2>/dev/null || true
197
+ exit 1
198
+ }
199
+ fi
200
+
201
+ # ── Start service ──
202
+ update_status "starting" "starting"
203
+ sudo systemctl start smart-panel 2>&1 || {
204
+ # Try to revert if start fails
205
+ if [ -n "$PREVIOUS_TARGET" ]; then
206
+ sudo ln -sfn "$PREVIOUS_TARGET" "$CURRENT_LINK"
207
+ sudo systemctl start smart-panel 2>/dev/null || true
208
+ fi
209
+ update_status "failed" "failed" "Failed to start service after update"
210
+ exit 1
211
+ }
212
+
213
+ # ── Cleanup old versions (keep max 2 previous) ──
214
+ cd "$IMAGE_BASE_DIR"
215
+
216
+ # Use the known current version rather than re-reading the symlink,
217
+ # so cleanup is safe even if readlink fails unexpectedly
218
+ CURRENT_BASENAME="v${CLEAN_VERSION}"
219
+
220
+ if [ -n "$CURRENT_BASENAME" ]; then
221
+ # Only match semver-versioned directories (v<digits>.<digits>.<digits>*)
222
+ # to avoid accidentally deleting unrelated v-prefixed directories
223
+ # shellcheck disable=SC2010
224
+ OLD_VERSIONS=$(ls -d v[0-9]*.[0-9]*.[0-9]*/ 2>/dev/null | grep -v "^${CURRENT_BASENAME}/" | sort -V | head -n -2 || true)
225
+
226
+ for old_dir in $OLD_VERSIONS; do
227
+ rm -rf "${IMAGE_BASE_DIR}/${old_dir}"
228
+ done
229
+ fi
230
+
231
+ # ── Mark complete ──
232
+ update_status "complete" "complete"
233
+ trap - EXIT
234
+ exit 0
235
+ fi
236
+
237
+ # ──────────────────────────────────────────────────────────────
238
+ # NPM-based update (global npm installs)
239
+ # ──────────────────────────────────────────────────────────────
240
+
241
+ # Downloading / preparing
242
+ update_status "downloading" "downloading"
243
+
244
+ # Stop the service
245
+ update_status "stopping" "stopping"
246
+ sudo systemctl stop smart-panel 2>/dev/null || true
247
+
248
+ # Install the update
249
+ update_status "installing" "installing"
250
+
251
+ if [ "$VERSION" = "latest" ]; then
252
+ npm update -g @fastybird/smart-panel 2>&1 || {
253
+ update_status "failed" "failed" "npm update failed"
254
+ sudo systemctl start smart-panel 2>/dev/null || true
255
+ exit 1
256
+ }
257
+ else
258
+ npm install -g "@fastybird/smart-panel@$VERSION" 2>&1 || {
259
+ update_status "failed" "failed" "npm install failed for version $VERSION"
260
+ sudo systemctl start smart-panel 2>/dev/null || true
261
+ exit 1
262
+ }
263
+ fi
264
+
265
+ # Run database migrations
266
+ update_status "migrating" "migrating"
267
+
268
+ DATA_DIR="${FB_DATA_DIR:-/var/lib/smart-panel}"
269
+ DB_PATH="${FB_DB_PATH:-${DATA_DIR}/data}"
270
+
271
+ if [ -f "$(npm root -g)/@fastybird/smart-panel/dataSource.js" ]; then
272
+ node "$(npm root -g)/@fastybird/smart-panel/node_modules/typeorm/cli.js" \
273
+ migration:run \
274
+ -d "$(npm root -g)/@fastybird/smart-panel/dataSource.js" 2>&1 || {
275
+ update_status "failed" "failed" "Database migration failed"
276
+ sudo systemctl start smart-panel 2>/dev/null || true
277
+ exit 1
278
+ }
279
+ fi
280
+
281
+ # Start the service
282
+ update_status "starting" "starting"
283
+ sudo systemctl start smart-panel 2>&1 || {
284
+ update_status "failed" "failed" "Failed to start service after update"
285
+ exit 1
286
+ }
287
+
288
+ # Mark as complete
289
+ update_status "complete" "complete"
290
+
291
+ # Remove the exit trap since we completed successfully
292
+ trap - EXIT
293
+
294
+ exit 0
@@ -158,7 +158,27 @@ let UpdateExecutorService = class UpdateExecutorService {
158
158
  error: null,
159
159
  startedAt: new Date(),
160
160
  });
161
- const updateScript = (0, path_1.join)(__dirname, '..', '..', '..', '..', '..', 'build', 'scripts', 'update-worker.sh');
161
+ const updateScript = (0, path_1.join)(__dirname, '..', 'scripts', 'update-worker.sh');
162
+ if (!(0, fs_1.existsSync)(updateScript)) {
163
+ this.updateService.releaseUpdateLock();
164
+ const errorMsg = `Update worker script not found at ${updateScript}`;
165
+ this.logger.error(errorMsg);
166
+ this.updateService.setStatus({
167
+ status: system_constants_1.UpdateStatusType.FAILED,
168
+ phase: system_constants_1.UpdatePhase.FAILED,
169
+ progressPercent: null,
170
+ message: null,
171
+ error: errorMsg,
172
+ });
173
+ this.writeStatusFile({
174
+ status: system_constants_1.UpdateStatusType.FAILED,
175
+ phase: system_constants_1.UpdatePhase.FAILED,
176
+ targetVersion,
177
+ startedAt: new Date().toISOString(),
178
+ error: errorMsg,
179
+ });
180
+ throw new Error(errorMsg);
181
+ }
162
182
  try {
163
183
  const { spawn } = await Promise.resolve().then(() => __importStar(require('child_process')));
164
184
  const child = spawn('bash', [updateScript, targetVersion], {