fix(deploy): 保留旧部署鉴权与命名卷配置
This commit is contained in:
@@ -99,23 +99,24 @@ def merge(base, local, remote, path=()):
|
||||
return clone(local)
|
||||
|
||||
|
||||
def delta(remote, merged):
|
||||
def delta(remote, merged, path=()):
|
||||
if remote == merged: return MISSING
|
||||
if isinstance(remote, dict) and isinstance(merged, dict):
|
||||
result = {}
|
||||
for key in merged:
|
||||
value = delta(remote.get(key, MISSING), merged[key])
|
||||
value = delta(remote.get(key, MISSING), merged[key], path + (key,))
|
||||
if value is not MISSING: result[key] = value
|
||||
# Removal cannot be safely represented by an ordinary Compose override.
|
||||
if set(remote) - set(merged):
|
||||
sys.exit('❌ 本地配置删除了新版字段,无法安全合并;尚未修改配置或容器')
|
||||
fields = ', '.join('.'.join(path + (key,)) for key in sorted(set(remote) - set(merged)))
|
||||
sys.exit('❌ 本地配置删除了新版字段,无法安全合并;尚未修改配置或容器: ' + fields)
|
||||
return result
|
||||
return copy.deepcopy(merged)
|
||||
|
||||
|
||||
def serialize(value, key=''):
|
||||
if isinstance(value, dict):
|
||||
if key == 'volumes': return list(value.values())
|
||||
if key == 'volumes' and value and all(isinstance(v, str) for v in value.values()): return list(value.values())
|
||||
return {k: serialize(v, k) for k, v in value.items()}
|
||||
return value
|
||||
|
||||
@@ -124,6 +125,17 @@ base = canonical(yaml.safe_load(git('show', 'HEAD:docker-compose.yml')))
|
||||
local = canonical(yaml.safe_load((root / 'docker-compose.yml').read_text()))
|
||||
remote_text = git('show', upstream + ':docker-compose.yml')
|
||||
remote = canonical(yaml.safe_load(remote_text))
|
||||
# Early managed deployments removed Watchtower's old token while disabling its
|
||||
# HTTP trigger. Current deployments require a shared internal token; restore the
|
||||
# upstream reference, whose value is initialized by update.sh, rather than
|
||||
# preserving an unauthenticated monitor. Other removals still stop adoption.
|
||||
monitor = local.get('services', {}).get('watchtower', {}).get('environment', {})
|
||||
old_monitor = base.get('services', {}).get('watchtower', {}).get('environment', {})
|
||||
new_monitor = remote.get('services', {}).get('watchtower', {}).get('environment', {})
|
||||
token_key = 'WATCHTOWER_HTTP_API_TOKEN'
|
||||
if token_key in old_monitor and token_key not in monitor and token_key in new_monitor:
|
||||
monitor = local['services']['watchtower'].setdefault('environment', {})
|
||||
monitor[token_key] = new_monitor[token_key]
|
||||
merged = merge(base, local, remote)
|
||||
override = delta(remote, merged)
|
||||
with tempfile.NamedTemporaryFile(mode='w', dir=root, prefix='.update-compose-', suffix='.json', delete=False) as candidate:
|
||||
|
||||
Reference in New Issue
Block a user