@alwaysai/device-agent 1.4.0 → 2.0.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.
Files changed (313) hide show
  1. package/lib/application-control/config.d.ts.map +1 -1
  2. package/lib/application-control/config.js +10 -5
  3. package/lib/application-control/config.js.map +1 -1
  4. package/lib/application-control/environment-variables.d.ts +1 -5
  5. package/lib/application-control/environment-variables.d.ts.map +1 -1
  6. package/lib/application-control/environment-variables.js +9 -26
  7. package/lib/application-control/environment-variables.js.map +1 -1
  8. package/lib/application-control/environment-variables.test.js +27 -7
  9. package/lib/application-control/environment-variables.test.js.map +1 -1
  10. package/lib/application-control/index.d.ts +4 -4
  11. package/lib/application-control/index.d.ts.map +1 -1
  12. package/lib/application-control/index.js +1 -4
  13. package/lib/application-control/index.js.map +1 -1
  14. package/lib/application-control/install.d.ts.map +1 -1
  15. package/lib/application-control/install.js +9 -7
  16. package/lib/application-control/install.js.map +1 -1
  17. package/lib/application-control/models.d.ts +5 -11
  18. package/lib/application-control/models.d.ts.map +1 -1
  19. package/lib/application-control/models.js +27 -64
  20. package/lib/application-control/models.js.map +1 -1
  21. package/lib/application-control/status.d.ts.map +1 -1
  22. package/lib/application-control/status.js +10 -12
  23. package/lib/application-control/status.js.map +1 -1
  24. package/lib/application-control/utils.d.ts +0 -4
  25. package/lib/application-control/utils.d.ts.map +1 -1
  26. package/lib/application-control/utils.js +3 -26
  27. package/lib/application-control/utils.js.map +1 -1
  28. package/lib/cloud-connection/bootstrap-provision.js +3 -2
  29. package/lib/cloud-connection/bootstrap-provision.js.map +1 -1
  30. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +11 -16
  31. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  32. package/lib/cloud-connection/device-agent-cloud-connection.js +295 -246
  33. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  34. package/lib/cloud-connection/device-agent.d.ts.map +1 -1
  35. package/lib/cloud-connection/device-agent.js +11 -9
  36. package/lib/cloud-connection/device-agent.js.map +1 -1
  37. package/lib/cloud-connection/live-updates-handler.d.ts +18 -27
  38. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -1
  39. package/lib/cloud-connection/live-updates-handler.js +58 -170
  40. package/lib/cloud-connection/live-updates-handler.js.map +1 -1
  41. package/lib/cloud-connection/live-updates-handler.test.js +76 -54
  42. package/lib/cloud-connection/live-updates-handler.test.js.map +1 -1
  43. package/lib/cloud-connection/passthrough-handler.d.ts +9 -4
  44. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -1
  45. package/lib/cloud-connection/passthrough-handler.js +95 -62
  46. package/lib/cloud-connection/passthrough-handler.js.map +1 -1
  47. package/lib/cloud-connection/shadow-handler.d.ts +5 -1
  48. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -1
  49. package/lib/cloud-connection/shadow-handler.js +63 -31
  50. package/lib/cloud-connection/shadow-handler.js.map +1 -1
  51. package/lib/cloud-connection/shadow-handler.test.js +45 -57
  52. package/lib/cloud-connection/shadow-handler.test.js.map +1 -1
  53. package/lib/cloud-connection/shadow.d.ts.map +1 -1
  54. package/lib/cloud-connection/shadow.js +2 -1
  55. package/lib/cloud-connection/shadow.js.map +1 -1
  56. package/lib/cloud-connection/transaction-manager.d.ts +7 -2
  57. package/lib/cloud-connection/transaction-manager.d.ts.map +1 -1
  58. package/lib/cloud-connection/transaction-manager.js +29 -29
  59. package/lib/cloud-connection/transaction-manager.js.map +1 -1
  60. package/lib/cloud-connection/transaction-manager.test.js +105 -3
  61. package/lib/cloud-connection/transaction-manager.test.js.map +1 -1
  62. package/lib/device-control/device-control.d.ts +14 -6
  63. package/lib/device-control/device-control.d.ts.map +1 -1
  64. package/lib/device-control/device-control.js +172 -72
  65. package/lib/device-control/device-control.js.map +1 -1
  66. package/lib/docker/docker-compose.d.ts +14 -0
  67. package/lib/docker/docker-compose.d.ts.map +1 -0
  68. package/lib/docker/docker-compose.js +57 -0
  69. package/lib/docker/docker-compose.js.map +1 -0
  70. package/lib/index.js +2 -5
  71. package/lib/index.js.map +1 -1
  72. package/lib/infrastructure/agent-config.d.ts +46 -14
  73. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  74. package/lib/infrastructure/agent-config.js +36 -21
  75. package/lib/infrastructure/agent-config.js.map +1 -1
  76. package/lib/infrastructure/agent-config.test.js +6 -1
  77. package/lib/infrastructure/agent-config.test.js.map +1 -1
  78. package/lib/infrastructure/config-check-utility.d.ts +6 -0
  79. package/lib/infrastructure/config-check-utility.d.ts.map +1 -0
  80. package/lib/infrastructure/config-check-utility.js +67 -0
  81. package/lib/infrastructure/config-check-utility.js.map +1 -0
  82. package/lib/infrastructure/config-check-utility.test.d.ts +2 -0
  83. package/lib/infrastructure/config-check-utility.test.d.ts.map +1 -0
  84. package/lib/infrastructure/config-check-utility.test.js +109 -0
  85. package/lib/infrastructure/config-check-utility.test.js.map +1 -0
  86. package/lib/infrastructure/device-certificate.d.ts +10 -0
  87. package/lib/infrastructure/device-certificate.d.ts.map +1 -0
  88. package/lib/infrastructure/device-certificate.js +47 -0
  89. package/lib/infrastructure/device-certificate.js.map +1 -0
  90. package/lib/infrastructure/device-certificate.test.d.ts +2 -0
  91. package/lib/infrastructure/device-certificate.test.d.ts.map +1 -0
  92. package/lib/infrastructure/device-certificate.test.js +24 -0
  93. package/lib/infrastructure/device-certificate.test.js.map +1 -0
  94. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts +2 -0
  95. package/lib/infrastructure/legacy-migration/legacy-file.test.d.ts.map +1 -0
  96. package/lib/infrastructure/legacy-migration/legacy-file.test.js +61 -0
  97. package/lib/infrastructure/legacy-migration/legacy-file.test.js.map +1 -0
  98. package/lib/infrastructure/legacy-migration/legacy-files.d.ts +75 -0
  99. package/lib/infrastructure/legacy-migration/legacy-files.d.ts.map +1 -0
  100. package/lib/infrastructure/legacy-migration/legacy-files.js +75 -0
  101. package/lib/infrastructure/legacy-migration/legacy-files.js.map +1 -0
  102. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts +6 -0
  103. package/lib/infrastructure/legacy-migration/legacy-migration.d.ts.map +1 -0
  104. package/lib/infrastructure/legacy-migration/legacy-migration.js +149 -0
  105. package/lib/infrastructure/legacy-migration/legacy-migration.js.map +1 -0
  106. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts +2 -0
  107. package/lib/infrastructure/legacy-migration/legacy-migration.test.d.ts.map +1 -0
  108. package/lib/infrastructure/legacy-migration/legacy-migration.test.js +226 -0
  109. package/lib/infrastructure/legacy-migration/legacy-migration.test.js.map +1 -0
  110. package/lib/infrastructure/require-files-present-ready.test.d.ts +2 -0
  111. package/lib/infrastructure/require-files-present-ready.test.d.ts.map +1 -0
  112. package/lib/infrastructure/require-files-present-ready.test.js +44 -0
  113. package/lib/infrastructure/require-files-present-ready.test.js.map +1 -0
  114. package/lib/infrastructure/required-config-checks.d.ts +2 -0
  115. package/lib/infrastructure/required-config-checks.d.ts.map +1 -0
  116. package/lib/infrastructure/required-config-checks.js +30 -0
  117. package/lib/infrastructure/required-config-checks.js.map +1 -0
  118. package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -1
  119. package/lib/infrastructure/tokens-and-device-cfg.js +11 -8
  120. package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -1
  121. package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -1
  122. package/lib/local-connection/rabbitmq-connection.js +21 -21
  123. package/lib/local-connection/rabbitmq-connection.js.map +1 -1
  124. package/lib/secure-tunneling/secure-tunneling.d.ts +15 -23
  125. package/lib/secure-tunneling/secure-tunneling.d.ts.map +1 -1
  126. package/lib/secure-tunneling/secure-tunneling.js +52 -47
  127. package/lib/secure-tunneling/secure-tunneling.js.map +1 -1
  128. package/lib/secure-tunneling/secure-tunneling.test.js +29 -31
  129. package/lib/secure-tunneling/secure-tunneling.test.js.map +1 -1
  130. package/lib/subcommands/app/analytics.d.ts.map +1 -1
  131. package/lib/subcommands/app/analytics.js +1 -2
  132. package/lib/subcommands/app/analytics.js.map +1 -1
  133. package/lib/subcommands/app/env-vars.d.ts +4 -0
  134. package/lib/subcommands/app/env-vars.d.ts.map +1 -1
  135. package/lib/subcommands/app/env-vars.js +52 -6
  136. package/lib/subcommands/app/env-vars.js.map +1 -1
  137. package/lib/subcommands/app/index.d.ts.map +1 -1
  138. package/lib/subcommands/app/index.js +1 -3
  139. package/lib/subcommands/app/index.js.map +1 -1
  140. package/lib/subcommands/app/models.d.ts +0 -11
  141. package/lib/subcommands/app/models.d.ts.map +1 -1
  142. package/lib/subcommands/app/models.js +2 -58
  143. package/lib/subcommands/app/models.js.map +1 -1
  144. package/lib/subcommands/app/shadow.d.ts.map +1 -1
  145. package/lib/subcommands/app/shadow.js +6 -5
  146. package/lib/subcommands/app/shadow.js.map +1 -1
  147. package/lib/subcommands/app/version.d.ts.map +1 -1
  148. package/lib/subcommands/app/version.js +2 -4
  149. package/lib/subcommands/app/version.js.map +1 -1
  150. package/lib/subcommands/config.d.ts +2 -0
  151. package/lib/subcommands/config.d.ts.map +1 -0
  152. package/lib/subcommands/config.js +39 -0
  153. package/lib/subcommands/config.js.map +1 -0
  154. package/lib/subcommands/device/clean.d.ts +1 -1
  155. package/lib/subcommands/device/clean.d.ts.map +1 -1
  156. package/lib/subcommands/device/clean.js +25 -15
  157. package/lib/subcommands/device/clean.js.map +1 -1
  158. package/lib/subcommands/device/get-info.d.ts +2 -0
  159. package/lib/subcommands/device/get-info.d.ts.map +1 -0
  160. package/lib/subcommands/device/get-info.js +36 -0
  161. package/lib/subcommands/device/get-info.js.map +1 -0
  162. package/lib/subcommands/device/index.d.ts.map +1 -1
  163. package/lib/subcommands/device/index.js +13 -2
  164. package/lib/subcommands/device/index.js.map +1 -1
  165. package/lib/subcommands/device/init.d.ts +5 -0
  166. package/lib/subcommands/device/init.d.ts.map +1 -0
  167. package/lib/subcommands/device/{device.js → init.js} +10 -49
  168. package/lib/subcommands/device/init.js.map +1 -0
  169. package/lib/subcommands/device/migrate.d.ts +2 -0
  170. package/lib/subcommands/device/migrate.d.ts.map +1 -0
  171. package/lib/subcommands/device/migrate.js +24 -0
  172. package/lib/subcommands/device/migrate.js.map +1 -0
  173. package/lib/subcommands/device/refresh.d.ts +2 -0
  174. package/lib/subcommands/device/refresh.d.ts.map +1 -0
  175. package/lib/subcommands/device/refresh.js +25 -0
  176. package/lib/subcommands/device/refresh.js.map +1 -0
  177. package/lib/subcommands/device/restart.d.ts +2 -0
  178. package/lib/subcommands/device/restart.d.ts.map +1 -0
  179. package/lib/subcommands/device/restart.js +14 -0
  180. package/lib/subcommands/device/restart.js.map +1 -0
  181. package/lib/subcommands/index.d.ts +1 -1
  182. package/lib/subcommands/index.d.ts.map +1 -1
  183. package/lib/subcommands/index.js +3 -1
  184. package/lib/subcommands/index.js.map +1 -1
  185. package/lib/subcommands/rabbitmq-connection.d.ts +1 -1
  186. package/lib/subcommands/rabbitmq-connection.d.ts.map +1 -1
  187. package/lib/util/aai-error.d.ts +12 -0
  188. package/lib/util/aai-error.d.ts.map +1 -0
  189. package/lib/util/aai-error.js +11 -0
  190. package/lib/util/aai-error.js.map +1 -0
  191. package/lib/util/aws-regions.d.ts +2 -0
  192. package/lib/util/aws-regions.d.ts.map +1 -0
  193. package/lib/util/{cloud-mode-ready.js → aws-regions.js} +2 -20
  194. package/lib/util/aws-regions.js.map +1 -0
  195. package/lib/util/check-for-updates.d.ts +3 -0
  196. package/lib/util/check-for-updates.d.ts.map +1 -0
  197. package/lib/util/check-for-updates.js +46 -0
  198. package/lib/util/check-for-updates.js.map +1 -0
  199. package/lib/util/clean-certs.d.ts.map +1 -1
  200. package/lib/util/clean-certs.js +5 -4
  201. package/lib/util/clean-certs.js.map +1 -1
  202. package/lib/util/directories.d.ts +4 -18
  203. package/lib/util/directories.d.ts.map +1 -1
  204. package/lib/util/directories.js +18 -32
  205. package/lib/util/directories.js.map +1 -1
  206. package/lib/util/file.d.ts +11 -0
  207. package/lib/util/file.d.ts.map +1 -0
  208. package/lib/util/file.js +127 -0
  209. package/lib/util/file.js.map +1 -0
  210. package/lib/util/file.test.d.ts +2 -0
  211. package/lib/util/file.test.d.ts.map +1 -0
  212. package/lib/util/file.test.js +87 -0
  213. package/lib/util/file.test.js.map +1 -0
  214. package/lib/util/get-device-id.d.ts.map +1 -1
  215. package/lib/util/get-device-id.js +7 -1
  216. package/lib/util/get-device-id.js.map +1 -1
  217. package/lib/util/http-client.js +3 -3
  218. package/lib/util/http-client.js.map +1 -1
  219. package/package.json +22 -19
  220. package/readme.md +15 -35
  221. package/src/application-control/config.ts +10 -13
  222. package/src/application-control/environment-variables.test.ts +28 -7
  223. package/src/application-control/environment-variables.ts +13 -40
  224. package/src/application-control/index.ts +3 -16
  225. package/src/application-control/install.ts +16 -10
  226. package/src/application-control/models.ts +40 -98
  227. package/src/application-control/status.ts +9 -7
  228. package/src/application-control/utils.ts +1 -29
  229. package/src/cloud-connection/bootstrap-provision.ts +7 -7
  230. package/src/cloud-connection/device-agent-cloud-connection.ts +647 -509
  231. package/src/cloud-connection/device-agent.ts +16 -7
  232. package/src/cloud-connection/live-updates-handler.test.ts +137 -64
  233. package/src/cloud-connection/live-updates-handler.ts +103 -234
  234. package/src/cloud-connection/passthrough-handler.ts +134 -75
  235. package/src/cloud-connection/shadow-handler.test.ts +45 -57
  236. package/src/cloud-connection/shadow-handler.ts +114 -56
  237. package/src/cloud-connection/shadow.ts +4 -1
  238. package/src/cloud-connection/transaction-manager.test.ts +127 -3
  239. package/src/cloud-connection/transaction-manager.ts +68 -39
  240. package/src/device-control/device-control.ts +179 -72
  241. package/src/docker/docker-compose.ts +61 -0
  242. package/src/index.ts +2 -6
  243. package/src/infrastructure/agent-config.test.ts +9 -2
  244. package/src/infrastructure/agent-config.ts +45 -46
  245. package/src/infrastructure/config-check-utility.test.ts +154 -0
  246. package/src/infrastructure/config-check-utility.ts +77 -0
  247. package/src/infrastructure/device-certificate.test.ts +40 -0
  248. package/src/infrastructure/device-certificate.ts +58 -0
  249. package/src/infrastructure/legacy-migration/legacy-file.test.ts +88 -0
  250. package/src/infrastructure/legacy-migration/legacy-files.ts +101 -0
  251. package/src/infrastructure/legacy-migration/legacy-migration.test.ts +396 -0
  252. package/src/infrastructure/legacy-migration/legacy-migration.ts +229 -0
  253. package/src/infrastructure/require-files-present-ready.test.ts +53 -0
  254. package/src/infrastructure/required-config-checks.ts +33 -0
  255. package/src/infrastructure/tokens-and-device-cfg.ts +12 -10
  256. package/src/local-connection/rabbitmq-connection.ts +28 -23
  257. package/src/secure-tunneling/secure-tunneling.test.ts +37 -39
  258. package/src/secure-tunneling/secure-tunneling.ts +74 -69
  259. package/src/subcommands/app/analytics.ts +2 -4
  260. package/src/subcommands/app/env-vars.ts +72 -9
  261. package/src/subcommands/app/index.ts +3 -11
  262. package/src/subcommands/app/models.ts +5 -81
  263. package/src/subcommands/app/shadow.ts +6 -5
  264. package/src/subcommands/app/version.ts +3 -4
  265. package/src/subcommands/config.ts +42 -0
  266. package/src/subcommands/device/clean.ts +32 -18
  267. package/src/subcommands/device/get-info.ts +49 -0
  268. package/src/subcommands/device/index.ts +13 -2
  269. package/src/subcommands/device/{device.ts → init.ts} +11 -69
  270. package/src/subcommands/device/migrate.ts +20 -0
  271. package/src/subcommands/device/refresh.ts +23 -0
  272. package/src/subcommands/device/restart.ts +11 -0
  273. package/src/subcommands/index.ts +3 -1
  274. package/src/util/aai-error.ts +20 -0
  275. package/src/util/{cloud-mode-ready.ts → aws-regions.ts} +0 -24
  276. package/src/util/check-for-updates.ts +53 -0
  277. package/src/util/clean-certs.ts +8 -4
  278. package/src/util/directories.ts +23 -67
  279. package/src/util/file.test.ts +90 -0
  280. package/src/util/file.ts +156 -0
  281. package/src/util/get-device-id.ts +7 -7
  282. package/src/util/http-client.ts +2 -2
  283. package/lib/docker/docker-compose-cmd.d.ts +0 -5
  284. package/lib/docker/docker-compose-cmd.d.ts.map +0 -1
  285. package/lib/docker/docker-compose-cmd.js +0 -16
  286. package/lib/docker/docker-compose-cmd.js.map +0 -1
  287. package/lib/subcommands/device/device.d.ts +0 -7
  288. package/lib/subcommands/device/device.d.ts.map +0 -1
  289. package/lib/subcommands/device/device.js.map +0 -1
  290. package/lib/util/cloud-mode-ready.d.ts +0 -3
  291. package/lib/util/cloud-mode-ready.d.ts.map +0 -1
  292. package/lib/util/cloud-mode-ready.js.map +0 -1
  293. package/lib/util/download-file.d.ts +0 -6
  294. package/lib/util/download-file.d.ts.map +0 -1
  295. package/lib/util/download-file.js +0 -25
  296. package/lib/util/download-file.js.map +0 -1
  297. package/lib/util/fetch-with-timeout.d.ts +0 -4
  298. package/lib/util/fetch-with-timeout.d.ts.map +0 -1
  299. package/lib/util/fetch-with-timeout.js +0 -30
  300. package/lib/util/fetch-with-timeout.js.map +0 -1
  301. package/lib/util/parsing.d.ts +0 -2
  302. package/lib/util/parsing.d.ts.map +0 -1
  303. package/lib/util/parsing.js +0 -17
  304. package/lib/util/parsing.js.map +0 -1
  305. package/lib/util/safe-rimraf.d.ts +0 -2
  306. package/lib/util/safe-rimraf.d.ts.map +0 -1
  307. package/lib/util/safe-rimraf.js +0 -16
  308. package/lib/util/safe-rimraf.js.map +0 -1
  309. package/src/docker/docker-compose-cmd.ts +0 -15
  310. package/src/util/download-file.ts +0 -25
  311. package/src/util/fetch-with-timeout.ts +0 -35
  312. package/src/util/parsing.ts +0 -11
  313. package/src/util/safe-rimraf.ts +0 -14
@@ -1,49 +1,42 @@
1
+ import {
2
+ SecureTunnelPortInfo,
3
+ SecureTunnelShadowUpdate
4
+ } from '@alwaysai/device-agent-schemas';
1
5
  import { AAI_DIR } from 'alwaysai/lib/paths';
2
- import { JsSpawner } from 'alwaysai/lib/util';
6
+ import { JsSpawner, stringifyError } from 'alwaysai/lib/util';
3
7
  import { ChildProcess } from 'child_process';
4
8
  import { join } from 'path';
5
9
  import { aaiArtifactsBucketUrl } from '../urls';
6
- import { isValidAwsRegion } from '../util/cloud-mode-ready';
10
+ import { isValidAwsRegion } from '../util/aws-regions';
7
11
  import {
8
12
  AWS_ROOT_CERTIFICATE_FILE_PATH,
9
13
  SECURE_TUNNEL_BIN_DIR,
10
14
  SECURE_TUNNEL_BIN_NAME,
11
15
  SECURE_TUNNEL_BIN_PATH
12
16
  } from '../util/directories';
13
- import { downloadFile } from '../util/download-file';
14
17
  import { logger } from '../util/logger';
15
18
  import { getArch, getDistribution, getOsVersion } from '../util/system-info';
16
19
  import { killDetachedProcess, runDetachedProcess } from './spawner-detached';
20
+ import { downloadToFile } from '../util/file';
17
21
 
18
22
  enum SecureTunnelServiceType {
19
23
  SSH = 'SSH',
20
24
  HTTP = 'HTTP'
21
25
  }
22
26
 
23
- export type SecureTunnelPortInfo = {
24
- enabled: boolean;
25
- type: string;
26
- ip: string;
27
- port: number;
28
- };
29
-
30
- export type SecureTunnelShadowDesRep = {
31
- st_ports: SecureTunnelPortInfo[];
32
- };
33
-
34
27
  export type SecureTunnelShadowState = {
35
- reported?: SecureTunnelShadowDesRep;
36
- desired?: SecureTunnelShadowDesRep;
28
+ reported?: SecureTunnelShadowUpdate;
29
+ desired?: SecureTunnelShadowUpdate;
37
30
  };
38
31
 
39
32
  export type SecureTunnelShadowUpdateDelta = {
40
33
  version: number;
41
34
  timestamp: number;
42
- state: SecureTunnelShadowDesRep;
35
+ state: SecureTunnelShadowUpdate;
43
36
  metadata?: any;
44
37
  };
45
38
 
46
- export type SecureTunnelShadowUpdate = {
39
+ export type SecureTunnelShadow = {
47
40
  version: number;
48
41
  state: SecureTunnelShadowState;
49
42
  };
@@ -54,7 +47,7 @@ type SecureTunnelProxyMap = {
54
47
  mapProcess: ChildProcess;
55
48
  };
56
49
 
57
- type SecureTunnelLocalproxyInfo = {
50
+ type SecureTunnelLocalProxyInfo = {
58
51
  lpDstAccessKey: string;
59
52
  lpRegion: string;
60
53
  lpServices: string;
@@ -83,9 +76,9 @@ const ST_START_PORT_NUMBER = 5010;
83
76
  */
84
77
  export class SecureTunnelHandlerSingleton {
85
78
  private static instance: SecureTunnelHandlerSingleton;
86
- private reported: SecureTunnelShadowDesRep;
79
+ private reported: SecureTunnelShadowUpdate;
87
80
  private httpProxyMap: SecureTunnelProxyMap[];
88
- private localproxyInfo: SecureTunnelLocalproxyInfo;
81
+ private localProxyInfo: SecureTunnelLocalProxyInfo;
89
82
 
90
83
  /**
91
84
  * Initializes private variables of SecureTunnel handler.
@@ -97,7 +90,7 @@ export class SecureTunnelHandlerSingleton {
97
90
  st_ports: [JSON.parse(JSON.stringify(defaultSecureTunnelPortInfo))]
98
91
  };
99
92
  this.httpProxyMap = [];
100
- this.localproxyInfo = {
93
+ this.localProxyInfo = {
101
94
  lpDstAccessKey: '',
102
95
  lpRegion: '',
103
96
  lpServices: '',
@@ -147,15 +140,15 @@ export class SecureTunnelHandlerSingleton {
147
140
  };
148
141
  logger.debug(`httpProxyMap after : ${JSON.stringify(this.httpProxyMap)}`);
149
142
  logger.debug(`reported after : ${JSON.stringify(this.reported)}`);
150
- await this.stopLocalproxy();
143
+ await this.stopLocalProxy();
151
144
  logger.debug('<- SecureTunnelHandlerSingleton.destroy');
152
145
  }
153
146
 
154
147
  /**
155
148
  * Returns current state of SecureTunnel shadow
156
- * @returns {SecureTunnelShadowDesRep} - reported state of the SecureTunnel shadow
149
+ * @returns {SecureTunnelShadowUpdate} - reported state of the SecureTunnel shadow
157
150
  */
158
- public getSecureTunnelShadow(): SecureTunnelShadowDesRep {
151
+ public getSecureTunnelShadow(): SecureTunnelShadowUpdate {
159
152
  logger.debug('-> SecureTunnelHandlerSingleton.getSecureTunnelShadow');
160
153
  logger.debug(`reported: ${JSON.stringify(this.reported)}`);
161
154
  logger.debug('<- SecureTunnelHandlerSingleton.getSecureTunnelShadow');
@@ -165,11 +158,11 @@ export class SecureTunnelHandlerSingleton {
165
158
  /**
166
159
  * Updates current state of SecureTunnel shadow
167
160
  * @param {SecureTunnelShadowUpdateDelta} deltaMsg - delta message, which includes desired state of the SecureTunnel shadow
168
- * @return {SecureTunnelShadowDesRep} update reported message to send back to AWS IoT device shadow
161
+ * @return {SecureTunnelShadowUpdate} update reported message to send back to AWS IoT device shadow
169
162
  */
170
163
  public async syncShadowToDeviceState(
171
164
  deltaMsg: SecureTunnelShadowUpdateDelta
172
- ): Promise<SecureTunnelShadowDesRep> {
165
+ ): Promise<SecureTunnelShadowUpdate> {
173
166
  logger.debug('-> SecureTunnelHandlerSingleton.syncShadowToDeviceState');
174
167
  const { version, state } = deltaMsg;
175
168
  if (!state || typeof state.st_ports === 'undefined') {
@@ -216,7 +209,7 @@ export class SecureTunnelHandlerSingleton {
216
209
 
217
210
  // if all entries are disabled, we need also to kill local proxy
218
211
  if (this.reported.st_ports.every((portInfo) => !portInfo.enabled)) {
219
- await this.stopLocalproxy();
212
+ await this.stopLocalProxy();
220
213
  }
221
214
 
222
215
  // need to order list in the same order as desired before sending back
@@ -237,15 +230,15 @@ export class SecureTunnelHandlerSingleton {
237
230
  logger.debug('-> SecureTunnelHandlerSingleton.secureTunnelNotifyHandler');
238
231
 
239
232
  try {
240
- await this.stopLocalproxy();
233
+ await this.stopLocalProxy();
241
234
  this.processNotifyMessage(message);
242
235
  await this.downloadSecureTunnel();
243
- await this.startLocalproxy();
244
- } catch (error) {
245
- logger.error(error);
236
+ await this.startLocalProxy();
237
+ } catch (e) {
238
+ logger.error(stringifyError(e));
246
239
  }
247
240
 
248
- logger.info(`Local Proxy Started: ${JSON.stringify(this.localproxyInfo)}`);
241
+ logger.info(`Local Proxy Started: ${JSON.stringify(this.localProxyInfo)}`);
249
242
  logger.debug('<- SecureTunnelHandlerSingleton.secureTunnelNotifyHandler');
250
243
  }
251
244
 
@@ -331,9 +324,11 @@ export class SecureTunnelHandlerSingleton {
331
324
  this.httpProxyMap[this.httpProxyMap.length - 1]
332
325
  )}`
333
326
  );
334
- } catch (error) {
327
+ } catch (e) {
335
328
  logger.error(
336
- `ERROR: starting socat for: ${portInfo.ip}:${portInfo.port} on localhost port: ${localPort}, error: ${error}`
329
+ `ERROR: starting socat for: ${portInfo.ip}:${
330
+ portInfo.port
331
+ } on localhost port: ${localPort}\nerror:\n${stringifyError(e)}`
337
332
  );
338
333
  const lastHttpProxyMap = this.httpProxyMap.pop();
339
334
  logger.info(`removed last proxyMap: ${JSON.stringify(lastHttpProxyMap)}`);
@@ -378,7 +373,7 @@ export class SecureTunnelHandlerSingleton {
378
373
  );
379
374
  logger.debug(`Remaining map: ${JSON.stringify(this.httpProxyMap)}`);
380
375
  } catch (e) {
381
- logger.error('ERROR: killing socat process:', e);
376
+ logger.error(`ERROR: killing socat process:\n${stringifyError(e)}`);
382
377
  }
383
378
  logger.debug(
384
379
  `Removing map: ${JSON.stringify(this.httpProxyMap[itemIndex])}`
@@ -389,60 +384,60 @@ export class SecureTunnelHandlerSingleton {
389
384
  }
390
385
 
391
386
  /**
392
- * Starts SecureTunnel localproxy process
387
+ * Starts SecureTunnel localProxy process
393
388
  */
394
- private async startLocalproxy(): Promise<void> {
395
- logger.debug('-> SecureTunnelHandlerSingleton.startLocalproxy');
389
+ private async startLocalProxy(): Promise<void> {
390
+ logger.debug('-> SecureTunnelHandlerSingleton.startLocalProxy');
396
391
 
397
392
  const args = [
398
393
  '--destination-app',
399
- this.localproxyInfo.lpServices,
394
+ this.localProxyInfo.lpServices,
400
395
  '--region',
401
- this.localproxyInfo.lpRegion,
396
+ this.localProxyInfo.lpRegion,
402
397
  '--capath',
403
398
  AWS_ROOT_CERTIFICATE_FILE_PATH,
404
399
  '--local-bind-address',
405
400
  '0.0.0.0',
406
401
  '-t',
407
- this.localproxyInfo.lpDstAccessKey
402
+ this.localProxyInfo.lpDstAccessKey
408
403
  ];
409
404
 
410
- this.localproxyInfo.lpProcess = await runDetachedProcess(
405
+ this.localProxyInfo.lpProcess = await runDetachedProcess(
411
406
  SECURE_TUNNEL_BIN_PATH,
412
407
  args
413
408
  );
414
- logger.debug('<- SecureTunnelHandlerSingleton.startLocalproxy');
409
+ logger.debug('<- SecureTunnelHandlerSingleton.startLocalProxy');
415
410
  }
416
411
 
417
412
  /**
418
- * Stops SecureTunnel localproxy process
413
+ * Stops SecureTunnel local proxy process
419
414
  */
420
- private async stopLocalproxy(): Promise<void> {
421
- logger.debug('-> SecureTunnelHandlerSingleton.stopLocalproxy');
422
- if (!this.localproxyInfo.lpProcess) {
423
- logger.debug('No localproxy process running');
424
- logger.debug('<- SecureTunnelHandlerSingleton.stopLocalproxy');
415
+ private async stopLocalProxy(): Promise<void> {
416
+ logger.debug('-> SecureTunnelHandlerSingleton.stopLocalProxy');
417
+ if (!this.localProxyInfo.lpProcess) {
418
+ logger.debug('No local proxy process running');
419
+ logger.debug('<- SecureTunnelHandlerSingleton.stopLocalProxy');
425
420
  return;
426
421
  }
427
422
 
428
423
  try {
429
424
  logger.debug(
430
- `About to kill localproxy: ${this.localproxyInfo.lpDstAccessKey}`
425
+ `About to kill local proxy: ${this.localProxyInfo.lpDstAccessKey}`
431
426
  );
432
- await killDetachedProcess(this.localproxyInfo.lpProcess, [
427
+ await killDetachedProcess(this.localProxyInfo.lpProcess, [
433
428
  SECURE_TUNNEL_BIN_PATH
434
429
  ]);
435
- logger.debug('SUCCESS: killing localproxy process');
430
+ logger.debug('SUCCESS: killing local proxy process');
436
431
  } catch (e) {
437
- logger.error('ERROR: killing localproxy process:', e);
432
+ logger.error(`ERROR: killing local proxy process:\n${stringifyError(e)}`);
438
433
  }
439
- this.localproxyInfo = {
434
+ this.localProxyInfo = {
440
435
  lpDstAccessKey: '',
441
436
  lpRegion: '',
442
437
  lpServices: '',
443
438
  lpProcess: null
444
439
  };
445
- logger.debug('<- SecureTunnelHandlerSingleton.stopLocalproxy');
440
+ logger.debug('<- SecureTunnelHandlerSingleton.stopLocalProxy');
446
441
  }
447
442
 
448
443
  /**
@@ -524,16 +519,16 @@ export class SecureTunnelHandlerSingleton {
524
519
  });
525
520
  }
526
521
 
527
- this.localproxyInfo.lpDstAccessKey = clientAccessToken;
528
- this.localproxyInfo.lpRegion = region;
529
- this.localproxyInfo.lpServices = portMappingList.join(',');
522
+ this.localProxyInfo.lpDstAccessKey = clientAccessToken;
523
+ this.localProxyInfo.lpRegion = region;
524
+ this.localProxyInfo.lpServices = portMappingList.join(',');
530
525
  logger.debug(`reported = ${JSON.stringify(this.reported.st_ports)}`);
531
- logger.debug(`localproxyInfo = ${JSON.stringify(this.localproxyInfo)}`);
526
+ logger.debug(`localProxyInfo = ${JSON.stringify(this.localProxyInfo)}`);
532
527
  logger.debug('<- SecureTunnelHandlerSingleton.processNotifyMessage');
533
528
  }
534
529
 
535
530
  /**
536
- * Downloads SecureTunnel localproxy, if it was not downloaded before
531
+ * Downloads SecureTunnel local proxy, if it was not downloaded before
537
532
  */
538
533
  private async downloadSecureTunnel(): Promise<void> {
539
534
  logger.debug('-> SecureTunnelHandlerSingleton.downloadSecureTunnel');
@@ -549,14 +544,24 @@ export class SecureTunnelHandlerSingleton {
549
544
  getOsVersion()
550
545
  ]);
551
546
 
552
- logger.info('Downloading SecureTunnel localproxy ...');
547
+ logger.info('Downloading SecureTunnel local proxy ...');
553
548
  const url = `${aaiArtifactsBucketUrl}/securetunnel/${linuxDistro}/${osVersion}/${arch}/${SECURE_TUNNEL_BIN_NAME}`;
554
549
  await JsSpawner().mkdirp(join(AAI_DIR, SECURE_TUNNEL_BIN_DIR));
555
- await downloadFile({
556
- url,
557
- path: SECURE_TUNNEL_BIN_PATH,
558
- errorMessage: `Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}`
559
- });
550
+ try {
551
+ await downloadToFile({
552
+ url,
553
+ path: SECURE_TUNNEL_BIN_PATH
554
+ });
555
+ } catch (error) {
556
+ logger.error(
557
+ `Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}: ${stringifyError(
558
+ error
559
+ )}`
560
+ );
561
+ throw new Error(
562
+ `Secure Tunnel bin for ${linuxDistro} ${osVersion} ${arch} not found}`
563
+ );
564
+ }
560
565
 
561
566
  await JsSpawner().run({
562
567
  exe: 'chmod',
@@ -585,8 +590,8 @@ export class SecureTunnelHandlerSingleton {
585
590
  }
586
591
 
587
592
  private sortPorts(
588
- desired: SecureTunnelShadowDesRep
589
- ): SecureTunnelShadowDesRep {
593
+ desired: SecureTunnelShadowUpdate
594
+ ): SecureTunnelShadowUpdate {
590
595
  logger.debug('-> SecureTunnelHandlerSingleton.sortPorts');
591
596
  const sortedPorts = JSON.parse(JSON.stringify(this.reported));
592
597
  sortedPorts.st_ports.sort((a, b) => {
@@ -7,10 +7,9 @@ import {
7
7
  import { readAppCfgFile } from '../../application-control';
8
8
  import { DeviceAgentCloudConnection } from '../../cloud-connection/device-agent-cloud-connection';
9
9
  import sleep from '../../util/sleep';
10
- import { logger } from '../../util/logger';
11
10
  import { assign, merge } from 'lodash';
12
11
  import {
13
- buildUpdateProjectShadowMessage,
12
+ buildUpdateShadowMessage,
14
13
  getShadowTopic
15
14
  } from '@alwaysai/device-agent-schemas';
16
15
 
@@ -64,7 +63,6 @@ export const setAnalyticsCfgCliLeaf = CliLeaf({
64
63
  }
65
64
  ) {
66
65
  const deviceAgent = new DeviceAgentCloudConnection();
67
- await deviceAgent.setupHandlers();
68
66
 
69
67
  const newAppCfg = {
70
68
  analytics: {
@@ -85,7 +83,7 @@ export const setAnalyticsCfgCliLeaf = CliLeaf({
85
83
  deviceAgent.publisher.publish(
86
84
  getShadowTopic(deviceAgent.getClientId(), 'projects', 'update'),
87
85
  JSON.stringify(
88
- buildUpdateProjectShadowMessage({
86
+ buildUpdateShadowMessage({
89
87
  clientId: 'client',
90
88
  desired: toDesire
91
89
  })
@@ -4,13 +4,13 @@ import {
4
4
  CliStringInput,
5
5
  CliTerseError
6
6
  } from '@alwaysai/alwayscli';
7
- import { EnvVars, getAllEnvs } from '../../application-control';
7
+ import { getAllEnvs } from '../../application-control';
8
8
  import { DeviceAgentCloudConnection } from '../../cloud-connection/device-agent-cloud-connection';
9
9
  import sleep from '../../util/sleep';
10
- import { logger } from '../../util/logger';
11
10
  import {
12
- buildUpdateProjectShadowMessage,
13
- getShadowTopic
11
+ buildUpdateShadowMessage,
12
+ getShadowTopic,
13
+ EnvVars
14
14
  } from '@alwaysai/device-agent-schemas';
15
15
 
16
16
  export const getAllEnvsCliLeaf = CliLeaf({
@@ -48,27 +48,90 @@ export const setEnvCliLeaf = CliLeaf({
48
48
  },
49
49
  async action(args, opts) {
50
50
  const { project: projectId, service } = opts;
51
- const envVars: EnvVars = { [service]: {} };
51
+ const currentEnvs = await getAllEnvs({ projectId });
52
+ const envVars: EnvVars = { [service]: { ...currentEnvs[service] } };
53
+
52
54
  args.forEach((arg: string) => {
53
55
  const nameVal = arg.split('=');
54
56
  if (nameVal.length !== 2) {
55
57
  throw new CliTerseError(`Invalid argument: ${arg}`);
56
58
  }
57
- const value = nameVal[1] === '' ? null : nameVal[1];
59
+ const value = nameVal[1];
58
60
  envVars[service][nameVal[0]] = value;
59
61
  });
60
62
  const deviceAgent = new DeviceAgentCloudConnection();
61
- await deviceAgent.setupHandlers();
62
63
 
63
64
  const toDesire = {
64
65
  [projectId]: {
65
- envVars
66
+ envVars: JSON.stringify(envVars)
67
+ }
68
+ };
69
+ deviceAgent.publisher.publish(
70
+ getShadowTopic(deviceAgent.getClientId(), 'projects', 'update'),
71
+ JSON.stringify(
72
+ buildUpdateShadowMessage({
73
+ clientId: 'client',
74
+ desired: toDesire
75
+ })
76
+ )
77
+ );
78
+ // Sleep for extra time to ensure time for shadow response
79
+ await sleep(10000);
80
+
81
+ while (deviceAgent.isCmdInProgress(projectId)) {
82
+ await sleep(1000);
83
+ }
84
+ await deviceAgent.stop();
85
+ }
86
+ });
87
+
88
+ export const rmEnvCliLeaf = CliLeaf({
89
+ name: 'rm-env',
90
+ description: 'Remove an environment variable from an application',
91
+ positionalInput: CliStringInput({
92
+ description: 'The key of the environment variable to be removed',
93
+ required: true
94
+ }),
95
+ namedInputs: {
96
+ project: CliStringInput({
97
+ description: 'Project Id',
98
+ required: true
99
+ }),
100
+ service: CliStringInput({
101
+ description:
102
+ 'Docker compose service to remove an environment variable from',
103
+ required: true
104
+ })
105
+ },
106
+ async action(arg, opts) {
107
+ const { project: projectId, service } = opts;
108
+ const envVar = arg;
109
+ const currentEnvs = await getAllEnvs({ projectId: projectId });
110
+
111
+ const newEnvs = { ...currentEnvs };
112
+ if (Object.keys(newEnvs[service]).includes(envVar)) {
113
+ delete newEnvs[service][envVar];
114
+ } else {
115
+ throw new CliTerseError(
116
+ `Could not find key "${envVar}" in service ${service}. Current keys are:\n ${JSON.stringify(
117
+ Object.keys(currentEnvs[service]),
118
+ null,
119
+ 2
120
+ )}.\nPlease check the key and try again.`
121
+ );
122
+ }
123
+
124
+ const deviceAgent = new DeviceAgentCloudConnection();
125
+
126
+ const toDesire = {
127
+ [projectId]: {
128
+ envVars: JSON.stringify(newEnvs)
66
129
  }
67
130
  };
68
131
  deviceAgent.publisher.publish(
69
132
  getShadowTopic(deviceAgent.getClientId(), 'projects', 'update'),
70
133
  JSON.stringify(
71
- buildUpdateProjectShadowMessage({
134
+ buildUpdateShadowMessage({
72
135
  clientId: 'client',
73
136
  desired: toDesire
74
137
  })
@@ -1,12 +1,6 @@
1
1
  import { CliBranch } from '@alwaysai/alwayscli';
2
- import { getAllEnvsCliLeaf, setEnvCliLeaf } from './env-vars';
3
- import {
4
- showAppModelsCliLeaf,
5
- addModelCliLeaf,
6
- removeModelCliLeaf,
7
- replaceModelsCliLeaf,
8
- updateModelsCliLeaf
9
- } from './models';
2
+ import { getAllEnvsCliLeaf, setEnvCliLeaf, rmEnvCliLeaf } from './env-vars';
3
+ import { showAppModelsCliLeaf, addModelCliLeaf } from './models';
10
4
  import {
11
5
  getAppStatusCliLeaf,
12
6
  startAppCliLeaf,
@@ -38,11 +32,9 @@ export const appCliBranch = CliBranch({
38
32
  rollbackAppCliLeaf,
39
33
  showAppModelsCliLeaf,
40
34
  addModelCliLeaf,
41
- removeModelCliLeaf,
42
- replaceModelsCliLeaf,
43
- updateModelsCliLeaf,
44
35
  getAllEnvsCliLeaf,
45
36
  setEnvCliLeaf,
37
+ rmEnvCliLeaf,
46
38
  getAnalyticsCfgCliLeaf,
47
39
  setAnalyticsCfgCliLeaf,
48
40
  getShadowCliLeaf,
@@ -1,23 +1,10 @@
1
- import {
2
- CliLeaf,
3
- CliNumberInput,
4
- CliStringArrayInput,
5
- CliStringInput
6
- } from '@alwaysai/alwayscli';
7
- import {
8
- getAppModels,
9
- readAppCfgFile,
10
- removeModel,
11
- replaceModels,
12
- updateModels
13
- } from '../../application-control';
1
+ import { CliLeaf, CliStringInput } from '@alwaysai/alwayscli';
2
+ import { getAppModels, readAppCfgFile } from '../../application-control';
14
3
  import { DeviceAgentCloudConnection } from '../../cloud-connection/device-agent-cloud-connection';
15
4
  import sleep from '../../util/sleep';
16
- import { logger } from '../../util/logger';
17
5
  import {
18
- buildUpdateProjectShadowMessage,
19
- getShadowTopic,
20
- validateShadowProjectsUpdateAll
6
+ buildUpdateShadowMessage,
7
+ getShadowTopic
21
8
  } from '@alwaysai/device-agent-schemas';
22
9
 
23
10
  export const showAppModelsCliLeaf = CliLeaf({
@@ -56,7 +43,6 @@ export const addModelCliLeaf = CliLeaf({
56
43
  async action(_, opts) {
57
44
  const { project: projectId, model, version } = opts;
58
45
  const deviceAgent = new DeviceAgentCloudConnection();
59
- await deviceAgent.setupHandlers();
60
46
 
61
47
  // Update the shadow as a client
62
48
 
@@ -71,7 +57,7 @@ export const addModelCliLeaf = CliLeaf({
71
57
  deviceAgent.publisher.publish(
72
58
  getShadowTopic(deviceAgent.getClientId(), 'projects', 'update'),
73
59
  JSON.stringify(
74
- buildUpdateProjectShadowMessage({
60
+ buildUpdateShadowMessage({
75
61
  clientId: 'client',
76
62
  desired: toDesire
77
63
  })
@@ -86,65 +72,3 @@ export const addModelCliLeaf = CliLeaf({
86
72
  await deviceAgent.stop();
87
73
  }
88
74
  });
89
-
90
- export const removeModelCliLeaf = CliLeaf({
91
- name: 'remove-model',
92
- description: 'Remove a model from an alwaysAI app',
93
- namedInputs: {
94
- project: CliStringInput({
95
- description: 'Project ID',
96
- required: true
97
- }),
98
- model: CliStringInput({
99
- description: 'Model ID',
100
- required: true
101
- })
102
- },
103
- async action(_, opts) {
104
- const { project, model } = opts;
105
- // TODO: Replace with handleMessage()
106
- await removeModel({ projectId: project, modelId: model });
107
- }
108
- });
109
-
110
- export const replaceModelsCliLeaf = CliLeaf({
111
- name: 'replace-models',
112
- description: 'Replace all models of an alwaysAI app with new models',
113
- namedInputs: {
114
- project: CliStringInput({
115
- description: 'Project Id',
116
- required: true
117
- }),
118
- models: CliStringArrayInput({
119
- description: 'One or more model IDs',
120
- required: true
121
- })
122
- },
123
- hidden: true,
124
- async action(_, opts) {
125
- const { project, models } = opts;
126
- console.log(
127
- 'This command is deprecated and will be removed in a future release'
128
- );
129
- await replaceModels({ projectId: project, modelIds: models });
130
- }
131
- });
132
-
133
- export const updateModelsCliLeaf = CliLeaf({
134
- name: 'update-models',
135
- description: 'Update all models for an alwaysAI app',
136
- namedInputs: {
137
- project: CliStringInput({
138
- description: 'Project Id',
139
- required: true
140
- })
141
- },
142
- hidden: true,
143
- async action(_, opts) {
144
- const { project } = opts;
145
- console.log(
146
- 'This command is deprecated and will be removed in a future release'
147
- );
148
- await updateModels({ projectId: project });
149
- }
150
- });
@@ -14,10 +14,9 @@ export const getShadowCliLeaf = CliLeaf({
14
14
  async action(_, opts) {
15
15
  const { project } = opts;
16
16
  const deviceAgent = new DeviceAgentCloudConnection();
17
- await deviceAgent.setupHandlers();
17
+ deviceAgent.shadowHandler.getProjectShadowUpdates();
18
18
 
19
- // The Device Agent always gets the latest shadow and updates
20
- // itself. 5 seconds should cover the initial response wait time
19
+ // 5 seconds should cover the response wait time
21
20
  await sleep(5000);
22
21
  while (deviceAgent.isCmdInProgress(project)) {
23
22
  await sleep(1000);
@@ -38,11 +37,13 @@ export const updateShadowCliLeaf = CliLeaf({
38
37
  async action(_, opts) {
39
38
  const { project } = opts;
40
39
  const deviceAgent = new DeviceAgentCloudConnection();
41
- await deviceAgent.setupHandlers();
42
- await deviceAgent.updateProjectShadow(project);
40
+ await deviceAgent.shadowHandler.updateProjectShadow(project);
43
41
 
44
42
  // 5 seconds should cover the response wait time
45
43
  await sleep(5000);
44
+ while (deviceAgent.isCmdInProgress(project)) {
45
+ await sleep(1000);
46
+ }
46
47
  await deviceAgent.stop();
47
48
  }
48
49
  });
@@ -2,6 +2,7 @@ import { CliLeaf, CliStringInput, CliTerseError } from '@alwaysai/alwayscli';
2
2
  import {
3
3
  AppVersionControlMessage,
4
4
  generateTxId,
5
+ getToDeviceTopic,
5
6
  keyMirrors
6
7
  } from '@alwaysai/device-agent-schemas';
7
8
  import { rollbackApp } from '../../application-control';
@@ -50,8 +51,7 @@ export const installAppCliLeaf = CliLeaf({
50
51
  throw new CliTerseError('--release-hash flag is required!');
51
52
  }
52
53
  const deviceAgent = new DeviceAgentCloudConnection();
53
- await deviceAgent.setupHandlers();
54
- const topic = deviceAgent.getToDeviceTopic();
54
+ const topic = getToDeviceTopic(deviceAgent.getClientId());
55
55
  const message: AppVersionControlMessage = {
56
56
  timestamp: '',
57
57
  topic,
@@ -83,8 +83,7 @@ export const uninstallAppCliLeaf = CliLeaf({
83
83
  async action(_, opts) {
84
84
  const { project } = opts;
85
85
  const deviceAgent = new DeviceAgentCloudConnection();
86
- await deviceAgent.setupHandlers();
87
- const topic = deviceAgent.getToDeviceTopic();
86
+ const topic = getToDeviceTopic(deviceAgent.getClientId());
88
87
  const message: AppVersionControlMessage = {
89
88
  timestamp: '',
90
89
  topic,