@dbos-inc/dbos-cloud 0.8.41-preview → 0.8.45-preview
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Gruntfile.js +9 -0
- package/applications/delete-app.ts +36 -0
- package/applications/deploy-app-code.ts +159 -0
- package/applications/get-app-logs.ts +36 -0
- package/applications/index.ts +7 -0
- package/applications/list-apps.ts +41 -0
- package/applications/register-app.ts +45 -0
- package/applications/types.ts +8 -0
- package/applications/update-app.ts +47 -0
- package/cli.ts +1 -15
- package/cloudutils.ts +42 -0
- package/dist/packages/dbos-cloud/cli.js +0 -12
- package/dist/packages/dbos-cloud/cli.js.map +1 -1
- package/dist/packages/dbos-cloud/userdb.d.ts +0 -2
- package/dist/packages/dbos-cloud/userdb.d.ts.map +1 -1
- package/dist/packages/dbos-cloud/userdb.js +1 -173
- package/dist/packages/dbos-cloud/userdb.js.map +1 -1
- package/dist/src/dbos-runtime/cli.d.ts.map +1 -1
- package/dist/src/dbos-runtime/cli.js +14 -0
- package/dist/src/dbos-runtime/cli.js.map +1 -1
- package/dist/src/dbos-runtime/migrate.d.ts +3 -0
- package/dist/src/dbos-runtime/migrate.d.ts.map +1 -0
- package/dist/src/dbos-runtime/migrate.js +175 -0
- package/dist/src/dbos-runtime/migrate.js.map +1 -0
- package/dist/src/system_database.d.ts +2 -0
- package/dist/src/system_database.d.ts.map +1 -1
- package/dist/src/system_database.js +26 -11
- package/dist/src/system_database.js.map +1 -1
- package/dist/src/utils.d.ts +1 -0
- package/dist/src/utils.d.ts.map +1 -1
- package/dist/src/utils.js +26 -1
- package/dist/src/utils.js.map +1 -1
- package/login.ts +122 -0
- package/package.json +1 -1
- package/register.ts +35 -0
- package/tsconfig.json +30 -0
- package/userdb.ts +100 -0
package/Gruntfile.js
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2
|
+
var nbgv = require('nerdbank-gitversioning')
|
|
3
|
+
|
|
4
|
+
module.exports = function (grunt) {
|
|
5
|
+
grunt.registerTask('setversion', function () {
|
|
6
|
+
var done = this.async();
|
|
7
|
+
nbgv.setPackageVersion().then(() => done());
|
|
8
|
+
});
|
|
9
|
+
};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { GlobalLogger } from "../../../src/telemetry/logs";
|
|
3
|
+
import { getCloudCredentials } from "../cloudutils";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
export async function deleteApp(host: string): Promise<number> {
|
|
7
|
+
const logger = new GlobalLogger();
|
|
8
|
+
const userCredentials = getCloudCredentials();
|
|
9
|
+
const bearerToken = "Bearer " + userCredentials.token;
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
+
const packageJson = require(path.join(process.cwd(), 'package.json')) as { name: string };
|
|
13
|
+
const appName = packageJson.name;
|
|
14
|
+
logger.info(`Loaded application name from package.json: ${appName}`)
|
|
15
|
+
logger.info(`Deleting application: ${appName}`)
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
await axios.delete(`https://${host}/${userCredentials.userName}/application/${appName}`, {
|
|
19
|
+
headers: {
|
|
20
|
+
"Content-Type": "application/json",
|
|
21
|
+
Authorization: bearerToken,
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
logger.info(`Successfully deleted application: ${appName}`);
|
|
26
|
+
return 0;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
if (axios.isAxiosError(e) && e.response) {
|
|
29
|
+
logger.error(`Failed to delete application ${appName}: ${e.response?.data}`);
|
|
30
|
+
return 1;
|
|
31
|
+
} else {
|
|
32
|
+
logger.error(`Failed to delete application ${appName}: ${(e as Error).message}`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { execSync } from "child_process";
|
|
3
|
+
import { writeFileSync, existsSync } from 'fs';
|
|
4
|
+
import { GlobalLogger } from "../../../src/telemetry/logs";
|
|
5
|
+
import { getCloudCredentials, runCommand } from "../cloudutils";
|
|
6
|
+
import { createDirectory, readFileSync, sleep } from "../../../src/utils";
|
|
7
|
+
import path from "path";
|
|
8
|
+
import { Application } from "./types";
|
|
9
|
+
|
|
10
|
+
const deployDirectoryName = "dbos_deploy";
|
|
11
|
+
|
|
12
|
+
type DeployOutput = {
|
|
13
|
+
ApplicationName: string;
|
|
14
|
+
ApplicationVersion: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export async function deployAppCode(host: string, docker: boolean): Promise<number> {
|
|
18
|
+
const logger = new GlobalLogger();
|
|
19
|
+
const userCredentials = getCloudCredentials();
|
|
20
|
+
const bearerToken = "Bearer " + userCredentials.token;
|
|
21
|
+
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
23
|
+
const packageJson = require(path.join(process.cwd(), 'package.json')) as { name: string };
|
|
24
|
+
const appName = packageJson.name;
|
|
25
|
+
logger.info(`Loaded application name from package.json: ${appName}`)
|
|
26
|
+
|
|
27
|
+
createDirectory(deployDirectoryName);
|
|
28
|
+
|
|
29
|
+
// Verify that package-lock.json exists
|
|
30
|
+
if (!existsSync(path.join(process.cwd(), 'package-lock.json'))) {
|
|
31
|
+
logger.error("package-lock.json not found. Please run 'npm install' before deploying.")
|
|
32
|
+
return 1;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
if (docker) {
|
|
36
|
+
// Build the application inside a Docker container using the same base image as our cloud setup
|
|
37
|
+
logger.info(`Building ${appName} using Docker`)
|
|
38
|
+
const dockerSuccess = await buildAppInDocker(appName);
|
|
39
|
+
if (!dockerSuccess) {
|
|
40
|
+
return 1;
|
|
41
|
+
}
|
|
42
|
+
} else {
|
|
43
|
+
// Zip the current directory and deploy from there. Requires app to have already been built. Only for testing.
|
|
44
|
+
execSync(`zip -ry ${deployDirectoryName}/${appName}.zip ./* -x ${deployDirectoryName}/* > /dev/null`);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
const zipData = readFileSync(`${deployDirectoryName}/${appName}.zip`, "base64");
|
|
49
|
+
|
|
50
|
+
// Submit the deploy request
|
|
51
|
+
logger.info(`Submitting deploy request for ${appName}`)
|
|
52
|
+
const response = await axios.post(
|
|
53
|
+
`https://${host}/${userCredentials.userName}/application/${appName}`,
|
|
54
|
+
{
|
|
55
|
+
application_archive: zipData,
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
headers: {
|
|
59
|
+
"Content-Type": "application/json",
|
|
60
|
+
Authorization: bearerToken,
|
|
61
|
+
},
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
const deployOutput = response.data as DeployOutput;
|
|
65
|
+
logger.info(`Submitted deploy request for ${appName}. Assigned version: ${deployOutput.ApplicationVersion}`);
|
|
66
|
+
|
|
67
|
+
// Wait for the application to become available
|
|
68
|
+
let count = 0
|
|
69
|
+
let applicationAvailable = false
|
|
70
|
+
while (!applicationAvailable) {
|
|
71
|
+
count += 1
|
|
72
|
+
if (count % 5 === 0) {
|
|
73
|
+
logger.info(`Waiting for ${appName} with version ${deployOutput.ApplicationVersion} to be available`);
|
|
74
|
+
if (count > 20) {
|
|
75
|
+
logger.info(`If ${appName} takes too long to become available, check its logs at...`);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Retrieve the application status, check if it is "AVAILABLE"
|
|
80
|
+
const list = await axios.get(
|
|
81
|
+
`https://${host}/${userCredentials.userName}/application`,
|
|
82
|
+
{
|
|
83
|
+
headers: {
|
|
84
|
+
Authorization: bearerToken,
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
);
|
|
88
|
+
const applications: Application[] = list.data as Application[];
|
|
89
|
+
for (const application of applications) {
|
|
90
|
+
if (application.Name === appName && application.Status === "AVAILABLE") {
|
|
91
|
+
applicationAvailable = true
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
await sleep(1000)
|
|
95
|
+
}
|
|
96
|
+
logger.info(`Application ${appName} successfuly deployed`)
|
|
97
|
+
logger.info(`Access your application at https://${host}/${userCredentials.userName}/application/${appName}`)
|
|
98
|
+
return 0;
|
|
99
|
+
} catch (e) {
|
|
100
|
+
if (axios.isAxiosError(e) && e.response) {
|
|
101
|
+
logger.error(`Failed to deploy application ${appName}: ${e.response?.data}`);
|
|
102
|
+
return 1;
|
|
103
|
+
} else {
|
|
104
|
+
logger.error(`Failed to deploy application ${appName}: ${(e as Error).message}`);
|
|
105
|
+
return 1;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
async function buildAppInDocker(appName: string): Promise<boolean> {
|
|
111
|
+
const logger = new GlobalLogger();
|
|
112
|
+
|
|
113
|
+
// Verify Docker is running
|
|
114
|
+
try {
|
|
115
|
+
execSync(`docker > /dev/null 2>&1`)
|
|
116
|
+
} catch (e) {
|
|
117
|
+
logger.error("Docker not available. To deploy, please start the Docker daemon and make the `docker` command runnable without sudo.")
|
|
118
|
+
return false
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
const dockerFileName = `${deployDirectoryName}/Dockerfile.dbos`;
|
|
122
|
+
const containerName = `dbos-builder-${appName}`;
|
|
123
|
+
|
|
124
|
+
// Dockerfile content
|
|
125
|
+
const dockerFileContent = `
|
|
126
|
+
FROM node:lts-bookworm-slim
|
|
127
|
+
RUN apt update
|
|
128
|
+
RUN apt install -y zip
|
|
129
|
+
WORKDIR /app
|
|
130
|
+
COPY . .
|
|
131
|
+
RUN npm clean-install
|
|
132
|
+
RUN npm run build
|
|
133
|
+
RUN npm prune --omit=dev
|
|
134
|
+
RUN zip -ry ${appName}.zip ./* -x "${appName}.zip" -x "${deployDirectoryName}/*" > /dev/null
|
|
135
|
+
`;
|
|
136
|
+
const dockerIgnoreContent = `
|
|
137
|
+
node_modules/
|
|
138
|
+
${deployDirectoryName}/
|
|
139
|
+
dist/
|
|
140
|
+
`;
|
|
141
|
+
try {
|
|
142
|
+
// Write the Dockerfile and .dockerignore
|
|
143
|
+
writeFileSync(dockerFileName, dockerFileContent);
|
|
144
|
+
writeFileSync(`${deployDirectoryName}/Dockerfile.dbos.dockerignore`, dockerIgnoreContent);
|
|
145
|
+
// Build the Docker image. As build takes a long time, use runCommand to stream its output to stdout.
|
|
146
|
+
await runCommand('docker', ['build', '-t', appName, '-f', dockerFileName, '.'])
|
|
147
|
+
// Run the container
|
|
148
|
+
execSync(`docker run -d --name ${containerName} ${appName}`);
|
|
149
|
+
// Copy the archive from the container to the local deploy directory
|
|
150
|
+
execSync(`docker cp ${containerName}:/app/${appName}.zip ${deployDirectoryName}/${appName}.zip`);
|
|
151
|
+
// Stop and remove the container
|
|
152
|
+
execSync(`docker stop ${containerName}`);
|
|
153
|
+
execSync(`docker rm ${containerName}`);
|
|
154
|
+
return true;
|
|
155
|
+
} catch (e) {
|
|
156
|
+
logger.error(`Failed to build application ${appName}: ${(e as Error).message}`);
|
|
157
|
+
return false;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { GlobalLogger } from "../../../src/telemetry/logs";
|
|
3
|
+
import { getCloudCredentials } from "../cloudutils";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
export async function getAppLogs(host: string): Promise<number> {
|
|
7
|
+
const logger = new GlobalLogger();
|
|
8
|
+
const userCredentials = getCloudCredentials();
|
|
9
|
+
const bearerToken = "Bearer " + userCredentials.token;
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
+
const packageJson = require(path.join(process.cwd(), 'package.json')) as { name: string };
|
|
13
|
+
const appName = packageJson.name;
|
|
14
|
+
logger.info(`Retrieving logs for application: ${appName}`)
|
|
15
|
+
|
|
16
|
+
try {
|
|
17
|
+
const res = await axios.get(`https://${host}/${userCredentials.userName}/logs/application/${appName}`, {
|
|
18
|
+
headers: {
|
|
19
|
+
"Content-Type": "application/json",
|
|
20
|
+
Authorization: bearerToken,
|
|
21
|
+
},
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
logger.info(`Successfully retrieved logs of application: ${appName}`);
|
|
25
|
+
logger.info(res.data)
|
|
26
|
+
return 0;
|
|
27
|
+
} catch (e) {
|
|
28
|
+
if (axios.isAxiosError(e) && e.response) {
|
|
29
|
+
logger.error(`Failed to retrieve logs of application ${appName}: ${e.response?.data}`);
|
|
30
|
+
return 1;
|
|
31
|
+
} else {
|
|
32
|
+
logger.error(`Failed to retrieve logs of application ${appName}: ${(e as Error).message}`);
|
|
33
|
+
return 1;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export { registerApp } from './register-app';
|
|
2
|
+
export { listApps } from './list-apps';
|
|
3
|
+
export { deleteApp } from './delete-app';
|
|
4
|
+
export { deployAppCode } from './deploy-app-code';
|
|
5
|
+
export { getAppLogs } from './get-app-logs';
|
|
6
|
+
export { updateApp } from './update-app';
|
|
7
|
+
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { GlobalLogger } from "../../../src/telemetry/logs";
|
|
3
|
+
import { getCloudCredentials } from "../cloudutils";
|
|
4
|
+
import { Application } from "./types";
|
|
5
|
+
|
|
6
|
+
export async function listApps(host: string): Promise<number> {
|
|
7
|
+
const logger = new GlobalLogger();
|
|
8
|
+
const userCredentials = getCloudCredentials();
|
|
9
|
+
const bearerToken = "Bearer " + userCredentials.token;
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
const list = await axios.get(
|
|
13
|
+
`https://${host}/${userCredentials.userName}/application`,
|
|
14
|
+
{
|
|
15
|
+
headers: {
|
|
16
|
+
Authorization: bearerToken,
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
const data: Application[] = list.data as Application[];
|
|
21
|
+
if (data.length === 0) {
|
|
22
|
+
logger.info("No applications found");
|
|
23
|
+
return 1;
|
|
24
|
+
}
|
|
25
|
+
const formattedData: Application[] = []
|
|
26
|
+
for (const application of data) {
|
|
27
|
+
formattedData.push({ "Name": application.Name, "ID": application.ID, "Version": application.Version, "DatabaseName": application.DatabaseName, "MaxVMs": application.MaxVMs, "Status": application.Status });
|
|
28
|
+
}
|
|
29
|
+
logger.info(`Listing applications for ${userCredentials.userName}`)
|
|
30
|
+
console.log(JSON.stringify(formattedData));
|
|
31
|
+
return 0;
|
|
32
|
+
} catch (e) {
|
|
33
|
+
if (axios.isAxiosError(e) && e.response) {
|
|
34
|
+
logger.error(`Failed to list applications: ${e.response?.data}`);
|
|
35
|
+
return 1;
|
|
36
|
+
} else {
|
|
37
|
+
logger.error(`Failed to list applications: ${(e as Error).message}`);
|
|
38
|
+
return 1;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { GlobalLogger } from "../../../src/telemetry/logs";
|
|
3
|
+
import { getCloudCredentials } from "../cloudutils";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
|
|
6
|
+
export async function registerApp(dbname: string, host: string, machines: number): Promise<number> {
|
|
7
|
+
const logger = new GlobalLogger();
|
|
8
|
+
const userCredentials = getCloudCredentials();
|
|
9
|
+
const bearerToken = "Bearer " + userCredentials.token;
|
|
10
|
+
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
12
|
+
const packageJson = require(path.join(process.cwd(), 'package.json')) as { name: string };
|
|
13
|
+
const appName = packageJson.name;
|
|
14
|
+
logger.info(`Loaded application name from package.json: ${appName}`)
|
|
15
|
+
logger.info(`Registering application: ${appName}`)
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
const register = await axios.put(
|
|
19
|
+
`https://${host}/${userCredentials.userName}/application`,
|
|
20
|
+
{
|
|
21
|
+
name: appName,
|
|
22
|
+
database: dbname,
|
|
23
|
+
max_vms: machines,
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
headers: {
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
Authorization: bearerToken,
|
|
29
|
+
},
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
const uuid = register.data as string;
|
|
33
|
+
logger.info(`Successfully registered: ${appName}`);
|
|
34
|
+
logger.info(`${appName} ID: ${uuid}`);
|
|
35
|
+
return 0;
|
|
36
|
+
} catch (e) {
|
|
37
|
+
if (axios.isAxiosError(e) && e.response) {
|
|
38
|
+
logger.error(`Failed to register application ${appName}: ${e.response?.data}`);
|
|
39
|
+
return 1;
|
|
40
|
+
} else {
|
|
41
|
+
logger.error(`Failed to register application ${appName}: ${(e as Error).message}`);
|
|
42
|
+
return 1;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import axios from "axios";
|
|
2
|
+
import { GlobalLogger } from "../../../src/telemetry/logs";
|
|
3
|
+
import { getCloudCredentials } from "../cloudutils";
|
|
4
|
+
import { Application } from "./types";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
|
|
7
|
+
export async function updateApp(host: string, machines: number): Promise<number> {
|
|
8
|
+
const logger = new GlobalLogger();
|
|
9
|
+
const userCredentials = getCloudCredentials();
|
|
10
|
+
const bearerToken = "Bearer " + userCredentials.token;
|
|
11
|
+
|
|
12
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
13
|
+
const packageJson = require(path.join(process.cwd(), 'package.json')) as { name: string };
|
|
14
|
+
const appName = packageJson.name;
|
|
15
|
+
logger.info(`Loaded application name from package.json: ${appName}`)
|
|
16
|
+
logger.info(`Updating application: ${appName}`)
|
|
17
|
+
|
|
18
|
+
try {
|
|
19
|
+
logger.info(`Updating application ${appName} to ${machines} machines`);
|
|
20
|
+
const update = await axios.patch(
|
|
21
|
+
`https://${host}/${userCredentials.userName}/application/${appName}`,
|
|
22
|
+
{
|
|
23
|
+
name: appName,
|
|
24
|
+
max_vms: machines
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
headers: {
|
|
28
|
+
"Content-Type": "application/json",
|
|
29
|
+
Authorization: bearerToken,
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
);
|
|
33
|
+
const application: Application = update.data as Application;
|
|
34
|
+
logger.info(`Successfully updated: ${application.Name}`);
|
|
35
|
+
console.log(JSON.stringify({ "Name": application.Name, "ID": application.ID, "Version": application.Version, "MaxVMs": application.MaxVMs }));
|
|
36
|
+
return 0;
|
|
37
|
+
} catch (e) {
|
|
38
|
+
if (axios.isAxiosError(e) && e.response) {
|
|
39
|
+
logger.error(`Failed to update application ${appName}: ${e.response?.data}`);
|
|
40
|
+
return 1;
|
|
41
|
+
} else {
|
|
42
|
+
(e as Error).message = `Failed to update application ${appName}: ${(e as Error).message}`;
|
|
43
|
+
logger.error(e);
|
|
44
|
+
return 1;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
package/cli.ts
CHANGED
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
import { Command } from 'commander';
|
|
12
12
|
import { login } from "./login";
|
|
13
13
|
import { registerUser } from "./register";
|
|
14
|
-
import { createUserDb, getUserDb, deleteUserDb
|
|
14
|
+
import { createUserDb, getUserDb, deleteUserDb } from "./userdb";
|
|
15
15
|
import { credentialsExist } from "./cloudutils";
|
|
16
16
|
|
|
17
17
|
const program = new Command();
|
|
@@ -155,20 +155,6 @@ userdbCommands
|
|
|
155
155
|
await deleteUserDb(host, dbname)
|
|
156
156
|
}))
|
|
157
157
|
|
|
158
|
-
userdbCommands
|
|
159
|
-
.command('migrate')
|
|
160
|
-
.action((async () => {
|
|
161
|
-
const exitCode = await migrate();
|
|
162
|
-
process.exit(exitCode);
|
|
163
|
-
}))
|
|
164
|
-
|
|
165
|
-
userdbCommands
|
|
166
|
-
.command('rollbackmigration')
|
|
167
|
-
.action((() => {
|
|
168
|
-
const exitCode = rollbackMigration();
|
|
169
|
-
process.exit(exitCode);
|
|
170
|
-
}))
|
|
171
|
-
|
|
172
158
|
program.parse(process.argv);
|
|
173
159
|
|
|
174
160
|
// If no arguments provided, display help by default
|
package/cloudutils.ts
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { DBOSCloudCredentials, dbosEnvPath } from "./login";
|
|
2
|
+
import fs from "fs";
|
|
3
|
+
import { spawn, StdioOptions } from 'child_process';
|
|
4
|
+
import { GlobalLogger } from "../../src/telemetry/logs";
|
|
5
|
+
|
|
6
|
+
export function getCloudCredentials(): DBOSCloudCredentials {
|
|
7
|
+
const logger = new GlobalLogger();
|
|
8
|
+
if (!credentialsExist()) {
|
|
9
|
+
logger.error("Error: not logged in")
|
|
10
|
+
process.exit(1)
|
|
11
|
+
}
|
|
12
|
+
const userCredentials = JSON.parse(fs.readFileSync(`./${dbosEnvPath}/credentials`).toString("utf-8")) as DBOSCloudCredentials;
|
|
13
|
+
return {
|
|
14
|
+
userName: userCredentials.userName,
|
|
15
|
+
token: userCredentials.token.replace(/\r|\n/g, ""), // Trim the trailing /r /n.
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function credentialsExist(): boolean {
|
|
20
|
+
return fs.existsSync(`./${dbosEnvPath}/credentials`);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Run a command, streaming its output to stdout
|
|
24
|
+
export function runCommand(command: string, args: string[] = []): Promise<number> {
|
|
25
|
+
return new Promise((resolve, reject) => {
|
|
26
|
+
const stdio: StdioOptions = 'inherit';
|
|
27
|
+
|
|
28
|
+
const process = spawn(command, args, { stdio });
|
|
29
|
+
|
|
30
|
+
process.on('close', (code) => {
|
|
31
|
+
if (code === 0) {
|
|
32
|
+
resolve(code);
|
|
33
|
+
} else {
|
|
34
|
+
reject(new Error(`Command "${command}" exited with code ${code}`));
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
process.on('error', (error) => {
|
|
39
|
+
reject(error);
|
|
40
|
+
});
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -129,18 +129,6 @@ userdbCommands
|
|
|
129
129
|
const { host } = userdbCommands.opts();
|
|
130
130
|
await (0, userdb_1.deleteUserDb)(host, dbname);
|
|
131
131
|
}));
|
|
132
|
-
userdbCommands
|
|
133
|
-
.command('migrate')
|
|
134
|
-
.action((async () => {
|
|
135
|
-
const exitCode = await (0, userdb_1.migrate)();
|
|
136
|
-
process.exit(exitCode);
|
|
137
|
-
}));
|
|
138
|
-
userdbCommands
|
|
139
|
-
.command('rollbackmigration')
|
|
140
|
-
.action((() => {
|
|
141
|
-
const exitCode = (0, userdb_1.rollbackMigration)();
|
|
142
|
-
process.exit(exitCode);
|
|
143
|
-
}));
|
|
144
132
|
program.parse(process.argv);
|
|
145
133
|
// If no arguments provided, display help by default
|
|
146
134
|
if (!process.argv.slice(2).length) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../cli.ts"],"names":[],"mappings":";;;AAEA,iDAOwB;AACxB,yCAAoC;AACpC,mCAAgC;AAChC,yCAA0C;AAC1C,
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -7,7 +7,5 @@ export interface UserDBInstance {
|
|
|
7
7
|
export declare function createUserDb(host: string, dbName: string, adminName: string, adminPassword: string, sync: boolean): Promise<void>;
|
|
8
8
|
export declare function deleteUserDb(host: string, dbName: string): Promise<void>;
|
|
9
9
|
export declare function getUserDb(host: string, dbName: string): Promise<void>;
|
|
10
|
-
export declare function migrate(): Promise<number>;
|
|
11
|
-
export declare function rollbackMigration(): number;
|
|
12
10
|
export declare function getUserDBInfo(host: string, dbName: string): Promise<UserDBInstance>;
|
|
13
11
|
//# sourceMappingURL=userdb.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"userdb.d.ts","sourceRoot":"","sources":["../../../userdb.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"userdb.d.ts","sourceRoot":"","sources":["../../../userdb.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;CACvB;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,iBAmCvH;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAoB9D;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,iBAa3D;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAYzF"}
|