aaden-cli 1.6.109-rc.0 → 1.6.110
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/AadenDeploy/Utils/enableNgrok.sh +21 -19
- package/AadenDeploy/Utils/fixCronJob.sh +5 -4
- package/AadenDeploy/aadensetup.sh +217 -163
- package/AadenDeploy/checkDeviceId.sh +104 -0
- package/AadenDeploy/setDeviceId.sh +130 -0
- package/README.md +2 -1
- package/dist/index.js +168 -13
- package/dist/patch/202608190700removeGitDoUpdateCron.sh +39 -0
- package/index.js +27 -6
- package/modules/tse-cert.js +89 -0
- package/modules/tse-info.js +44 -6
- package/package.json +2 -2
- package/patch/202608190700removeGitDoUpdateCron.sh +39 -0
- package/dist/patch/202304051415FixDatevMemory.sh +0 -19
- package/patch/202304051415FixDatevMemory.sh +0 -19
package/modules/tse-info.js
CHANGED
|
@@ -2,6 +2,8 @@ const fs = require('fs')
|
|
|
2
2
|
const os = require('os')
|
|
3
3
|
const http = require('http')
|
|
4
4
|
const https = require('https')
|
|
5
|
+
const {execFileSync} = require('child_process')
|
|
6
|
+
const {parseTseCertificate} = require('./tse-cert')
|
|
5
7
|
|
|
6
8
|
// do-log 顺带上报的 TSE 适配服务(TseHost)信息,用来在云端看车队的 TSE 版本和服务状态。
|
|
7
9
|
// WSL 门店的 TseHost 跑在 Windows 侧,网站目录里的 jar 不一定是实际在跑的那个,
|
|
@@ -29,18 +31,18 @@ async function safe(fn, fallback = null) {
|
|
|
29
31
|
}
|
|
30
32
|
}
|
|
31
33
|
|
|
32
|
-
function
|
|
34
|
+
function readIniSection(name) {
|
|
33
35
|
const section = {}
|
|
34
|
-
let
|
|
36
|
+
let inSection = false
|
|
35
37
|
for (const raw of fs.readFileSync(CONFIG_INI, 'utf-8').split(/\r?\n/)) {
|
|
36
38
|
const line = raw.trim()
|
|
37
39
|
if (!line || line.startsWith(';') || line.startsWith('#')) continue
|
|
38
40
|
const header = line.match(/^\[(.+)]$/)
|
|
39
41
|
if (header) {
|
|
40
|
-
|
|
42
|
+
inSection = header[1].trim() === name
|
|
41
43
|
continue
|
|
42
44
|
}
|
|
43
|
-
if (!
|
|
45
|
+
if (!inSection) continue
|
|
44
46
|
const eq = line.indexOf('=')
|
|
45
47
|
if (eq < 0) continue
|
|
46
48
|
section[line.slice(0, eq).trim()] = line.slice(eq + 1).trim().replace(/^"(.*)"$/, '$1')
|
|
@@ -101,8 +103,42 @@ function servingJarPath() {
|
|
|
101
103
|
return match ? match[1] : LINUX_DEFAULT_JAR
|
|
102
104
|
}
|
|
103
105
|
|
|
106
|
+
// 门店库里最新的那块 TSE(换过 TSE 会有多行);只读数据库,TSE 坏了也读得到
|
|
107
|
+
function readCertFromDb() {
|
|
108
|
+
const db = readIniSection('DB')
|
|
109
|
+
const out = execFileSync('mysql', [
|
|
110
|
+
'-h', db.host || 'localhost', '-u', db.user || 'aaden', '-N', '-B', '--raw', db.name || 'aaden',
|
|
111
|
+
'-e', 'select serialNumber, certificate from RealTseInfo order by id desc limit 1',
|
|
112
|
+
], {
|
|
113
|
+
encoding: 'utf-8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'],
|
|
114
|
+
// 密码走环境变量,不出现在进程列表里
|
|
115
|
+
env: Object.assign({}, process.env, {MYSQL_PWD: db.password || ''}),
|
|
116
|
+
}).trim()
|
|
117
|
+
if (!out) return null
|
|
118
|
+
const [serial, certificate] = out.split('\t')
|
|
119
|
+
return {serial, certificate: certificate && certificate !== 'NULL' ? certificate : null}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// TSE 自己的序列号、证书有效期和型号(dnQualifier:BSI-DSZ-CC-1121 是第一代,-V2 是第二代)
|
|
123
|
+
async function collectCert(tseHost, serviceUp) {
|
|
124
|
+
const fromDb = await safe(readCertFromDb)
|
|
125
|
+
let certificate = fromDb && fromDb.certificate
|
|
126
|
+
// 库里还没存证书(新装、或从没取到过)时再问服务;服务连不上就算了
|
|
127
|
+
if (!certificate && serviceUp) {
|
|
128
|
+
const res = await httpGet(`${tseHost}/certificate`)
|
|
129
|
+
if (res.status === 200) certificate = await safe(() => JSON.parse(res.body).certificate)
|
|
130
|
+
}
|
|
131
|
+
const parsed = certificate ? await safe(() => parseTseCertificate(certificate), {}) : {}
|
|
132
|
+
return {
|
|
133
|
+
tseSerial: (fromDb && fromDb.serial) || null,
|
|
134
|
+
tseCertNotBefore: parsed.tseCertNotBefore || null,
|
|
135
|
+
tseCertNotAfter: parsed.tseCertNotAfter || null,
|
|
136
|
+
tseCertProfile: parsed.tseCertProfile || null,
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
|
|
104
140
|
async function probeTse() {
|
|
105
|
-
const section = await safe(
|
|
141
|
+
const section = await safe(() => readIniSection('TSE'), {})
|
|
106
142
|
const tseEnabled = parseEnabled(section.TseEnabled)
|
|
107
143
|
const tseHost = (section.TseHost || DEFAULT_TSE_HOST).replace(/\/+$/, '')
|
|
108
144
|
// 不同版本的 jar 大小不同,没有 /adapterVersion 的老版本只能靠它区分
|
|
@@ -133,7 +169,9 @@ async function probeTse() {
|
|
|
133
169
|
}
|
|
134
170
|
}
|
|
135
171
|
|
|
136
|
-
|
|
172
|
+
const cert = await collectCert(tseHost, ping.status !== 0)
|
|
173
|
+
|
|
174
|
+
return {tseEnabled, tseHost, tseStatus, tseAdapterVersion, tseJarSize, ...cert}
|
|
137
175
|
}
|
|
138
176
|
|
|
139
177
|
// 整体出错就什么都不报,云端保留上次的值
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "aaden-cli",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.110",
|
|
4
4
|
"description": "",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"license": "ISC",
|
|
20
20
|
"release-it": {
|
|
21
21
|
"hooks": {
|
|
22
|
-
"after:bump": "ncc build index.js -o dist -C"
|
|
22
|
+
"after:bump": "rm -rf dist && ncc build index.js -o dist -C"
|
|
23
23
|
},
|
|
24
24
|
"npm": {
|
|
25
25
|
"publish": false
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
# 一次性修复:摘掉老 git 通道的 doUpdate cron。
|
|
3
|
+
#
|
|
4
|
+
# 病症:设备 crontab 里有
|
|
5
|
+
# 59 4 * * * curl -X POST 'http://localhost/PHP/UpdateSelf.php?op=doUpdate'
|
|
6
|
+
# @reboot ... curl -X POST '.../UpdateSelf.php?op=doUpdate'
|
|
7
|
+
# 它每天 04:59(和 @reboot)从**设备本地陈旧 gitCache** 部署后端;而 git fetch 因 deploy key
|
|
8
|
+
# 未分发到全网而失败(FETCH_HEAD 0 字节),缓存卡在旧版本;git 通道又没有"绝不降级"保护 →
|
|
9
|
+
# 于是把 light-update 刚更好的新版本降级回退(实测 1.9.63 → 1.9.62/1.9.61,每天来回打架)。
|
|
10
|
+
#
|
|
11
|
+
# 结论:light-update(S3/code.zip 通道)已是后端唯一活着的更新通道,且自带"只升不降"版本门。
|
|
12
|
+
# 摘掉 doUpdate cron,终结两条通道打架。crontab 不走 git/S3 部署 → 改了就稳。
|
|
13
|
+
#
|
|
14
|
+
# 幂等:没有该行就不动;grep -vF 精确匹配整串,不误伤 crontab.sh / light-update 那几行。
|
|
15
|
+
set -u
|
|
16
|
+
|
|
17
|
+
MARK='UpdateSelf.php?op=doUpdate'
|
|
18
|
+
|
|
19
|
+
strip_for() { # $1 = 目标用户(空=当前用户)
|
|
20
|
+
local u="$1" cur new
|
|
21
|
+
local args=()
|
|
22
|
+
[ -n "$u" ] && args=(-u "$u")
|
|
23
|
+
cur=$(crontab "${args[@]}" -l 2>/dev/null) || return 0
|
|
24
|
+
printf '%s\n' "$cur" | grep -qF "$MARK" || return 0 # 没有该 cron → 不动
|
|
25
|
+
new=$(printf '%s\n' "$cur" | grep -vF "$MARK")
|
|
26
|
+
printf '%s\n' "$new" | crontab "${args[@]}" - \
|
|
27
|
+
&& echo " 已从 ${u:-当前用户} 的 crontab 摘除 doUpdate cron"
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
# doUpdate cron 在 aaden 用户的 crontab。patch 正常由 root 的 auto-upgrade 触发 → 用 -u aaden;
|
|
31
|
+
# 兜底再扫一遍当前用户(万一某些设备以 aaden 直接跑 patch),谁有就摘谁。
|
|
32
|
+
if [ "$(id -u)" = "0" ]; then
|
|
33
|
+
strip_for aaden
|
|
34
|
+
strip_for ""
|
|
35
|
+
else
|
|
36
|
+
strip_for ""
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
echo " removeGitDoUpdateCron 完成(light-update 成为后端唯一更新通道)"
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
echo "Innerken322." | sudo -S su
|
|
2
|
-
sudo touch /etc/aaden/AbstractDatevCsvFile.php
|
|
3
|
-
sudo chmod 777 /etc/aaden/AbstractDatevCsvFile.php
|
|
4
|
-
php -r $'print preg_replace(\'/ {4}public function toCsvArray\(\$items\)\r?\n(?:.*\r?\n)+? {4}}/\', <<<\'PHP\'
|
|
5
|
-
public function toCsvArray($items)
|
|
6
|
-
{
|
|
7
|
-
yield $this->getHeader()->toArray($items[\'header\']);
|
|
8
|
-
|
|
9
|
-
$fields = $this->getFields();
|
|
10
|
-
|
|
11
|
-
yield array_map(Utils::itAccessMethod(\'getName\'), $fields);
|
|
12
|
-
|
|
13
|
-
foreach ($items[\'body\'] as $item) {
|
|
14
|
-
yield array_map(Utils::itAccessMethod(\'transform\', $item), $fields);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
PHP
|
|
18
|
-
, file_get_contents("/var/www/html/PHP/Datev/FileStructures/AbstractDatevCsvFile.php"));' > /etc/aaden/AbstractDatevCsvFile.php
|
|
19
|
-
sudo cp /etc/aaden/AbstractDatevCsvFile.php /var/www/html/PHP/Datev/FileStructures/AbstractDatevCsvFile.php
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
echo "Innerken322." | sudo -S su
|
|
2
|
-
sudo touch /etc/aaden/AbstractDatevCsvFile.php
|
|
3
|
-
sudo chmod 777 /etc/aaden/AbstractDatevCsvFile.php
|
|
4
|
-
php -r $'print preg_replace(\'/ {4}public function toCsvArray\(\$items\)\r?\n(?:.*\r?\n)+? {4}}/\', <<<\'PHP\'
|
|
5
|
-
public function toCsvArray($items)
|
|
6
|
-
{
|
|
7
|
-
yield $this->getHeader()->toArray($items[\'header\']);
|
|
8
|
-
|
|
9
|
-
$fields = $this->getFields();
|
|
10
|
-
|
|
11
|
-
yield array_map(Utils::itAccessMethod(\'getName\'), $fields);
|
|
12
|
-
|
|
13
|
-
foreach ($items[\'body\'] as $item) {
|
|
14
|
-
yield array_map(Utils::itAccessMethod(\'transform\', $item), $fields);
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
PHP
|
|
18
|
-
, file_get_contents("/var/www/html/PHP/Datev/FileStructures/AbstractDatevCsvFile.php"));' > /etc/aaden/AbstractDatevCsvFile.php
|
|
19
|
-
sudo cp /etc/aaden/AbstractDatevCsvFile.php /var/www/html/PHP/Datev/FileStructures/AbstractDatevCsvFile.php
|