@alwaysai/device-agent 1.5.0 → 2.0.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.
- package/lib/application-control/config.d.ts.map +1 -1
- package/lib/application-control/config.js +8 -3
- package/lib/application-control/config.js.map +1 -1
- package/lib/application-control/environment-variables.d.ts +5 -5
- package/lib/application-control/environment-variables.d.ts.map +1 -1
- package/lib/application-control/environment-variables.js +25 -38
- package/lib/application-control/environment-variables.js.map +1 -1
- package/lib/application-control/environment-variables.test.js +27 -7
- package/lib/application-control/environment-variables.test.js.map +1 -1
- package/lib/application-control/index.d.ts +4 -4
- package/lib/application-control/index.d.ts.map +1 -1
- package/lib/application-control/index.js +1 -4
- package/lib/application-control/index.js.map +1 -1
- package/lib/application-control/install.d.ts +4 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +24 -8
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +0 -11
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +5 -54
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/utils.d.ts +0 -4
- package/lib/application-control/utils.d.ts.map +1 -1
- package/lib/application-control/utils.js +12 -22
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/base-message-handler.d.ts +27 -0
- package/lib/cloud-connection/base-message-handler.d.ts.map +1 -0
- package/lib/cloud-connection/base-message-handler.js +72 -0
- package/lib/cloud-connection/base-message-handler.js.map +1 -0
- package/lib/cloud-connection/bootstrap-provision.js +3 -2
- package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
- package/lib/cloud-connection/connection-manager.d.ts +21 -0
- package/lib/cloud-connection/connection-manager.d.ts.map +1 -0
- package/lib/cloud-connection/connection-manager.js +158 -0
- package/lib/cloud-connection/connection-manager.js.map +1 -0
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +9 -30
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +69 -508
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/device-agent-message-handler.d.ts +22 -0
- package/lib/cloud-connection/device-agent-message-handler.d.ts.map +1 -0
- package/lib/cloud-connection/device-agent-message-handler.js +357 -0
- package/lib/cloud-connection/device-agent-message-handler.js.map +1 -0
- package/lib/cloud-connection/device-agent.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent.js +11 -9
- package/lib/cloud-connection/device-agent.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +19 -28
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +60 -172
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.test.js +71 -165
- package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
- package/lib/cloud-connection/message-dispatcher.d.ts +10 -0
- package/lib/cloud-connection/message-dispatcher.d.ts.map +1 -0
- package/lib/cloud-connection/message-dispatcher.js +27 -0
- package/lib/cloud-connection/message-dispatcher.js.map +1 -0
- package/lib/cloud-connection/passthrough-handler.d.ts +4 -1
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
- package/lib/cloud-connection/passthrough-handler.js +30 -11
- package/lib/cloud-connection/passthrough-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +11 -3
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +133 -28
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.js +45 -57
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
- package/lib/cloud-connection/shadow.d.ts.map +1 -1
- package/lib/cloud-connection/shadow.js +2 -1
- package/lib/cloud-connection/shadow.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.d.ts +12 -3
- package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
- package/lib/cloud-connection/transaction-manager.js +29 -28
- package/lib/cloud-connection/transaction-manager.js.map +1 -1
- package/lib/cloud-connection/transaction-manager.test.js +46 -5
- package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
- package/lib/device-control/device-control.d.ts +8 -8
- package/lib/device-control/device-control.d.ts.map +1 -1
- package/lib/device-control/device-control.js +95 -71
- package/lib/device-control/device-control.js.map +1 -1
- package/lib/docker/docker-compose.d.ts.map +1 -1
- package/lib/docker/docker-compose.js +2 -1
- package/lib/docker/docker-compose.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +2 -1
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js +7 -7
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +3 -1
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/infrastructure/config-check-utility.d.ts +6 -0
- package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.js +67 -0
- package/lib/infrastructure/config-check-utility.js.map +1 -0
- package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
- package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
- package/lib/infrastructure/config-check-utility.test.js +109 -0
- package/lib/infrastructure/config-check-utility.test.js.map +1 -0
- package/lib/infrastructure/device-certificate.d.ts +10 -0
- package/lib/infrastructure/device-certificate.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.js +47 -0
- package/lib/infrastructure/device-certificate.js.map +1 -0
- package/lib/infrastructure/device-certificate.test.d.ts +2 -0
- package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
- package/lib/infrastructure/device-certificate.test.js +24 -0
- package/lib/infrastructure/device-certificate.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
- package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
- package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
- package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
- package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
- package/lib/infrastructure/require-files-present-ready.test.js +44 -0
- package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
- package/lib/infrastructure/required-config-checks.d.ts +2 -0
- package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
- package/lib/infrastructure/required-config-checks.js +30 -0
- package/lib/infrastructure/required-config-checks.js.map +1 -0
- package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
- package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
- package/lib/jobs/job-handler.d.ts +23 -0
- package/lib/jobs/job-handler.d.ts.map +1 -0
- package/lib/jobs/job-handler.js +131 -0
- package/lib/jobs/job-handler.js.map +1 -0
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
- package/lib/local-connection/rabbitmq-connection.js +14 -14
- package/lib/local-connection/rabbitmq-connection.js.map +1 -1
- package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts +8 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.d.ts.map +1 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.js +42 -0
- package/lib/secure-tunneling/secure-tunnel-message-handler.js.map +1 -0
- package/lib/secure-tunneling/secure-tunneling.d.ts +9 -9
- package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.js +21 -16
- package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
- package/lib/secure-tunneling/secure-tunneling.test.js +11 -13
- package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
- package/lib/subcommands/app/analytics.d.ts.map +1 -1
- package/lib/subcommands/app/analytics.js +1 -2
- package/lib/subcommands/app/analytics.js.map +1 -1
- package/lib/subcommands/app/env-vars.d.ts +4 -0
- package/lib/subcommands/app/env-vars.d.ts.map +1 -1
- package/lib/subcommands/app/env-vars.js +52 -6
- package/lib/subcommands/app/env-vars.js.map +1 -1
- package/lib/subcommands/app/index.d.ts.map +1 -1
- package/lib/subcommands/app/index.js +1 -3
- package/lib/subcommands/app/index.js.map +1 -1
- package/lib/subcommands/app/models.d.ts +0 -11
- package/lib/subcommands/app/models.d.ts.map +1 -1
- package/lib/subcommands/app/models.js +2 -58
- package/lib/subcommands/app/models.js.map +1 -1
- package/lib/subcommands/app/shadow.d.ts.map +1 -1
- package/lib/subcommands/app/shadow.js +6 -5
- package/lib/subcommands/app/shadow.js.map +1 -1
- package/lib/subcommands/app/version.d.ts +2 -0
- package/lib/subcommands/app/version.d.ts.map +1 -1
- package/lib/subcommands/app/version.js +16 -6
- package/lib/subcommands/app/version.js.map +1 -1
- package/lib/subcommands/config.d.ts +2 -0
- package/lib/subcommands/config.d.ts.map +1 -0
- package/lib/subcommands/config.js +39 -0
- package/lib/subcommands/config.js.map +1 -0
- package/lib/subcommands/device/clean.d.ts +1 -1
- package/lib/subcommands/device/clean.d.ts.map +1 -1
- package/lib/subcommands/device/clean.js +23 -13
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/index.d.ts.map +1 -1
- package/lib/subcommands/device/index.js +3 -1
- package/lib/subcommands/device/index.js.map +1 -1
- package/lib/subcommands/device/init.js +8 -8
- package/lib/subcommands/device/init.js.map +1 -1
- package/lib/subcommands/device/migrate.d.ts +2 -0
- package/lib/subcommands/device/migrate.d.ts.map +1 -0
- package/lib/subcommands/device/migrate.js +24 -0
- package/lib/subcommands/device/migrate.js.map +1 -0
- package/lib/subcommands/device/refresh.d.ts.map +1 -1
- package/lib/subcommands/device/refresh.js +1 -0
- package/lib/subcommands/device/refresh.js.map +1 -1
- package/lib/subcommands/index.d.ts +1 -1
- package/lib/subcommands/index.d.ts.map +1 -1
- package/lib/subcommands/index.js +3 -1
- package/lib/subcommands/index.js.map +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
- package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
- package/lib/util/aai-error.d.ts +12 -0
- package/lib/util/aai-error.d.ts.map +1 -0
- package/lib/util/aai-error.js +11 -0
- package/lib/util/aai-error.js.map +1 -0
- package/lib/util/aws-regions.d.ts +2 -0
- package/lib/util/aws-regions.d.ts.map +1 -0
- package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
- package/lib/util/aws-regions.js.map +1 -0
- package/lib/util/check-for-updates.d.ts.map +1 -1
- package/lib/util/check-for-updates.js +5 -28
- package/lib/util/check-for-updates.js.map +1 -1
- package/lib/util/clean-certs.d.ts.map +1 -1
- package/lib/util/clean-certs.js +5 -4
- package/lib/util/clean-certs.js.map +1 -1
- package/lib/util/directories.d.ts +4 -18
- package/lib/util/directories.d.ts.map +1 -1
- package/lib/util/directories.js +18 -32
- package/lib/util/directories.js.map +1 -1
- package/lib/util/file.d.ts +4 -0
- package/lib/util/file.d.ts.map +1 -1
- package/lib/util/file.js +65 -4
- package/lib/util/file.js.map +1 -1
- package/lib/util/get-device-id.d.ts.map +1 -1
- package/lib/util/get-device-id.js +7 -1
- package/lib/util/get-device-id.js.map +1 -1
- package/lib/util/http-client.js +3 -3
- package/lib/util/http-client.js.map +1 -1
- package/package.json +19 -17
- package/readme.md +12 -32
- package/src/application-control/config.ts +9 -12
- package/src/application-control/environment-variables.test.ts +28 -7
- package/src/application-control/environment-variables.ts +42 -59
- package/src/application-control/index.ts +3 -16
- package/src/application-control/install.ts +39 -13
- package/src/application-control/models.ts +6 -87
- package/src/application-control/utils.ts +10 -25
- package/src/cloud-connection/base-message-handler.ts +118 -0
- package/src/cloud-connection/bootstrap-provision.ts +7 -7
- package/src/cloud-connection/connection-manager.ts +187 -0
- package/src/cloud-connection/device-agent-cloud-connection.ts +130 -723
- package/src/cloud-connection/device-agent-message-handler.ts +642 -0
- package/src/cloud-connection/device-agent.ts +16 -7
- package/src/cloud-connection/live-updates-handler.test.ts +121 -189
- package/src/cloud-connection/live-updates-handler.ts +105 -232
- package/src/cloud-connection/message-dispatcher.ts +33 -0
- package/src/cloud-connection/passthrough-handler.ts +55 -18
- package/src/cloud-connection/shadow-handler.test.ts +45 -57
- package/src/cloud-connection/shadow-handler.ts +224 -54
- package/src/cloud-connection/shadow.ts +4 -1
- package/src/cloud-connection/transaction-manager.test.ts +68 -6
- package/src/cloud-connection/transaction-manager.ts +69 -41
- package/src/device-control/device-control.ts +102 -70
- package/src/docker/docker-compose.ts +3 -2
- package/src/infrastructure/agent-config.test.ts +6 -2
- package/src/infrastructure/agent-config.ts +8 -7
- package/src/infrastructure/config-check-utility.test.ts +154 -0
- package/src/infrastructure/config-check-utility.ts +77 -0
- package/src/infrastructure/device-certificate.test.ts +40 -0
- package/src/infrastructure/device-certificate.ts +58 -0
- package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
- package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
- package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
- package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
- package/src/infrastructure/require-files-present-ready.test.ts +53 -0
- package/src/infrastructure/required-config-checks.ts +33 -0
- package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
- package/src/jobs/job-handler.ts +146 -0
- package/src/local-connection/rabbitmq-connection.ts +22 -17
- package/src/secure-tunneling/secure-tunnel-message-handler.ts +56 -0
- package/src/secure-tunneling/secure-tunneling.test.ts +20 -22
- package/src/secure-tunneling/secure-tunneling.ts +41 -29
- package/src/subcommands/app/analytics.ts +2 -4
- package/src/subcommands/app/env-vars.ts +72 -9
- package/src/subcommands/app/index.ts +3 -11
- package/src/subcommands/app/models.ts +5 -81
- package/src/subcommands/app/shadow.ts +6 -5
- package/src/subcommands/app/version.ts +23 -6
- package/src/subcommands/config.ts +42 -0
- package/src/subcommands/device/clean.ts +31 -17
- package/src/subcommands/device/index.ts +3 -1
- package/src/subcommands/device/init.ts +11 -11
- package/src/subcommands/device/migrate.ts +20 -0
- package/src/subcommands/device/refresh.ts +1 -0
- package/src/subcommands/index.ts +3 -1
- package/src/util/aai-error.ts +20 -0
- package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
- package/src/util/check-for-updates.ts +14 -30
- package/src/util/clean-certs.ts +8 -4
- package/src/util/directories.ts +23 -67
- package/src/util/file.ts +83 -3
- package/src/util/get-device-id.ts +7 -7
- package/src/util/http-client.ts +2 -2
- package/lib/util/cloud-mode-ready.d.ts +0 -3
- package/lib/util/cloud-mode-ready.d.ts.map +0 -1
- package/lib/util/cloud-mode-ready.js.map +0 -1
- package/lib/util/download-file.d.ts +0 -6
- package/lib/util/download-file.d.ts.map +0 -1
- package/lib/util/download-file.js +0 -25
- package/lib/util/download-file.js.map +0 -1
- package/lib/util/fetch-with-timeout.d.ts +0 -4
- package/lib/util/fetch-with-timeout.d.ts.map +0 -1
- package/lib/util/fetch-with-timeout.js +0 -30
- package/lib/util/fetch-with-timeout.js.map +0 -1
- package/lib/util/parsing.d.ts +0 -2
- package/lib/util/parsing.d.ts.map +0 -1
- package/lib/util/parsing.js +0 -17
- package/lib/util/parsing.js.map +0 -1
- package/src/util/download-file.ts +0 -25
- package/src/util/fetch-with-timeout.ts +0 -35
- package/src/util/parsing.ts +0 -11
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import {
|
|
2
|
+
EnvVars,
|
|
2
3
|
ToClientStatusResponseMessage,
|
|
3
4
|
generateTxId,
|
|
4
|
-
keyMirrors
|
|
5
|
+
keyMirrors,
|
|
6
|
+
buildToClientStatusResponseMessage
|
|
5
7
|
} from '@alwaysai/device-agent-schemas';
|
|
6
8
|
import { TransactionManager } from './transaction-manager';
|
|
7
9
|
import { v4 as uuidv4 } from 'uuid';
|
|
8
10
|
import { Publisher } from './publisher';
|
|
9
11
|
import { LiveUpdatesHandler } from './live-updates-handler';
|
|
10
12
|
import { AppConfigUpdate, ShadowUpdate } from './shadow-handler';
|
|
13
|
+
import { AppContent } from './device-agent-message-handler';
|
|
14
|
+
import { AppConfig } from '@alwaysai/app-configuration-schemas';
|
|
11
15
|
|
|
12
16
|
const mockClient = {
|
|
13
17
|
publish: jest.fn()
|
|
@@ -15,8 +19,8 @@ const mockClient = {
|
|
|
15
19
|
const clientId = 'test-client';
|
|
16
20
|
|
|
17
21
|
const mockLiveUpdatesHandler = {
|
|
18
|
-
|
|
19
|
-
|
|
22
|
+
enable: jest.fn(),
|
|
23
|
+
disable: jest.fn()
|
|
20
24
|
} as any as LiveUpdatesHandler;
|
|
21
25
|
|
|
22
26
|
describe('Test Transaction Manager', () => {
|
|
@@ -58,11 +62,22 @@ describe('Test Transaction Manager', () => {
|
|
|
58
62
|
test('Start a new transaction which completes in one step', async () => {
|
|
59
63
|
const txId = generateTxId();
|
|
60
64
|
const projectId = generateRandomProjectId();
|
|
65
|
+
|
|
66
|
+
const successFn = (txId: string) => {
|
|
67
|
+
const msg = buildToClientStatusResponseMessage(
|
|
68
|
+
clientId,
|
|
69
|
+
{ status: keyMirrors.statusResponse.success },
|
|
70
|
+
txId
|
|
71
|
+
);
|
|
72
|
+
publisher.publishToClient(msg);
|
|
73
|
+
};
|
|
74
|
+
|
|
61
75
|
await txnMgr.runTransactionStep({
|
|
62
76
|
func: func_complete,
|
|
63
77
|
projectId,
|
|
64
78
|
txId,
|
|
65
|
-
start: true
|
|
79
|
+
start: true,
|
|
80
|
+
successFn
|
|
66
81
|
});
|
|
67
82
|
expect(txnMgr.isOngoingTransaction(txId)).toBe(false);
|
|
68
83
|
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(false);
|
|
@@ -188,7 +203,7 @@ describe('Test Transaction Manager', () => {
|
|
|
188
203
|
throw new Error('Expected start transaction to fail!');
|
|
189
204
|
} catch (e) {
|
|
190
205
|
console.log(e);
|
|
191
|
-
expect(e.code).toBe(txnMgr.Errors.
|
|
206
|
+
expect(e.code).toBe(txnMgr.Errors.PROJECT_TRANSACTION_ONGOING);
|
|
192
207
|
}
|
|
193
208
|
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
|
|
194
209
|
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);
|
|
@@ -198,6 +213,19 @@ describe('Test Transaction Manager', () => {
|
|
|
198
213
|
test('Handle error in step function', async () => {
|
|
199
214
|
const txId = generateTxId();
|
|
200
215
|
const projectId = generateRandomProjectId();
|
|
216
|
+
|
|
217
|
+
const errorFn = (txId: string, errorMsg: string) => {
|
|
218
|
+
const msg = buildToClientStatusResponseMessage(
|
|
219
|
+
clientId,
|
|
220
|
+
{
|
|
221
|
+
status: keyMirrors.statusResponse.failure,
|
|
222
|
+
message: errorMsg
|
|
223
|
+
},
|
|
224
|
+
txId
|
|
225
|
+
);
|
|
226
|
+
publisher.publishToClient(msg);
|
|
227
|
+
};
|
|
228
|
+
|
|
201
229
|
await txnMgr.runTransactionStep({
|
|
202
230
|
func: jest.fn().mockImplementation(() => {
|
|
203
231
|
throw new Error('Test error!');
|
|
@@ -205,7 +233,8 @@ describe('Test Transaction Manager', () => {
|
|
|
205
233
|
projectId,
|
|
206
234
|
txId,
|
|
207
235
|
start: true,
|
|
208
|
-
stepName: 'step1'
|
|
236
|
+
stepName: 'step1',
|
|
237
|
+
errorFn
|
|
209
238
|
});
|
|
210
239
|
expect(txnMgr.isOngoingTransaction(txId)).toBe(false);
|
|
211
240
|
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(false);
|
|
@@ -369,4 +398,37 @@ describe('Test Transaction Manager', () => {
|
|
|
369
398
|
expect(txnMgr.isAnyOngoingTransaction()).toBe(false);
|
|
370
399
|
expect(txnMgr.getAppCfgUpdateFromTxID(txId)).toEqual(undefined);
|
|
371
400
|
});
|
|
401
|
+
|
|
402
|
+
test('store appContent', async () => {
|
|
403
|
+
const txId = generateTxId();
|
|
404
|
+
const projectId = generateRandomProjectId();
|
|
405
|
+
const appCfg: AppConfig = {
|
|
406
|
+
models: {},
|
|
407
|
+
scripts: { start: 'python app.py' }
|
|
408
|
+
};
|
|
409
|
+
const envVars: EnvVars = { alwaysai: { TEST: '1' } };
|
|
410
|
+
const cfgUpdate: AppContent = {
|
|
411
|
+
projectId: projectId,
|
|
412
|
+
appCfg: appCfg,
|
|
413
|
+
envVars: envVars
|
|
414
|
+
};
|
|
415
|
+
|
|
416
|
+
await txnMgr.runTransactionStep({
|
|
417
|
+
func: func_incomplete,
|
|
418
|
+
projectId,
|
|
419
|
+
txId,
|
|
420
|
+
start: true
|
|
421
|
+
});
|
|
422
|
+
|
|
423
|
+
expect(txnMgr.getAppContentFromTxId(txId)).toEqual(undefined);
|
|
424
|
+
|
|
425
|
+
txnMgr.setAppContentToTx(txId, cfgUpdate);
|
|
426
|
+
|
|
427
|
+
expect(txnMgr.getProjectFromTransaction(txId)).toEqual(projectId);
|
|
428
|
+
expect(txnMgr.getTransactionFromProject(projectId)).toEqual(txId);
|
|
429
|
+
expect(txnMgr.isOngoingTransaction(txId)).toBe(true);
|
|
430
|
+
expect(txnMgr.isOngoingTransactionForProjectID(projectId)).toBe(true);
|
|
431
|
+
expect(txnMgr.isAnyOngoingTransaction()).toBe(true);
|
|
432
|
+
expect(txnMgr.getAppContentFromTxId(txId)).toEqual(cfgUpdate);
|
|
433
|
+
});
|
|
372
434
|
});
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
2
|
+
ToClientStatusResponseMessage,
|
|
3
3
|
buildToClientStatusResponseMessage,
|
|
4
4
|
keyMirrors
|
|
5
5
|
} from '@alwaysai/device-agent-schemas';
|
|
6
6
|
import { LiveUpdatesHandler } from './live-updates-handler';
|
|
7
7
|
import { Publisher } from './publisher';
|
|
8
8
|
import { logger } from '../util/logger';
|
|
9
|
-
import { keyMirror } from 'alwaysai/lib/util';
|
|
9
|
+
import { keyMirror, stringifyError } from 'alwaysai/lib/util';
|
|
10
10
|
import { CodedError } from '@carnesen/coded-error';
|
|
11
11
|
import { ShadowUpdate } from './shadow-handler';
|
|
12
|
+
import { AppContent } from './device-agent-message-handler';
|
|
12
13
|
|
|
13
14
|
interface TransactionDetails {
|
|
14
15
|
txId: string;
|
|
@@ -18,19 +19,24 @@ interface TransactionDetails {
|
|
|
18
19
|
update?: string;
|
|
19
20
|
stop?: string;
|
|
20
21
|
appCfgUpdate?: ShadowUpdate;
|
|
22
|
+
appContent?: AppContent;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
export type ErrorFunction = (txid: string, message: string) => void;
|
|
26
|
+
|
|
27
|
+
export type SuccessFunction = (txId: string) => void;
|
|
28
|
+
|
|
23
29
|
export class TransactionManager {
|
|
24
30
|
private detailsByTx: Record<string, TransactionDetails> = {};
|
|
25
31
|
private detailsByProject: Record<string, TransactionDetails> = {};
|
|
26
|
-
private liveUpdatesHandler: LiveUpdatesHandler;
|
|
32
|
+
private readonly liveUpdatesHandler: LiveUpdatesHandler;
|
|
27
33
|
private publisher: Publisher;
|
|
28
|
-
|
|
29
|
-
private startTransaction(
|
|
34
|
+
private async startTransaction(
|
|
30
35
|
txId: string,
|
|
31
36
|
projectId: string,
|
|
37
|
+
liveUpdatesPublishFn?: () => Promise<void>,
|
|
32
38
|
stepName?: string
|
|
33
|
-
): void {
|
|
39
|
+
): Promise<void> {
|
|
34
40
|
// Check if the transaction already exists
|
|
35
41
|
if (this.detailsByTx[txId]) {
|
|
36
42
|
const txnDetails = this.detailsByTx[txId];
|
|
@@ -53,7 +59,7 @@ export class TransactionManager {
|
|
|
53
59
|
null,
|
|
54
60
|
2
|
|
55
61
|
)}`,
|
|
56
|
-
this.Errors.
|
|
62
|
+
this.Errors.PROJECT_TRANSACTION_ONGOING
|
|
57
63
|
);
|
|
58
64
|
}
|
|
59
65
|
|
|
@@ -67,10 +73,14 @@ export class TransactionManager {
|
|
|
67
73
|
this.detailsByTx[txId] = txDetails;
|
|
68
74
|
this.detailsByProject[projectId] = txDetails;
|
|
69
75
|
logger.info(`Started transaction:\n${JSON.stringify(txDetails, null, 2)}`);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
76
|
+
|
|
77
|
+
if (liveUpdatesPublishFn) {
|
|
78
|
+
await this.liveUpdatesHandler.enable(
|
|
79
|
+
keyMirrors.toClientMessageType.status_response,
|
|
80
|
+
liveUpdatesPublishFn,
|
|
81
|
+
txId
|
|
82
|
+
);
|
|
83
|
+
}
|
|
74
84
|
}
|
|
75
85
|
|
|
76
86
|
private updateTransaction(txId: string, stepName?: string): void {
|
|
@@ -95,7 +105,7 @@ export class TransactionManager {
|
|
|
95
105
|
|
|
96
106
|
public Errors = keyMirror({
|
|
97
107
|
TRANSACTION_ONGOING: null,
|
|
98
|
-
|
|
108
|
+
PROJECT_TRANSACTION_ONGOING: null,
|
|
99
109
|
TRANSACTION_NOT_ONGOING: null
|
|
100
110
|
});
|
|
101
111
|
|
|
@@ -104,11 +114,28 @@ export class TransactionManager {
|
|
|
104
114
|
projectId: string;
|
|
105
115
|
txId: string;
|
|
106
116
|
start: boolean;
|
|
117
|
+
liveUpdatesPublishFn?: () => Promise<void>;
|
|
107
118
|
stepName?: string;
|
|
119
|
+
errorFn?: ErrorFunction;
|
|
120
|
+
successFn?: SuccessFunction;
|
|
108
121
|
}) {
|
|
109
|
-
const {
|
|
122
|
+
const {
|
|
123
|
+
func,
|
|
124
|
+
projectId,
|
|
125
|
+
txId,
|
|
126
|
+
start,
|
|
127
|
+
liveUpdatesPublishFn,
|
|
128
|
+
stepName,
|
|
129
|
+
errorFn,
|
|
130
|
+
successFn
|
|
131
|
+
} = props;
|
|
110
132
|
if (start) {
|
|
111
|
-
this.startTransaction(
|
|
133
|
+
await this.startTransaction(
|
|
134
|
+
txId,
|
|
135
|
+
projectId,
|
|
136
|
+
liveUpdatesPublishFn,
|
|
137
|
+
stepName
|
|
138
|
+
);
|
|
112
139
|
} else {
|
|
113
140
|
this.updateTransaction(txId, stepName);
|
|
114
141
|
}
|
|
@@ -116,36 +143,19 @@ export class TransactionManager {
|
|
|
116
143
|
const completed = await func();
|
|
117
144
|
if (completed) {
|
|
118
145
|
this.completeTransaction(txId);
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
}
|
|
122
|
-
// Send final status message
|
|
123
|
-
const message = buildToClientStatusResponseMessage(
|
|
124
|
-
this.publisher.getClientId(),
|
|
125
|
-
successStatusResponsePayload,
|
|
126
|
-
txId
|
|
127
|
-
);
|
|
128
|
-
this.publisher.publishToClient(message);
|
|
146
|
+
if (successFn) {
|
|
147
|
+
successFn(txId);
|
|
148
|
+
}
|
|
129
149
|
}
|
|
130
150
|
} catch (e) {
|
|
131
|
-
const message: string = e.message;
|
|
132
151
|
logger.error(
|
|
133
|
-
`Failed to execute cmd for ${projectId}
|
|
152
|
+
`Failed to execute cmd for ${projectId}!\n${stringifyError(e)}`
|
|
134
153
|
);
|
|
135
154
|
|
|
136
155
|
this.completeTransaction(txId);
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
message
|
|
141
|
-
};
|
|
142
|
-
// Send final status message
|
|
143
|
-
const failureStatusResponseMessage = buildToClientStatusResponseMessage(
|
|
144
|
-
this.publisher.getClientId(),
|
|
145
|
-
failureStatusResponsePayload,
|
|
146
|
-
txId
|
|
147
|
-
);
|
|
148
|
-
this.publisher.publishToClient(failureStatusResponseMessage);
|
|
156
|
+
if (errorFn) {
|
|
157
|
+
errorFn(txId, e.message);
|
|
158
|
+
}
|
|
149
159
|
}
|
|
150
160
|
}
|
|
151
161
|
|
|
@@ -175,6 +185,10 @@ export class TransactionManager {
|
|
|
175
185
|
return this.detailsByTx[txId]?.appCfgUpdate;
|
|
176
186
|
}
|
|
177
187
|
|
|
188
|
+
public getAppContentFromTxId(txId: string): AppContent | undefined {
|
|
189
|
+
return this.detailsByTx[txId]?.appContent;
|
|
190
|
+
}
|
|
191
|
+
|
|
178
192
|
public setAppCfgUpdateToTx(txId: string, appCfgUpdate: ShadowUpdate) {
|
|
179
193
|
if (this.isOngoingTransaction(txId)) {
|
|
180
194
|
this.detailsByTx[txId].appCfgUpdate = appCfgUpdate;
|
|
@@ -184,7 +198,20 @@ export class TransactionManager {
|
|
|
184
198
|
);
|
|
185
199
|
}
|
|
186
200
|
|
|
187
|
-
public
|
|
201
|
+
public setAppContentToTx(txId: string, appContent: AppContent) {
|
|
202
|
+
if (this.isOngoingTransaction(txId)) {
|
|
203
|
+
logger.debug(`${txId}: Setting AppContent:${JSON.stringify(appContent)}`);
|
|
204
|
+
this.detailsByTx[txId].appContent = appContent;
|
|
205
|
+
} else
|
|
206
|
+
throw new Error(
|
|
207
|
+
`Could not set appCfgUpdate, the transaction ${txId} does not exist.`
|
|
208
|
+
);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
public completeTransaction(
|
|
212
|
+
txId: string,
|
|
213
|
+
messageToPublish?: ToClientStatusResponseMessage
|
|
214
|
+
): void {
|
|
188
215
|
const txDetails = this.detailsByTx[txId];
|
|
189
216
|
if (txDetails === undefined) {
|
|
190
217
|
throw new CodedError(
|
|
@@ -199,8 +226,9 @@ export class TransactionManager {
|
|
|
199
226
|
delete this.detailsByTx[txId];
|
|
200
227
|
delete this.detailsByProject[txDetails.projectId];
|
|
201
228
|
|
|
202
|
-
|
|
229
|
+
this.liveUpdatesHandler.disable(
|
|
230
|
+
keyMirrors.toClientMessageType.status_response,
|
|
203
231
|
txId
|
|
204
|
-
|
|
232
|
+
);
|
|
205
233
|
}
|
|
206
234
|
}
|
|
@@ -4,9 +4,10 @@ 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';
|
|
7
|
+
import { JsSpawner, stringifyError } from 'alwaysai/lib/util';
|
|
8
8
|
import { DeviceStatsPayload } from '@alwaysai/device-agent-schemas';
|
|
9
9
|
import { getDeviceAgentVersion } from '../util/check-for-updates';
|
|
10
|
+
import AaiError from '../util/aai-error';
|
|
10
11
|
|
|
11
12
|
const exec_promise = promisify(exec);
|
|
12
13
|
|
|
@@ -14,63 +15,84 @@ const exec_promise = promisify(exec);
|
|
|
14
15
|
export async function getCpuDetails(): Promise<
|
|
15
16
|
DeviceStatsPayload['cpuDetails']
|
|
16
17
|
> {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
let cpuFree, cpuTemp;
|
|
19
|
+
try {
|
|
20
|
+
[cpuFree, cpuTemp] = await Promise.all([
|
|
21
|
+
osu.cpu.free(),
|
|
22
|
+
si.cpuTemperature()
|
|
23
|
+
]);
|
|
24
|
+
} catch (error) {
|
|
25
|
+
logger.error('Error fetching CPU details:', error);
|
|
26
|
+
return {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
return {
|
|
30
|
+
usedPerc: cpuFree !== null ? 100 - cpuFree : undefined,
|
|
31
|
+
temperature: cpuTemp?.main !== null ? cpuTemp.main : undefined
|
|
32
|
+
};
|
|
23
33
|
}
|
|
24
34
|
|
|
25
35
|
export async function getDiskDetails(): Promise<
|
|
26
36
|
DeviceStatsPayload['diskDetails']
|
|
27
37
|
> {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
38
|
+
let driveInfo;
|
|
39
|
+
try {
|
|
40
|
+
// Types incorrectly specify diskname as required instead of optional
|
|
41
|
+
// @ts-expect-error
|
|
42
|
+
driveInfo = await osu.drive.info();
|
|
43
|
+
} catch (error) {
|
|
44
|
+
logger.error('Error fetching disk details:', error);
|
|
45
|
+
return {};
|
|
36
46
|
}
|
|
37
|
-
|
|
47
|
+
|
|
48
|
+
return {
|
|
49
|
+
usedGb:
|
|
50
|
+
driveInfo?.usedGb !== null ? parseFloat(driveInfo.usedGb) : undefined,
|
|
51
|
+
freeGb:
|
|
52
|
+
driveInfo?.freeGb !== null ? parseFloat(driveInfo.freeGb) : undefined
|
|
53
|
+
};
|
|
38
54
|
}
|
|
39
55
|
|
|
40
56
|
export async function getMemDetails(): Promise<
|
|
41
57
|
DeviceStatsPayload['memDetails']
|
|
42
58
|
> {
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
59
|
+
let memInfo;
|
|
60
|
+
try {
|
|
61
|
+
memInfo = await osu.mem.info();
|
|
62
|
+
} catch (error) {
|
|
63
|
+
logger.error('Error fetching memory details:', error);
|
|
64
|
+
return {};
|
|
65
|
+
}
|
|
66
|
+
return {
|
|
67
|
+
usedMb: memInfo?.usedMemMb !== null ? memInfo.usedMemMb : undefined,
|
|
68
|
+
freeMb: memInfo?.freeMemMb !== null ? memInfo.freeMemMb : undefined
|
|
69
|
+
};
|
|
48
70
|
}
|
|
49
71
|
|
|
50
|
-
// System information
|
|
72
|
+
// System information casted to a string
|
|
51
73
|
export async function getOsInfo() {
|
|
52
74
|
const osInfo = await si.osInfo();
|
|
53
75
|
return {
|
|
54
|
-
platform: osInfo.platform,
|
|
55
|
-
distro: osInfo.distro,
|
|
56
|
-
release: osInfo.release,
|
|
57
|
-
kernel: osInfo.kernel,
|
|
58
|
-
architecture: osInfo.arch,
|
|
59
|
-
hostname: osInfo.hostname
|
|
76
|
+
platform: String(osInfo.platform),
|
|
77
|
+
distro: String(osInfo.distro),
|
|
78
|
+
release: String(osInfo.release),
|
|
79
|
+
kernel: String(osInfo.kernel),
|
|
80
|
+
architecture: String(osInfo.arch),
|
|
81
|
+
hostname: String(osInfo.hostname)
|
|
60
82
|
};
|
|
61
83
|
}
|
|
62
84
|
|
|
63
85
|
export async function getCpuInfo() {
|
|
64
86
|
const cpuInfo = await si.cpu();
|
|
65
87
|
return {
|
|
66
|
-
manufacturer: cpuInfo.manufacturer,
|
|
67
|
-
brand: cpuInfo.brand,
|
|
68
|
-
vendor: cpuInfo.vendor,
|
|
69
|
-
model: cpuInfo.model,
|
|
70
|
-
cores: cpuInfo.cores,
|
|
71
|
-
physicalCores: cpuInfo.physicalCores,
|
|
72
|
-
efficiencyCores: cpuInfo.efficiencyCores,
|
|
73
|
-
processors: cpuInfo.processors
|
|
88
|
+
manufacturer: String(cpuInfo.manufacturer),
|
|
89
|
+
brand: String(cpuInfo.brand),
|
|
90
|
+
vendor: String(cpuInfo.vendor),
|
|
91
|
+
model: String(cpuInfo.model),
|
|
92
|
+
cores: String(cpuInfo.cores),
|
|
93
|
+
physicalCores: String(cpuInfo.physicalCores),
|
|
94
|
+
efficiencyCores: String(cpuInfo.efficiencyCores),
|
|
95
|
+
processors: String(cpuInfo.processors)
|
|
74
96
|
};
|
|
75
97
|
}
|
|
76
98
|
|
|
@@ -78,11 +100,11 @@ export async function getDiskInfo() {
|
|
|
78
100
|
const diskInfo = await si.diskLayout();
|
|
79
101
|
return {
|
|
80
102
|
drives: diskInfo.map((drive) => ({
|
|
81
|
-
device: drive.device,
|
|
82
|
-
type: drive.type,
|
|
83
|
-
name: drive.name,
|
|
84
|
-
vendor: drive.vendor,
|
|
85
|
-
size: drive.size
|
|
103
|
+
device: String(drive.device),
|
|
104
|
+
type: String(drive.type),
|
|
105
|
+
name: String(drive.name),
|
|
106
|
+
vendor: String(drive.vendor),
|
|
107
|
+
size: String(drive.size)
|
|
86
108
|
}))
|
|
87
109
|
};
|
|
88
110
|
}
|
|
@@ -90,14 +112,14 @@ export async function getDiskInfo() {
|
|
|
90
112
|
export async function getDeviceInfo() {
|
|
91
113
|
const deviceInfo = await si.system();
|
|
92
114
|
return {
|
|
93
|
-
manufacturer: deviceInfo.manufacturer,
|
|
94
|
-
model: deviceInfo.model,
|
|
95
|
-
version: deviceInfo.version,
|
|
115
|
+
manufacturer: String(deviceInfo.manufacturer),
|
|
116
|
+
model: String(deviceInfo.model),
|
|
117
|
+
version: String(deviceInfo.version),
|
|
96
118
|
serial:
|
|
97
119
|
deviceInfo.serial && deviceInfo.serial !== '-'
|
|
98
|
-
? deviceInfo.serial
|
|
120
|
+
? String(deviceInfo.serial)
|
|
99
121
|
: undefined,
|
|
100
|
-
virtual: deviceInfo.virtual
|
|
122
|
+
virtual: deviceInfo.virtual // this should be a boolean
|
|
101
123
|
};
|
|
102
124
|
}
|
|
103
125
|
|
|
@@ -108,9 +130,9 @@ export async function getNetworkInfo() {
|
|
|
108
130
|
? networkInterfaces.filter((iface: any) => iface.ip4 !== '127.0.0.1')[0]
|
|
109
131
|
: networkInterfaces;
|
|
110
132
|
return {
|
|
111
|
-
ipv4Address: defaultNetworkInterface.ip4,
|
|
112
|
-
ipv6Address: defaultNetworkInterface.ip6,
|
|
113
|
-
macAddress: defaultNetworkInterface.mac
|
|
133
|
+
ipv4Address: String(defaultNetworkInterface.ip4),
|
|
134
|
+
ipv6Address: String(defaultNetworkInterface.ip6),
|
|
135
|
+
macAddress: String(defaultNetworkInterface.mac)
|
|
114
136
|
};
|
|
115
137
|
}
|
|
116
138
|
|
|
@@ -123,9 +145,9 @@ export async function getDockerVersion() {
|
|
|
123
145
|
args: ['info', '--format', 'json']
|
|
124
146
|
})
|
|
125
147
|
);
|
|
126
|
-
return result.ClientInfo.Version;
|
|
148
|
+
return String(result.ClientInfo.Version);
|
|
127
149
|
} catch (e) {
|
|
128
|
-
logger.warn(`Cannot get Docker version
|
|
150
|
+
logger.warn(`Cannot get Docker version!\n${stringifyError(e)}`);
|
|
129
151
|
return 'Not found';
|
|
130
152
|
}
|
|
131
153
|
}
|
|
@@ -138,7 +160,7 @@ export async function getDockerComposeVersion() {
|
|
|
138
160
|
args: ['compose', 'version']
|
|
139
161
|
});
|
|
140
162
|
} catch (e) {
|
|
141
|
-
logger.warn(`Cannot get Docker Compose version
|
|
163
|
+
logger.warn(`Cannot get Docker Compose version!\n${stringifyError(e)}`);
|
|
142
164
|
return 'Not found';
|
|
143
165
|
}
|
|
144
166
|
}
|
|
@@ -151,7 +173,7 @@ export async function getNpmVersion() {
|
|
|
151
173
|
args: ['--version']
|
|
152
174
|
});
|
|
153
175
|
} catch (e) {
|
|
154
|
-
logger.warn(`Cannot get npm version
|
|
176
|
+
logger.warn(`Cannot get npm version!\n${stringifyError(e)}`);
|
|
155
177
|
return 'Not found';
|
|
156
178
|
}
|
|
157
179
|
}
|
|
@@ -164,7 +186,7 @@ export async function getNodeVersion() {
|
|
|
164
186
|
args: ['-v']
|
|
165
187
|
});
|
|
166
188
|
} catch (e) {
|
|
167
|
-
logger.warn(`Cannot get Node version
|
|
189
|
+
logger.warn(`Cannot get Node version!\n${stringifyError(e)}`);
|
|
168
190
|
return 'Not found';
|
|
169
191
|
}
|
|
170
192
|
}
|
|
@@ -174,7 +196,6 @@ export async function getPackageVersions() {
|
|
|
174
196
|
// eslint-disable-next-line
|
|
175
197
|
const deviceAgentSchemasJson = require('../../node_modules/@alwaysai/device-agent-schemas/package.json');
|
|
176
198
|
|
|
177
|
-
// Concurrent asynchronous function call
|
|
178
199
|
const [dockerVersion, dockerComposeVersion, nodeVersion, npmVersion] =
|
|
179
200
|
await Promise.all([
|
|
180
201
|
getDockerVersion(),
|
|
@@ -207,27 +228,39 @@ export async function getLastBootTime() {
|
|
|
207
228
|
|
|
208
229
|
const tokens = latestBootStdout.trim().split(' ');
|
|
209
230
|
|
|
210
|
-
return new Date(`${tokens[2]} ${tokens[3]} ${tokens[4]}`);
|
|
231
|
+
return String(new Date(`${tokens[2]} ${tokens[3]} ${tokens[4]}`));
|
|
211
232
|
} catch (e) {
|
|
212
|
-
logger.error(`Issue getting last boot time
|
|
233
|
+
logger.error(`Issue getting last boot time!\n${stringifyError(e)}`);
|
|
213
234
|
return undefined;
|
|
214
235
|
}
|
|
215
236
|
}
|
|
216
237
|
|
|
217
238
|
export async function getSystemInformation(): Promise<SystemInformationShadowUpdate> {
|
|
218
239
|
try {
|
|
240
|
+
const [os, cpu, disk, device, network, versions, lastBootTime] =
|
|
241
|
+
await Promise.all([
|
|
242
|
+
getOsInfo(),
|
|
243
|
+
getCpuInfo(),
|
|
244
|
+
getDiskInfo(),
|
|
245
|
+
getDeviceInfo(),
|
|
246
|
+
getNetworkInfo(),
|
|
247
|
+
getPackageVersions(),
|
|
248
|
+
getLastBootTime()
|
|
249
|
+
]);
|
|
219
250
|
const systemInfo: SystemInformationShadowUpdate = {
|
|
220
|
-
os
|
|
221
|
-
cpu
|
|
222
|
-
disk
|
|
223
|
-
device
|
|
224
|
-
network
|
|
225
|
-
versions
|
|
226
|
-
lastBootTime
|
|
251
|
+
os,
|
|
252
|
+
cpu,
|
|
253
|
+
disk,
|
|
254
|
+
device,
|
|
255
|
+
network,
|
|
256
|
+
versions,
|
|
257
|
+
lastBootTime
|
|
227
258
|
};
|
|
228
259
|
return systemInfo;
|
|
229
260
|
} catch (e) {
|
|
230
|
-
logger.error(
|
|
261
|
+
logger.error(
|
|
262
|
+
`There was a problem getting system information!\n${stringifyError(e)}`
|
|
263
|
+
);
|
|
231
264
|
}
|
|
232
265
|
return {};
|
|
233
266
|
}
|
|
@@ -242,11 +275,10 @@ export async function reboot() {
|
|
|
242
275
|
timeout: 5000
|
|
243
276
|
});
|
|
244
277
|
logger.info(result.stdout.trim());
|
|
245
|
-
} catch (
|
|
246
|
-
throw new
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
)}`
|
|
278
|
+
} catch (e) {
|
|
279
|
+
throw new AaiError(
|
|
280
|
+
"Could not reboot device. You may need to add passwordless access to '/sbin/shutdown'.",
|
|
281
|
+
{ cause: e }
|
|
250
282
|
);
|
|
251
283
|
}
|
|
252
284
|
}
|
|
@@ -2,7 +2,7 @@ import * as DockerComposeV1 from 'docker-compose';
|
|
|
2
2
|
import { v2 as DockerComposeV2 } from 'docker-compose';
|
|
3
3
|
import { execSync } from 'child_process';
|
|
4
4
|
import { logger } from '../util/logger';
|
|
5
|
-
import { JsSpawner } from 'alwaysai/lib/util';
|
|
5
|
+
import { JsSpawner, stringifyError } from 'alwaysai/lib/util';
|
|
6
6
|
|
|
7
7
|
let dockerCmd = 'docker';
|
|
8
8
|
|
|
@@ -14,11 +14,12 @@ export function importDockerCompose():
|
|
|
14
14
|
logger.debug('Using Docker Compose V2.');
|
|
15
15
|
return DockerComposeV2;
|
|
16
16
|
} catch (e) {
|
|
17
|
+
// TODO: Log this error as well
|
|
17
18
|
try {
|
|
18
19
|
execSync('docker-compose -v').toString();
|
|
19
20
|
logger.warn('Using docker-compose V1. Please consider updating to V2.');
|
|
20
21
|
} catch (e) {
|
|
21
|
-
logger.warn(`Could not determine compose
|
|
22
|
+
logger.warn(`Could not determine compose!\n${stringifyError(e)}`);
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
dockerCmd = 'docker-compose';
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { getDeviceConfigPath } from 'alwaysai/lib/infrastructure';
|
|
2
|
+
import { join } from 'path';
|
|
1
3
|
import * as tempy from 'tempy';
|
|
2
|
-
import { AgentConfigFile } from './agent-config';
|
|
4
|
+
import { AGENT_CONFIG_FILE_NAME, AgentConfigFile } from './agent-config';
|
|
3
5
|
|
|
4
|
-
const configFile = AgentConfigFile(
|
|
6
|
+
const configFile = AgentConfigFile(
|
|
7
|
+
join(tempy.directory(), getDeviceConfigPath(), AGENT_CONFIG_FILE_NAME)
|
|
8
|
+
);
|
|
5
9
|
|
|
6
10
|
describe('Test Agent Config', () => {
|
|
7
11
|
beforeEach(() => {
|