@alwaysai/device-agent 0.0.3 → 0.0.5

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 (210) hide show
  1. package/lib/application-control/backup.d.ts +8 -0
  2. package/lib/application-control/backup.d.ts.map +1 -0
  3. package/lib/application-control/backup.js +34 -0
  4. package/lib/application-control/backup.js.map +1 -0
  5. package/lib/application-control/environment-variables.d.ts +9 -0
  6. package/lib/application-control/environment-variables.d.ts.map +1 -0
  7. package/lib/application-control/environment-variables.js +82 -0
  8. package/lib/application-control/environment-variables.js.map +1 -0
  9. package/lib/application-control/index.d.ts +9 -0
  10. package/lib/application-control/index.d.ts.map +1 -0
  11. package/lib/application-control/index.js +27 -0
  12. package/lib/application-control/index.js.map +1 -0
  13. package/lib/application-control/install.d.ts +16 -0
  14. package/lib/application-control/install.d.ts.map +1 -0
  15. package/lib/application-control/install.js +117 -0
  16. package/lib/application-control/install.js.map +1 -0
  17. package/lib/application-control/models.d.ts +8 -0
  18. package/lib/application-control/models.d.ts.map +1 -1
  19. package/lib/application-control/models.js +44 -11
  20. package/lib/application-control/models.js.map +1 -1
  21. package/lib/application-control/status.d.ts +26 -0
  22. package/lib/application-control/status.d.ts.map +1 -0
  23. package/lib/application-control/status.js +138 -0
  24. package/lib/application-control/status.js.map +1 -0
  25. package/lib/application-control/types.d.ts +5 -0
  26. package/lib/application-control/types.d.ts.map +1 -0
  27. package/lib/{util/spawner → application-control}/types.js +0 -0
  28. package/lib/{util/spawner → application-control}/types.js.map +1 -1
  29. package/lib/application-control/utils.d.ts +2 -9
  30. package/lib/application-control/utils.d.ts.map +1 -1
  31. package/lib/application-control/utils.js +14 -29
  32. package/lib/application-control/utils.js.map +1 -1
  33. package/lib/cloud-connection/device-agent-cloud-connection.d.ts +16 -1
  34. package/lib/cloud-connection/device-agent-cloud-connection.d.ts.map +1 -1
  35. package/lib/cloud-connection/device-agent-cloud-connection.js +239 -9
  36. package/lib/cloud-connection/device-agent-cloud-connection.js.map +1 -1
  37. package/lib/docker/docker-cmd.js +2 -2
  38. package/lib/docker/docker-cmd.js.map +1 -1
  39. package/lib/docker/docker-compose-cmd.js +2 -2
  40. package/lib/docker/docker-compose-cmd.js.map +1 -1
  41. package/lib/environment.d.ts +2 -0
  42. package/lib/environment.d.ts.map +1 -1
  43. package/lib/environment.js +3 -1
  44. package/lib/environment.js.map +1 -1
  45. package/lib/index.js +10 -8
  46. package/lib/index.js.map +1 -1
  47. package/lib/infrastructure/agent-config.d.ts +73 -0
  48. package/lib/infrastructure/agent-config.d.ts.map +1 -0
  49. package/lib/infrastructure/agent-config.js +186 -0
  50. package/lib/infrastructure/agent-config.js.map +1 -0
  51. package/lib/infrastructure/agent-config.test.d.ts +2 -0
  52. package/lib/infrastructure/agent-config.test.d.ts.map +1 -0
  53. package/lib/infrastructure/agent-config.test.js +135 -0
  54. package/lib/infrastructure/agent-config.test.js.map +1 -0
  55. package/lib/infrastructure/certificates-and-tokens.d.ts +6 -0
  56. package/lib/infrastructure/certificates-and-tokens.d.ts.map +1 -0
  57. package/lib/infrastructure/certificates-and-tokens.js +69 -0
  58. package/lib/infrastructure/certificates-and-tokens.js.map +1 -0
  59. package/lib/{util → infrastructure}/urls.d.ts +0 -0
  60. package/lib/infrastructure/urls.d.ts.map +1 -0
  61. package/lib/{util → infrastructure}/urls.js +3 -3
  62. package/lib/infrastructure/urls.js.map +1 -0
  63. package/lib/root.js +3 -3
  64. package/lib/root.js.map +1 -1
  65. package/lib/subcommands/app/app.d.ts +31 -14
  66. package/lib/subcommands/app/app.d.ts.map +1 -1
  67. package/lib/subcommands/app/app.js +117 -62
  68. package/lib/subcommands/app/app.js.map +1 -1
  69. package/lib/subcommands/app/index.d.ts.map +1 -1
  70. package/lib/subcommands/app/index.js +6 -1
  71. package/lib/subcommands/app/index.js.map +1 -1
  72. package/lib/subcommands/device/device.d.ts +6 -0
  73. package/lib/subcommands/device/device.d.ts.map +1 -0
  74. package/lib/subcommands/device/device.js +62 -0
  75. package/lib/subcommands/device/device.js.map +1 -0
  76. package/lib/subcommands/device/index.d.ts +2 -0
  77. package/lib/subcommands/device/index.d.ts.map +1 -0
  78. package/lib/subcommands/device/index.js +11 -0
  79. package/lib/subcommands/device/index.js.map +1 -0
  80. package/lib/subcommands/get-model-package.d.ts +5 -0
  81. package/lib/subcommands/get-model-package.d.ts.map +1 -0
  82. package/lib/subcommands/get-model-package.js +51 -0
  83. package/lib/subcommands/get-model-package.js.map +1 -0
  84. package/lib/subcommands/index.d.ts +8 -1
  85. package/lib/subcommands/index.d.ts.map +1 -1
  86. package/lib/subcommands/index.js +6 -6
  87. package/lib/subcommands/index.js.map +1 -1
  88. package/lib/subcommands/login.d.ts +3 -2
  89. package/lib/subcommands/login.d.ts.map +1 -1
  90. package/lib/subcommands/login.js +11 -4
  91. package/lib/subcommands/login.js.map +1 -1
  92. package/lib/util/copy-dir.js +3 -3
  93. package/lib/util/copy-dir.js.map +1 -1
  94. package/lib/util/directories.d.ts +1 -1
  95. package/lib/util/directories.d.ts.map +1 -1
  96. package/lib/util/directories.js +9 -14
  97. package/lib/util/directories.js.map +1 -1
  98. package/lib/util/get-device-id.d.ts +2 -0
  99. package/lib/util/get-device-id.d.ts.map +1 -0
  100. package/lib/util/get-device-id.js +24 -0
  101. package/lib/util/get-device-id.js.map +1 -0
  102. package/package.json +19 -14
  103. package/readme.md +176 -72
  104. package/src/application-control/backup.ts +32 -0
  105. package/src/application-control/environment-variables.ts +81 -0
  106. package/src/application-control/index.ts +40 -0
  107. package/src/application-control/install.ts +126 -0
  108. package/src/application-control/models.ts +51 -11
  109. package/src/application-control/status.ts +156 -0
  110. package/src/application-control/types.ts +1 -0
  111. package/src/application-control/utils.ts +12 -27
  112. package/src/cloud-connection/device-agent-cloud-connection.ts +280 -13
  113. package/src/docker/docker-cmd.ts +1 -1
  114. package/src/docker/docker-compose-cmd.ts +1 -1
  115. package/src/environment.ts +2 -0
  116. package/src/index.ts +10 -7
  117. package/src/infrastructure/agent-config.test.ts +143 -0
  118. package/src/infrastructure/agent-config.ts +217 -0
  119. package/src/infrastructure/certificates-and-tokens.ts +71 -0
  120. package/src/{util → infrastructure}/urls.ts +1 -1
  121. package/src/root.ts +3 -3
  122. package/src/subcommands/app/app.ts +135 -62
  123. package/src/subcommands/app/index.ts +11 -1
  124. package/src/subcommands/device/device.ts +63 -0
  125. package/src/subcommands/device/index.ts +8 -0
  126. package/src/subcommands/get-model-package.ts +60 -0
  127. package/src/subcommands/index.ts +5 -5
  128. package/src/subcommands/login.ts +11 -4
  129. package/src/util/copy-dir.ts +1 -1
  130. package/src/util/directories.ts +12 -17
  131. package/src/util/get-device-id.ts +22 -0
  132. package/lib/application-control/application-control.d.ts +0 -46
  133. package/lib/application-control/application-control.d.ts.map +0 -1
  134. package/lib/application-control/application-control.js +0 -234
  135. package/lib/application-control/application-control.js.map +0 -1
  136. package/lib/constants.d.ts +0 -17
  137. package/lib/constants.d.ts.map +0 -1
  138. package/lib/constants.js +0 -24
  139. package/lib/constants.js.map +0 -1
  140. package/lib/subcommands/device-control.d.ts +0 -2
  141. package/lib/subcommands/device-control.d.ts.map +0 -1
  142. package/lib/subcommands/device-control.js +0 -19
  143. package/lib/subcommands/device-control.js.map +0 -1
  144. package/lib/subcommands/test-app.d.ts +0 -2
  145. package/lib/subcommands/test-app.d.ts.map +0 -1
  146. package/lib/subcommands/test-app.js +0 -29
  147. package/lib/subcommands/test-app.js.map +0 -1
  148. package/lib/util/spawner/gnu-spawner.d.ts +0 -9
  149. package/lib/util/spawner/gnu-spawner.d.ts.map +0 -1
  150. package/lib/util/spawner/gnu-spawner.js +0 -102
  151. package/lib/util/spawner/gnu-spawner.js.map +0 -1
  152. package/lib/util/spawner/js-spawner.d.ts +0 -5
  153. package/lib/util/spawner/js-spawner.d.ts.map +0 -1
  154. package/lib/util/spawner/js-spawner.js +0 -89
  155. package/lib/util/spawner/js-spawner.js.map +0 -1
  156. package/lib/util/spawner/types.d.ts +0 -28
  157. package/lib/util/spawner/types.d.ts.map +0 -1
  158. package/lib/util/spawner-base/index.d.ts +0 -17
  159. package/lib/util/spawner-base/index.d.ts.map +0 -1
  160. package/lib/util/spawner-base/index.js +0 -30
  161. package/lib/util/spawner-base/index.js.map +0 -1
  162. package/lib/util/spawner-base/run-foreground-sync.d.ts +0 -3
  163. package/lib/util/spawner-base/run-foreground-sync.d.ts.map +0 -1
  164. package/lib/util/spawner-base/run-foreground-sync.js +0 -18
  165. package/lib/util/spawner-base/run-foreground-sync.js.map +0 -1
  166. package/lib/util/spawner-base/run-foreground.d.ts +0 -3
  167. package/lib/util/spawner-base/run-foreground.d.ts.map +0 -1
  168. package/lib/util/spawner-base/run-foreground.js +0 -49
  169. package/lib/util/spawner-base/run-foreground.js.map +0 -1
  170. package/lib/util/spawner-base/run-streaming.d.ts +0 -4
  171. package/lib/util/spawner-base/run-streaming.d.ts.map +0 -1
  172. package/lib/util/spawner-base/run-streaming.js +0 -35
  173. package/lib/util/spawner-base/run-streaming.js.map +0 -1
  174. package/lib/util/spawner-base/run.d.ts +0 -4
  175. package/lib/util/spawner-base/run.d.ts.map +0 -1
  176. package/lib/util/spawner-base/run.js +0 -56
  177. package/lib/util/spawner-base/run.js.map +0 -1
  178. package/lib/util/urls.d.ts.map +0 -1
  179. package/lib/util/urls.js.map +0 -1
  180. package/lib/web/index.html +0 -229
  181. package/lib/web/static/Karla.css +0 -18
  182. package/lib/web/static/bootstrap-4.3.1.min.css +0 -7
  183. package/lib/web/static/bootstrap-4.3.1.min.js +0 -7
  184. package/lib/web/static/favicon.ico +0 -0
  185. package/lib/web/static/jquery-3.3.1.slim.min.js +0 -2
  186. package/lib/web/static/popper-1.14.7.min.js +0 -5
  187. package/lib/web/web-interface.d.ts +0 -2
  188. package/lib/web/web-interface.d.ts.map +0 -1
  189. package/lib/web/web-interface.js +0 -74
  190. package/lib/web/web-interface.js.map +0 -1
  191. package/src/application-control/application-control.ts +0 -273
  192. package/src/constants.ts +0 -32
  193. package/src/subcommands/device-control.ts +0 -16
  194. package/src/subcommands/test-app.ts +0 -30
  195. package/src/util/spawner/gnu-spawner.ts +0 -114
  196. package/src/util/spawner/js-spawner.ts +0 -110
  197. package/src/util/spawner/types.ts +0 -28
  198. package/src/util/spawner-base/index.ts +0 -28
  199. package/src/util/spawner-base/run-foreground-sync.ts +0 -16
  200. package/src/util/spawner-base/run-foreground.ts +0 -49
  201. package/src/util/spawner-base/run-streaming.ts +0 -40
  202. package/src/util/spawner-base/run.ts +0 -60
  203. package/src/web/index.html +0 -229
  204. package/src/web/static/Karla.css +0 -18
  205. package/src/web/static/bootstrap-4.3.1.min.css +0 -7
  206. package/src/web/static/bootstrap-4.3.1.min.js +0 -7
  207. package/src/web/static/favicon.ico +0 -0
  208. package/src/web/static/jquery-3.3.1.slim.min.js +0 -2
  209. package/src/web/static/popper-1.14.7.min.js +0 -5
  210. package/src/web/web-interface.ts +0 -89
@@ -0,0 +1,143 @@
1
+ import * as tempy from 'tempy';
2
+ import { AgentConfigFile } from './agent-config';
3
+
4
+ const mockAgentModeGetter = jest.fn().mockReturnValue(undefined);
5
+ jest.mock('../environment', () => ({
6
+ get ALWAYSAI_DEVICE_AGENT_MODE() {
7
+ return mockAgentModeGetter();
8
+ },
9
+ }));
10
+
11
+ const configFile = AgentConfigFile(tempy.directory());
12
+
13
+ describe('Test Agent Config', () => {
14
+ beforeEach(() => {
15
+ configFile.remove();
16
+ configFile.initialize();
17
+ });
18
+ describe('Test applications', () => {
19
+ test('Commands with no apps', async () => {
20
+ const apps = await configFile.getApps();
21
+ expect(apps).toEqual([]);
22
+ const app = await configFile.getApp({ projectId: 'wrong-id' });
23
+ expect(app).toBeNull();
24
+ const present = await configFile.isAppPresent({ projectId: 'another-id' });
25
+ expect(present).toBeFalsy();
26
+ const ready = await configFile.isAppReady({ projectId: 'yet-another-id' });
27
+ expect(ready).toBeFalsy();
28
+ });
29
+
30
+ test('Indicate app installation in progress', async () => {
31
+ const projectId = 'add-me';
32
+ const version = 'im-a-version';
33
+
34
+ await configFile.setAppInstalling({ projectId, version });
35
+ const apps = await configFile.getApps();
36
+ expect(apps).toEqual([
37
+ {
38
+ projectId,
39
+ version,
40
+ ready: false,
41
+ },
42
+ ]);
43
+ const readyApps = await configFile.getReadyApps();
44
+ expect(readyApps).toEqual([]);
45
+ const app = await configFile.getApp({ projectId });
46
+ expect(app).toEqual({
47
+ projectId,
48
+ version,
49
+ ready: false,
50
+ });
51
+ const present = await configFile.isAppPresent({ projectId });
52
+ expect(present).toBeTruthy();
53
+ const ready = await configFile.isAppReady({ projectId });
54
+ expect(ready).toBeFalsy();
55
+ });
56
+
57
+ test('Indicate app installation complete', async () => {
58
+ const projectId = 'add-me';
59
+ const version = 'im-a-version';
60
+
61
+ await configFile.setAppInstalling({ projectId, version });
62
+ await configFile.setAppInstalled({ projectId, version });
63
+ const apps = await configFile.getApps();
64
+ expect(apps).toEqual([
65
+ {
66
+ projectId,
67
+ version,
68
+ ready: true,
69
+ },
70
+ ]);
71
+ const readyApps = await configFile.getReadyApps();
72
+ expect(readyApps).toEqual([
73
+ {
74
+ projectId,
75
+ version,
76
+ ready: true,
77
+ },
78
+ ]);
79
+ const app = await configFile.getApp({ projectId });
80
+ expect(app).toEqual({
81
+ projectId,
82
+ version,
83
+ ready: true,
84
+ });
85
+ const appVersion = await configFile.getAppVersion({ projectId });
86
+ expect(appVersion).toEqual(version);
87
+ const present = await configFile.isAppPresent({ projectId });
88
+ expect(present).toBeTruthy();
89
+ const ready = await configFile.isAppReady({ projectId });
90
+ expect(ready).toBeTruthy();
91
+ });
92
+
93
+ test('Indicate app uninstalled', async () => {
94
+ const projectId = 'add-me';
95
+ const version = 'im-a-version';
96
+
97
+ await configFile.setAppInstalling({ projectId, version });
98
+ await configFile.setAppInstalled({ projectId, version });
99
+ await configFile.setAppUninstalled({ projectId });
100
+ const apps = await configFile.getApps();
101
+ expect(apps).toEqual([]);
102
+ const app = await configFile.getApp({ projectId: 'wrong-id' });
103
+ expect(app).toBeNull();
104
+ const present = await configFile.isAppPresent({ projectId: 'another-id' });
105
+ expect(present).toBeFalsy();
106
+ const ready = await configFile.isAppReady({ projectId: 'yet-another-id' });
107
+ expect(ready).toBeFalsy();
108
+ });
109
+
110
+ test('Set and get backup', async () => {
111
+ const projectId = 'add-me';
112
+ const version = 'im-a-version';
113
+
114
+ await configFile.setAppInstalling({ projectId, version });
115
+ await configFile.setAppInstalled({ projectId, version });
116
+ const backup1 = await configFile.getAppBackup({ projectId });
117
+ expect(backup1).toBeNull();
118
+ await configFile.setAppBackup({ projectId });
119
+ const apps = await configFile.getApps();
120
+ expect(apps).toEqual([
121
+ {
122
+ projectId,
123
+ version,
124
+ ready: true,
125
+ backup: {
126
+ version,
127
+ },
128
+ },
129
+ ]);
130
+ const app = await configFile.getApp({ projectId });
131
+ expect(app).toEqual({
132
+ projectId,
133
+ version,
134
+ ready: true,
135
+ backup: {
136
+ version,
137
+ },
138
+ });
139
+ const backup2 = await configFile.getAppBackup({ projectId });
140
+ expect(backup2).toEqual({ version });
141
+ });
142
+ });
143
+ });
@@ -0,0 +1,217 @@
1
+ import { ConfigFileSchema } from '@alwaysai/config-nodejs';
2
+ import { JSONSchemaType } from 'ajv';
3
+ import { homedir } from 'os';
4
+ import { join } from 'path';
5
+ import { ALWAYSAI_DEVICE_AGENT_MODE } from '../environment';
6
+
7
+ export interface AppBackupConfig {
8
+ version: string;
9
+ }
10
+
11
+ export interface InstalledAppConfig {
12
+ projectId: string;
13
+ version: string;
14
+ ready: boolean;
15
+ backup?: AppBackupConfig;
16
+ }
17
+
18
+ export interface AgentConfig {
19
+ applications: InstalledAppConfig[];
20
+ }
21
+
22
+ const schema: JSONSchemaType<AgentConfig> = {
23
+ type: 'object',
24
+ properties: {
25
+ applications: {
26
+ type: 'array',
27
+ items: {
28
+ type: 'object',
29
+ properties: {
30
+ projectId: { type: 'string' },
31
+ version: { type: 'string' },
32
+ ready: { type: 'boolean' },
33
+ backup: {
34
+ type: 'object',
35
+ nullable: true,
36
+ properties: {
37
+ version: { type: 'string' },
38
+ },
39
+ required: ['version'],
40
+ additionalProperties: true,
41
+ },
42
+ },
43
+ required: ['projectId', 'version', 'ready'],
44
+ additionalProperties: true,
45
+ },
46
+ },
47
+ },
48
+ required: ['applications'],
49
+ additionalProperties: true,
50
+ };
51
+
52
+ const ALWAYSAI_CONFIG_DIR = join(homedir(), '.config', 'alwaysai');
53
+
54
+ const AGENT_CONFIG_FILE_NAME = 'alwaysai.agent.json';
55
+
56
+ export function AgentConfigFile(dir = ALWAYSAI_CONFIG_DIR) {
57
+ const path = join(dir, AGENT_CONFIG_FILE_NAME);
58
+ const initialValue: AgentConfig = {
59
+ applications: [],
60
+ };
61
+ const configFile = ConfigFileSchema({
62
+ path,
63
+ schema,
64
+ initialValue,
65
+ });
66
+
67
+ return {
68
+ ...configFile,
69
+ name: AGENT_CONFIG_FILE_NAME,
70
+ getApps,
71
+ getReadyApps,
72
+ getApp,
73
+ isAppPresent,
74
+ isAppReady,
75
+ removeApp,
76
+ setAppInstalling,
77
+ setAppInstalled,
78
+ setAppUninstalled,
79
+ getAppVersion,
80
+ setAppBackup,
81
+ getAppBackup,
82
+ };
83
+
84
+ async function getApps() {
85
+ const config = configFile.read();
86
+ return config.applications;
87
+ }
88
+
89
+ async function getReadyApps() {
90
+ const config = configFile.read();
91
+ return config.applications.filter((app) => {
92
+ return app.ready;
93
+ });
94
+ }
95
+
96
+ async function getApp(props: { projectId: string }) {
97
+ const { projectId } = props;
98
+ const apps = await getApps();
99
+ for (const app of apps) {
100
+ if (app.projectId === projectId) {
101
+ return app;
102
+ }
103
+ }
104
+ return null;
105
+ }
106
+
107
+ async function isAppPresent(props: { projectId: string }): Promise<boolean> {
108
+ const { projectId } = props;
109
+ const app = await getApp({ projectId });
110
+ if (app) {
111
+ return true;
112
+ }
113
+ return false;
114
+ }
115
+
116
+ async function isAppReady(props: { projectId: string }): Promise<boolean> {
117
+ const { projectId } = props;
118
+ const app = await getApp({ projectId });
119
+ if (app && app.ready) {
120
+ return true;
121
+ }
122
+ return false;
123
+ }
124
+
125
+ async function removeApp(props: { projectId: string }) {
126
+ const { projectId } = props;
127
+ const config = configFile.read();
128
+ const newList = config.applications.filter((app) => {
129
+ return app.projectId !== projectId;
130
+ });
131
+ config.applications = newList;
132
+ configFile.write(config);
133
+ }
134
+
135
+ async function setAppInstalling(props: { projectId: string; version: string }) {
136
+ const { projectId, version } = props;
137
+ const app = await getApp({ projectId });
138
+ if (app) {
139
+ await removeApp({ projectId });
140
+ const config = configFile.read();
141
+ config.applications.push({
142
+ projectId,
143
+ version,
144
+ ready: false,
145
+ });
146
+ configFile.write(config);
147
+ } else {
148
+ const config = configFile.read();
149
+ config.applications.push({
150
+ projectId,
151
+ version,
152
+ ready: false,
153
+ });
154
+ configFile.write(config);
155
+ }
156
+ }
157
+
158
+ async function setAppInstalled(props: { projectId: string; version: string }) {
159
+ const { projectId, version } = props;
160
+ const app = await getApp({ projectId });
161
+ if (app) {
162
+ await removeApp({ projectId });
163
+ const config = configFile.read();
164
+ app.version = version;
165
+ config.applications.push({
166
+ projectId,
167
+ version,
168
+ ready: true,
169
+ });
170
+ configFile.write(config);
171
+ } else {
172
+ const config = configFile.read();
173
+ config.applications.push({
174
+ projectId,
175
+ version,
176
+ ready: true,
177
+ });
178
+ configFile.write(config);
179
+ }
180
+ }
181
+
182
+ async function setAppUninstalled(props: { projectId: string }) {
183
+ const { projectId } = props;
184
+ await removeApp({ projectId });
185
+ }
186
+
187
+ async function getAppVersion(props: { projectId: string }) {
188
+ const { projectId } = props;
189
+ const app = await getApp({ projectId });
190
+ if (!app) {
191
+ throw new Error(`App ${projectId} not installed`);
192
+ }
193
+ return app.version;
194
+ }
195
+
196
+ async function setAppBackup(props: { projectId: string }) {
197
+ const { projectId } = props;
198
+ const app = await getApp({ projectId });
199
+ if (!app) {
200
+ throw new Error(`Project ${projectId} not installed!`);
201
+ }
202
+ await removeApp({ projectId });
203
+ const config = configFile.read();
204
+ app.backup = { version: app.version };
205
+ config.applications.push(app);
206
+ configFile.write(config);
207
+ }
208
+
209
+ async function getAppBackup(props: { projectId: string }) {
210
+ const { projectId } = props;
211
+ const app = await getApp({ projectId });
212
+ if (app && app.backup) {
213
+ return app.backup;
214
+ }
215
+ return null;
216
+ }
217
+ }
@@ -0,0 +1,71 @@
1
+ import { DeviceTokens, writeOrUpdateDeviceCfgFile } from 'alwaysai/lib/components/device';
2
+ import { checkUserIsLoggedInComponent } from 'alwaysai/lib/components/user';
3
+ import { LOCAL_AAI_CFG_DIR, LOCAL_CERT_AND_KEY_DIR } from 'alwaysai/lib/constants';
4
+ import { checkPaidPlan } from 'alwaysai/lib/core/project';
5
+ import {
6
+ CliRpcClient,
7
+ getDeviceCertificates,
8
+ IotRpcDevice,
9
+ refreshDevice,
10
+ } from 'alwaysai/lib/infrastructure';
11
+ import { JsSpawner, Spawner, writeCertificate, writeTokens } from 'alwaysai/lib/util';
12
+
13
+ // NOTE: This is reimplemented from the CLI to work for local checks
14
+ export async function getTargetHardwareUuid(spawner: Spawner) {
15
+ if (await spawner.exists('/var/lib/dbus/machine-id')) {
16
+ return await spawner.run({ exe: 'cat', args: ['/var/lib/dbus/machine-id'] });
17
+ }
18
+ if (await spawner.exists('/etc/machine-id')) {
19
+ return await spawner.run({ exe: 'cat', args: ['/etc/machine-id'] });
20
+ }
21
+ return await spawner.run({ exe: 'hostname' });
22
+ }
23
+
24
+ // NOTE: This closely follows the flow of deviceCheckAndUpdateComponent in the CLI
25
+ export async function writeCertificateAndToken(props: { deviceUuid: string }) {
26
+ const { deviceUuid } = props;
27
+ await checkUserIsLoggedInComponent({ yes: true });
28
+ if (!(await checkPaidPlan())) {
29
+ throw new Error(`This action only supported for Enterprise alwaysAI accounts!`);
30
+ }
31
+ const device: IotRpcDevice = (await CliRpcClient().getDeviceByUUID({
32
+ uuid: deviceUuid,
33
+ })) as IotRpcDevice;
34
+ if (!device) {
35
+ throw new Error(`Device not found for deviceId=${deviceUuid}`);
36
+ }
37
+ // TODO: Update HW ID if not there
38
+ if (device.hardware_ids && device.hardware_ids !== '') {
39
+ const spawner = JsSpawner();
40
+ const hardwareId = await getTargetHardwareUuid(spawner);
41
+ if (hardwareId !== device.hardware_ids) {
42
+ throw new Error('Certificates not intended for this device!');
43
+ }
44
+ }
45
+ const response = await refreshDevice(device.uuid);
46
+ const tokens: DeviceTokens = {
47
+ deviceId: deviceUuid,
48
+ accessToken: response.accessToken,
49
+ refreshToken: response.refreshToken,
50
+ idToken: response.idToken,
51
+ };
52
+ const tokenSpawner = JsSpawner({ path: LOCAL_AAI_CFG_DIR });
53
+ await writeTokens({ spawner: tokenSpawner, tokens });
54
+ await writeOrUpdateDeviceCfgFile({ spawner: tokenSpawner });
55
+
56
+ let iotKeys = device.iot_keys;
57
+ if (!iotKeys) {
58
+ // there are no certificates, we need to generate new ones
59
+ console.log('Generating new certificate');
60
+ const response = await getDeviceCertificates(device.uuid, device.mode);
61
+ iotKeys = response.iotKeys;
62
+ }
63
+ const certSpawner = JsSpawner({ path: LOCAL_CERT_AND_KEY_DIR });
64
+ await writeCertificate({
65
+ spawner: certSpawner,
66
+ certificate: iotKeys.certificatePem,
67
+ privateKey: iotKeys.keyPair.PrivateKey,
68
+ rootCa: iotKeys.rootCA,
69
+ });
70
+ console.log('Updated tokens and certificate');
71
+ }
@@ -1,5 +1,5 @@
1
- import { getSystemId } from 'alwaysai';
2
1
  import { CliTerseError } from '@alwaysai/alwayscli';
2
+ import { getSystemId } from 'alwaysai/lib/infrastructure';
3
3
 
4
4
  export function getIoTCoreEndpointUrl() {
5
5
  let iotCoreEndpointUrl = '';
package/src/root.ts CHANGED
@@ -3,16 +3,16 @@ const winston = require('winston');
3
3
  import { CliBranch } from '@alwaysai/alwayscli';
4
4
 
5
5
  import { subcommands } from './subcommands';
6
- import { ALWAYSAI_CLI_EXECUTABLE_NAME } from './constants';
6
+ import { ALWAYSAI_LOG_LEVEL } from './environment';
7
7
 
8
8
  winston.configure({
9
- level: process.env.AAI_LOG_LEVEL || 'info',
9
+ level: ALWAYSAI_LOG_LEVEL || 'info',
10
10
  transports: [new winston.transports.Console()],
11
11
  format: winston.format.simple(),
12
12
  });
13
13
 
14
14
  export const root = CliBranch({
15
- name: ALWAYSAI_CLI_EXECUTABLE_NAME,
15
+ name: 'aai-agent',
16
16
  description: 'Manage your alwaysAI production device',
17
17
  subcommands,
18
18
  });