@alwaysai/device-agent 1.3.1 → 1.5.0
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.
- package/lib/application-control/config.js +2 -2
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +9 -4
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +1 -1
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +7 -2
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +5 -0
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +28 -14
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/status.d.ts.map +1 -1
- package/lib/application-control/status.js +14 -17
- package/lib/application-control/status.js.map +1 -1
- package/lib/application-control/utils.js +2 -2
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +5 -5
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +140 -105
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +4 -2
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +46 -25
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +132 -16
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/messages.d.ts.map +1 -1
- package/lib/cloud-connection/messages.js +3 -4
- package/lib/cloud-connection/messages.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +5 -3
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +76 -62
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +16 -21
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +162 -108
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +100 -83
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +3 -0
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +11 -0
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +102 -0
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +16 -15
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +117 -18
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts +14 -0
- package/lib/docker/docker-compose.d.ts.map +1 -0
- package/lib/docker/docker-compose.js +56 -0
- package/lib/docker/docker-compose.js.map +1 -0
- package/lib/index.js +2 -5
- package/lib/index.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +45 -14
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +30 -15
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -0
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +11 -11
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.d.ts +97 -0
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.js +435 -0
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.test.d.ts +2 -0
- package/lib/secure-tunneling/secure-tunneling.test.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.test.js +1070 -0
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -0
- package/lib/secure-tunneling/spawner-detached.d.ts +6 -0
- package/lib/secure-tunneling/spawner-detached.d.ts.map +1 -0
- package/lib/secure-tunneling/spawner-detached.js +107 -0
- package/lib/secure-tunneling/spawner-detached.js.map +1 -0
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +9 -13
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +11 -16
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +12 -16
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +8 -6
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/get-info.d.ts +2 -0
- package/lib/subcommands/device/get-info.d.ts.map +1 -0
- package/lib/subcommands/device/get-info.js +36 -0
- package/lib/subcommands/device/get-info.js.map +1 -0
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +11 -2
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.d.ts +5 -0
- package/lib/subcommands/device/init.d.ts.map +1 -0
- package/lib/subcommands/device/{device.js → init.js} +5 -36
- package/lib/subcommands/device/init.js.map +1 -0
- package/lib/subcommands/device/refresh.d.ts +2 -0
- package/lib/subcommands/device/refresh.d.ts.map +1 -0
- package/lib/subcommands/device/refresh.js +24 -0
- package/lib/subcommands/device/refresh.js.map +1 -0
- package/lib/subcommands/device/restart.d.ts +2 -0
- package/lib/subcommands/device/restart.d.ts.map +1 -0
- package/lib/subcommands/device/restart.js +14 -0
- package/lib/subcommands/device/restart.js.map +1 -0
- package/lib/util/check-for-updates.d.ts +3 -0
- package/lib/util/check-for-updates.d.ts.map +1 -0
- package/lib/util/check-for-updates.js +69 -0
- package/lib/util/check-for-updates.js.map +1 -0
- package/lib/util/cloud-mode-ready.d.ts +1 -0
- package/lib/util/cloud-mode-ready.d.ts.map +1 -1
- package/lib/util/cloud-mode-ready.js +36 -1
- package/lib/util/cloud-mode-ready.js.map +1 -1
- package/lib/util/file.d.ts +7 -0
- package/lib/util/file.d.ts.map +1 -0
- package/lib/util/file.js +66 -0
- package/lib/util/file.js.map +1 -0
- package/lib/util/file.test.d.ts +2 -0
- package/lib/util/file.test.d.ts.map +1 -0
- package/lib/util/file.test.js +87 -0
- package/lib/util/file.test.js.map +1 -0
- package/package.json +8 -7
- package/readme.md +3 -3
- package/src/application-control/config.ts +1 -1
- package/src/application-control/environment-variables.test.ts +1 -1
- package/src/application-control/environment-variables.ts +9 -6
- package/src/application-control/install.ts +8 -3
- package/src/application-control/models.ts +47 -19
- package/src/application-control/status.ts +16 -14
- package/src/application-control/utils.ts +1 -1
- package/src/cloud-connection/device-agent-cloud-connection.ts +202 -148
- package/src/cloud-connection/live-updates-handler.test.ts +161 -20
- package/src/cloud-connection/live-updates-handler.ts +63 -31
- package/src/cloud-connection/messages.ts +3 -4
- package/src/cloud-connection/passthrough-handler.ts +98 -76
- package/src/cloud-connection/shadow-handler.test.ts +101 -84
- package/src/cloud-connection/shadow-handler.ts +287 -133
- package/src/cloud-connection/transaction-manager.test.ts +124 -0
- package/src/cloud-connection/transaction-manager.ts +15 -0
- package/src/device-control/device-control.ts +125 -23
- package/src/docker/docker-compose.ts +60 -0
- package/src/index.ts +2 -6
- package/src/infrastructure/agent-config.test.ts +3 -0
- package/src/infrastructure/agent-config.ts +38 -40
- package/src/local-connection/rabbitmq-connection.ts +8 -8
- package/src/secure-tunneling/secure-tunneling.test.ts +1239 -0
- package/src/secure-tunneling/secure-tunneling.ts +599 -0
- package/src/secure-tunneling/spawner-detached.ts +123 -0
- package/src/subcommands/app/analytics.ts +16 -13
- package/src/subcommands/app/env-vars.ts +18 -16
- package/src/subcommands/app/models.ts +20 -16
- package/src/subcommands/device/clean.ts +5 -2
- package/src/subcommands/device/get-info.ts +49 -0
- package/src/subcommands/device/index.ts +11 -2
- package/src/subcommands/device/{device.ts → init.ts} +5 -47
- package/src/subcommands/device/refresh.ts +22 -0
- package/src/subcommands/device/restart.ts +11 -0
- package/src/util/check-for-updates.ts +69 -0
- package/src/util/cloud-mode-ready.ts +36 -0
- package/src/util/file.test.ts +90 -0
- package/src/util/file.ts +76 -0
- package/lib/docker/docker-compose-cmd.d.ts +0 -5
- package/lib/docker/docker-compose-cmd.d.ts.map +0 -1
- package/lib/docker/docker-compose-cmd.js +0 -16
- package/lib/docker/docker-compose-cmd.js.map +0 -1
- package/lib/secure-tunneling/index.d.ts +0 -5
- package/lib/secure-tunneling/index.d.ts.map +0 -1
- package/lib/secure-tunneling/index.js +0 -64
- package/lib/secure-tunneling/index.js.map +0 -1
- package/lib/subcommands/device/device.d.ts +0 -7
- package/lib/subcommands/device/device.d.ts.map +0 -1
- package/lib/subcommands/device/device.js.map +0 -1
- package/lib/util/safe-rimraf.d.ts +0 -2
- package/lib/util/safe-rimraf.d.ts.map +0 -1
- package/lib/util/safe-rimraf.js +0 -16
- package/lib/util/safe-rimraf.js.map +0 -1
- package/src/docker/docker-compose-cmd.ts +0 -15
- package/src/secure-tunneling/index.ts +0 -74
- package/src/util/safe-rimraf.ts +0 -14
|
@@ -1,38 +1,50 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { SystemInformationShadowUpdate } from '@alwaysai/device-agent-schemas';
|
|
2
2
|
import { logger } from '../util/logger';
|
|
3
3
|
import * as osu from 'node-os-utils';
|
|
4
4
|
import * as si from 'systeminformation';
|
|
5
5
|
import { exec } from 'child_process';
|
|
6
6
|
import { promisify } from 'util';
|
|
7
|
+
import { JsSpawner } from 'alwaysai/lib/util';
|
|
8
|
+
import { DeviceStatsPayload } from '@alwaysai/device-agent-schemas';
|
|
9
|
+
import { getDeviceAgentVersion } from '../util/check-for-updates';
|
|
7
10
|
|
|
8
11
|
const exec_promise = promisify(exec);
|
|
9
12
|
|
|
10
13
|
// Device Stats
|
|
11
|
-
export async function getCpuDetails()
|
|
14
|
+
export async function getCpuDetails(): Promise<
|
|
15
|
+
DeviceStatsPayload['cpuDetails']
|
|
16
|
+
> {
|
|
12
17
|
const cpuFree = await osu.cpu.free();
|
|
13
18
|
const cpuTemp = await si.cpuTemperature();
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
19
|
+
const cpuDetails: DeviceStatsPayload['cpuDetails'] = {};
|
|
20
|
+
if (cpuFree !== null) cpuDetails.usedPerc = 100 - cpuFree;
|
|
21
|
+
if (cpuTemp?.main !== null) cpuDetails.temperature = cpuTemp.main;
|
|
22
|
+
return cpuDetails;
|
|
18
23
|
}
|
|
19
24
|
|
|
20
|
-
export async function getDiskDetails()
|
|
25
|
+
export async function getDiskDetails(): Promise<
|
|
26
|
+
DeviceStatsPayload['diskDetails']
|
|
27
|
+
> {
|
|
21
28
|
// Types incorrectly specify diskname as required instead of optional
|
|
22
29
|
// @ts-expect-error
|
|
23
30
|
const driveInfo = await osu.drive.info();
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
31
|
+
const diskDetails: DeviceStatsPayload['diskDetails'] = {};
|
|
32
|
+
if (driveInfo?.usedGb !== null)
|
|
33
|
+
diskDetails.usedGb = parseFloat(driveInfo.usedGb);
|
|
34
|
+
if (driveInfo?.freeGb !== null) {
|
|
35
|
+
diskDetails.freeGb = parseFloat(driveInfo.freeGb);
|
|
36
|
+
}
|
|
37
|
+
return diskDetails;
|
|
28
38
|
}
|
|
29
39
|
|
|
30
|
-
export async function getMemDetails()
|
|
40
|
+
export async function getMemDetails(): Promise<
|
|
41
|
+
DeviceStatsPayload['memDetails']
|
|
42
|
+
> {
|
|
31
43
|
const memInfo = await osu.mem.info();
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
44
|
+
const memDetails: DeviceStatsPayload['memDetails'] = {};
|
|
45
|
+
if (memInfo?.usedMemMb !== null) memDetails.usedMb = memInfo.usedMemMb;
|
|
46
|
+
if (memInfo?.freeMemMb !== null) memDetails.freeMb = memInfo.freeMemMb;
|
|
47
|
+
return memDetails;
|
|
36
48
|
}
|
|
37
49
|
|
|
38
50
|
// System information
|
|
@@ -102,26 +114,116 @@ export async function getNetworkInfo() {
|
|
|
102
114
|
};
|
|
103
115
|
}
|
|
104
116
|
|
|
117
|
+
export async function getDockerVersion() {
|
|
118
|
+
try {
|
|
119
|
+
const spawner = JsSpawner();
|
|
120
|
+
const result = JSON.parse(
|
|
121
|
+
await spawner.run({
|
|
122
|
+
exe: 'docker',
|
|
123
|
+
args: ['info', '--format', 'json']
|
|
124
|
+
})
|
|
125
|
+
);
|
|
126
|
+
return result.ClientInfo.Version;
|
|
127
|
+
} catch (e) {
|
|
128
|
+
logger.warn(`Cannot get Docker version: ${e}`);
|
|
129
|
+
return 'Not found';
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export async function getDockerComposeVersion() {
|
|
134
|
+
try {
|
|
135
|
+
const spawner = JsSpawner();
|
|
136
|
+
return await spawner.run({
|
|
137
|
+
exe: 'docker',
|
|
138
|
+
args: ['compose', 'version']
|
|
139
|
+
});
|
|
140
|
+
} catch (e) {
|
|
141
|
+
logger.warn(`Cannot get Docker Compose version: ${e}`);
|
|
142
|
+
return 'Not found';
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export async function getNpmVersion() {
|
|
147
|
+
try {
|
|
148
|
+
const spawner = JsSpawner();
|
|
149
|
+
return await spawner.run({
|
|
150
|
+
exe: 'npm',
|
|
151
|
+
args: ['--version']
|
|
152
|
+
});
|
|
153
|
+
} catch (e) {
|
|
154
|
+
logger.warn(`Cannot get npm version: ${e}`);
|
|
155
|
+
return 'Not found';
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export async function getNodeVersion() {
|
|
160
|
+
try {
|
|
161
|
+
const spawner = JsSpawner();
|
|
162
|
+
return await spawner.run({
|
|
163
|
+
exe: 'node',
|
|
164
|
+
args: ['-v']
|
|
165
|
+
});
|
|
166
|
+
} catch (e) {
|
|
167
|
+
logger.warn(`Cannot get Node version: ${e}`);
|
|
168
|
+
return 'Not found';
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
105
172
|
export async function getPackageVersions() {
|
|
106
|
-
|
|
107
|
-
const agentJson = require('../../package.json');
|
|
173
|
+
const agentVersion = await getDeviceAgentVersion();
|
|
108
174
|
// eslint-disable-next-line
|
|
109
175
|
const deviceAgentSchemasJson = require('../../node_modules/@alwaysai/device-agent-schemas/package.json');
|
|
176
|
+
|
|
177
|
+
// Concurrent asynchronous function call
|
|
178
|
+
const [dockerVersion, dockerComposeVersion, nodeVersion, npmVersion] =
|
|
179
|
+
await Promise.all([
|
|
180
|
+
getDockerVersion(),
|
|
181
|
+
getDockerComposeVersion(),
|
|
182
|
+
getNodeVersion(),
|
|
183
|
+
getNpmVersion()
|
|
184
|
+
]);
|
|
185
|
+
|
|
110
186
|
return {
|
|
111
|
-
agent:
|
|
112
|
-
deviceAgentSchemas: deviceAgentSchemasJson.version
|
|
187
|
+
agent: agentVersion,
|
|
188
|
+
deviceAgentSchemas: deviceAgentSchemasJson.version,
|
|
189
|
+
docker: dockerVersion,
|
|
190
|
+
dockerCompose: dockerComposeVersion,
|
|
191
|
+
node: nodeVersion,
|
|
192
|
+
npm: npmVersion
|
|
113
193
|
};
|
|
114
194
|
}
|
|
115
195
|
|
|
116
|
-
export async function
|
|
196
|
+
export async function getLastBootTime() {
|
|
197
|
+
try {
|
|
198
|
+
const out = await exec_promise('journalctl --list-boots');
|
|
199
|
+
if (!out || out.stderr) {
|
|
200
|
+
logger.error(`Stderr when getting last boot time: ${out.stderr}`);
|
|
201
|
+
return undefined;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const bootTimes = out.stdout.split('\n');
|
|
205
|
+
const latestBootStdout = (bootTimes.pop() || bootTimes.pop())?.trim(); // possible last \n causes '' at end of array
|
|
206
|
+
if (!latestBootStdout) return undefined;
|
|
207
|
+
|
|
208
|
+
const tokens = latestBootStdout.trim().split(' ');
|
|
209
|
+
|
|
210
|
+
return new Date(`${tokens[2]} ${tokens[3]} ${tokens[4]}`);
|
|
211
|
+
} catch (e) {
|
|
212
|
+
logger.error(`Issue getting last boot time: ${e.message}`);
|
|
213
|
+
return undefined;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
export async function getSystemInformation(): Promise<SystemInformationShadowUpdate> {
|
|
117
218
|
try {
|
|
118
|
-
const systemInfo:
|
|
219
|
+
const systemInfo: SystemInformationShadowUpdate = {
|
|
119
220
|
os: await getOsInfo(),
|
|
120
221
|
cpu: await getCpuInfo(),
|
|
121
222
|
disk: await getDiskInfo(),
|
|
122
223
|
device: await getDeviceInfo(),
|
|
123
224
|
network: await getNetworkInfo(),
|
|
124
|
-
versions: await getPackageVersions()
|
|
225
|
+
versions: await getPackageVersions(),
|
|
226
|
+
lastBootTime: (await getLastBootTime())?.toString()
|
|
125
227
|
};
|
|
126
228
|
return systemInfo;
|
|
127
229
|
} catch (e) {
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as DockerComposeV1 from 'docker-compose';
|
|
2
|
+
import { v2 as DockerComposeV2 } from 'docker-compose';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { logger } from '../util/logger';
|
|
5
|
+
import { JsSpawner } from 'alwaysai/lib/util';
|
|
6
|
+
|
|
7
|
+
let dockerCmd = 'docker';
|
|
8
|
+
|
|
9
|
+
export function importDockerCompose():
|
|
10
|
+
| typeof DockerComposeV1
|
|
11
|
+
| typeof DockerComposeV2 {
|
|
12
|
+
try {
|
|
13
|
+
execSync('docker compose version').toString();
|
|
14
|
+
logger.debug('Using Docker Compose V2.');
|
|
15
|
+
return DockerComposeV2;
|
|
16
|
+
} catch (e) {
|
|
17
|
+
try {
|
|
18
|
+
execSync('docker-compose -v').toString();
|
|
19
|
+
logger.warn('Using docker-compose V1. Please consider updating to V2.');
|
|
20
|
+
} catch (e) {
|
|
21
|
+
logger.warn(`Could not determine compose: ${e}`);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
dockerCmd = 'docker-compose';
|
|
25
|
+
return DockerComposeV1;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export const compose = importDockerCompose();
|
|
29
|
+
|
|
30
|
+
export async function runDockerComposeCmd(props: {
|
|
31
|
+
args: string[];
|
|
32
|
+
dir: string;
|
|
33
|
+
}) {
|
|
34
|
+
const { args, dir } = props;
|
|
35
|
+
const spawner = JsSpawner();
|
|
36
|
+
if (dockerCmd === 'docker') {
|
|
37
|
+
args.unshift('compose');
|
|
38
|
+
}
|
|
39
|
+
const output = await spawner.run({
|
|
40
|
+
exe: dockerCmd,
|
|
41
|
+
args,
|
|
42
|
+
cwd: dir
|
|
43
|
+
});
|
|
44
|
+
return output;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export async function runStreamingDockerComposeCmd(props: {
|
|
48
|
+
args: string[];
|
|
49
|
+
dir: string;
|
|
50
|
+
}) {
|
|
51
|
+
const { args, dir } = props;
|
|
52
|
+
if (dockerCmd === 'docker') {
|
|
53
|
+
args.unshift('compose');
|
|
54
|
+
}
|
|
55
|
+
return await JsSpawner().runStreaming({
|
|
56
|
+
exe: dockerCmd,
|
|
57
|
+
args,
|
|
58
|
+
cwd: dir
|
|
59
|
+
});
|
|
60
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -10,13 +10,9 @@ import { root } from './root';
|
|
|
10
10
|
import { runDeviceAgentCloudInterface } from './cloud-connection/device-agent-cloud-connection';
|
|
11
11
|
import { AgentConfigFile } from './infrastructure/agent-config';
|
|
12
12
|
import { ALWAYSAI_DEVICE_AGENT_MODE } from './environment';
|
|
13
|
-
import {
|
|
14
|
-
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
16
|
-
const { version } = require('../package.json');
|
|
13
|
+
import { checkForUpdatesAndPrompt } from './util/check-for-updates';
|
|
17
14
|
|
|
18
15
|
if (module === require.main) {
|
|
19
|
-
logger.info(`Starting alwaysAI Device Agent v${version}`);
|
|
20
16
|
if (!AgentConfigFile().exists()) {
|
|
21
17
|
AgentConfigFile().initialize();
|
|
22
18
|
}
|
|
@@ -24,6 +20,6 @@ if (module === require.main) {
|
|
|
24
20
|
if (ALWAYSAI_DEVICE_AGENT_MODE === 'cloud') {
|
|
25
21
|
void runDeviceAgentCloudInterface();
|
|
26
22
|
} else {
|
|
27
|
-
void runCliAndExit(root, {});
|
|
23
|
+
void runCliAndExit(root, { postRun: checkForUpdatesAndPrompt });
|
|
28
24
|
}
|
|
29
25
|
}
|
|
@@ -95,6 +95,9 @@ describe('Test Agent Config', () => {
|
|
|
95
95
|
expect(await configFile.getAppVersion({ projectId })).toEqual(version);
|
|
96
96
|
await configFile.setAppInstalled({ projectId, version });
|
|
97
97
|
expect(await configFile.getAppVersion({ projectId })).toEqual(version);
|
|
98
|
+
expect(await configFile.isAppReady({ projectId })).toEqual(true);
|
|
99
|
+
await configFile.setAppUninstalling({ projectId });
|
|
100
|
+
expect(await configFile.isAppReady({ projectId })).toEqual(false);
|
|
98
101
|
await configFile.setAppUninstalled({ projectId });
|
|
99
102
|
const apps = await configFile.getApps();
|
|
100
103
|
expect(apps).toEqual([]);
|
|
@@ -58,26 +58,7 @@ const ALWAYSAI_CONFIG_DIR = join(homedir(), '.config', 'alwaysai');
|
|
|
58
58
|
|
|
59
59
|
const AGENT_CONFIG_FILE_NAME = 'alwaysai.agent.json';
|
|
60
60
|
|
|
61
|
-
export
|
|
62
|
-
extends ConfigFileSchemaReturnType<AgentConfig> {
|
|
63
|
-
name: string;
|
|
64
|
-
getApps: () => Promise<InstalledAppConfig[]>;
|
|
65
|
-
getReadyApps;
|
|
66
|
-
getApp;
|
|
67
|
-
isAppPresent;
|
|
68
|
-
isAppReady;
|
|
69
|
-
removeApp;
|
|
70
|
-
setAppInstalling;
|
|
71
|
-
setAppInstalled;
|
|
72
|
-
setAppUninstalled;
|
|
73
|
-
getAppVersion: (props: { projectId: string }) => Promise<string>;
|
|
74
|
-
setAppBackup;
|
|
75
|
-
getAppBackup;
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
export function AgentConfigFile(
|
|
79
|
-
dir = ALWAYSAI_CONFIG_DIR
|
|
80
|
-
): AgentJsonFileReturnType {
|
|
61
|
+
export function AgentConfigFile(dir = ALWAYSAI_CONFIG_DIR) {
|
|
81
62
|
const path = join(dir, AGENT_CONFIG_FILE_NAME);
|
|
82
63
|
const initialValue: AgentConfig = {
|
|
83
64
|
applications: []
|
|
@@ -88,31 +69,14 @@ export function AgentConfigFile(
|
|
|
88
69
|
initialValue
|
|
89
70
|
});
|
|
90
71
|
|
|
91
|
-
return {
|
|
92
|
-
...configFile,
|
|
93
|
-
name: AGENT_CONFIG_FILE_NAME,
|
|
94
|
-
getApps,
|
|
95
|
-
getReadyApps,
|
|
96
|
-
getApp,
|
|
97
|
-
isAppPresent,
|
|
98
|
-
isAppReady,
|
|
99
|
-
removeApp,
|
|
100
|
-
setAppInstalling,
|
|
101
|
-
setAppInstalled,
|
|
102
|
-
setAppUninstalled,
|
|
103
|
-
getAppVersion,
|
|
104
|
-
setAppBackup,
|
|
105
|
-
getAppBackup
|
|
106
|
-
};
|
|
107
|
-
|
|
108
72
|
async function getApps() {
|
|
109
73
|
const config = configFile.read();
|
|
110
|
-
return config
|
|
74
|
+
return config?.applications ? config.applications : [];
|
|
111
75
|
}
|
|
112
76
|
|
|
113
77
|
async function getReadyApps() {
|
|
114
78
|
const config = configFile.read();
|
|
115
|
-
return config
|
|
79
|
+
return config?.applications
|
|
116
80
|
? config.applications.filter((app) => {
|
|
117
81
|
return app.ready;
|
|
118
82
|
})
|
|
@@ -205,6 +169,23 @@ export function AgentConfigFile(
|
|
|
205
169
|
}
|
|
206
170
|
}
|
|
207
171
|
|
|
172
|
+
async function setAppUninstalling(props: { projectId: string }) {
|
|
173
|
+
const { projectId } = props;
|
|
174
|
+
const app = await getApp({ projectId });
|
|
175
|
+
if (app) {
|
|
176
|
+
await removeApp({ projectId });
|
|
177
|
+
const config = configFile.read();
|
|
178
|
+
config.applications.push({ ...app, ...{ ready: false } });
|
|
179
|
+
configFile.write(config);
|
|
180
|
+
} else {
|
|
181
|
+
// NOTE: we should never be setting an app as installed
|
|
182
|
+
// if it doesn't exist (setAppInstalling was never called)
|
|
183
|
+
throw new Error(
|
|
184
|
+
`App ${projectId} was not previously configured and could not be set to installed!`
|
|
185
|
+
);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
208
189
|
async function setAppUninstalled(props: { projectId: string }) {
|
|
209
190
|
const { projectId } = props;
|
|
210
191
|
await removeApp({ projectId });
|
|
@@ -235,9 +216,26 @@ export function AgentConfigFile(
|
|
|
235
216
|
async function getAppBackup(props: { projectId: string }) {
|
|
236
217
|
const { projectId } = props;
|
|
237
218
|
const app = await getApp({ projectId });
|
|
238
|
-
if (app
|
|
219
|
+
if (app?.backup) {
|
|
239
220
|
return app.backup;
|
|
240
221
|
}
|
|
241
222
|
return null;
|
|
242
223
|
}
|
|
224
|
+
|
|
225
|
+
return {
|
|
226
|
+
...configFile,
|
|
227
|
+
name: AGENT_CONFIG_FILE_NAME,
|
|
228
|
+
getApps,
|
|
229
|
+
getReadyApps,
|
|
230
|
+
getApp,
|
|
231
|
+
isAppPresent,
|
|
232
|
+
isAppReady,
|
|
233
|
+
setAppInstalling,
|
|
234
|
+
setAppInstalled,
|
|
235
|
+
setAppUninstalling,
|
|
236
|
+
setAppUninstalled,
|
|
237
|
+
getAppVersion,
|
|
238
|
+
setAppBackup,
|
|
239
|
+
getAppBackup
|
|
240
|
+
};
|
|
243
241
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { logger } from '../util/logger';
|
|
2
2
|
import sleep from '../util/sleep';
|
|
3
|
-
import compose from 'docker-compose';
|
|
3
|
+
import { compose } from '../docker/docker-compose';
|
|
4
4
|
import * as YAML from 'yaml';
|
|
5
5
|
|
|
6
6
|
import {
|
|
@@ -23,19 +23,19 @@ export async function checkRabbitMQContainerRunning() {
|
|
|
23
23
|
return false;
|
|
24
24
|
}
|
|
25
25
|
const containerData = await compose.ps({ cwd: DEVICE_AGENT_CFG_PATH });
|
|
26
|
-
if (
|
|
26
|
+
if (containerData !== undefined) {
|
|
27
27
|
const rabbitmqService = containerData.data.services[0];
|
|
28
28
|
if (
|
|
29
|
-
rabbitmqService
|
|
30
|
-
rabbitmqService.state
|
|
29
|
+
rabbitmqService?.name === rabbitMQContainerName &&
|
|
30
|
+
rabbitmqService.state.includes('Up')
|
|
31
31
|
) {
|
|
32
|
-
logger.debug('alwaysAI Local Connection is
|
|
32
|
+
logger.debug('alwaysAI Local Connection Container is up');
|
|
33
33
|
return true;
|
|
34
34
|
}
|
|
35
|
-
logger.debug('alwaysAI Local Connection is not
|
|
35
|
+
logger.debug('alwaysAI Local Connection Container is not up');
|
|
36
36
|
return false;
|
|
37
37
|
}
|
|
38
|
-
logger.warn('alwaysAI Local Connection
|
|
38
|
+
logger.warn('alwaysAI Local Connection Container is undefined');
|
|
39
39
|
return false;
|
|
40
40
|
}
|
|
41
41
|
|
|
@@ -97,7 +97,7 @@ export async function setupRabbitMQContainer() {
|
|
|
97
97
|
}
|
|
98
98
|
} catch (e) {
|
|
99
99
|
logger.error(
|
|
100
|
-
`Unable to start alwaysAI Device Agent Local Connection Container:\n${e
|
|
100
|
+
`Unable to start alwaysAI Device Agent Local Connection Container:\n${e}`
|
|
101
101
|
);
|
|
102
102
|
}
|
|
103
103
|
}
|