UNPKG

11.4 kBJavaScriptView Raw
1/*
2
3 ----------------------------------------------------------------------------
4 | qewd-server: Start-up file for Dockerised version of QEWD |
5 | |
6 | Copyright (c) 2017-19 M/Gateway Developments Ltd, |
7 | Redhill, Surrey UK. |
8 | All rights reserved. |
9 | |
10 | http://www.mgateway.com |
11 | Email: rtweed@mgateway.com |
12 | |
13 | |
14 | Licensed under the Apache License, Version 2.0 (the "License"); |
15 | you may not use this file except in compliance with the License. |
16 | You may obtain a copy of the License at |
17 | |
18 | http://www.apache.org/licenses/LICENSE-2.0 |
19 | |
20 | Unless required by applicable law or agreed to in writing, software |
21 | distributed under the License is distributed on an "AS IS" BASIS, |
22 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
23 | See the License for the specific language governing permissions and |
24 | limitations under the License. |
25 ----------------------------------------------------------------------------
26
27 22 November 2019
28
29*/
30
31var fs = require('fs');
32var module_exists = require('module-exists');
33var child_process = require('child_process');
34var qewd = require('qewd');
35
36const gtm_version = 'V6.3-007';
37const ydb_versionp = 'r1.28';
38const ydb_version = 'r128';
39const ydb_arch = 'armv7l';
40const updateScriptName = 'update_to_r128';
41
42function setEnv(params) {
43 for (var name in params) {
44 process.env[name] = params[name];
45 }
46}
47
48function installModule(moduleName, modulePath) {
49 var pieces = moduleName.split('@');
50 var rootName;
51 if (moduleName.startsWith('@')) {
52 rootName = '@' + pieces[1];
53 }
54 else {
55 rootName = pieces[0];
56 }
57 if (!module_exists(rootName) && !fs.existsSync('/opt/qewd/mapped/node_modules/' + rootName)) {
58 var prefix = '';
59 if (typeof modulePath !== 'undefined') {
60 prefix = ' --prefix ' + modulePath;
61 }
62 child_process.execSync('npm install --unsafe-perm ' + moduleName + prefix, {stdio:[0,1,2]});
63 console.log('\n' + moduleName + ' installed');
64 }
65 else {
66 console.log(moduleName + ' already installed');
67 }
68}
69
70process.env.USER = 'root';
71process.env.HOME = '/opt/qewd';
72if (!process.env.NODE_PATH) {
73 process.env.NODE_PATH = '/opt/qewd/mapped/modules';
74}
75
76var startup;
77var qewd_up = false;
78var qewd_up_config_path = '/opt/qewd/mapped/configuration/config.json';
79var qewd_up_path = '/opt/qewd/node_modules/qewd/up';
80
81if (fs.existsSync(qewd_up_config_path)) {
82 var config = require(qewd_up_config_path);
83 qewd_up = (config.qewd_up === true);
84}
85
86if (qewd_up) {
87 if (process.env.microservice) {
88 console.log('starting up microservice ' + process.env.microservice);
89 startup = require(qewd_up_path + '/run')(true);
90 }
91 else {
92 console.log('starting up Docker Orchestrator service');
93 startup = require(qewd_up_path + '/run')(true);
94 }
95 if (!startup) {
96 console.log('Unable to start QEWD');
97 return;
98 }
99}
100else {
101 startup = require('/opt/qewd/mapped/startup');
102}
103
104var userDefined = startup.userDefined;
105if (!userDefined && fs.existsSync('/opt/qewd/mapped/userDefined.json')) {
106 userDefined = require('/opt/qewd/mapped/userDefined.json');
107}
108
109if (userDefined && userDefined.startup_commands) {
110 console.log('Running custom startup commands:');
111 userDefined.startup_commands.forEach(function(cmnd) {
112 console.log(cmnd);
113 child_process.execSync(cmnd, {stdio:[0,1,2]});
114 });
115}
116
117var npmModules;
118var modulePath;
119if (fs.existsSync('/opt/qewd/mapped/install_modules.json')) {
120 if (!fs.existsSync('/opt/qewd/mapped/node_modules')) {
121 fs.mkdirSync('/opt/qewd/mapped/node_modules');
122 }
123
124 modulePath = '/opt/qewd/mapped';
125 if (!process.env.NODE_PATH.includes('/opt/qewd/mapped/node_modules:')) {
126 process.env.NODE_PATH = '/opt/qewd/mapped/node_modules:' + process.env.NODE_PATH;
127 }
128 require('module').Module._initPaths();
129
130 npmModules = require('/opt/qewd/mapped/install_modules.json');
131 npmModules.forEach(function(moduleName) {
132 console.log('\nInstalling module ' + moduleName + ' to ' + modulePath);
133 installModule(moduleName, modulePath);
134 });
135 console.log('** NODE_PATH = ' + process.env.NODE_PATH);
136}
137
138var config = startup.config;
139
140var ydb_default_params = {
141 database: 'YottaDB',
142 release: ydb_versionp,
143 architecture: 'arm',
144 multithreaded: false
145};
146
147if (!config.database) {
148 config.database = {
149 type: 'dbx',
150 params: ydb_default_params
151 };
152}
153if (!config.database.type) {
154 config.database.type = 'dbx';
155}
156if (config.database.type === 'dbx' && !config.database.params) {
157 config.database.params = ydb_default_params;
158}
159
160// shortened name for QEWD Session global, for maximum subscript length tolerance
161
162config.sessionDocumentName = 'qs';
163
164if (config.database && (config.database.type === 'gtm' || (config.database.type === 'dbx' && config.database.params.database === 'YottaDB'))) {
165
166
167 // Define YottaDB Environment Variables for Worker Processes
168
169 console.log('Setting up YottaDB Environment');
170
171 var ydb_path = ydb_versionp + '_' + ydb_arch;
172 var gtm_path = gtm_version + '_' + ydb_arch;
173
174 var ydb_env = {
175 ydb_retention: 42,
176 gtm_retention: 42,
177 LD_LIBRARY_PATH: '/usr/local/lib/yottadb/' + ydb_version,
178 ydb_log: '/tmp/yottadb/' + ydb_path,
179 gtm_log: '/tmp/yottadb/' + ydb_path,
180 gtm_repl_instance: '/root/.yottadb/' + ydb_path + '/g/yottadb.repl',
181 ydb_repl_instance: '/root/.yottadb/' + ydb_path + '/g/yottadb.repl',
182 ydb_gbldir: '/root/.yottadb/' + ydb_path + '/g/yottadb.gld',
183 ydb_etrap: 'Write:(0=$STACK) "Error occurred: ",$ZStatus,!',
184 ydb_dir: '/root/.yottadb',
185 gtmver: gtm_path,
186 ydb_rel: ydb_path,
187 gtmgbldir: '/root/.yottadb/' + ydb_path + '/g/yottadb.gld',
188 ydb_routines: '/opt/qewd/node_modules/nodem/src /root/.yottadb/' + ydb_path + '/o*(/root/.yottadb/' + ydb_path + '/r /root/.yottadb/r) /usr/local/lib/yottadb/' + ydb_version + '/libyottadbutil.so',
189 gtmroutines: '/opt/qewd/node_modules/nodem/src /root/.yottadb/' + ydb_path + '/o*(/root/.yottadb/' + ydb_path + '/r /root/.yottadb/r) /usr/local/lib/yottadb/' + ydb_version + '/libyottadbutil.so',
190 GTMCI: '/opt/qewd/node_modules/nodem/resources/nodem.ci',
191 ydb_ci: '/opt/qewd/node_modules/nodem/resources/nodem.ci',
192 gtmdir: '/root/.fis-gtm',
193 gtm_etrap: 'Write:(0=$STACK) "Error occurred: ",$ZStatus,!',
194 ydb_tmp: '/tmp/yottadb/' + ydb_path,
195 gtm_tmp: '/tmp/yottadb/' + ydb_path,
196 gtm_dist: '/usr/local/lib/yottadb/' + ydb_version,
197 ydb_dist: '/usr/local/lib/yottadb/' + ydb_version
198 };
199
200 setEnv(ydb_env);
201
202 if (config.database.type === 'gtm') {
203 config.database = {
204 type: 'gtm',
205 params:{
206 ydb_env: ydb_env
207 }
208 };
209
210 // workaround NPM5 bug
211
212 try {
213 var nm = require('nodem');
214 }
215 catch(err) {
216 installModule('nodem@0.14.2');
217 }
218 }
219
220 // rundown the default region database (all globals except CacheTempEWDSession)
221 // it may return an error, so wrap in a try/catch
222
223 // also max out the allowed global subscript and data length
224
225 try {
226 console.log('Running down YottaDB...');
227 child_process.execSync(ydb_env.ydb_dist + '/mupip rundown -region DEFAULT', {stdio:[0,1,2]});
228 child_process.execSync(ydb_env.ydb_dist + '/mupip rundown -region qewdreg', {stdio:[0,1,2]});
229
230 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip rundown -region DEFAULT', {stdio:[0,1,2]});
231 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip set -key_size=1019 -region DEFAULT', {stdio:[0,1,2]});
232 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip set -record_size=1048576 -region DEFAULT', {stdio:[0,1,2]});
233 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip rundown -region qewdreg', {stdio:[0,1,2]});
234 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip set -key_size=1019 -region qewdreg', {stdio:[0,1,2]});
235 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip set -record_size=1048576 -region qewdreg', {stdio:[0,1,2]});
236 console.log('Rundown completed');
237 }
238 catch(err) {
239 console.log('Error running down YottaDB: ' + err);
240 console.log('Recovering journal...');
241 child_process.execSync(ydb_env.ydb_dist + '/mupip journal -recover -backward /root/.yottadb/' + ydb_path + '/g/yottadb.mjl', {stdio:[0,1,2]});
242 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip journal -recover -backward /root/.yottadb/' + ydb_path + '/g/yottadb.mjl', {stdio:[0,1,2]});
243 console.log('Journal recovered');
244 }
245
246 try {
247 console.log('Max out the global subscript and data lengths');
248 child_process.execSync(ydb_env.ydb_dist + '/mupip set -key_size=1019 -region DEFAULT', {stdio:[0,1,2]});
249 child_process.execSync(ydb_env.ydb_dist + '/mupip set -record_size=1048576 -region DEFAULT', {stdio:[0,1,2]});
250 child_process.execSync(ydb_env.ydb_dist + '/mupip set -key_size=1019 -region qewdreg', {stdio:[0,1,2]});
251 child_process.execSync(ydb_env.ydb_dist + '/mupip set -record_size=1048576 -region qewdreg', {stdio:[0,1,2]});
252 }
253 catch(err) {
254 console.log('Unable to increase subscript and global lengths');
255 }
256
257 // update database journal file if it's for an old version
258
259 try {
260 child_process.execSync(ydb_env.ydb_dist + '/mupip journal -show=header -backward /root/.yottadb/' + ydb_path + '/g/yottadb.mjl', {stdio:[0,1,2]});
261 //child_process.execSync(config.database.params.ydb_env.ydb_dist + '/mupip journal -show=header -backward /root/.yottadb/' + ydb_path + '/g/yottadb.mjl', {stdio:[0,1,2]});
262 }
263 catch(err) {
264 // journal file is for previous YDB version - replace it with new version
265 var updateScript = '/opt/qewd/' + updateScriptName;
266 child_process.execSync(updateScript, {stdio:[0,1,2]});
267 }
268
269}
270
271// ready to start QEWD now
272
273var qewd_master = qewd.master;
274console.log('Starting QEWD');
275
276var q = qewd_master.start(config, startup.routes);
277if (userDefined) {
278 for (var name in userDefined) {
279 q.userDefined[name] = userDefined[name];
280 }
281}
282
283if (q.userDefined && q.userDefined.config) {
284 q.userDefined.config.qewd_up = qewd_up;
285}
286
287var xp = qewd_master.intercept();
288
289// invoke user-specific startup code
290
291if (startup.onStarted) {
292 startup.onStarted.call(q, config, xp.app, xp.qx.router, xp.qx);
293}
294