dbgate-api 5.2.1 → 5.2.2-alpha.11
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/package.json +7 -6
- package/src/controllers/archive.js +4 -1
- package/src/controllers/auth.js +6 -3
- package/src/controllers/config.js +3 -1
- package/src/controllers/connections.js +23 -13
- package/src/controllers/databaseConnections.js +35 -12
- package/src/controllers/runners.js +21 -13
- package/src/controllers/scheduler.js +4 -1
- package/src/controllers/serverConnections.js +37 -10
- package/src/controllers/sessions.js +27 -10
- package/src/controllers/uploads.js +3 -1
- package/src/currentVersion.js +2 -2
- package/src/index.js +96 -2
- package/src/main.js +12 -9
- package/src/proc/databaseConnectionProcess.js +8 -6
- package/src/proc/serverConnectionProcess.js +4 -3
- package/src/proc/sessionProcess.js +26 -1
- package/src/proc/sshForwardProcess.js +5 -2
- package/src/shell/archiveWriter.js +4 -1
- package/src/shell/dumpDatabase.js +5 -2
- package/src/shell/executeQuery.js +5 -2
- package/src/shell/generateModelSql.js +30 -0
- package/src/shell/importDatabase.js +5 -2
- package/src/shell/index.js +4 -0
- package/src/shell/jsonArrayWriter.js +4 -1
- package/src/shell/jsonLinesReader.js +3 -1
- package/src/shell/jsonLinesWriter.js +3 -1
- package/src/shell/loadDatabase.js +21 -0
- package/src/shell/queryReader.js +4 -2
- package/src/shell/requirePlugin.js +3 -1
- package/src/shell/runScript.js +3 -1
- package/src/shell/sqlDataWriter.js +3 -2
- package/src/shell/tableReader.js +6 -5
- package/src/shell/tableWriter.js +4 -3
- package/src/utility/DatastoreProxy.js +29 -9
- package/src/utility/childProcessChecker.js +6 -2
- package/src/utility/cleanDirectory.js +2 -2
- package/src/utility/directories.js +22 -6
- package/src/utility/pipeForkLogs.js +19 -0
- package/src/utility/processArgs.js +2 -0
- package/src/utility/sshTunnel.js +23 -14
- package/src/utility/sshTunnelProxy.js +7 -1
- package/src/utility/useController.js +9 -7
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "5.2.
|
|
4
|
+
"version": "5.2.2-alpha.11",
|
|
5
5
|
"homepage": "https://dbgate.org/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -27,8 +27,8 @@
|
|
|
27
27
|
"cors": "^2.8.5",
|
|
28
28
|
"cross-env": "^6.0.3",
|
|
29
29
|
"dbgate-query-splitter": "^4.9.3",
|
|
30
|
-
"dbgate-sqltree": "^5.2.
|
|
31
|
-
"dbgate-tools": "^5.2.
|
|
30
|
+
"dbgate-sqltree": "^5.2.2-alpha.11",
|
|
31
|
+
"dbgate-tools": "^5.2.2-alpha.11",
|
|
32
32
|
"debug": "^4.3.4",
|
|
33
33
|
"diff": "^5.0.0",
|
|
34
34
|
"diff2html": "^3.4.13",
|
|
@@ -49,6 +49,7 @@
|
|
|
49
49
|
"ncp": "^2.0.0",
|
|
50
50
|
"node-cron": "^2.0.3",
|
|
51
51
|
"on-finished": "^2.4.1",
|
|
52
|
+
"pinomin": "^1.0.1",
|
|
52
53
|
"portfinder": "^1.0.28",
|
|
53
54
|
"simple-encryptor": "^4.0.0",
|
|
54
55
|
"ssh2": "^1.11.0",
|
|
@@ -69,7 +70,7 @@
|
|
|
69
70
|
"devDependencies": {
|
|
70
71
|
"@types/fs-extra": "^9.0.11",
|
|
71
72
|
"@types/lodash": "^4.14.149",
|
|
72
|
-
"dbgate-types": "^5.2.
|
|
73
|
+
"dbgate-types": "^5.2.2-alpha.11",
|
|
73
74
|
"env-cmd": "^10.1.0",
|
|
74
75
|
"node-loader": "^1.0.2",
|
|
75
76
|
"nodemon": "^2.0.2",
|
|
@@ -79,7 +80,7 @@
|
|
|
79
80
|
},
|
|
80
81
|
"optionalDependencies": {
|
|
81
82
|
"better-sqlite3": "7.6.2",
|
|
82
|
-
"
|
|
83
|
-
"
|
|
83
|
+
"msnodesqlv8": "^2.6.0",
|
|
84
|
+
"oracledb": "^5.5.0"
|
|
84
85
|
}
|
|
85
86
|
}
|
|
@@ -6,6 +6,9 @@ const socket = require('../utility/socket');
|
|
|
6
6
|
const { saveFreeTableData } = require('../utility/freeTableStorage');
|
|
7
7
|
const loadFilesRecursive = require('../utility/loadFilesRecursive');
|
|
8
8
|
const getJslFileName = require('../utility/getJslFileName');
|
|
9
|
+
const { getLogger } = require('dbgate-tools');
|
|
10
|
+
|
|
11
|
+
const logger = getLogger('archive');
|
|
9
12
|
|
|
10
13
|
module.exports = {
|
|
11
14
|
folders_meta: true,
|
|
@@ -68,7 +71,7 @@ module.exports = {
|
|
|
68
71
|
...fileType('.matview.sql', 'matview.sql'),
|
|
69
72
|
];
|
|
70
73
|
} catch (err) {
|
|
71
|
-
|
|
74
|
+
logger.error({ err }, 'Error reading archive files');
|
|
72
75
|
return [];
|
|
73
76
|
}
|
|
74
77
|
},
|
package/src/controllers/auth.js
CHANGED
|
@@ -3,8 +3,11 @@ const jwt = require('jsonwebtoken');
|
|
|
3
3
|
const getExpressPath = require('../utility/getExpressPath');
|
|
4
4
|
const uuidv1 = require('uuid/v1');
|
|
5
5
|
const { getLogins } = require('../utility/hasPermission');
|
|
6
|
+
const { getLogger } = require('dbgate-tools');
|
|
6
7
|
const AD = require('activedirectory2').promiseWrapper;
|
|
7
8
|
|
|
9
|
+
const logger = getLogger('auth');
|
|
10
|
+
|
|
8
11
|
const tokenSecret = uuidv1();
|
|
9
12
|
|
|
10
13
|
function shouldAuthorizeApi() {
|
|
@@ -51,7 +54,7 @@ function authMiddleware(req, res, next) {
|
|
|
51
54
|
return next();
|
|
52
55
|
}
|
|
53
56
|
|
|
54
|
-
|
|
57
|
+
logger.error({ err }, 'Sending invalid token error');
|
|
55
58
|
|
|
56
59
|
return unauthorizedResponse(req, res, 'invalid token');
|
|
57
60
|
}
|
|
@@ -74,7 +77,7 @@ module.exports = {
|
|
|
74
77
|
|
|
75
78
|
const payload = jwt.decode(access_token);
|
|
76
79
|
|
|
77
|
-
|
|
80
|
+
logger.info({ payload }, 'User payload returned from OAUTH');
|
|
78
81
|
|
|
79
82
|
const login =
|
|
80
83
|
process.env.OAUTH_LOGIN_FIELD && payload && payload[process.env.OAUTH_LOGIN_FIELD]
|
|
@@ -122,7 +125,7 @@ module.exports = {
|
|
|
122
125
|
accessToken: jwt.sign({ login }, tokenSecret, { expiresIn: getTokenLifetime() }),
|
|
123
126
|
};
|
|
124
127
|
} catch (err) {
|
|
125
|
-
|
|
128
|
+
logger.error({ err }, 'Failed active directory authentization');
|
|
126
129
|
return {
|
|
127
130
|
error: err.message,
|
|
128
131
|
};
|
|
@@ -2,7 +2,7 @@ const fs = require('fs-extra');
|
|
|
2
2
|
const os = require('os');
|
|
3
3
|
const path = require('path');
|
|
4
4
|
const axios = require('axios');
|
|
5
|
-
const { datadir } = require('../utility/directories');
|
|
5
|
+
const { datadir, getLogsFilePath } = require('../utility/directories');
|
|
6
6
|
const { hasPermission, getLogins } = require('../utility/hasPermission');
|
|
7
7
|
const socket = require('../utility/socket');
|
|
8
8
|
const _ = require('lodash');
|
|
@@ -48,6 +48,8 @@ module.exports = {
|
|
|
48
48
|
oauthScope: process.env.OAUTH_SCOPE,
|
|
49
49
|
oauthLogout: process.env.OAUTH_LOGOUT,
|
|
50
50
|
isLoginForm: !!process.env.AD_URL || (!!logins && !process.env.BASIC_AUTH),
|
|
51
|
+
logsFilePath: getLogsFilePath(),
|
|
52
|
+
connectionsFilePath: path.join(datadir(), 'connections.jsonl'),
|
|
51
53
|
...currentVersion,
|
|
52
54
|
};
|
|
53
55
|
},
|
|
@@ -12,9 +12,12 @@ const { pickSafeConnectionInfo } = require('../utility/crypting');
|
|
|
12
12
|
const JsonLinesDatabase = require('../utility/JsonLinesDatabase');
|
|
13
13
|
|
|
14
14
|
const processArgs = require('../utility/processArgs');
|
|
15
|
-
const { safeJsonParse } = require('dbgate-tools');
|
|
15
|
+
const { safeJsonParse, getLogger } = require('dbgate-tools');
|
|
16
16
|
const platformInfo = require('../utility/platformInfo');
|
|
17
17
|
const { connectionHasPermission, testConnectionPermission } = require('../utility/hasPermission');
|
|
18
|
+
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
19
|
+
|
|
20
|
+
const logger = getLogger('connections');
|
|
18
21
|
|
|
19
22
|
let volatileConnections = {};
|
|
20
23
|
|
|
@@ -86,13 +89,13 @@ function getPortalCollections() {
|
|
|
86
89
|
sslKeyFile: process.env[`SSL_KEY_FILE_${id}`],
|
|
87
90
|
sslRejectUnauthorized: process.env[`SSL_REJECT_UNAUTHORIZED_${id}`],
|
|
88
91
|
}));
|
|
89
|
-
|
|
90
|
-
|
|
92
|
+
|
|
93
|
+
logger.info({ connections: connections.map(pickSafeConnectionInfo) }, 'Using connections from ENV variables');
|
|
91
94
|
const noengine = connections.filter(x => !x.engine);
|
|
92
95
|
if (noengine.length > 0) {
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
+
logger.warn(
|
|
97
|
+
{ connections: noengine.map(x => x._id) },
|
|
98
|
+
'Invalid CONNECTIONS configutation, missing ENGINE for connection ID'
|
|
96
99
|
);
|
|
97
100
|
}
|
|
98
101
|
return connections;
|
|
@@ -203,13 +206,20 @@ module.exports = {
|
|
|
203
206
|
|
|
204
207
|
test_meta: true,
|
|
205
208
|
test(connection) {
|
|
206
|
-
const subprocess = fork(
|
|
207
|
-
'
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
209
|
+
const subprocess = fork(
|
|
210
|
+
global['API_PACKAGE'] || process.argv[1],
|
|
211
|
+
[
|
|
212
|
+
'--is-forked-api',
|
|
213
|
+
'--start-process',
|
|
214
|
+
'connectProcess',
|
|
215
|
+
...processArgs.getPassArgs(),
|
|
216
|
+
// ...process.argv.slice(3),
|
|
217
|
+
],
|
|
218
|
+
{
|
|
219
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
220
|
+
}
|
|
221
|
+
);
|
|
222
|
+
pipeForkLogs(subprocess);
|
|
213
223
|
subprocess.send(connection);
|
|
214
224
|
return new Promise(resolve => {
|
|
215
225
|
subprocess.on('message', resp => {
|
|
@@ -12,6 +12,7 @@ const {
|
|
|
12
12
|
matchPairedObjects,
|
|
13
13
|
extendDatabaseInfo,
|
|
14
14
|
modelCompareDbDiffOptions,
|
|
15
|
+
getLogger,
|
|
15
16
|
} = require('dbgate-tools');
|
|
16
17
|
const { html, parse } = require('diff2html');
|
|
17
18
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
@@ -28,6 +29,9 @@ const diff2htmlPage = require('../utility/diff2htmlPage');
|
|
|
28
29
|
const processArgs = require('../utility/processArgs');
|
|
29
30
|
const { testConnectionPermission } = require('../utility/hasPermission');
|
|
30
31
|
const { MissingCredentialsError } = require('../utility/exceptions');
|
|
32
|
+
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
33
|
+
|
|
34
|
+
const logger = getLogger('databaseConnections');
|
|
31
35
|
|
|
32
36
|
module.exports = {
|
|
33
37
|
/** @type {import('dbgate-types').OpenedDatabaseConnection[]} */
|
|
@@ -60,7 +64,7 @@ module.exports = {
|
|
|
60
64
|
|
|
61
65
|
handle_error(conid, database, props) {
|
|
62
66
|
const { error } = props;
|
|
63
|
-
|
|
67
|
+
logger.error(`Error in database connection ${conid}, database ${database}: ${error}`);
|
|
64
68
|
},
|
|
65
69
|
handle_response(conid, database, { msgid, ...response }) {
|
|
66
70
|
const [resolve, reject] = this.requests[msgid];
|
|
@@ -85,13 +89,20 @@ module.exports = {
|
|
|
85
89
|
if (connection.passwordMode == 'askPassword' || connection.passwordMode == 'askUser') {
|
|
86
90
|
throw new MissingCredentialsError({ conid, passwordMode: connection.passwordMode });
|
|
87
91
|
}
|
|
88
|
-
const subprocess = fork(
|
|
89
|
-
'
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
92
|
+
const subprocess = fork(
|
|
93
|
+
global['API_PACKAGE'] || process.argv[1],
|
|
94
|
+
[
|
|
95
|
+
'--is-forked-api',
|
|
96
|
+
'--start-process',
|
|
97
|
+
'databaseConnectionProcess',
|
|
98
|
+
...processArgs.getPassArgs(),
|
|
99
|
+
// ...process.argv.slice(3),
|
|
100
|
+
],
|
|
101
|
+
{
|
|
102
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
103
|
+
}
|
|
104
|
+
);
|
|
105
|
+
pipeForkLogs(subprocess);
|
|
95
106
|
const lastClosed = this.closed[`${conid}/${database}`];
|
|
96
107
|
const newOpened = {
|
|
97
108
|
conid,
|
|
@@ -129,7 +140,12 @@ module.exports = {
|
|
|
129
140
|
const msgid = uuidv1();
|
|
130
141
|
const promise = new Promise((resolve, reject) => {
|
|
131
142
|
this.requests[msgid] = [resolve, reject];
|
|
132
|
-
|
|
143
|
+
try {
|
|
144
|
+
conn.subprocess.send({ msgid, ...message });
|
|
145
|
+
} catch (err) {
|
|
146
|
+
logger.error({ err }, 'Error sending request do process');
|
|
147
|
+
this.close(conn.conid, conn.database);
|
|
148
|
+
}
|
|
133
149
|
});
|
|
134
150
|
return promise;
|
|
135
151
|
},
|
|
@@ -137,7 +153,7 @@ module.exports = {
|
|
|
137
153
|
queryData_meta: true,
|
|
138
154
|
async queryData({ conid, database, sql }, req) {
|
|
139
155
|
testConnectionPermission(conid, req);
|
|
140
|
-
|
|
156
|
+
logger.info({ conid, database, sql }, 'Processing query');
|
|
141
157
|
const opened = await this.ensureOpened(conid, database);
|
|
142
158
|
// if (opened && opened.status && opened.status.name == 'error') {
|
|
143
159
|
// return opened.status;
|
|
@@ -157,7 +173,7 @@ module.exports = {
|
|
|
157
173
|
runScript_meta: true,
|
|
158
174
|
async runScript({ conid, database, sql }, req) {
|
|
159
175
|
testConnectionPermission(conid, req);
|
|
160
|
-
|
|
176
|
+
logger.info({ conid, database, sql }, 'Processing script');
|
|
161
177
|
const opened = await this.ensureOpened(conid, database);
|
|
162
178
|
const res = await this.sendRequest(opened, { msgtype: 'runScript', sql });
|
|
163
179
|
return res;
|
|
@@ -278,6 +294,7 @@ module.exports = {
|
|
|
278
294
|
if (existing) {
|
|
279
295
|
existing.subprocess.send({ msgtype: 'ping' });
|
|
280
296
|
} else {
|
|
297
|
+
// @ts-ignore
|
|
281
298
|
existing = await this.ensureOpened(conid, database);
|
|
282
299
|
}
|
|
283
300
|
|
|
@@ -308,7 +325,13 @@ module.exports = {
|
|
|
308
325
|
const existing = this.opened.find(x => x.conid == conid && x.database == database);
|
|
309
326
|
if (existing) {
|
|
310
327
|
existing.disconnected = true;
|
|
311
|
-
if (kill)
|
|
328
|
+
if (kill) {
|
|
329
|
+
try {
|
|
330
|
+
existing.subprocess.kill();
|
|
331
|
+
} catch (err) {
|
|
332
|
+
logger.error({ err }, 'Error killing subprocess');
|
|
333
|
+
}
|
|
334
|
+
}
|
|
312
335
|
this.opened = this.opened.filter(x => x.conid != conid || x.database != database);
|
|
313
336
|
this.closed[`${conid}/${database}`] = {
|
|
314
337
|
status: {
|
|
@@ -6,10 +6,17 @@ const byline = require('byline');
|
|
|
6
6
|
const socket = require('../utility/socket');
|
|
7
7
|
const { fork } = require('child_process');
|
|
8
8
|
const { rundir, uploadsdir, pluginsdir, getPluginBackendPath, packagedPluginList } = require('../utility/directories');
|
|
9
|
-
const {
|
|
9
|
+
const {
|
|
10
|
+
extractShellApiPlugins,
|
|
11
|
+
extractShellApiFunctionName,
|
|
12
|
+
jsonScriptToJavascript,
|
|
13
|
+
getLogger,
|
|
14
|
+
safeJsonParse,
|
|
15
|
+
} = require('dbgate-tools');
|
|
10
16
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
11
17
|
const processArgs = require('../utility/processArgs');
|
|
12
18
|
const platformInfo = require('../utility/platformInfo');
|
|
19
|
+
const logger = getLogger('runners');
|
|
13
20
|
|
|
14
21
|
function extractPlugins(script) {
|
|
15
22
|
const requireRegex = /\s*\/\/\s*@require\s+([^\s]+)\s*\n/g;
|
|
@@ -29,13 +36,14 @@ const requirePluginsTemplate = (plugins, isExport) =>
|
|
|
29
36
|
|
|
30
37
|
const scriptTemplate = (script, isExport) => `
|
|
31
38
|
const dbgateApi = require(${isExport ? `'dbgate-api'` : 'process.env.DBGATE_API'});
|
|
39
|
+
const logger = dbgateApi.getLogger('script');
|
|
32
40
|
dbgateApi.initializeApiEnvironment();
|
|
33
41
|
${requirePluginsTemplate(extractPlugins(script), isExport)}
|
|
34
42
|
require=null;
|
|
35
43
|
async function run() {
|
|
36
44
|
${script}
|
|
37
45
|
await dbgateApi.finalizer.run();
|
|
38
|
-
|
|
46
|
+
logger.info('Finished job script');
|
|
39
47
|
}
|
|
40
48
|
dbgateApi.runScript(run);
|
|
41
49
|
`;
|
|
@@ -59,19 +67,17 @@ module.exports = {
|
|
|
59
67
|
requests: {},
|
|
60
68
|
|
|
61
69
|
dispatchMessage(runid, message) {
|
|
62
|
-
if (message)
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
if (_.isPlainObject(message)) {
|
|
70
|
+
if (message) {
|
|
71
|
+
const json = safeJsonParse(message.message);
|
|
72
|
+
|
|
73
|
+
if (json) logger.info(json);
|
|
74
|
+
else logger.info(message.message);
|
|
75
|
+
|
|
71
76
|
socket.emit(`runner-info-${runid}`, {
|
|
72
77
|
time: new Date(),
|
|
73
78
|
severity: 'info',
|
|
74
79
|
...message,
|
|
80
|
+
message: json ? json.msg : message.message,
|
|
75
81
|
});
|
|
76
82
|
}
|
|
77
83
|
},
|
|
@@ -98,13 +104,15 @@ module.exports = {
|
|
|
98
104
|
fs.writeFileSync(`${scriptFile}`, scriptText);
|
|
99
105
|
fs.mkdirSync(directory);
|
|
100
106
|
const pluginNames = _.union(fs.readdirSync(pluginsdir()), packagedPluginList);
|
|
101
|
-
|
|
107
|
+
logger.info({ scriptFile }, 'Running script');
|
|
102
108
|
// const subprocess = fork(scriptFile, ['--checkParent', '--max-old-space-size=8192'], {
|
|
103
109
|
const subprocess = fork(
|
|
104
110
|
scriptFile,
|
|
105
111
|
[
|
|
106
112
|
'--checkParent', // ...process.argv.slice(3)
|
|
107
113
|
'--is-forked-api',
|
|
114
|
+
'--process-display-name',
|
|
115
|
+
'script',
|
|
108
116
|
...processArgs.getPassArgs(),
|
|
109
117
|
],
|
|
110
118
|
{
|
|
@@ -124,7 +132,7 @@ module.exports = {
|
|
|
124
132
|
byline(subprocess.stderr).on('data', pipeDispatcher('error'));
|
|
125
133
|
subprocess.on('exit', code => {
|
|
126
134
|
this.rejectRequest(runid, { message: 'No data retured, maybe input data source is too big' });
|
|
127
|
-
|
|
135
|
+
logger.info({ code, pid: subprocess.pid }, 'Exited process');
|
|
128
136
|
socket.emit(`runner-done-${runid}`, code);
|
|
129
137
|
});
|
|
130
138
|
subprocess.on('error', error => {
|
|
@@ -4,6 +4,9 @@ const path = require('path');
|
|
|
4
4
|
const cron = require('node-cron');
|
|
5
5
|
const runners = require('./runners');
|
|
6
6
|
const { hasPermission } = require('../utility/hasPermission');
|
|
7
|
+
const { getLogger } = require('dbgate-tools');
|
|
8
|
+
|
|
9
|
+
const logger = getLogger('scheduler');
|
|
7
10
|
|
|
8
11
|
const scheduleRegex = /\s*\/\/\s*@schedule\s+([^\n]+)\n/;
|
|
9
12
|
|
|
@@ -21,7 +24,7 @@ module.exports = {
|
|
|
21
24
|
if (!match) return;
|
|
22
25
|
const pattern = match[1];
|
|
23
26
|
if (!cron.validate(pattern)) return;
|
|
24
|
-
|
|
27
|
+
logger.info(`Schedule script ${file} with pattern ${pattern}`);
|
|
25
28
|
const task = cron.schedule(pattern, () => runners.start({ script: text }));
|
|
26
29
|
this.tasks.push(task);
|
|
27
30
|
},
|
|
@@ -10,6 +10,10 @@ const config = require('./config');
|
|
|
10
10
|
const processArgs = require('../utility/processArgs');
|
|
11
11
|
const { testConnectionPermission } = require('../utility/hasPermission');
|
|
12
12
|
const { MissingCredentialsError } = require('../utility/exceptions');
|
|
13
|
+
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
14
|
+
const { getLogger } = require('dbgate-tools');
|
|
15
|
+
|
|
16
|
+
const logger = getLogger('serverConnection');
|
|
13
17
|
|
|
14
18
|
module.exports = {
|
|
15
19
|
opened: [],
|
|
@@ -53,13 +57,20 @@ module.exports = {
|
|
|
53
57
|
if (connection.passwordMode == 'askPassword' || connection.passwordMode == 'askUser') {
|
|
54
58
|
throw new MissingCredentialsError({ conid, passwordMode: connection.passwordMode });
|
|
55
59
|
}
|
|
56
|
-
const subprocess = fork(
|
|
57
|
-
'
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
60
|
+
const subprocess = fork(
|
|
61
|
+
global['API_PACKAGE'] || process.argv[1],
|
|
62
|
+
[
|
|
63
|
+
'--is-forked-api',
|
|
64
|
+
'--start-process',
|
|
65
|
+
'serverConnectionProcess',
|
|
66
|
+
...processArgs.getPassArgs(),
|
|
67
|
+
// ...process.argv.slice(3),
|
|
68
|
+
],
|
|
69
|
+
{
|
|
70
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
71
|
+
}
|
|
72
|
+
);
|
|
73
|
+
pipeForkLogs(subprocess);
|
|
63
74
|
const newOpened = {
|
|
64
75
|
conid,
|
|
65
76
|
subprocess,
|
|
@@ -94,7 +105,13 @@ module.exports = {
|
|
|
94
105
|
const existing = this.opened.find(x => x.conid == conid);
|
|
95
106
|
if (existing) {
|
|
96
107
|
existing.disconnected = true;
|
|
97
|
-
if (kill)
|
|
108
|
+
if (kill) {
|
|
109
|
+
try {
|
|
110
|
+
existing.subprocess.kill();
|
|
111
|
+
} catch (err) {
|
|
112
|
+
logger.error({ err }, 'Error killing subprocess');
|
|
113
|
+
}
|
|
114
|
+
}
|
|
98
115
|
this.opened = this.opened.filter(x => x.conid != conid);
|
|
99
116
|
this.closed[conid] = {
|
|
100
117
|
...existing.status,
|
|
@@ -144,7 +161,12 @@ module.exports = {
|
|
|
144
161
|
}
|
|
145
162
|
this.lastPinged[conid] = new Date().getTime();
|
|
146
163
|
const opened = await this.ensureOpened(conid);
|
|
147
|
-
|
|
164
|
+
try {
|
|
165
|
+
opened.subprocess.send({ msgtype: 'ping' });
|
|
166
|
+
} catch (err) {
|
|
167
|
+
logger.error({ err }, 'Error calling ping');
|
|
168
|
+
this.close(conid);
|
|
169
|
+
}
|
|
148
170
|
})
|
|
149
171
|
);
|
|
150
172
|
return { status: 'ok' };
|
|
@@ -181,7 +203,12 @@ module.exports = {
|
|
|
181
203
|
const msgid = uuidv1();
|
|
182
204
|
const promise = new Promise((resolve, reject) => {
|
|
183
205
|
this.requests[msgid] = [resolve, reject];
|
|
184
|
-
|
|
206
|
+
try {
|
|
207
|
+
conn.subprocess.send({ msgid, ...message });
|
|
208
|
+
} catch (err) {
|
|
209
|
+
logger.error({ err }, 'Error sending request');
|
|
210
|
+
this.close(conn.conid);
|
|
211
|
+
}
|
|
185
212
|
});
|
|
186
213
|
return promise;
|
|
187
214
|
},
|
|
@@ -8,6 +8,11 @@ const path = require('path');
|
|
|
8
8
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
9
9
|
const processArgs = require('../utility/processArgs');
|
|
10
10
|
const { appdir } = require('../utility/directories');
|
|
11
|
+
const { getLogger } = require('dbgate-tools');
|
|
12
|
+
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
13
|
+
const config = require('./config');
|
|
14
|
+
|
|
15
|
+
const logger = getLogger('sessions');
|
|
11
16
|
|
|
12
17
|
module.exports = {
|
|
13
18
|
/** @type {import('dbgate-types').OpenedSession[]} */
|
|
@@ -82,13 +87,20 @@ module.exports = {
|
|
|
82
87
|
async create({ conid, database }) {
|
|
83
88
|
const sesid = uuidv1();
|
|
84
89
|
const connection = await connections.getCore({ conid });
|
|
85
|
-
const subprocess = fork(
|
|
86
|
-
'
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
90
|
+
const subprocess = fork(
|
|
91
|
+
global['API_PACKAGE'] || process.argv[1],
|
|
92
|
+
[
|
|
93
|
+
'--is-forked-api',
|
|
94
|
+
'--start-process',
|
|
95
|
+
'sessionProcess',
|
|
96
|
+
...processArgs.getPassArgs(),
|
|
97
|
+
// ...process.argv.slice(3),
|
|
98
|
+
],
|
|
99
|
+
{
|
|
100
|
+
stdio: ['ignore', 'pipe', 'pipe', 'ipc'],
|
|
101
|
+
}
|
|
102
|
+
);
|
|
103
|
+
pipeForkLogs(subprocess);
|
|
92
104
|
const newOpened = {
|
|
93
105
|
conid,
|
|
94
106
|
database,
|
|
@@ -109,7 +121,12 @@ module.exports = {
|
|
|
109
121
|
socket.emit(`session-closed-${sesid}`);
|
|
110
122
|
});
|
|
111
123
|
|
|
112
|
-
subprocess.send({
|
|
124
|
+
subprocess.send({
|
|
125
|
+
msgtype: 'connect',
|
|
126
|
+
...connection,
|
|
127
|
+
database,
|
|
128
|
+
globalSettings: await config.getSettings(),
|
|
129
|
+
});
|
|
113
130
|
return _.pick(newOpened, ['conid', 'database', 'sesid']);
|
|
114
131
|
},
|
|
115
132
|
|
|
@@ -120,7 +137,7 @@ module.exports = {
|
|
|
120
137
|
throw new Error('Invalid session');
|
|
121
138
|
}
|
|
122
139
|
|
|
123
|
-
|
|
140
|
+
logger.info({ sesid, sql }, 'Processing query');
|
|
124
141
|
this.dispatchMessage(sesid, 'Query execution started');
|
|
125
142
|
session.subprocess.send({ msgtype: 'executeQuery', sql });
|
|
126
143
|
|
|
@@ -158,7 +175,7 @@ module.exports = {
|
|
|
158
175
|
throw new Error('Invalid session');
|
|
159
176
|
}
|
|
160
177
|
|
|
161
|
-
|
|
178
|
+
logger.info({ sesid }, 'Starting profiler');
|
|
162
179
|
session.loadingReader_jslid = jslid;
|
|
163
180
|
session.subprocess.send({ msgtype: 'startProfiler', jslid });
|
|
164
181
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
const path = require('path');
|
|
2
2
|
const { uploadsdir } = require('../utility/directories');
|
|
3
3
|
const uuidv1 = require('uuid/v1');
|
|
4
|
+
const { getLogger } = require('dbgate-tools');
|
|
5
|
+
const logger = getLogger('uploads');
|
|
4
6
|
|
|
5
7
|
module.exports = {
|
|
6
8
|
upload_meta: {
|
|
@@ -15,7 +17,7 @@ module.exports = {
|
|
|
15
17
|
}
|
|
16
18
|
const uploadName = uuidv1();
|
|
17
19
|
const filePath = path.join(uploadsdir(), uploadName);
|
|
18
|
-
|
|
20
|
+
logger.info(`Uploading file ${data.name}, size=${data.size}`);
|
|
19
21
|
|
|
20
22
|
data.mv(filePath, () => {
|
|
21
23
|
res.json({
|
package/src/currentVersion.js
CHANGED