@alwaysai/device-agent 0.0.12 → 0.0.14

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 (227) hide show
  1. package/lib/application-control/backup.d.ts.map +1 -1
  2. package/lib/application-control/backup.js +11 -5
  3. package/lib/application-control/backup.js.map +1 -1
  4. package/lib/application-control/config.d.ts +12 -4
  5. package/lib/application-control/config.d.ts.map +1 -1
  6. package/lib/application-control/config.js +59 -16
  7. package/lib/application-control/config.js.map +1 -1
  8. package/lib/application-control/environment-variables.d.ts.map +1 -1
  9. package/lib/application-control/environment-variables.js.map +1 -1
  10. package/lib/application-control/index.d.ts +5 -5
  11. package/lib/application-control/index.d.ts.map +1 -1
  12. package/lib/application-control/index.js +4 -6
  13. package/lib/application-control/index.js.map +1 -1
  14. package/lib/application-control/install.d.ts +1 -1
  15. package/lib/application-control/install.d.ts.map +1 -1
  16. package/lib/application-control/install.js +58 -57
  17. package/lib/application-control/install.js.map +1 -1
  18. package/lib/application-control/models.d.ts +7 -5
  19. package/lib/application-control/models.d.ts.map +1 -1
  20. package/lib/application-control/models.js +78 -57
  21. package/lib/application-control/models.js.map +1 -1
  22. package/lib/application-control/status.d.ts +0 -6
  23. package/lib/application-control/status.d.ts.map +1 -1
  24. package/lib/application-control/status.js +21 -33
  25. package/lib/application-control/status.js.map +1 -1
  26. package/lib/application-control/utils.d.ts +3 -2
  27. package/lib/application-control/utils.d.ts.map +1 -1
  28. package/lib/application-control/utils.js +54 -34
  29. package/lib/application-control/utils.js.map +1 -1
  30. package/lib/cloud-connection/app-install-status.d.ts +16 -0
  31. package/lib/cloud-connection/app-install-status.d.ts.map +1 -0
  32. package/lib/cloud-connection/app-install-status.js +53 -0
  33. package/lib/cloud-connection/app-install-status.js.map +1 -0
  34. package/lib/cloud-connection/bootstrap-provision.d.ts +2 -0
  35. package/lib/cloud-connection/bootstrap-provision.d.ts.map +1 -0
  36. package/lib/cloud-connection/bootstrap-provision.js +34 -0
  37. package/lib/cloud-connection/bootstrap-provision.js.map +1 -0
  38. package/lib/cloud-connection/cmd-status.d.ts +16 -0
  39. package/lib/cloud-connection/cmd-status.d.ts.map +1 -0
  40. package/lib/cloud-connection/cmd-status.js +49 -0
  41. package/lib/cloud-connection/cmd-status.js.map +1 -0
  42. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +21 -34
  43. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  44. package/lib/cloud-connection/device-agent-cloud-connection.js +211 -387
  45. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  46. package/lib/cloud-connection/device-agent.d.ts.map +1 -1
  47. package/lib/cloud-connection/device-agent.js +22 -26
  48. package/lib/cloud-connection/device-agent.js.map +1 -1
  49. package/lib/cloud-connection/live-updates-handler.d.ts +34 -0
  50. package/lib/cloud-connection/live-updates-handler.d.ts.map +1 -0
  51. package/lib/cloud-connection/live-updates-handler.js +167 -0
  52. package/lib/cloud-connection/live-updates-handler.js.map +1 -0
  53. package/lib/cloud-connection/messages.d.ts +14 -0
  54. package/lib/cloud-connection/messages.d.ts.map +1 -0
  55. package/lib/cloud-connection/messages.js +38 -0
  56. package/lib/cloud-connection/messages.js.map +1 -0
  57. package/lib/cloud-connection/passthrough-handler.d.ts +11 -0
  58. package/lib/cloud-connection/passthrough-handler.d.ts.map +1 -0
  59. package/lib/cloud-connection/passthrough-handler.js +59 -0
  60. package/lib/cloud-connection/passthrough-handler.js.map +1 -0
  61. package/lib/cloud-connection/publisher.d.ts +15 -0
  62. package/lib/cloud-connection/publisher.d.ts.map +1 -0
  63. package/lib/cloud-connection/publisher.js +58 -0
  64. package/lib/cloud-connection/publisher.js.map +1 -0
  65. package/lib/cloud-connection/shadow-handler.d.ts +33 -0
  66. package/lib/cloud-connection/shadow-handler.d.ts.map +1 -0
  67. package/lib/cloud-connection/shadow-handler.js +108 -0
  68. package/lib/cloud-connection/shadow-handler.js.map +1 -0
  69. package/lib/cloud-connection/shadow-handler.test.d.ts +2 -0
  70. package/lib/cloud-connection/shadow-handler.test.d.ts.map +1 -0
  71. package/lib/cloud-connection/shadow-handler.test.js +321 -0
  72. package/lib/cloud-connection/shadow-handler.test.js.map +1 -0
  73. package/lib/cloud-connection/shadow.d.ts +16 -0
  74. package/lib/cloud-connection/shadow.d.ts.map +1 -0
  75. package/lib/cloud-connection/shadow.js +36 -0
  76. package/lib/cloud-connection/shadow.js.map +1 -0
  77. package/lib/device-control/device-control.d.ts.map +1 -1
  78. package/lib/device-control/device-control.js +1 -0
  79. package/lib/device-control/device-control.js.map +1 -1
  80. package/lib/docker/docker-cmd.js +1 -1
  81. package/lib/docker/docker-compose-cmd.d.ts.map +1 -1
  82. package/lib/docker/docker-compose-cmd.js +1 -1
  83. package/lib/docker/docker-compose-cmd.js.map +1 -1
  84. package/lib/endpoints.js +10 -10
  85. package/lib/endpoints.js.map +1 -1
  86. package/lib/environment.d.ts +1 -0
  87. package/lib/environment.d.ts.map +1 -1
  88. package/lib/environment.js +2 -1
  89. package/lib/environment.js.map +1 -1
  90. package/lib/infrastructure/agent-config.d.ts +15 -58
  91. package/lib/infrastructure/agent-config.d.ts.map +1 -1
  92. package/lib/infrastructure/agent-config.js +22 -15
  93. package/lib/infrastructure/agent-config.js.map +1 -1
  94. package/lib/infrastructure/agent-config.test.js +25 -23
  95. package/lib/infrastructure/agent-config.test.js.map +1 -1
  96. package/lib/infrastructure/system-id.d.ts +2 -0
  97. package/lib/infrastructure/system-id.d.ts.map +1 -0
  98. package/lib/infrastructure/system-id.js +21 -0
  99. package/lib/infrastructure/system-id.js.map +1 -0
  100. package/lib/infrastructure/tokens-and-device-cfg.d.ts +4 -0
  101. package/lib/infrastructure/tokens-and-device-cfg.d.ts.map +1 -0
  102. package/lib/infrastructure/tokens-and-device-cfg.js +27 -0
  103. package/lib/infrastructure/tokens-and-device-cfg.js.map +1 -0
  104. package/lib/infrastructure/urls.d.ts.map +1 -1
  105. package/lib/infrastructure/urls.js +3 -3
  106. package/lib/infrastructure/urls.js.map +1 -1
  107. package/lib/local-connection/rabbitmq-connection.d.ts +4 -0
  108. package/lib/local-connection/rabbitmq-connection.d.ts.map +1 -0
  109. package/lib/local-connection/rabbitmq-connection.js +58 -0
  110. package/lib/local-connection/rabbitmq-connection.js.map +1 -0
  111. package/lib/root.d.ts.map +1 -1
  112. package/lib/root.js +2 -7
  113. package/lib/root.js.map +1 -1
  114. package/lib/subcommands/app/app.d.ts +2 -1
  115. package/lib/subcommands/app/app.d.ts.map +1 -1
  116. package/lib/subcommands/app/app.js +112 -77
  117. package/lib/subcommands/app/app.js.map +1 -1
  118. package/lib/subcommands/app/index.js +2 -2
  119. package/lib/subcommands/device/clean.d.ts +2 -0
  120. package/lib/subcommands/device/clean.d.ts.map +1 -0
  121. package/lib/subcommands/device/clean.js +29 -0
  122. package/lib/subcommands/device/clean.js.map +1 -0
  123. package/lib/subcommands/device/device.d.ts +1 -1
  124. package/lib/subcommands/device/device.d.ts.map +1 -1
  125. package/lib/subcommands/device/device.js +44 -33
  126. package/lib/subcommands/device/device.js.map +1 -1
  127. package/lib/subcommands/device/index.d.ts.map +1 -1
  128. package/lib/subcommands/device/index.js +2 -1
  129. package/lib/subcommands/device/index.js.map +1 -1
  130. package/lib/subcommands/get-model-package.js +5 -5
  131. package/lib/subcommands/index.d.ts +0 -1
  132. package/lib/subcommands/index.d.ts.map +1 -1
  133. package/lib/subcommands/index.js +1 -1
  134. package/lib/subcommands/login.d.ts +0 -1
  135. package/lib/subcommands/login.d.ts.map +1 -1
  136. package/lib/subcommands/login.js +6 -14
  137. package/lib/subcommands/login.js.map +1 -1
  138. package/lib/util/clean-certs.d.ts +2 -0
  139. package/lib/util/clean-certs.d.ts.map +1 -0
  140. package/lib/util/clean-certs.js +16 -0
  141. package/lib/util/clean-certs.js.map +1 -0
  142. package/lib/util/directories.d.ts +16 -15
  143. package/lib/util/directories.d.ts.map +1 -1
  144. package/lib/util/directories.js +45 -26
  145. package/lib/util/directories.js.map +1 -1
  146. package/lib/util/fetch-with-timeout.d.ts +4 -0
  147. package/lib/util/fetch-with-timeout.d.ts.map +1 -0
  148. package/lib/util/fetch-with-timeout.js +15 -0
  149. package/lib/util/fetch-with-timeout.js.map +1 -0
  150. package/lib/util/get-device-id.d.ts +1 -1
  151. package/lib/util/get-device-id.d.ts.map +1 -1
  152. package/lib/util/get-device-id.js +14 -19
  153. package/lib/util/get-device-id.js.map +1 -1
  154. package/lib/util/http-client.d.ts +1 -1
  155. package/lib/util/http-client.d.ts.map +1 -1
  156. package/lib/util/http-client.js +10 -8
  157. package/lib/util/http-client.js.map +1 -1
  158. package/lib/util/logger.d.ts.map +1 -1
  159. package/lib/util/logger.js +4 -5
  160. package/lib/util/logger.js.map +1 -1
  161. package/lib/util/require-logged-in-and-paid-plan.d.ts +2 -0
  162. package/lib/util/require-logged-in-and-paid-plan.d.ts.map +1 -0
  163. package/lib/util/require-logged-in-and-paid-plan.js +18 -0
  164. package/lib/util/require-logged-in-and-paid-plan.js.map +1 -0
  165. package/lib/util/run-in-dir.d.ts.map +1 -1
  166. package/lib/util/run-in-dir.js +1 -0
  167. package/lib/util/run-in-dir.js.map +1 -1
  168. package/lib/util/timer.d.ts +2 -0
  169. package/lib/util/timer.d.ts.map +1 -0
  170. package/lib/util/timer.js +6 -0
  171. package/lib/util/timer.js.map +1 -0
  172. package/package.json +32 -35
  173. package/readme.md +100 -89
  174. package/src/application-control/backup.ts +11 -6
  175. package/src/application-control/config.ts +75 -13
  176. package/src/application-control/environment-variables.ts +3 -3
  177. package/src/application-control/index.ts +18 -11
  178. package/src/application-control/install.ts +82 -78
  179. package/src/application-control/models.ts +104 -72
  180. package/src/application-control/status.ts +29 -40
  181. package/src/application-control/utils.ts +66 -38
  182. package/src/cloud-connection/app-install-status.ts +62 -0
  183. package/src/cloud-connection/bootstrap-provision.ts +40 -0
  184. package/src/cloud-connection/cmd-status.ts +52 -0
  185. package/src/cloud-connection/device-agent-cloud-connection.ts +302 -526
  186. package/src/cloud-connection/device-agent.ts +31 -38
  187. package/src/cloud-connection/live-updates-handler.ts +226 -0
  188. package/src/cloud-connection/messages.ts +39 -0
  189. package/src/cloud-connection/passthrough-handler.ts +67 -0
  190. package/src/cloud-connection/publisher.ts +86 -0
  191. package/src/cloud-connection/shadow-handler.test.ts +361 -0
  192. package/src/cloud-connection/shadow-handler.ts +175 -0
  193. package/src/cloud-connection/shadow.ts +50 -0
  194. package/src/device-control/device-control.ts +1 -0
  195. package/src/docker/docker-cmd.ts +1 -1
  196. package/src/docker/docker-compose-cmd.ts +5 -2
  197. package/src/endpoints.ts +9 -9
  198. package/src/environment.ts +11 -3
  199. package/src/infrastructure/agent-config.test.ts +33 -29
  200. package/src/infrastructure/agent-config.ts +57 -22
  201. package/src/infrastructure/system-id.ts +18 -0
  202. package/src/infrastructure/tokens-and-device-cfg.ts +34 -0
  203. package/src/infrastructure/urls.ts +4 -2
  204. package/src/local-connection/rabbitmq-connection.ts +53 -0
  205. package/src/root.ts +2 -8
  206. package/src/subcommands/app/app.ts +119 -83
  207. package/src/subcommands/app/index.ts +3 -3
  208. package/src/subcommands/device/clean.ts +26 -0
  209. package/src/subcommands/device/device.ts +67 -54
  210. package/src/subcommands/device/index.ts +2 -1
  211. package/src/subcommands/get-model-package.ts +5 -5
  212. package/src/subcommands/index.ts +1 -1
  213. package/src/subcommands/login.ts +6 -14
  214. package/src/util/clean-certs.ts +12 -0
  215. package/src/util/directories.ts +68 -52
  216. package/src/util/fetch-with-timeout.ts +18 -0
  217. package/src/util/get-device-id.ts +16 -18
  218. package/src/util/http-client.ts +18 -13
  219. package/src/util/logger.ts +6 -6
  220. package/src/util/require-logged-in-and-paid-plan.ts +16 -0
  221. package/src/util/run-in-dir.ts +2 -1
  222. package/src/util/timer.ts +1 -0
  223. package/lib/infrastructure/certificates-and-tokens.d.ts +0 -6
  224. package/lib/infrastructure/certificates-and-tokens.d.ts.map +0 -1
  225. package/lib/infrastructure/certificates-and-tokens.js +0 -43
  226. package/lib/infrastructure/certificates-and-tokens.js.map +0 -1
  227. package/src/infrastructure/certificates-and-tokens.ts +0 -53
@@ -1,35 +1,97 @@
1
- import { AppConfig, AppJsonFile } from 'alwaysai/lib/core/app';
2
1
  import { AgentConfigFile } from '../infrastructure/agent-config';
3
2
  import { parse, stringify } from 'yaml';
4
- import { getAppDir } from './utils';
3
+ import { buildApp, getAppDir } from './utils';
5
4
  import { JsSpawner } from 'alwaysai/lib/util';
6
5
  import compose from 'docker-compose';
7
6
  import { assign, merge } from 'lodash';
7
+ import { AppJsonFile } from 'alwaysai/lib/core/app';
8
+ import { AppConfig } from '@alwaysai/app-configuration-schemas';
9
+ import { restartApp } from './status';
10
+ import { logger } from '../util/logger';
8
11
 
9
- export async function readAppCfg(props: { projectId: string }): Promise<AppConfig> {
12
+ export async function readAppCfgFile(props: {
13
+ projectId: string;
14
+ }): Promise<AppConfig> {
10
15
  const { projectId } = props;
11
- if (!(await AgentConfigFile().isAppReady({ projectId }))) {
12
- throw new Error(`App ${projectId} is not ready!`);
16
+ if (!(await AgentConfigFile().isAppPresent({ projectId }))) {
17
+ throw new Error(`App ${projectId} is not present!`);
13
18
  }
14
19
  const appDir = getAppDir(projectId);
15
20
  const appJson = AppJsonFile(appDir);
16
- return appJson.read();
21
+ if (!appJson.exists()) {
22
+ throw new Error(`App config for ${projectId} doesn't exist!`);
23
+ }
24
+ try {
25
+ return appJson.read();
26
+ } catch (err) {
27
+ throw new Error(
28
+ `Error reading app config for ${projectId}:\n${err}\n${appJson.getErrors()}`
29
+ );
30
+ }
17
31
  }
18
32
 
19
- export async function writeAppCfg(props: { projectId: string; appCfg: AppConfig }) {
33
+ export async function writeAppCfgFile(props: {
34
+ projectId: string;
35
+ appCfg: AppConfig;
36
+ }) {
20
37
  const { projectId, appCfg } = props;
21
- if (!(await AgentConfigFile().isAppReady({ projectId }))) {
22
- throw new Error(`App ${projectId} is not ready!`);
38
+ if (!(await AgentConfigFile().isAppPresent({ projectId }))) {
39
+ throw new Error(`App ${projectId} is not present!`);
23
40
  }
24
41
  const appDir = getAppDir(projectId);
25
42
  const appJson = AppJsonFile(appDir);
26
- appJson.write(appCfg);
43
+ try {
44
+ appJson.write(appCfg);
45
+ } catch (err) {
46
+ throw new Error(
47
+ `Error writing app config for ${projectId}:\n${err}\n${appJson.getErrors()}`
48
+ );
49
+ }
27
50
  }
28
51
 
29
- export async function updateAppConfig(appDir: string, newAppCfg: AppConfig) {
30
- const existingAppCfg = await readAppCfg({ projectId: appDir });
52
+ export async function updateAppCfgFile(props: {
53
+ projectId: string;
54
+ newAppCfg: any;
55
+ }) {
56
+ const { projectId, newAppCfg } = props;
57
+ const existingAppCfg = await readAppCfgFile({ projectId });
31
58
  const appCfg = assign(existingAppCfg, merge(existingAppCfg, newAppCfg));
32
- await writeAppCfg({ projectId: appDir, appCfg });
59
+ await writeAppCfgFile({ projectId, appCfg });
60
+ }
61
+
62
+ export async function updateAppCfg(props: {
63
+ projectId: string;
64
+ appReleaseHash: string;
65
+ newAppCfg: AppConfig;
66
+ }) {
67
+ const { projectId, appReleaseHash, newAppCfg } = props;
68
+ logger.info(`Updating app config for ${projectId}:${appReleaseHash}.`);
69
+ const appDir = getAppDir(projectId);
70
+
71
+ if (await AgentConfigFile().isAppPresent({ projectId })) {
72
+ if (!(await AgentConfigFile().isAppReady({ projectId }))) {
73
+ throw new Error('Application already has installation in progress!');
74
+ }
75
+ logger.info('Application is already installed, updating');
76
+ await AgentConfigFile().setAppInstalling({
77
+ projectId,
78
+ version: appReleaseHash
79
+ });
80
+ } else {
81
+ throw new Error('Application is not installed!');
82
+ }
83
+
84
+ await writeAppCfgFile({ projectId, appCfg: newAppCfg });
85
+ await buildApp({ appDir });
86
+
87
+ await AgentConfigFile().setAppInstalled({
88
+ projectId,
89
+ version: appReleaseHash
90
+ });
91
+
92
+ await restartApp({ projectId });
93
+
94
+ logger.info(`Updated app config and rebuilt ${projectId}:${appReleaseHash}.`);
33
95
  }
34
96
 
35
97
  export async function readDockerCompose(props: { projectId: string }) {
@@ -1,6 +1,4 @@
1
1
  import { JsSpawner } from 'alwaysai/lib/util';
2
- import compose from 'docker-compose';
3
- import { parse, stringify } from 'yaml';
4
2
  import { AgentConfigFile } from '../infrastructure/agent-config';
5
3
  import { readDockerCompose, writeDockerCompose } from './config';
6
4
  import { getAppDir } from './utils';
@@ -56,7 +54,9 @@ export async function getAllEnvs(props: { projectId: string }) {
56
54
  if ('env_file' in service) {
57
55
  const envFiles: string[] = service['env_file'];
58
56
  for (const ef of envFiles) {
59
- envVars[s] = envVars[s].concat((await spawner.readFile(ef)).split('\n'));
57
+ envVars[s] = envVars[s].concat(
58
+ (await spawner.readFile(ef)).split('\n')
59
+ );
60
60
  }
61
61
  }
62
62
  if ('environment' in service) {
@@ -1,28 +1,29 @@
1
- import { readAppCfg, writeAppCfg, readDockerCompose, writeDockerCompose } from './config';
1
+ import {
2
+ readAppCfgFile,
3
+ updateAppCfg,
4
+ readDockerCompose,
5
+ writeDockerCompose
6
+ } from './config';
2
7
  import { installApp, uninstallApp } from './install';
3
8
  import { rollbackApp } from './backup';
4
9
  import {
5
- listAppReleases,
6
- listAppLatestRelease,
7
10
  getAppStatus,
8
11
  startApp,
9
12
  getAppLogs,
10
13
  stopApp,
11
- restartApp,
14
+ restartApp
12
15
  } from './status';
13
16
  import { ModelDetails } from './types';
14
17
  import { getAllEnvs, setEnv } from './environment-variables';
15
18
 
16
19
  export {
17
- readAppCfg,
18
- writeAppCfg,
20
+ readAppCfgFile,
21
+ updateAppCfg,
19
22
  readDockerCompose,
20
23
  writeDockerCompose,
21
24
  installApp,
22
25
  uninstallApp,
23
26
  rollbackApp,
24
- listAppReleases,
25
- listAppLatestRelease,
26
27
  getAppStatus,
27
28
  startApp,
28
29
  getAppLogs,
@@ -30,16 +31,22 @@ export {
30
31
  restartApp,
31
32
  ModelDetails,
32
33
  getAllEnvs,
33
- setEnv,
34
+ setEnv
34
35
  };
35
36
 
36
37
  // CLI-mode only
37
38
  import {
38
- addModel,
39
39
  getAppModels,
40
40
  removeModel,
41
41
  replaceModels,
42
42
  updateModels,
43
+ updateModelsWithPresignedUrls
43
44
  } from './models';
44
45
 
45
- export { addModel, getAppModels, removeModel, replaceModels, updateModels };
46
+ export {
47
+ getAppModels,
48
+ removeModel,
49
+ replaceModels,
50
+ updateModels,
51
+ updateModelsWithPresignedUrls
52
+ };
@@ -1,10 +1,11 @@
1
- import * as rimraf from 'rimraf';
1
+ import { rimraf } from 'rimraf';
2
2
  import * as fs from 'fs';
3
3
  import * as path from 'path';
4
+ import { buildDockerImage } from 'alwaysai/lib/util/docker';
4
5
  import { JsSpawner, Spawner } from 'alwaysai/lib/util';
5
6
  import { getAppDir, downloadPackageUsingPresignedUrl, buildApp } from './utils';
6
- import { AppDetailsPacket, ModelInstallPayload } from '@alwaysai/device-agent-schemas';
7
- import { BACKUP_EXT, createAppBackup } from './backup';
7
+ import { AppDetailsPacket } from '@alwaysai/device-agent-schemas';
8
+ import { BACKUP_EXT } from './backup';
8
9
  import { stopApp } from './status';
9
10
  import { AgentConfigFile } from '../infrastructure/agent-config';
10
11
  import { ProjectJsonFile } from 'alwaysai/lib/core/project';
@@ -12,14 +13,16 @@ import {
12
13
  getTargetHardwareType,
13
14
  AppJsonFile,
14
15
  TargetJsonFile,
16
+ appCleanDocker,
17
+ getPythonVenvPaths,
18
+ installPythonVenv,
19
+ installPythonReqs
15
20
  } from 'alwaysai/lib/core/app';
16
- import { appCleanDockerComponent, buildDocker } from 'alwaysai/lib/components/app';
17
21
  import {
18
- appInstallComponent,
19
- installVenv,
20
- } from 'alwaysai/lib/components/app/app-install-component';
21
- import { DOCKERFILE, DOCKER_IMAGE_ID_INITIAL_VALUE } from 'alwaysai/lib/constants';
22
- import { appReleasePullComponent } from 'alwaysai/lib/components/release';
22
+ DOCKERFILE,
23
+ DOCKER_IMAGE_ID_INITIAL_VALUE,
24
+ PYTHON_REQUIREMENTS_FILE_NAME
25
+ } from 'alwaysai/lib/constants';
23
26
  import { runInDir } from '../util/run-in-dir';
24
27
  import { installModelsWithPresignedURLs } from './models';
25
28
  import { logger } from '../util/logger';
@@ -48,9 +51,10 @@ export async function getInstalledApps(): Promise<AppDetailsPacket[]> {
48
51
  export async function installApp(props: {
49
52
  projectId: string;
50
53
  appReleaseHash: string;
51
- signedUrlsPayload?: SignedUrlPayloadType;
54
+ signedUrlsPayload: SignedUrlPayloadType;
52
55
  }): Promise<void> {
53
56
  const { projectId, appReleaseHash, signedUrlsPayload } = props;
57
+ logger.info(`Installing ${projectId}:${appReleaseHash}`);
54
58
 
55
59
  const appDir = getAppDir(projectId);
56
60
  const spawner = JsSpawner();
@@ -59,32 +63,27 @@ export async function installApp(props: {
59
63
  throw new Error('Application already has installation in progress!');
60
64
  }
61
65
  logger.info('Application is already installed, updating');
62
- await AgentConfigFile().setAppInstalling({ projectId, version: appReleaseHash });
66
+ await AgentConfigFile().setAppInstalling({
67
+ projectId,
68
+ version: appReleaseHash
69
+ });
63
70
  await spawner.rimraf(appDir);
64
71
  } else {
65
- await AgentConfigFile().setAppInstalling({ projectId, version: appReleaseHash });
72
+ await AgentConfigFile().setAppInstalling({
73
+ projectId,
74
+ version: appReleaseHash
75
+ });
66
76
  }
67
77
 
68
78
  await spawner.mkdirp(appDir);
69
79
 
70
80
  // download app package
71
81
  const localDest = path.join(appDir, `${path.basename(appReleaseHash)}.tgz`);
72
- if (!signedUrlsPayload) {
73
- await runInDir(
74
- appReleasePullComponent,
75
- [
76
- {
77
- yes: true,
78
- project: projectId,
79
- releaseHash: appReleaseHash,
80
- },
81
- ],
82
- appDir,
83
- );
84
- } else {
85
- const { appSignedUrl } = signedUrlsPayload.appInstallPayload;
86
- await downloadPackageUsingPresignedUrl({ localDest, presignedUrl: appSignedUrl });
87
- }
82
+ const { appSignedUrl } = signedUrlsPayload.appInstallPayload;
83
+ await downloadPackageUsingPresignedUrl({
84
+ localDest,
85
+ presignedUrl: appSignedUrl
86
+ });
88
87
 
89
88
  // Unpack app package and remove tar file
90
89
  await unPackApp({ spawner, localDest, appDir });
@@ -95,71 +94,73 @@ export async function installApp(props: {
95
94
  // NOTE: this process no longer checks project collaboration
96
95
  await checkValidProjectFiles({ appDir });
97
96
 
98
- // install models, python venv, and docker image
99
- if (!signedUrlsPayload) {
100
- await runInDir(
101
- appInstallComponent,
102
- [
103
- {
104
- yes: true,
105
- pull: true,
106
- clean: true,
107
- skipModels: false,
108
- source: false,
109
- },
110
- ],
111
- appDir,
112
- );
113
- } else {
114
- await installAppBuildReqs({ appDir });
115
- await installModelsWithPresignedURLs(
116
- signedUrlsPayload.modelsInstallPayload,
117
- path.join(appDir, 'models'),
118
- );
119
- }
97
+ await installAppBuildReqs({ appDir });
98
+ await installModelsWithPresignedURLs(
99
+ signedUrlsPayload.modelsInstallPayload,
100
+ path.join(appDir, 'models')
101
+ );
120
102
 
121
103
  await buildApp({ appDir });
122
104
 
123
- await AgentConfigFile().setAppInstalled({ projectId, version: appReleaseHash });
105
+ await AgentConfigFile().setAppInstalled({
106
+ projectId,
107
+ version: appReleaseHash
108
+ });
124
109
 
125
- logger.info(
126
- `Installed app version ${appReleaseHash} from project ${projectId} to ${appDir}.`,
127
- );
110
+ logger.info(`Completed installing ${projectId}:${appReleaseHash}`);
128
111
  }
129
112
 
130
113
  async function installAppBuildReqs(props: { appDir: string }) {
131
114
  const { appDir } = props;
132
115
  const targetJsonFile = TargetJsonFile(appDir);
133
- const targetJson = targetJsonFile.readIfExists();
134
- if (!targetJson) {
135
- throw new Error('Target json file does not exist!');
116
+ const targetCfg = targetJsonFile.readIfExists();
117
+ if (!targetCfg || targetCfg.targetProtocol !== 'docker:') {
118
+ throw new Error('Target json file does not exist or is invalid!');
136
119
  }
137
120
 
138
121
  await runInDir(
139
122
  async () => {
140
- const targetHostSpawner = targetJsonFile.readHostSpawner();
123
+ const hostSpawner = targetJsonFile.readHostSpawner();
141
124
 
142
- await appCleanDockerComponent({ targetHostSpawner });
125
+ await appCleanDocker({ targetHostSpawner: hostSpawner });
143
126
 
144
- await buildDocker({
145
- targetJson,
146
- targetJsonFile,
147
- targetHostSpawner,
148
- pull: true,
127
+ const dockerImageId = await buildDockerImage({
128
+ targetHostSpawner: hostSpawner,
129
+ targetHardware: targetCfg.targetHardware,
130
+ dockerImageTag: targetCfg.dockerImageId,
131
+ pullBaseImage: true,
132
+ logger
149
133
  });
150
-
151
- await installVenv({
152
- targetJson,
153
- sourceSpawner: targetHostSpawner,
154
- targetJsonFile,
134
+ targetCfg.dockerImageId = dockerImageId;
135
+ // FIXME: This should use async internally
136
+ targetJsonFile.update((cfg) => {
137
+ if (cfg.targetProtocol === 'docker:') {
138
+ cfg.dockerImageId = dockerImageId;
139
+ }
155
140
  });
141
+
142
+ const targetSpawner = targetJsonFile.readContainerSpawner();
143
+ const pythonVenvPaths = await getPythonVenvPaths({ targetCfg });
144
+ await installPythonVenv({ targetSpawner, pythonVenvPaths, logger });
145
+ if (await hostSpawner.exists(PYTHON_REQUIREMENTS_FILE_NAME)) {
146
+ await installPythonReqs({
147
+ reqFilePath: PYTHON_REQUIREMENTS_FILE_NAME,
148
+ targetSpawner,
149
+ pythonVenvPaths,
150
+ logger
151
+ });
152
+ }
156
153
  },
157
154
  [],
158
- appDir,
155
+ appDir
159
156
  );
160
157
  }
161
158
 
162
- async function unPackApp(props: { spawner: Spawner; localDest: string; appDir: string }) {
159
+ async function unPackApp(props: {
160
+ spawner: Spawner;
161
+ localDest: string;
162
+ appDir: string;
163
+ }) {
163
164
  const { spawner, localDest, appDir } = props;
164
165
  await spawner.untar(fs.createReadStream(localDest), appDir);
165
166
  await spawner.rimraf(localDest);
@@ -182,25 +183,28 @@ async function checkValidProjectFiles({ appDir }) {
182
183
  TargetJsonFile(appDir).write({
183
184
  targetProtocol: 'docker:',
184
185
  dockerImageId: DOCKER_IMAGE_ID_INITIAL_VALUE,
185
- targetHardware: await getTargetHardwareType({}),
186
+ targetHardware: await getTargetHardwareType({})
186
187
  });
187
188
  }
188
189
 
189
- export async function uninstallApp(props: { projectId: string }): Promise<void> {
190
+ export async function uninstallApp(props: {
191
+ projectId: string;
192
+ }): Promise<void> {
190
193
  const { projectId } = props;
194
+ logger.info(`Uninstalling ${projectId}`);
191
195
  if (!(await AgentConfigFile().isAppPresent({ projectId }))) {
192
196
  logger.info(`Application ${projectId} not installed`);
193
197
  return;
194
198
  }
195
199
  try {
196
200
  await stopApp({ projectId });
197
- } catch {
198
- logger.info('Failed to stop app, may be left running...');
201
+ } catch (e) {
202
+ logger.warn(`Failed to stop ${projectId}, may be left running...\n${e}`);
199
203
  }
200
204
  await AgentConfigFile().setAppUninstalled({ projectId });
201
205
  // Delete application directory and backup
202
206
  const appDir = getAppDir(projectId);
203
- rimraf.sync(appDir);
204
- rimraf.sync(`${appDir}${BACKUP_EXT}`);
205
- logger.info('Uninstalled', projectId);
207
+ await rimraf(appDir);
208
+ await rimraf(`${appDir}${BACKUP_EXT}`);
209
+ logger.info(`Completed uninstalling ${projectId}`);
206
210
  }