fix(deploy): 修复组件版本解析和安装升级验收流程

This commit is contained in:
2026-10-18 00:18:00 +08:00
parent 895d92317e
commit b99eb849b4
30 changed files with 1579 additions and 270 deletions
+57
View File
@@ -0,0 +1,57 @@
#!/usr/bin/env python3
"""Cross-shell safeguards for real Compose volume names and existing bind paths."""
import json
import os
from pathlib import Path
import shutil
import subprocess
import tempfile
source = Path(__file__).resolve().parent.parent
with tempfile.TemporaryDirectory(prefix='easyai-storage-check-') as temporary:
root = Path(temporary)
(root / 'upload').mkdir()
(root / 'compose.yml').write_text('''name: fixture-project
services:
mongo:
container_name: fixture-mongo
image: mongo:7
volumes: [database:/data/db]
easyai-server:
container_name: fixture-server
image: alpine:3
volumes: [./upload:/app/upload]
volumes:
database:
name: existing-database
''')
configuration = subprocess.check_output(['docker','compose','config','--format','json'], cwd=root, text=True)
(root / 'config.json').write_text(configuration)
binaries = root / 'bin'
binaries.mkdir()
docker = binaries / 'docker'
docker.write_text('''#!/usr/bin/env python3
import json,os,sys
from pathlib import Path
args=sys.argv[1:]
if args[:2]==['compose','config']: print(Path('config.json').read_text());sys.exit(0)
if args[:1]==['info']:sys.exit(0)
if args[:2]==['container','inspect']:
project='another-project' if os.environ['STORAGE_CASE']=='wrong-project' else 'fixture-project'
mount={'Type':'volume','Name':'old-database' if os.environ['STORAGE_CASE']=='changed-volume' else 'existing-database','Destination':'/data/db'}
if args[-1]=='fixture-server':mount={'Type':'bind','Source':str(Path('upload').resolve()),'Destination':'/app/upload'}
print(json.dumps([{'Config':{'Labels':{'com.docker.compose.project':project}},'Mounts':[mount]}]));sys.exit(0)
sys.exit(1)
''')
docker.chmod(0o755)
script = root / 'check.ps1'
script.write_text('param($Runtime)\n$ErrorActionPreference="Stop"\n. $Runtime\n$selection = @($env:STORAGE_SELECTED -split " " | Where-Object { $_ })\nTest-DeploymentStorage -ComposeCommand @("docker","compose") -Services $selection\n')
for case, selected, success in [('same-storage','',True),('wrong-project','',False),('changed-volume','',False),('changed-volume','easyai-server',True),('missing-bind','',False)]:
if case == 'missing-bind': (root / 'upload').rmdir()
env = {**os.environ, 'PATH':str(binaries)+os.pathsep+os.environ['PATH'], 'STORAGE_CASE':case, 'STORAGE_SELECTED':selected}
commands = [(['python3',str(source/'scripts/check-deployment-storage.py'),'--services',*selected.split()], configuration),
(['pwsh','-NoProfile','-NonInteractive','-File',str(script),str(source/'scripts/DeploymentRuntime.ps1')], None)]
for command, stdin in commands:
result = subprocess.run(command, input=stdin, cwd=root, env=env, capture_output=True, text=True, timeout=90)
assert (result.returncode == 0) == success, (case, selected, result.stdout, result.stderr)
print(case + '/' + (selected or 'all') + ': passed in Python/Bash and PowerShell')