145 lines
5.8 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# pipeline-opportunity 一键部署脚本(在宿主应用根目录执行或从本目录定位宿主)。
# 职责:建表(运行期禁止 schema 变更,建表只在部署期)+ 种子数据appcodes + pipelines 产线记录)
# + wwwroot 软链 + pip install 本包。
# 参考模式pipeline-bidding/build.sh。
set -e
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# 定位宿主应用根目录(含 wwwroot + py3
APP_ROOT=""
for candidate in "$SCRIPT_DIR/../../pipeline-app" "$SCRIPT_DIR/../.." "$HOME/work/pipeline/pipeline-app"; do
if [ -d "$candidate/wwwroot" ] && [ -d "$candidate/py3" ]; then
APP_ROOT="$(cd "$candidate" && pwd)"
break
fi
done
if [ -z "$APP_ROOT" ]; then
echo "ERROR: host app (pipeline-app) root not found"
exit 1
fi
PYTHON="$APP_ROOT/py3/bin/python"
echo "Host app root: $APP_ROOT"
# ── 1. 建表幂等CREATE TABLE IF NOT EXISTS──
cd "$SCRIPT_DIR"
"$PYTHON" - "$APP_ROOT" <<'PYEOF'
import re
ddl = open('mysql.ddl.sql', encoding='utf-8').read()
ddl = re.sub(r'drop table if exists (\w+);', '', ddl)
ddl = re.sub(r'CREATE TABLE (\w+)\s*\(', r'CREATE TABLE IF NOT EXISTS \1 (', ddl)
open('/tmp/pipeline_opportunity_ddl.sql', 'w', encoding='utf-8').write(ddl)
print('DDL prepared:', ddl.count('CREATE TABLE IF NOT EXISTS'), 'tables')
PYEOF
"$PYTHON" - "$APP_ROOT" <<'PYEOF'
import sys, os, subprocess
sys.path.insert(0, os.getcwd())
from appPublic.jsonConfig import getConfig
from appPublic.aes import aes_decode_b64
cfg = getConfig(sys.argv[1], {'workdir': sys.argv[1]})
kw = cfg.databases['pipeline'].kwargs
pwd = aes_decode_b64(cfg.password_key, kw.password)
with open('/tmp/pipeline_opportunity_ddl.sql', 'rb') as f:
r = subprocess.run(['mysql', '-h', str(kw.host), '-P', str(kw.port),
'-u', str(kw.user), '-p%s' % pwd, str(kw.db)],
stdin=f, capture_output=True)
if r.returncode == 0:
print('tables applied')
else:
print('ERROR:', r.stderr.decode('utf-8', 'replace').strip()[:300])
sys.exit(1)
PYEOF
# ── 2. 种子数据appcodes 字典 + pipelines 产线记录(数据源 init/data.json幂等──
cd "$APP_ROOT"
"$PYTHON" - "$SCRIPT_DIR" "$APP_ROOT" <<'PYEOF'
import sys, os, json, asyncio
CDIR = sys.argv[1]
sys.path.insert(0, os.getcwd())
from appPublic.jsonConfig import getConfig
from sqlor.dbpools import DBPools
from appPublic.uniqueID import getID
data = json.load(open(os.path.join(CDIR, 'init', 'data.json')))
async def seed():
config = getConfig(sys.argv[2], {'workdir': sys.argv[2]})
db = DBPools(config.databases)
async with db.sqlorContext('pipeline') as sor:
for pl in data.get('pipelines', []):
recs = await sor.sqlExe("SELECT id FROM pipelines WHERE id=${i}$", {"i": pl['id']})
if not recs:
await sor.C('pipelines', {
'id': pl['id'], 'name': pl['name'],
'description': pl.get('description', ''),
'pipeline_type': pl.get('pipeline_type', 'opportunity'),
'version': '1.0.0', 'status': pl.get('status', 'published'),
'org_id': pl.get('org_id', '0'), 'created_by': 'system',
})
print('pipeline registered:', pl['id'])
for ac in data.get('appcodes', []):
pid = ac['parentid']
rows = await sor.R('appcodes', {'id': pid})
if not rows:
await sor.C('appcodes', {'id': pid, 'name': ac.get('parentname', pid),
'hierarchy_flg': '0'})
for item in ac.get('items', []):
chk = await sor.sqlExe(
"SELECT id FROM appcodes_kv WHERE parentid=${p}$ AND k=${k}$",
{'p': pid, 'k': item['k']})
if not chk:
await sor.C('appcodes_kv', {'id': getID(), 'parentid': pid,
'k': item['k'], 'v': item['v']})
await sor.sqlExe("COMMIT", {})
print('seeded %d code groups' % len(data.get('appcodes', [])))
asyncio.run(seed())
PYEOF
# ── 2b. params 种子:挖掘算法参数(幂等:已存在不覆盖,运行期可在 params 表调)──
cd "$APP_ROOT"
"$PYTHON" - "$SCRIPT_DIR" "$APP_ROOT" <<'PYEOF'
import sys, os, json, asyncio
CDIR = sys.argv[1]
sys.path.insert(0, os.getcwd())
from appPublic.jsonConfig import getConfig
from sqlor.dbpools import DBPools
from appPublic.uniqueID import getID
data = json.load(open(os.path.join(CDIR, 'init', 'data.json')))
params_seed = data.get('params', [])
async def seed_params():
if not params_seed:
return
config = getConfig(sys.argv[2], {'workdir': sys.argv[2]})
db = DBPools(config.databases)
n = 0
async with db.sqlorContext('pipeline') as sor:
for pitem in params_seed:
chk = await sor.sqlExe(
"SELECT id FROM params WHERE params_name=${n}$", {"n": pitem['name']})
if not chk:
await sor.C('params', {'id': getID(),
'params_name': pitem['name'],
'params_value': str(pitem['value'])})
n += 1
await sor.sqlExe("COMMIT", {})
print('params seeded:', n, '(existing kept)')
asyncio.run(seed_params())
PYEOF
# ── 3. wwwroot 软链 + pip install ──
rm -f "$APP_ROOT/wwwroot/pipeline-opportunity"
ln -sf "$SCRIPT_DIR/wwwroot" "$APP_ROOT/wwwroot/pipeline-opportunity"
echo "wwwroot linked: pipeline-opportunity"
"$APP_ROOT/py3/bin/pip" install "$SCRIPT_DIR/" 2>&1 | tail -1
echo "pipeline-opportunity module deploy complete."
echo "后续宿主负责app 入口 import load_pipeline_opportunityRBAC 用 scripts/load_path.py。"
echo "爬虫平台接入配置appbase params 表设 tender_api_base / tender_api_token默认 http://192.168.16.2:9085。"