diff --git a/scripts/prepare-update-repository.py b/scripts/prepare-update-repository.py index 741866b..aeae4d5 100644 --- a/scripts/prepare-update-repository.py +++ b/scripts/prepare-update-repository.py @@ -44,7 +44,15 @@ allowed = {'scripts/init-security-env.sh'} if any(p not in allowed and not (Path(p).parent == Path('.') and p.endswith('.conf')) for p in collisions): sys.exit('❌ 存在新版仓库会覆盖的其他本地文件;尚未修改配置或容器') if not changed and not collisions: - sys.exit(0) + existing_override_path = root / 'data/deployment-config/legacy-compose.json' + restore_existing_pin = False + if restore_images and existing_override_path.exists(): + if existing_override_path.is_symlink() or not existing_override_path.is_file(): + sys.exit('❌ 旧配置覆盖文件类型不受支持;尚未修改配置或容器') + existing_override = json.loads(existing_override_path.read_text()) + restore_existing_pin = any('image' in existing_override.get('services', {}).get(service, {}) for service in restore_images) + if not restore_existing_pin: + sys.exit(0) for name in changed | collisions: if not (root / name).is_file() or (root / name).is_symlink(): sys.exit('❌ 配置文件类型不受支持;尚未修改配置或容器') diff --git a/scripts/test-repository-image-restore.py b/scripts/test-repository-image-restore.py index d349a5e..858645d 100644 --- a/scripts/test-repository-image-restore.py +++ b/scripts/test-repository-image-restore.py @@ -102,6 +102,18 @@ for restore in ('', 'easyai-web', 'redis', 'ws-gateway'): newest = max(backups, key=lambda p: p.stat().st_mtime) assert (newest / 'data/deployment-config/legacy-compose.json').read_bytes() == previous_override assert (newest / 'data/deployment-config/legacy-compose.json').stat().st_mode & 0o077 == 0 + if not restore: + # Main is clean, but an existing override still pins the web image. + # Explicit restoration must act on that override and be idempotent. + restoration_env = {**env, 'UPDATE_RESTORE_REPOSITORY_IMAGES': 'easyai-web'} + checked(['python3', str(prepare), str(root)], root, restoration_env) + config = json.loads(checked(['docker', 'compose', '--env-file', '.env', 'config', '--format', 'json'], root)) + assert config['services']['easyai-web']['image'] == 'repository-web:latest' + assert config['services']['redis']['image'] == 'redis:6.2' + assert config['services']['easyai-server']['environment']['LOCAL_SETTING'] == 'second-custom' + assert len(list((root / 'data/deployment-backups').glob('legacy-update-*'))) == 3 + checked(['python3', str(prepare), str(root)], root, restoration_env) + assert len(list((root / 'data/deployment-backups').glob('legacy-update-*'))) == 3 for mode, adopt in (('image', '1'), ('full', '0')): env = {**os.environ, 'UPDATE_MODE': mode, 'UPDATE_ADOPT_LEGACY_CONFIG': adopt, 'UPDATE_RESTORE_REPOSITORY_IMAGES': 'easyai-web'}