@webos-tools/cli 3.2.1 → 3.2.2

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 (149) hide show
  1. package/.eslintignore +1 -1
  2. package/.eslintrc.js +52 -52
  3. package/APIs.js +79 -79
  4. package/CHANGELOG.md +7 -0
  5. package/LICENSE +201 -201
  6. package/bin/ares-config.js +0 -0
  7. package/bin/ares-device-info.js +30 -30
  8. package/bin/ares-device.js +0 -0
  9. package/bin/ares-generate.js +274 -274
  10. package/bin/ares-inspect.js +179 -179
  11. package/bin/ares-install.js +223 -223
  12. package/bin/ares-launch.js +0 -0
  13. package/bin/ares-log.js +258 -258
  14. package/bin/ares-novacom.js +0 -0
  15. package/bin/ares-package.js +0 -0
  16. package/bin/ares-pull.js +156 -156
  17. package/bin/ares-push.js +155 -155
  18. package/bin/ares-server.js +174 -174
  19. package/bin/ares-setup-device.js +0 -0
  20. package/bin/ares-shell.js +132 -132
  21. package/bin/ares.js +166 -166
  22. package/files/conf/ipk.json +30 -30
  23. package/files/conf/query/query-app.json +14 -14
  24. package/files/conf/query/query-hosted.json +18 -18
  25. package/files/conf/query/query-package.json +10 -10
  26. package/files/conf/query/query-service.json +6 -6
  27. package/files/conf/webos_emul +27 -27
  28. package/files/conf-base/env/sdk-apollo.json +7 -7
  29. package/files/conf-base/env/sdk-ose.json +8 -8
  30. package/files/conf-base/env/sdk-tv.json +8 -8
  31. package/files/conf-base/profile/config-apollo.json +28 -28
  32. package/files/conf-base/profile/config-ose.json +29 -29
  33. package/files/conf-base/profile/config-tv.json +31 -31
  34. package/files/conf-base/query/query-app.json +14 -14
  35. package/files/conf-base/query/query-hosted.json +18 -18
  36. package/files/conf-base/query/query-package.json +10 -10
  37. package/files/conf-base/query/query-service.json +6 -6
  38. package/files/conf-base/template-conf/ose-templates.json +67 -67
  39. package/files/conf-base/template-conf/tv-sdk-templates.json +57 -57
  40. package/files/help/ares-device.help +109 -109
  41. package/files/help/ares-install.help +95 -95
  42. package/files/help/ares-log-pmlogd.help +84 -84
  43. package/files/help/ares-log.help +101 -101
  44. package/files/help/ares-novacom.help +68 -68
  45. package/files/help/ares-pull.help +38 -38
  46. package/files/help/ares-push.help +38 -38
  47. package/files/help/ares-server.help +44 -44
  48. package/files/help/ares-shell.help +42 -42
  49. package/files/help/ares.help +52 -52
  50. package/files/help/readme.help +23 -23
  51. package/files/schema/ApplicationDescription.schema +319 -319
  52. package/files/templates/apollo-sdk-templates/appinfo/appinfo.json +10 -10
  53. package/files/templates/apollo-sdk-templates/bootplate-web/index.html +88 -88
  54. package/files/templates/apollo-sdk-templates/hosted-webapp/index.html +13 -13
  55. package/files/templates/apollo-sdk-templates/js-service/helloclient.js +31 -31
  56. package/files/templates/apollo-sdk-templates/js-service/helloworld_webos_service.js +188 -188
  57. package/files/templates/apollo-sdk-templates/serviceinfo/package.json +11 -11
  58. package/files/templates/apollo-sdk-templates/serviceinfo/services.json +8 -8
  59. package/files/templates/ose-sdk-templates/appinfo/appinfo.json +10 -10
  60. package/files/templates/ose-sdk-templates/bootplate-web/index.html +88 -88
  61. package/files/templates/ose-sdk-templates/hosted-webapp/index.html +13 -13
  62. package/files/templates/ose-sdk-templates/icon/icon.png +0 -0
  63. package/files/templates/ose-sdk-templates/js-service/helloclient.js +31 -31
  64. package/files/templates/ose-sdk-templates/js-service/helloworld_webos_service.js +188 -188
  65. package/files/templates/ose-sdk-templates/qml-app/main.qml +68 -68
  66. package/files/templates/ose-sdk-templates/qmlappinfo/appinfo.json +10 -10
  67. package/files/templates/ose-sdk-templates/serviceinfo/package.json +11 -11
  68. package/files/templates/ose-sdk-templates/serviceinfo/services.json +8 -8
  69. package/files/templates/tv-sdk-templates/appinfo/appinfo.json +10 -10
  70. package/files/templates/tv-sdk-templates/bootplate-web/index.html +58 -58
  71. package/files/templates/tv-sdk-templates/bootplate-web/webOSTVjs-1.2.10/LICENSE-2.0.txt +202 -202
  72. package/files/templates/tv-sdk-templates/hosted-webapp/index.html +14 -14
  73. package/files/templates/tv-sdk-templates/js-service/helloworld_service.js +39 -39
  74. package/files/templates/tv-sdk-templates/packageinfo/packageinfo.json +3 -3
  75. package/files/templates/tv-sdk-templates/serviceinfo/package.json +11 -11
  76. package/files/templates/tv-sdk-templates/serviceinfo/services.json +8 -8
  77. package/files/templates/tv-sdk-templates/webicon/icon.png +0 -0
  78. package/files/templates/tv-sdk-templates/webicon/largeIcon.png +0 -0
  79. package/lib/base/ares.html +40 -40
  80. package/lib/base/cli-appdata.js +290 -290
  81. package/lib/base/cli-control.js +44 -44
  82. package/lib/base/common-tools.js +29 -29
  83. package/lib/base/error-handler.js +265 -265
  84. package/lib/base/file-watcher.js +155 -155
  85. package/lib/base/help-format.js +147 -147
  86. package/lib/base/luna.js +178 -178
  87. package/lib/base/sdkenv.js +59 -59
  88. package/lib/base/server.js +137 -137
  89. package/lib/base/version-tools.js +79 -79
  90. package/lib/device.js +1419 -1419
  91. package/lib/inspect.js +493 -493
  92. package/lib/log.js +584 -584
  93. package/lib/package.js +1 -3
  94. package/lib/pull.js +231 -231
  95. package/lib/pusher.js +210 -210
  96. package/lib/session.js +74 -74
  97. package/lib/shell.js +193 -193
  98. package/lib/tar-filter-pack.js +62 -62
  99. package/lib/util/copy.js +31 -31
  100. package/lib/util/createFileName.js +40 -40
  101. package/lib/util/eof.js +30 -30
  102. package/lib/util/json.js +63 -63
  103. package/lib/util/merge.js +14 -14
  104. package/lib/util/objclone.js +40 -40
  105. package/lib/util/spinner.js +37 -37
  106. package/npm-shrinkwrap.json +1 -1
  107. package/package.json +1 -1
  108. package/scripts/postinstall.js +24 -24
  109. package/spec/helpers/reporter.js +65 -65
  110. package/spec/jsSpecs/apiTest/generator.spec.js +372 -372
  111. package/spec/jsSpecs/apiTest/inspector.spec.js +89 -89
  112. package/spec/jsSpecs/apiTest/installer.spec.js +67 -67
  113. package/spec/jsSpecs/apiTest/launcher.spec.js +150 -150
  114. package/spec/jsSpecs/apiTest/packager.spec.js +194 -194
  115. package/spec/jsSpecs/apiTest/puller.spec.js +101 -101
  116. package/spec/jsSpecs/apiTest/pusher.spec.js +103 -103
  117. package/spec/jsSpecs/apiTest/server.spec.js +115 -115
  118. package/spec/jsSpecs/apiTest/setupDevice.spec.js +93 -93
  119. package/spec/jsSpecs/apiTest/shell.spec.js +49 -49
  120. package/spec/jsSpecs/ares-config.spec.js +88 -88
  121. package/spec/jsSpecs/ares-device.spec.js +443 -443
  122. package/spec/jsSpecs/ares-generate.spec.js +397 -397
  123. package/spec/jsSpecs/ares-inspect.spec.js +252 -252
  124. package/spec/jsSpecs/ares-install.spec.js +150 -150
  125. package/spec/jsSpecs/ares-log.spec.js +824 -824
  126. package/spec/jsSpecs/ares-novacom.spec.js +149 -149
  127. package/spec/jsSpecs/ares-pull.spec.js +157 -157
  128. package/spec/jsSpecs/ares-push.spec.js +146 -146
  129. package/spec/jsSpecs/ares-shell.spec.js +220 -220
  130. package/spec/jsSpecs/ares.spec.js +83 -83
  131. package/spec/support/jasmine.json +22 -22
  132. package/spec/tempFiles/nativeApp/auto/pkg_arm64/GLES2 +0 -0
  133. package/spec/tempFiles/nativeApp/auto/pkg_arm64/appinfo.json +9 -9
  134. package/spec/tempFiles/nativeApp/ose/pkg_arm/Hello +0 -0
  135. package/spec/tempFiles/nativeApp/ose/pkg_arm/appinfo.json +8 -8
  136. package/spec/tempFiles/nativeApp/ose/pkg_arm/package.properties +2 -2
  137. package/spec/tempFiles/nativeApp/oseEmul/pkg_x86/Hello +0 -0
  138. package/spec/tempFiles/nativeApp/oseEmul/pkg_x86/appinfo.json +9 -9
  139. package/spec/tempFiles/nativeApp/rsi/pkg_x86/GLES2 +0 -0
  140. package/spec/tempFiles/nativeApp/rsi/pkg_x86/appinfo.json +9 -9
  141. package/spec/tempFiles/sign/sign.crt +32 -32
  142. package/spec/tempFiles/sign/signPriv.key +52 -52
  143. package/spec/test_data/ares-generate.json +57 -57
  144. package/spec/test_data/ares.json +50 -50
  145. package/.vscode/c_cpp_properties.json +0 -21
  146. package/.vscode/launch.json +0 -97
  147. package/.vscode/settings.json +0 -13
  148. package/.vscode/tasks.json +0 -32
  149. package/webos-tools-cli-3.2.1.tgz +0 -0
package/lib/log.js CHANGED
@@ -1,584 +1,584 @@
1
- /*
2
- * Copyright (c) 2021-2024 LG Electronics Inc.
3
- *
4
- * SPDX-License-Identifier: Apache-2.0
5
- */
6
-
7
- const util = require('util'),
8
- async = require('async'),
9
- npmlog = require('npmlog'),
10
- fs = require('fs'),
11
- path = require('path'),
12
- novacom = require('./base/novacom'),
13
- errHndl = require('./base/error-handler'),
14
- sessionLib = require('./session'),
15
- createDateFileName = require('./util/createFileName').createDateFileName;
16
-
17
- (function() {
18
-
19
- const log = npmlog;
20
- log.heading = 'log';
21
- log.level = 'warn';
22
-
23
- const reservedOption = ["--level", "--device", "--save"];
24
- let idx, savedFilePath;
25
-
26
- const logLib = {
27
-
28
- /**
29
- * @property {Object} log an npm log instance
30
- */
31
- log: log,
32
-
33
- show: function(options, next) {
34
- log.info("log#show()");
35
- if (typeof next !== 'function') {
36
- throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
37
- }
38
-
39
- options = options || {};
40
- async.series([
41
- _makeSession,
42
- _checkUser,
43
- this.checkLogDaemon.bind(this, options),
44
- _getSession,
45
- _createLogFile,
46
- _generateCmd,
47
- function(next) {
48
- // For id-filter with follow options, the pty option is required for ssh connection.
49
- if (options.argv["id-filter"]) {
50
- options.session.runWithOption(options.cmd, {pty:true}, process.stdin, _onData, process.stderr, next);
51
- } else {
52
- options.session.run(options.cmd, process.stdin, _onData, process.stderr, next);
53
- }
54
- },
55
- ], function(err) {
56
- if (options.argv.save) {
57
- next(err, {msg: "\nCreated " + savedFilePath + "\nSuccess"});
58
- } else if (options.argv["id-filter"] && err && err[0].heading === "[ssh exec failure]:") {
59
- next(errHndl.getErrMsg("NOT_MATCHED_LOG"));
60
- } else {
61
- next(err, null);
62
- }
63
- });
64
-
65
- function _onData(data) {
66
- log.info("log#show()#_onData()");
67
- const strLogs = (Buffer.isBuffer(data)) ? data.toString() : data;
68
- process.stdout.write(strLogs);
69
-
70
- if (options.argv.save) {
71
- fs.writeFileSync(savedFilePath, data, {encoding: 'utf8', flag:'a'});
72
- }
73
- }
74
-
75
- function _getSession(next) {
76
- log.info("log#show()#_getSession()");
77
- if (options.display) {
78
- options.returnWithError = true;
79
- sessionLib.getSessionList(options, next);
80
- } else {
81
- next();
82
- }
83
- }
84
-
85
- function _createLogFile(next) {
86
- log.info("log#show()#_createLogFile()");
87
- if (options.argv.save) {
88
- createLogFile(options, next);
89
- } else {
90
- next();
91
- }
92
- }
93
-
94
- function _makeSession(next) {
95
- options.printTarget = false;
96
- makeSession(options, next);
97
- }
98
-
99
- function _checkUser(next) {
100
- checkUser(options, next);
101
- }
102
-
103
- function _generateCmd(next) {
104
- generateCmd(options, next);
105
- }
106
- },
107
-
108
- readMode: function(options, next) {
109
- log.info("log#readMode()");
110
- if (typeof next !== 'function') {
111
- throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
112
- }
113
-
114
- options = options || {};
115
- async.series([
116
- _makeSession,
117
- _checkUser,
118
- this.checkLogDaemon.bind(this, options),
119
- _getLogDir,
120
- _generateCmd,
121
- _createLogFile,
122
- function(next) {
123
- options.session.run(options.cmd, process.stdin, _onData, process.stderr, next);
124
- },
125
- ], function(err) {
126
- if (options.argv.save) {
127
- next(err, {msg: "\nCreated " + savedFilePath + "\nSuccess"});
128
- } else {
129
- next(err, null);
130
- }
131
- });
132
-
133
- function _onData(data) {
134
- log.info("log#readMode()#_onData()");
135
- const str = (Buffer.isBuffer(data)) ? data.toString() : data;
136
- console.log(str); // Do not remove
137
-
138
- if (options.argv.save) {
139
- fs.writeFileSync(savedFilePath, data, {encoding: 'utf8', flag:'a'});
140
- }
141
- }
142
-
143
- function _getLogDir(next) {
144
- log.info("log#readMode()#_getLogDir()");
145
- const getLogDirCmd = "ls /run/log/journal/";
146
- options.session.run(getLogDirCmd, process.stdin, _onDirData, process.stderr, next);
147
- }
148
-
149
- function _onDirData(data) {
150
- log.info("log#readMode()#_onDirData()");
151
- options.logDir = (Buffer.isBuffer(data)) ? data.toString() : data;
152
- options.logDir = options.logDir.trim();
153
- }
154
-
155
- function _generateCmd(next) {
156
- log.info("log#readMode()#_generateCmd()");
157
- if (options.argv.file === "true") {
158
- return next(errHndl.getErrMsg("EMPTY_FILENAME"));
159
- }
160
-
161
- if (options.argv.file) {
162
- options.cmd = "journalctl --file /run/log/journal/" + options.logDir + "/" + options.argv.file;
163
- if (options.argv.output) {
164
- options.cmd += " --output " + options.argv.argv.remain;
165
- }
166
- }
167
-
168
- if (options.argv['file-list']) {
169
- options.cmd = "ls /run/log/journal/" + options.logDir;
170
- }
171
-
172
- log.verbose("log#readMode()#_generateCmd()", "options.cmd:" + options.cmd);
173
- next();
174
- }
175
-
176
- function _createLogFile(next) {
177
- log.info("log#readMode()#_createLogFile()");
178
- if (options.argv.save) {
179
- createLogFile(options, next);
180
- } else {
181
- next();
182
- }
183
- }
184
-
185
- function _makeSession(next) {
186
- options.printTarget = false;
187
- makeSession(options, next);
188
- }
189
-
190
- function _checkUser(next) {
191
- checkUser(options, next);
192
- }
193
- },
194
-
195
- printUnitList: function(options, next) {
196
- log.info("log#printUnitList()");
197
- if (typeof next !== 'function') {
198
- throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
199
- }
200
-
201
- options = options || {};
202
- async.series([
203
- _makeSession,
204
- _checkUser,
205
- this.checkLogDaemon.bind(this, options),
206
- _getSession,
207
- _generateCmd,
208
- function(next) {
209
- options.session.run(options.cmd, process.stdin, _onData, process.stderr, next);
210
- },
211
- ], function(err) {
212
- next(err, null);
213
- });
214
-
215
- function _onData(data) {
216
- log.info("log#printUnitList()#_onData()");
217
- const str = (Buffer.isBuffer(data)) ? data.toString() : data;
218
- const exp = /(\s\w[\S]*\.service)/g;
219
-
220
- if (Array.isArray(str.match(exp))) {
221
- str.match(exp).forEach(function(item) {
222
- console.log(item.trim()); // Do not remove
223
- });
224
- }
225
- }
226
-
227
- function _getSession(next) {
228
- log.info("log#printUnitList()#_getSession()");
229
- if (options.display) {
230
- options.returnWithError = true;
231
- sessionLib.getSessionList(options, next);
232
- } else {
233
- next();
234
- }
235
- }
236
-
237
- function _generateCmd(next) {
238
- log.info("log#printUnitList()#_generateCmd()");
239
- options.cmd = "systemctl list-units --type service";
240
-
241
- if (options.sessionId) {
242
- options.cmd = "systemctl --user list-units --type service";
243
- options.cmd = `su ${options.sessionId} -l -c "${options.cmd}"`;
244
- }
245
-
246
- log.verbose("log#printUnitList()#_generateCmd()", "options.cmd:" + options.cmd);
247
- next();
248
- }
249
-
250
- function _makeSession(next) {
251
- options.printTarget = false;
252
- makeSession(options, next);
253
- }
254
-
255
- function _checkUser(next) {
256
- checkUser(options, next);
257
- }
258
- },
259
-
260
- contextMode: function(options, next) {
261
- log.info("log#contextMode()");
262
- if (typeof next !== 'function') {
263
- throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
264
- }
265
-
266
- options = options || {};
267
- async.series([
268
- _makeSession,
269
- _checkUser,
270
- this.checkLogDaemon.bind(this, options),
271
- _getSession,
272
- _generateCmd,
273
- function(next) {
274
- if (options.argv["context-list"]) {
275
- options.session.run(options.cmd, process.stdin, _onListData, process.stderr, next);
276
- } else if (options.argv["set-level"]) {
277
- options.session.run(options.cmd, process.stdin, _onSetData, process.stderr, next);
278
- }
279
- },
280
- ], function(err) {
281
- next(err, null);
282
- });
283
-
284
- function _onListData(data) {
285
- log.info("log#contextMode()#_onListData()");
286
- const str = (Buffer.isBuffer(data)) ? data.toString() : data;
287
- console.log(str.replace(/PmLogCtl: Context '(.*)'/g, '$1').trim());
288
- }
289
-
290
- function _onSetData(data) {
291
- log.info("log#contextMode()#_onSetData()");
292
- const str = (Buffer.isBuffer(data)) ? data.toString() : data;
293
- console.log(str.replace(/PmLogCtl: /g, '').trim());
294
- }
295
-
296
- function _getSession(next) {
297
- log.info("log#contextMode()#_getSession()");
298
- if (options.display) {
299
- options.returnWithError = true;
300
- sessionLib.getSessionList(options, next);
301
- } else {
302
- next();
303
- }
304
- }
305
-
306
- function _generateCmd(next) {
307
- log.info("log#contextMode()#_generateCmd()");
308
- if (options.argv["context-list"]) {
309
- options.cmd = "PmLogCtl show";
310
- } else if (options.argv["set-level"]) {
311
- reservedOption.forEach(function(item) {
312
- idx = options.argv.argv.cooked.indexOf(item);
313
- if (idx > -1) {
314
- options.argv.argv.cooked.splice(idx, 1);
315
- options.argv.argv.cooked.splice(idx, 1);
316
- }
317
- });
318
-
319
- options.argv.argv.cooked.splice(0, 1);
320
- options.cmd = `PmLogCtl set ${options.argv.argv.cooked.join(" ")}`;
321
- }
322
- log.verbose("log#contextMode()#_generateCmd()", "options.cmd:" + options.cmd);
323
- next();
324
- }
325
-
326
- function _makeSession(next) {
327
- options.printTarget = true;
328
- makeSession(options, next);
329
- }
330
-
331
- function _checkUser(next) {
332
- checkUser(options, next);
333
- }
334
- },
335
-
336
- checkLogDaemon: function(options, next) {
337
- log.info("log#checkLogDaemon()");
338
- if (typeof next !== 'function') {
339
- throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
340
- }
341
-
342
- options = options || {};
343
-
344
- let serviceParam = "",
345
- cmd = "",
346
- logFilePath = "",
347
- returnData = "",
348
- logDaemonStatus = false,
349
- existLogFile = false;
350
-
351
- async.series([
352
- _makeSession,
353
- _setparam,
354
- function(next) {
355
- options.session.run(cmd, process.stdin, _checkService, process.stderr, function(err) {
356
- if (err) {
357
- return next(err);
358
- }
359
- if (!logDaemonStatus) {
360
- return next(errHndl.getErrMsg("NOT_MATCHED_LOGDAEMON", options.currentDaemon === "journald" ? "pmlogd" : "journald"));
361
- }
362
-
363
- cmd = `ls -al ${logFilePath}`;
364
- options.session.run(cmd, process.stdin, _checkFile, process.stderr, function(error) {
365
- if (error) {
366
- return next(err);
367
- }
368
- if (!existLogFile) {
369
- return next(errHndl.getErrMsg("NOT_EXIST_LOGFILE"));
370
- }
371
- next();
372
- });
373
- });
374
- },
375
- ], function(err) {
376
- if (err) {
377
- console.log("CLI's current logging daemon : " + options.currentDaemon);
378
- next(err, null);
379
- } else {
380
- next(null, {msg: "CLI's current logging daemon : " + options.currentDaemon
381
- + "\nThe target's current logging daemon : " + options.currentDaemon});
382
- }
383
- });
384
-
385
- function _setparam(next) {
386
- log.info("log#checkLogDaemon()#_setparam()");
387
- if (options.currentDaemon === "journald") {
388
- serviceParam = "systemd-journald";
389
- logFilePath = "/run/log/journal";
390
- } else if (options.currentDaemon === "pmlogd") {
391
- serviceParam = "pm-log-daemon";
392
- logFilePath = "/var/log/messages";
393
- }
394
-
395
- cmd = `systemctl status ${serviceParam}.service | tee`;
396
- next();
397
- }
398
-
399
- function _checkService(data) {
400
- log.info("log#checkLogDaemon()#_checkService()");
401
- returnData += (Buffer.isBuffer(data)) ? data.toString() : data;
402
-
403
- if (returnData.indexOf("active (running)") !== -1) {
404
- logDaemonStatus = true;
405
- }
406
- }
407
-
408
- function _checkFile(data) {
409
- log.info("log#checkLogDaemon()#_checkFile()");
410
- const str = (Buffer.isBuffer(data)) ? data.toString() : data;
411
-
412
- if (str.length) {
413
- existLogFile = true;
414
- }
415
- }
416
-
417
- function _makeSession(next) {
418
- options.printTarget = true;
419
- makeSession(options, next);
420
- }
421
- }
422
- };
423
-
424
- function makeSession(options, next) {
425
- if (!options.session) {
426
- log.info("log#makeSession()", "need to make new session");
427
- const printTarget = options.printTarget;
428
- options.session = new novacom.Session(options.device, printTarget, next);
429
- } else {
430
- log.info("log#makeSession()", "already exist session");
431
- next();
432
- }
433
- }
434
-
435
- function checkUser(options, next) {
436
- log.info("log#checkUser()", "username:", options.session.getDevice().username);
437
- if (options.session.getDevice().username !== 'root') {
438
- return next(errHndl.getErrMsg("NEED_ROOT_PERMISSION"));
439
- } else {
440
- next();
441
- }
442
- }
443
-
444
- function generateCmd(options, next) {
445
- log.info("log#generateCmd()", "options.currentDaemon:", options.currentDaemon);
446
-
447
- if (options.currentDaemon === "pmlogd") {
448
- const pmLogFilePath = " /var/log/messages";
449
-
450
- if (options.argv.follow) {
451
- options.cmd = "tail -f";
452
- } else if (options.argv.lines) {
453
- options.cmd = "tail";
454
- } else {
455
- options.cmd = "cat";
456
- }
457
-
458
- if (options.argv.lines) {
459
- options.cmd += ` -n ${options.argv.lines}`;
460
- }
461
- options.cmd += pmLogFilePath;
462
-
463
- if (options.argv["id-filter"]) {
464
- // Handle when another option appears without id-filter value
465
- const idReg = /^-/;
466
- if (options.argv["id-filter"] === "true" || options.argv["id-filter"].match(idReg)) {
467
- return next(errHndl.getErrMsg("EMPTY_VALUE", "id-filter"));
468
- } else {
469
- const convertReg = /\./g;
470
- let filter = options.argv["id-filter"];
471
- filter = filter.replace(convertReg, '\\.');
472
-
473
- options.cmd += ` | grep -E "\\[(\\d*|\\d*\\:\\d*)\\] ${filter}"`;
474
- }
475
- }
476
- } else if (options.currentDaemon === "journald") {
477
- if (options.display && !options.argv.unit) {
478
- return next(errHndl.getErrMsg("INVALID_COMBINATION"));
479
- }
480
-
481
- reservedOption.forEach(function(item) {
482
- idx = options.argv.argv.cooked.indexOf(item);
483
- if (idx > -1) {
484
- options.argv.argv.cooked.splice(idx, 1);
485
- options.argv.argv.cooked.splice(idx, 1);
486
- }
487
- });
488
-
489
- if (options.argv.pid) {
490
- idx = options.argv.argv.cooked.indexOf("-pid");
491
-
492
- if (idx === -1) {
493
- idx = options.argv.argv.cooked.indexOf("--pid");
494
- }
495
-
496
- if (idx > -1) {
497
- options.argv.argv.cooked.splice(idx, 1, "_PID=");
498
- }
499
- }
500
-
501
- if (options.argv.since) {
502
- if (options.argv.argv.remain.length > 0) {
503
- idx = options.argv.argv.cooked.indexOf("--since");
504
-
505
- let sinceTmp = options.argv.argv.cooked[idx+1];
506
- if (options.argv.argv.cooked[idx+2]) {
507
- sinceTmp += " " + options.argv.argv.cooked[idx+2];
508
- }
509
-
510
- options.argv.argv.cooked.splice(idx+1, 2, "\"" + sinceTmp + "\"");
511
- }
512
- }
513
-
514
- if (options.argv.until) {
515
- if (options.argv.argv.remain.length > 0) {
516
- idx = options.argv.argv.cooked.indexOf("--until");
517
-
518
- let untilTmp = options.argv.argv.cooked[idx+1];
519
- if (options.argv.argv.cooked[idx+2]) {
520
- untilTmp += " " + options.argv.argv.cooked[idx+2];
521
- }
522
-
523
- options.argv.argv.cooked.splice(idx+1, 2, "\"" + untilTmp + "\"");
524
- }
525
- }
526
-
527
- options.cmd = `journalctl ${options.argv.argv.cooked.join(" ")}`;
528
- options.cmd = options.cmd.replace('_PID= ', '_PID=');
529
-
530
- if (options.display && options.argv.unit) {
531
- idx = options.argv.argv.cooked.indexOf("--unit");
532
- options.argv.argv.cooked.splice(idx, 1, "--user-unit");
533
-
534
- idx = options.argv.argv.cooked.indexOf("--display");
535
- options.argv.argv.cooked.splice(idx, 2);
536
-
537
- options.cmd = `journalctl ${options.argv.argv.cooked.join(" ")}`;
538
- options.cmd = `su ${options.sessionId} -l -c "${options.cmd}"`;
539
- }
540
- }
541
- log.verbose("log#generateCmd()", "options.cmd:", options.cmd);
542
- next();
543
- }
544
-
545
- function createLogFile(options, next) {
546
- log.info("log#createLogFile()");
547
-
548
- const fileNameSeperator = "_",
549
- fileExt = "log";
550
-
551
- if (options.argv.argv.remain.length === 0) {
552
- savedFilePath = path.resolve(createDateFileName(fileNameSeperator, fileExt));
553
- } else {
554
- if (path.extname(options.argv.argv.remain[0]) === "") {
555
- options.argv.argv.remain[0] = options.argv.argv.remain[0] + "." + fileExt;
556
- }
557
-
558
- if (path.extname(options.argv.argv.remain[0]) === ".") {
559
- options.argv.argv.remain[0] = options.argv.argv.remain[0] + fileExt;
560
- }
561
-
562
- savedFilePath = path.resolve(options.argv.argv.remain[0]);
563
- }
564
- log.verbose("log#createLogFile()", "savedFilePath:" + savedFilePath);
565
-
566
- // For error handling of non exist path
567
- fs.open(savedFilePath, 'w', function(err, fd) {
568
- if (err) {
569
- return next(errHndl.getErrMsg(err));
570
- }
571
- fs.closeSync(fd);
572
- next();
573
- });
574
- // Defense code
575
- if (fs.existsSync(savedFilePath)) {
576
- fs.unlinkSync(savedFilePath);
577
- }
578
- log.verbose("log#createLogFile()", savedFilePath + " is exist: " + fs.existsSync(savedFilePath));
579
- }
580
-
581
- if (typeof module !== 'undefined' && module.exports) {
582
- module.exports = logLib;
583
- }
584
- }());
1
+ /*
2
+ * Copyright (c) 2021-2024 LG Electronics Inc.
3
+ *
4
+ * SPDX-License-Identifier: Apache-2.0
5
+ */
6
+
7
+ const util = require('util'),
8
+ async = require('async'),
9
+ npmlog = require('npmlog'),
10
+ fs = require('fs'),
11
+ path = require('path'),
12
+ novacom = require('./base/novacom'),
13
+ errHndl = require('./base/error-handler'),
14
+ sessionLib = require('./session'),
15
+ createDateFileName = require('./util/createFileName').createDateFileName;
16
+
17
+ (function() {
18
+
19
+ const log = npmlog;
20
+ log.heading = 'log';
21
+ log.level = 'warn';
22
+
23
+ const reservedOption = ["--level", "--device", "--save"];
24
+ let idx, savedFilePath;
25
+
26
+ const logLib = {
27
+
28
+ /**
29
+ * @property {Object} log an npm log instance
30
+ */
31
+ log: log,
32
+
33
+ show: function(options, next) {
34
+ log.info("log#show()");
35
+ if (typeof next !== 'function') {
36
+ throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
37
+ }
38
+
39
+ options = options || {};
40
+ async.series([
41
+ _makeSession,
42
+ _checkUser,
43
+ this.checkLogDaemon.bind(this, options),
44
+ _getSession,
45
+ _createLogFile,
46
+ _generateCmd,
47
+ function(next) {
48
+ // For id-filter with follow options, the pty option is required for ssh connection.
49
+ if (options.argv["id-filter"]) {
50
+ options.session.runWithOption(options.cmd, {pty:true}, process.stdin, _onData, process.stderr, next);
51
+ } else {
52
+ options.session.run(options.cmd, process.stdin, _onData, process.stderr, next);
53
+ }
54
+ },
55
+ ], function(err) {
56
+ if (options.argv.save) {
57
+ next(err, {msg: "\nCreated " + savedFilePath + "\nSuccess"});
58
+ } else if (options.argv["id-filter"] && err && err[0].heading === "[ssh exec failure]:") {
59
+ next(errHndl.getErrMsg("NOT_MATCHED_LOG"));
60
+ } else {
61
+ next(err, null);
62
+ }
63
+ });
64
+
65
+ function _onData(data) {
66
+ log.info("log#show()#_onData()");
67
+ const strLogs = (Buffer.isBuffer(data)) ? data.toString() : data;
68
+ process.stdout.write(strLogs);
69
+
70
+ if (options.argv.save) {
71
+ fs.writeFileSync(savedFilePath, data, {encoding: 'utf8', flag:'a'});
72
+ }
73
+ }
74
+
75
+ function _getSession(next) {
76
+ log.info("log#show()#_getSession()");
77
+ if (options.display) {
78
+ options.returnWithError = true;
79
+ sessionLib.getSessionList(options, next);
80
+ } else {
81
+ next();
82
+ }
83
+ }
84
+
85
+ function _createLogFile(next) {
86
+ log.info("log#show()#_createLogFile()");
87
+ if (options.argv.save) {
88
+ createLogFile(options, next);
89
+ } else {
90
+ next();
91
+ }
92
+ }
93
+
94
+ function _makeSession(next) {
95
+ options.printTarget = false;
96
+ makeSession(options, next);
97
+ }
98
+
99
+ function _checkUser(next) {
100
+ checkUser(options, next);
101
+ }
102
+
103
+ function _generateCmd(next) {
104
+ generateCmd(options, next);
105
+ }
106
+ },
107
+
108
+ readMode: function(options, next) {
109
+ log.info("log#readMode()");
110
+ if (typeof next !== 'function') {
111
+ throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
112
+ }
113
+
114
+ options = options || {};
115
+ async.series([
116
+ _makeSession,
117
+ _checkUser,
118
+ this.checkLogDaemon.bind(this, options),
119
+ _getLogDir,
120
+ _generateCmd,
121
+ _createLogFile,
122
+ function(next) {
123
+ options.session.run(options.cmd, process.stdin, _onData, process.stderr, next);
124
+ },
125
+ ], function(err) {
126
+ if (options.argv.save) {
127
+ next(err, {msg: "\nCreated " + savedFilePath + "\nSuccess"});
128
+ } else {
129
+ next(err, null);
130
+ }
131
+ });
132
+
133
+ function _onData(data) {
134
+ log.info("log#readMode()#_onData()");
135
+ const str = (Buffer.isBuffer(data)) ? data.toString() : data;
136
+ console.log(str); // Do not remove
137
+
138
+ if (options.argv.save) {
139
+ fs.writeFileSync(savedFilePath, data, {encoding: 'utf8', flag:'a'});
140
+ }
141
+ }
142
+
143
+ function _getLogDir(next) {
144
+ log.info("log#readMode()#_getLogDir()");
145
+ const getLogDirCmd = "ls /run/log/journal/";
146
+ options.session.run(getLogDirCmd, process.stdin, _onDirData, process.stderr, next);
147
+ }
148
+
149
+ function _onDirData(data) {
150
+ log.info("log#readMode()#_onDirData()");
151
+ options.logDir = (Buffer.isBuffer(data)) ? data.toString() : data;
152
+ options.logDir = options.logDir.trim();
153
+ }
154
+
155
+ function _generateCmd(next) {
156
+ log.info("log#readMode()#_generateCmd()");
157
+ if (options.argv.file === "true") {
158
+ return next(errHndl.getErrMsg("EMPTY_FILENAME"));
159
+ }
160
+
161
+ if (options.argv.file) {
162
+ options.cmd = "journalctl --file /run/log/journal/" + options.logDir + "/" + options.argv.file;
163
+ if (options.argv.output) {
164
+ options.cmd += " --output " + options.argv.argv.remain;
165
+ }
166
+ }
167
+
168
+ if (options.argv['file-list']) {
169
+ options.cmd = "ls /run/log/journal/" + options.logDir;
170
+ }
171
+
172
+ log.verbose("log#readMode()#_generateCmd()", "options.cmd:" + options.cmd);
173
+ next();
174
+ }
175
+
176
+ function _createLogFile(next) {
177
+ log.info("log#readMode()#_createLogFile()");
178
+ if (options.argv.save) {
179
+ createLogFile(options, next);
180
+ } else {
181
+ next();
182
+ }
183
+ }
184
+
185
+ function _makeSession(next) {
186
+ options.printTarget = false;
187
+ makeSession(options, next);
188
+ }
189
+
190
+ function _checkUser(next) {
191
+ checkUser(options, next);
192
+ }
193
+ },
194
+
195
+ printUnitList: function(options, next) {
196
+ log.info("log#printUnitList()");
197
+ if (typeof next !== 'function') {
198
+ throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
199
+ }
200
+
201
+ options = options || {};
202
+ async.series([
203
+ _makeSession,
204
+ _checkUser,
205
+ this.checkLogDaemon.bind(this, options),
206
+ _getSession,
207
+ _generateCmd,
208
+ function(next) {
209
+ options.session.run(options.cmd, process.stdin, _onData, process.stderr, next);
210
+ },
211
+ ], function(err) {
212
+ next(err, null);
213
+ });
214
+
215
+ function _onData(data) {
216
+ log.info("log#printUnitList()#_onData()");
217
+ const str = (Buffer.isBuffer(data)) ? data.toString() : data;
218
+ const exp = /(\s\w[\S]*\.service)/g;
219
+
220
+ if (Array.isArray(str.match(exp))) {
221
+ str.match(exp).forEach(function(item) {
222
+ console.log(item.trim()); // Do not remove
223
+ });
224
+ }
225
+ }
226
+
227
+ function _getSession(next) {
228
+ log.info("log#printUnitList()#_getSession()");
229
+ if (options.display) {
230
+ options.returnWithError = true;
231
+ sessionLib.getSessionList(options, next);
232
+ } else {
233
+ next();
234
+ }
235
+ }
236
+
237
+ function _generateCmd(next) {
238
+ log.info("log#printUnitList()#_generateCmd()");
239
+ options.cmd = "systemctl list-units --type service";
240
+
241
+ if (options.sessionId) {
242
+ options.cmd = "systemctl --user list-units --type service";
243
+ options.cmd = `su ${options.sessionId} -l -c "${options.cmd}"`;
244
+ }
245
+
246
+ log.verbose("log#printUnitList()#_generateCmd()", "options.cmd:" + options.cmd);
247
+ next();
248
+ }
249
+
250
+ function _makeSession(next) {
251
+ options.printTarget = false;
252
+ makeSession(options, next);
253
+ }
254
+
255
+ function _checkUser(next) {
256
+ checkUser(options, next);
257
+ }
258
+ },
259
+
260
+ contextMode: function(options, next) {
261
+ log.info("log#contextMode()");
262
+ if (typeof next !== 'function') {
263
+ throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
264
+ }
265
+
266
+ options = options || {};
267
+ async.series([
268
+ _makeSession,
269
+ _checkUser,
270
+ this.checkLogDaemon.bind(this, options),
271
+ _getSession,
272
+ _generateCmd,
273
+ function(next) {
274
+ if (options.argv["context-list"]) {
275
+ options.session.run(options.cmd, process.stdin, _onListData, process.stderr, next);
276
+ } else if (options.argv["set-level"]) {
277
+ options.session.run(options.cmd, process.stdin, _onSetData, process.stderr, next);
278
+ }
279
+ },
280
+ ], function(err) {
281
+ next(err, null);
282
+ });
283
+
284
+ function _onListData(data) {
285
+ log.info("log#contextMode()#_onListData()");
286
+ const str = (Buffer.isBuffer(data)) ? data.toString() : data;
287
+ console.log(str.replace(/PmLogCtl: Context '(.*)'/g, '$1').trim());
288
+ }
289
+
290
+ function _onSetData(data) {
291
+ log.info("log#contextMode()#_onSetData()");
292
+ const str = (Buffer.isBuffer(data)) ? data.toString() : data;
293
+ console.log(str.replace(/PmLogCtl: /g, '').trim());
294
+ }
295
+
296
+ function _getSession(next) {
297
+ log.info("log#contextMode()#_getSession()");
298
+ if (options.display) {
299
+ options.returnWithError = true;
300
+ sessionLib.getSessionList(options, next);
301
+ } else {
302
+ next();
303
+ }
304
+ }
305
+
306
+ function _generateCmd(next) {
307
+ log.info("log#contextMode()#_generateCmd()");
308
+ if (options.argv["context-list"]) {
309
+ options.cmd = "PmLogCtl show";
310
+ } else if (options.argv["set-level"]) {
311
+ reservedOption.forEach(function(item) {
312
+ idx = options.argv.argv.cooked.indexOf(item);
313
+ if (idx > -1) {
314
+ options.argv.argv.cooked.splice(idx, 1);
315
+ options.argv.argv.cooked.splice(idx, 1);
316
+ }
317
+ });
318
+
319
+ options.argv.argv.cooked.splice(0, 1);
320
+ options.cmd = `PmLogCtl set ${options.argv.argv.cooked.join(" ")}`;
321
+ }
322
+ log.verbose("log#contextMode()#_generateCmd()", "options.cmd:" + options.cmd);
323
+ next();
324
+ }
325
+
326
+ function _makeSession(next) {
327
+ options.printTarget = true;
328
+ makeSession(options, next);
329
+ }
330
+
331
+ function _checkUser(next) {
332
+ checkUser(options, next);
333
+ }
334
+ },
335
+
336
+ checkLogDaemon: function(options, next) {
337
+ log.info("log#checkLogDaemon()");
338
+ if (typeof next !== 'function') {
339
+ throw errHndl.getErrMsg("MISSING_CALLBACK", "next", util.inspect(next));
340
+ }
341
+
342
+ options = options || {};
343
+
344
+ let serviceParam = "",
345
+ cmd = "",
346
+ logFilePath = "",
347
+ returnData = "",
348
+ logDaemonStatus = false,
349
+ existLogFile = false;
350
+
351
+ async.series([
352
+ _makeSession,
353
+ _setparam,
354
+ function(next) {
355
+ options.session.run(cmd, process.stdin, _checkService, process.stderr, function(err) {
356
+ if (err) {
357
+ return next(err);
358
+ }
359
+ if (!logDaemonStatus) {
360
+ return next(errHndl.getErrMsg("NOT_MATCHED_LOGDAEMON", options.currentDaemon === "journald" ? "pmlogd" : "journald"));
361
+ }
362
+
363
+ cmd = `ls -al ${logFilePath}`;
364
+ options.session.run(cmd, process.stdin, _checkFile, process.stderr, function(error) {
365
+ if (error) {
366
+ return next(err);
367
+ }
368
+ if (!existLogFile) {
369
+ return next(errHndl.getErrMsg("NOT_EXIST_LOGFILE"));
370
+ }
371
+ next();
372
+ });
373
+ });
374
+ },
375
+ ], function(err) {
376
+ if (err) {
377
+ console.log("CLI's current logging daemon : " + options.currentDaemon);
378
+ next(err, null);
379
+ } else {
380
+ next(null, {msg: "CLI's current logging daemon : " + options.currentDaemon
381
+ + "\nThe target's current logging daemon : " + options.currentDaemon});
382
+ }
383
+ });
384
+
385
+ function _setparam(next) {
386
+ log.info("log#checkLogDaemon()#_setparam()");
387
+ if (options.currentDaemon === "journald") {
388
+ serviceParam = "systemd-journald";
389
+ logFilePath = "/run/log/journal";
390
+ } else if (options.currentDaemon === "pmlogd") {
391
+ serviceParam = "pm-log-daemon";
392
+ logFilePath = "/var/log/messages";
393
+ }
394
+
395
+ cmd = `systemctl status ${serviceParam}.service | tee`;
396
+ next();
397
+ }
398
+
399
+ function _checkService(data) {
400
+ log.info("log#checkLogDaemon()#_checkService()");
401
+ returnData += (Buffer.isBuffer(data)) ? data.toString() : data;
402
+
403
+ if (returnData.indexOf("active (running)") !== -1) {
404
+ logDaemonStatus = true;
405
+ }
406
+ }
407
+
408
+ function _checkFile(data) {
409
+ log.info("log#checkLogDaemon()#_checkFile()");
410
+ const str = (Buffer.isBuffer(data)) ? data.toString() : data;
411
+
412
+ if (str.length) {
413
+ existLogFile = true;
414
+ }
415
+ }
416
+
417
+ function _makeSession(next) {
418
+ options.printTarget = true;
419
+ makeSession(options, next);
420
+ }
421
+ }
422
+ };
423
+
424
+ function makeSession(options, next) {
425
+ if (!options.session) {
426
+ log.info("log#makeSession()", "need to make new session");
427
+ const printTarget = options.printTarget;
428
+ options.session = new novacom.Session(options.device, printTarget, next);
429
+ } else {
430
+ log.info("log#makeSession()", "already exist session");
431
+ next();
432
+ }
433
+ }
434
+
435
+ function checkUser(options, next) {
436
+ log.info("log#checkUser()", "username:", options.session.getDevice().username);
437
+ if (options.session.getDevice().username !== 'root') {
438
+ return next(errHndl.getErrMsg("NEED_ROOT_PERMISSION"));
439
+ } else {
440
+ next();
441
+ }
442
+ }
443
+
444
+ function generateCmd(options, next) {
445
+ log.info("log#generateCmd()", "options.currentDaemon:", options.currentDaemon);
446
+
447
+ if (options.currentDaemon === "pmlogd") {
448
+ const pmLogFilePath = " /var/log/messages";
449
+
450
+ if (options.argv.follow) {
451
+ options.cmd = "tail -f";
452
+ } else if (options.argv.lines) {
453
+ options.cmd = "tail";
454
+ } else {
455
+ options.cmd = "cat";
456
+ }
457
+
458
+ if (options.argv.lines) {
459
+ options.cmd += ` -n ${options.argv.lines}`;
460
+ }
461
+ options.cmd += pmLogFilePath;
462
+
463
+ if (options.argv["id-filter"]) {
464
+ // Handle when another option appears without id-filter value
465
+ const idReg = /^-/;
466
+ if (options.argv["id-filter"] === "true" || options.argv["id-filter"].match(idReg)) {
467
+ return next(errHndl.getErrMsg("EMPTY_VALUE", "id-filter"));
468
+ } else {
469
+ const convertReg = /\./g;
470
+ let filter = options.argv["id-filter"];
471
+ filter = filter.replace(convertReg, '\\.');
472
+
473
+ options.cmd += ` | grep -E "\\[(\\d*|\\d*\\:\\d*)\\] ${filter}"`;
474
+ }
475
+ }
476
+ } else if (options.currentDaemon === "journald") {
477
+ if (options.display && !options.argv.unit) {
478
+ return next(errHndl.getErrMsg("INVALID_COMBINATION"));
479
+ }
480
+
481
+ reservedOption.forEach(function(item) {
482
+ idx = options.argv.argv.cooked.indexOf(item);
483
+ if (idx > -1) {
484
+ options.argv.argv.cooked.splice(idx, 1);
485
+ options.argv.argv.cooked.splice(idx, 1);
486
+ }
487
+ });
488
+
489
+ if (options.argv.pid) {
490
+ idx = options.argv.argv.cooked.indexOf("-pid");
491
+
492
+ if (idx === -1) {
493
+ idx = options.argv.argv.cooked.indexOf("--pid");
494
+ }
495
+
496
+ if (idx > -1) {
497
+ options.argv.argv.cooked.splice(idx, 1, "_PID=");
498
+ }
499
+ }
500
+
501
+ if (options.argv.since) {
502
+ if (options.argv.argv.remain.length > 0) {
503
+ idx = options.argv.argv.cooked.indexOf("--since");
504
+
505
+ let sinceTmp = options.argv.argv.cooked[idx+1];
506
+ if (options.argv.argv.cooked[idx+2]) {
507
+ sinceTmp += " " + options.argv.argv.cooked[idx+2];
508
+ }
509
+
510
+ options.argv.argv.cooked.splice(idx+1, 2, "\"" + sinceTmp + "\"");
511
+ }
512
+ }
513
+
514
+ if (options.argv.until) {
515
+ if (options.argv.argv.remain.length > 0) {
516
+ idx = options.argv.argv.cooked.indexOf("--until");
517
+
518
+ let untilTmp = options.argv.argv.cooked[idx+1];
519
+ if (options.argv.argv.cooked[idx+2]) {
520
+ untilTmp += " " + options.argv.argv.cooked[idx+2];
521
+ }
522
+
523
+ options.argv.argv.cooked.splice(idx+1, 2, "\"" + untilTmp + "\"");
524
+ }
525
+ }
526
+
527
+ options.cmd = `journalctl ${options.argv.argv.cooked.join(" ")}`;
528
+ options.cmd = options.cmd.replace('_PID= ', '_PID=');
529
+
530
+ if (options.display && options.argv.unit) {
531
+ idx = options.argv.argv.cooked.indexOf("--unit");
532
+ options.argv.argv.cooked.splice(idx, 1, "--user-unit");
533
+
534
+ idx = options.argv.argv.cooked.indexOf("--display");
535
+ options.argv.argv.cooked.splice(idx, 2);
536
+
537
+ options.cmd = `journalctl ${options.argv.argv.cooked.join(" ")}`;
538
+ options.cmd = `su ${options.sessionId} -l -c "${options.cmd}"`;
539
+ }
540
+ }
541
+ log.verbose("log#generateCmd()", "options.cmd:", options.cmd);
542
+ next();
543
+ }
544
+
545
+ function createLogFile(options, next) {
546
+ log.info("log#createLogFile()");
547
+
548
+ const fileNameSeperator = "_",
549
+ fileExt = "log";
550
+
551
+ if (options.argv.argv.remain.length === 0) {
552
+ savedFilePath = path.resolve(createDateFileName(fileNameSeperator, fileExt));
553
+ } else {
554
+ if (path.extname(options.argv.argv.remain[0]) === "") {
555
+ options.argv.argv.remain[0] = options.argv.argv.remain[0] + "." + fileExt;
556
+ }
557
+
558
+ if (path.extname(options.argv.argv.remain[0]) === ".") {
559
+ options.argv.argv.remain[0] = options.argv.argv.remain[0] + fileExt;
560
+ }
561
+
562
+ savedFilePath = path.resolve(options.argv.argv.remain[0]);
563
+ }
564
+ log.verbose("log#createLogFile()", "savedFilePath:" + savedFilePath);
565
+
566
+ // For error handling of non exist path
567
+ fs.open(savedFilePath, 'w', function(err, fd) {
568
+ if (err) {
569
+ return next(errHndl.getErrMsg(err));
570
+ }
571
+ fs.closeSync(fd);
572
+ next();
573
+ });
574
+ // Defense code
575
+ if (fs.existsSync(savedFilePath)) {
576
+ fs.unlinkSync(savedFilePath);
577
+ }
578
+ log.verbose("log#createLogFile()", savedFilePath + " is exist: " + fs.existsSync(savedFilePath));
579
+ }
580
+
581
+ if (typeof module !== 'undefined' && module.exports) {
582
+ module.exports = logLib;
583
+ }
584
+ }());