@alwaysai/device-agent 0.0.13 → 0.0.15
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/backup.js +3 -3
- package/lib/application-control/backup.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 +1 -1
- package/lib/application-control/install.d.ts.map +1 -1
- package/lib/application-control/install.js +41 -54
- package/lib/application-control/install.js.map +1 -1
- package/lib/application-control/models.d.ts +0 -4
- package/lib/application-control/models.d.ts.map +1 -1
- package/lib/application-control/models.js +13 -22
- package/lib/application-control/models.js.map +1 -1
- package/lib/application-control/status.d.ts +0 -6
- package/lib/application-control/status.d.ts.map +1 -1
- package/lib/application-control/status.js +3 -19
- package/lib/application-control/status.js.map +1 -1
- package/lib/application-control/utils.d.ts +3 -0
- package/lib/application-control/utils.d.ts.map +1 -1
- package/lib/application-control/utils.js +50 -21
- package/lib/application-control/utils.js.map +1 -1
- package/lib/cloud-connection/bootstrap-provision.d.ts +1 -1
- package/lib/cloud-connection/bootstrap-provision.d.ts.map +1 -1
- package/lib/cloud-connection/bootstrap-provision.js +9 -9
- package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
- package/lib/cloud-connection/cmd-status.d.ts +8 -0
- package/lib/cloud-connection/cmd-status.d.ts.map +1 -0
- package/lib/cloud-connection/cmd-status.js +62 -0
- package/lib/cloud-connection/cmd-status.js.map +1 -0
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts +10 -2
- package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent-cloud-connection.js +156 -66
- package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
- package/lib/cloud-connection/device-agent.d.ts.map +1 -1
- package/lib/cloud-connection/device-agent.js +4 -3
- package/lib/cloud-connection/device-agent.js.map +1 -1
- package/lib/cloud-connection/live-updates-handler.d.ts +10 -18
- package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
- package/lib/cloud-connection/live-updates-handler.js +50 -50
- package/lib/cloud-connection/live-updates-handler.js.map +1 -1
- package/lib/cloud-connection/messages.d.ts +3 -1
- package/lib/cloud-connection/messages.d.ts.map +1 -1
- package/lib/cloud-connection/messages.js +13 -1
- package/lib/cloud-connection/messages.js.map +1 -1
- package/lib/cloud-connection/passthrough-handler.d.ts +11 -0
- package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -0
- package/lib/cloud-connection/passthrough-handler.js +59 -0
- package/lib/cloud-connection/passthrough-handler.js.map +1 -0
- package/lib/cloud-connection/publisher.d.ts +1 -0
- package/lib/cloud-connection/publisher.d.ts.map +1 -1
- package/lib/cloud-connection/publisher.js +14 -0
- package/lib/cloud-connection/publisher.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.d.ts +2 -3
- package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
- package/lib/cloud-connection/shadow-handler.js +18 -4
- package/lib/cloud-connection/shadow-handler.js.map +1 -1
- package/lib/cloud-connection/shadow-handler.test.d.ts +2 -0
- package/lib/cloud-connection/shadow-handler.test.d.ts.map +1 -0
- package/lib/cloud-connection/shadow-handler.test.js +321 -0
- package/lib/cloud-connection/shadow-handler.test.js.map +1 -0
- package/lib/environment.d.ts +1 -0
- package/lib/environment.d.ts.map +1 -1
- package/lib/environment.js +3 -2
- package/lib/environment.js.map +1 -1
- package/lib/index.js +2 -2
- package/lib/index.js.map +1 -1
- package/lib/infrastructure/agent-config.d.ts +15 -48
- package/lib/infrastructure/agent-config.d.ts.map +1 -1
- package/lib/infrastructure/agent-config.js.map +1 -1
- package/lib/infrastructure/agent-config.test.js +0 -6
- package/lib/infrastructure/agent-config.test.js.map +1 -1
- package/lib/infrastructure/system-id.js +2 -2
- package/lib/infrastructure/system-id.js.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
- package/lib/infrastructure/tokens-and-device-cfg.js +5 -9
- package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
- package/lib/local-connection/rabbitmq-connection.d.ts +4 -0
- package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -0
- package/lib/local-connection/rabbitmq-connection.js +58 -0
- package/lib/local-connection/rabbitmq-connection.js.map +1 -0
- package/lib/subcommands/app/app.d.ts +4 -3
- package/lib/subcommands/app/app.d.ts.map +1 -1
- package/lib/subcommands/app/app.js +78 -27
- package/lib/subcommands/app/app.js.map +1 -1
- package/lib/subcommands/app/index.js +2 -2
- package/lib/subcommands/device/clean.js +4 -4
- package/lib/subcommands/device/clean.js.map +1 -1
- package/lib/subcommands/device/device.d.ts +1 -1
- package/lib/subcommands/device/device.d.ts.map +1 -1
- package/lib/subcommands/device/device.js +9 -10
- package/lib/subcommands/device/device.js.map +1 -1
- package/lib/subcommands/index.d.ts +0 -1
- package/lib/subcommands/index.d.ts.map +1 -1
- package/lib/subcommands/login.d.ts +0 -1
- package/lib/subcommands/login.d.ts.map +1 -1
- package/lib/subcommands/login.js +1 -9
- package/lib/subcommands/login.js.map +1 -1
- package/lib/util/directories.d.ts +11 -12
- package/lib/util/directories.d.ts.map +1 -1
- package/lib/util/directories.js +24 -29
- package/lib/util/directories.js.map +1 -1
- package/lib/util/fetch-with-timeout.d.ts +4 -0
- package/lib/util/fetch-with-timeout.d.ts.map +1 -0
- package/lib/util/fetch-with-timeout.js +15 -0
- package/lib/util/fetch-with-timeout.js.map +1 -0
- package/lib/util/logger.js +1 -0
- package/lib/util/logger.js.map +1 -1
- package/lib/util/require-logged-in-and-paid-plan.d.ts +2 -0
- package/lib/util/require-logged-in-and-paid-plan.d.ts.map +1 -0
- package/lib/util/require-logged-in-and-paid-plan.js +18 -0
- package/lib/util/require-logged-in-and-paid-plan.js.map +1 -0
- package/package.json +20 -32
- package/readme.md +100 -89
- package/src/application-control/backup.ts +3 -3
- package/src/application-control/index.ts +0 -6
- package/src/application-control/install.ts +53 -73
- package/src/application-control/models.ts +7 -19
- package/src/application-control/status.ts +3 -19
- package/src/application-control/utils.ts +61 -22
- package/src/cloud-connection/bootstrap-provision.ts +13 -10
- package/src/cloud-connection/cmd-status.ts +71 -0
- package/src/cloud-connection/device-agent-cloud-connection.ts +211 -102
- package/src/cloud-connection/device-agent.ts +7 -4
- package/src/cloud-connection/live-updates-handler.ts +79 -86
- package/src/cloud-connection/messages.ts +22 -1
- package/src/cloud-connection/passthrough-handler.ts +67 -0
- package/src/cloud-connection/publisher.ts +21 -0
- package/src/cloud-connection/shadow-handler.test.ts +361 -0
- package/src/cloud-connection/shadow-handler.ts +28 -7
- package/src/environment.ts +4 -1
- package/src/index.ts +2 -2
- package/src/infrastructure/agent-config.test.ts +0 -7
- package/src/infrastructure/agent-config.ts +24 -2
- package/src/infrastructure/system-id.ts +1 -1
- package/src/infrastructure/tokens-and-device-cfg.ts +8 -13
- package/src/local-connection/rabbitmq-connection.ts +53 -0
- package/src/subcommands/app/app.ts +82 -31
- package/src/subcommands/app/index.ts +4 -4
- package/src/subcommands/device/clean.ts +4 -4
- package/src/subcommands/device/device.ts +13 -13
- package/src/subcommands/login.ts +1 -9
- package/src/util/directories.ts +31 -29
- package/src/util/fetch-with-timeout.ts +18 -0
- package/src/util/logger.ts +2 -0
- package/src/util/require-logged-in-and-paid-plan.ts +16 -0
- package/lib/cloud-connection/app-install-status.d.ts +0 -16
- package/lib/cloud-connection/app-install-status.d.ts.map +0 -1
- package/lib/cloud-connection/app-install-status.js +0 -53
- package/lib/cloud-connection/app-install-status.js.map +0 -1
- package/src/cloud-connection/app-install-status.ts +0 -62
|
@@ -1,15 +1,24 @@
|
|
|
1
1
|
import compose from 'docker-compose';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import * as fs from 'fs';
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
DOCKER_COMPOSE_FILE,
|
|
6
|
+
TARGET_JSON_FILE_NAME
|
|
7
|
+
} from 'alwaysai/lib/constants';
|
|
5
8
|
|
|
6
9
|
import { AgentConfigFile } from '../infrastructure/agent-config';
|
|
7
|
-
import
|
|
8
|
-
import {
|
|
9
|
-
|
|
10
|
+
import { fetchWithTimeout } from '../util/fetch-with-timeout';
|
|
11
|
+
import {
|
|
12
|
+
getDockerComposeCmdForApp,
|
|
13
|
+
TargetJsonFile,
|
|
14
|
+
updateDockerComposeTargetHw,
|
|
15
|
+
writeDockerComposeFile,
|
|
16
|
+
writeStandaloneDockerfile
|
|
17
|
+
} from 'alwaysai/lib/core/app';
|
|
10
18
|
import { runInDir } from '../util/run-in-dir';
|
|
11
19
|
import { logger } from '../util/logger';
|
|
12
20
|
import { APP_ROOT } from '../util/directories';
|
|
21
|
+
import { JsSpawner } from 'alwaysai/lib/util/spawner';
|
|
13
22
|
|
|
14
23
|
export function getAppDir(projectId: string): string {
|
|
15
24
|
return path.join(APP_ROOT, projectId);
|
|
@@ -21,6 +30,11 @@ export async function requireAppInstalled(props: { projectId: string }) {
|
|
|
21
30
|
if (!(await AgentConfigFile().isAppPresent({ projectId }))) {
|
|
22
31
|
throw new Error('Application is not installed');
|
|
23
32
|
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export async function requireAppReady(props: { projectId: string }) {
|
|
36
|
+
const { projectId } = props;
|
|
37
|
+
await requireAppInstalled({ projectId });
|
|
24
38
|
if (!(await AgentConfigFile().isAppReady({ projectId }))) {
|
|
25
39
|
throw new Error('Application is not done installing or updating');
|
|
26
40
|
}
|
|
@@ -30,23 +44,28 @@ export async function buildApp(props: { appDir: string }) {
|
|
|
30
44
|
const { appDir } = props;
|
|
31
45
|
|
|
32
46
|
// Build standalone image and docker-compose
|
|
33
|
-
const
|
|
34
|
-
const
|
|
35
|
-
if (
|
|
47
|
+
const targetJsonFile = TargetJsonFile(appDir);
|
|
48
|
+
const targetCfg = targetJsonFile.read();
|
|
49
|
+
if (targetCfg.targetProtocol !== 'docker:') {
|
|
36
50
|
throw new Error(`${TARGET_JSON_FILE_NAME} is not properly configured!`);
|
|
37
51
|
}
|
|
38
52
|
await runInDir(
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
53
|
+
async () => {
|
|
54
|
+
await writeStandaloneDockerfile();
|
|
55
|
+
const spawner = JsSpawner();
|
|
56
|
+
const targetHardware = targetCfg.targetHardware;
|
|
57
|
+
if (await spawner.exists(DOCKER_COMPOSE_FILE)) {
|
|
58
|
+
await updateDockerComposeTargetHw({
|
|
59
|
+
targetHardware
|
|
60
|
+
});
|
|
61
|
+
} else {
|
|
62
|
+
await writeDockerComposeFile({
|
|
63
|
+
spawner: JsSpawner(),
|
|
64
|
+
cmd: await getDockerComposeCmdForApp({ targetHardware })
|
|
65
|
+
});
|
|
48
66
|
}
|
|
49
|
-
|
|
67
|
+
},
|
|
68
|
+
[],
|
|
50
69
|
appDir
|
|
51
70
|
);
|
|
52
71
|
|
|
@@ -59,17 +78,37 @@ export async function buildApp(props: { appDir: string }) {
|
|
|
59
78
|
}
|
|
60
79
|
}
|
|
61
80
|
|
|
81
|
+
class HTTPResponseError extends Error {
|
|
82
|
+
public response;
|
|
83
|
+
constructor(response) {
|
|
84
|
+
super(`HTTP Error Response: ${response.status} ${response.statusText}`);
|
|
85
|
+
this.response = response;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const checkStatus = (response) => {
|
|
90
|
+
if (response.ok) {
|
|
91
|
+
// response.status >= 200 && response.status < 300
|
|
92
|
+
return response;
|
|
93
|
+
} else {
|
|
94
|
+
throw new HTTPResponseError(response);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
|
|
62
98
|
export async function downloadPackageUsingPresignedUrl(props: {
|
|
63
99
|
localDest: string;
|
|
64
100
|
presignedUrl: string;
|
|
65
101
|
}): Promise<void> {
|
|
66
102
|
const { localDest, presignedUrl } = props;
|
|
67
|
-
logger.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
103
|
+
logger.debug(`Downloading package from ${presignedUrl}`);
|
|
104
|
+
let response: any;
|
|
105
|
+
try {
|
|
106
|
+
response = await fetchWithTimeout(presignedUrl);
|
|
107
|
+
} catch (error) {
|
|
108
|
+
const errorBody =
|
|
109
|
+
error.type === 'aborted' ? error : await error.response.text();
|
|
71
110
|
throw new Error(
|
|
72
|
-
`
|
|
111
|
+
`downloadPackageUsingPresignedUrl: Error=${error}\n${errorBody}`
|
|
73
112
|
);
|
|
74
113
|
}
|
|
75
114
|
|
|
@@ -1,28 +1,28 @@
|
|
|
1
|
-
import { logger } from 'alwaysai/lib/util';
|
|
2
1
|
import { getIoTCoreEndpointUrl } from '../infrastructure/urls';
|
|
3
2
|
import { rmBootstrapCertsAndClose } from '../util/clean-certs';
|
|
4
3
|
import {
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
BOOTSTRAP_PRIVATE_KEY_FILE_PATH,
|
|
5
|
+
BOOTSTRAP_CERTIFICATE_FILE_PATH,
|
|
7
6
|
AWS_ROOT_CERTIFICATE_FILE_PATH
|
|
8
7
|
} from '../util/directories';
|
|
9
8
|
import { getDeviceUuid } from '../util/get-device-id';
|
|
9
|
+
import { logger } from '../util/logger';
|
|
10
10
|
import { BootstrapAgent } from './device-agent';
|
|
11
11
|
|
|
12
|
-
export function bootstrapProvision() {
|
|
12
|
+
export async function bootstrapProvision() {
|
|
13
13
|
setTimeout(rmBootstrapCertsAndClose, 60000);
|
|
14
14
|
|
|
15
15
|
const clientId = getDeviceUuid();
|
|
16
16
|
const bootstrapConfig = {
|
|
17
|
-
keyPath:
|
|
18
|
-
certPath:
|
|
17
|
+
keyPath: BOOTSTRAP_PRIVATE_KEY_FILE_PATH(),
|
|
18
|
+
certPath: BOOTSTRAP_CERTIFICATE_FILE_PATH(),
|
|
19
19
|
caPath: AWS_ROOT_CERTIFICATE_FILE_PATH,
|
|
20
20
|
clientId,
|
|
21
21
|
host: getIoTCoreEndpointUrl()
|
|
22
22
|
};
|
|
23
23
|
|
|
24
24
|
const bootstrapAgent = new BootstrapAgent(bootstrapConfig);
|
|
25
|
-
bootstrapAgent.subscribeToAllTopics();
|
|
25
|
+
await bootstrapAgent.subscribeToAllTopics();
|
|
26
26
|
|
|
27
27
|
bootstrapAgent.publishMessage('$aws/certificates/create/json', '');
|
|
28
28
|
|
|
@@ -30,9 +30,12 @@ export function bootstrapProvision() {
|
|
|
30
30
|
logger.info('Your device is being provisioned');
|
|
31
31
|
});
|
|
32
32
|
|
|
33
|
-
bootstrapAgent.device.on(
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
bootstrapAgent.device.on(
|
|
34
|
+
'message',
|
|
35
|
+
async (topic: string, payload: string) => {
|
|
36
|
+
await bootstrapAgent.handleAwsCertificateTopics(topic, payload);
|
|
37
|
+
}
|
|
38
|
+
);
|
|
36
39
|
|
|
37
40
|
bootstrapAgent.device.on('packetsend', (packet: any) => {
|
|
38
41
|
logger.debug(`Sending packet: ${JSON.stringify({ packet }, null, 2)}`);
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { logger } from '../util/logger';
|
|
2
|
+
|
|
3
|
+
type CmdStatusType = 'idle' | 'in_progress';
|
|
4
|
+
|
|
5
|
+
class CmdStatus {
|
|
6
|
+
private projectId: string;
|
|
7
|
+
private status: CmdStatusType;
|
|
8
|
+
|
|
9
|
+
constructor(projectId: string, status: CmdStatusType) {
|
|
10
|
+
this.projectId = projectId;
|
|
11
|
+
this.status = status;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public getProjectId() {
|
|
15
|
+
return this.projectId;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
public update(status: CmdStatusType) {
|
|
19
|
+
this.status = status;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
public getStatus(): CmdStatusType {
|
|
23
|
+
return this.status;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export class CmdStatusManager {
|
|
28
|
+
private apps: { [projectId: string]: CmdStatus } = {};
|
|
29
|
+
|
|
30
|
+
public async start(projectId: string) {
|
|
31
|
+
if (!(projectId in this.apps)) {
|
|
32
|
+
const cmdStatus = new CmdStatus(projectId, 'in_progress');
|
|
33
|
+
this.apps[projectId] = cmdStatus;
|
|
34
|
+
} else if (this.apps[projectId].getStatus() !== 'in_progress') {
|
|
35
|
+
this.apps[projectId].update('in_progress');
|
|
36
|
+
} else {
|
|
37
|
+
logger.debug(
|
|
38
|
+
`Ignoring start for ${projectId} since it already has a command in progress`
|
|
39
|
+
);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
logger.debug(`Started command for ${projectId}`);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
public async stop(projectId: string) {
|
|
46
|
+
if (
|
|
47
|
+
!(projectId in this.apps) ||
|
|
48
|
+
this.apps[projectId].getStatus() === 'idle'
|
|
49
|
+
) {
|
|
50
|
+
throw new Error(`No ongoing command to stop for ${projectId}`);
|
|
51
|
+
}
|
|
52
|
+
this.apps[projectId].update('idle');
|
|
53
|
+
logger.debug(`Stopped command for ${projectId}`);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
public isCmdInProgress(projectId: string): boolean {
|
|
57
|
+
if (!(projectId in this.apps)) {
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
return this.apps[projectId].getStatus() === 'in_progress';
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
public anyCmdInProgress() {
|
|
64
|
+
for (const projectId in this.apps) {
|
|
65
|
+
if (this.apps[projectId].getStatus() === 'in_progress') {
|
|
66
|
+
return true;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
}
|