fix(oci): call the editing of an application Modify everywhere

- The option that edits an installed application is Modify for one container and for a multi-container application, in the OCI menu and on the Monitor button. Recreate is only the rebuild of a multi-container application as it is.
- A stack recreation says "Recreating" and "Recreated" in its steps instead of "Updating".
- The notes of the GPU, Coral, disk and share menus no longer name the option.
- Spanish for the new texts; the English copies of the stack texts are removed from de, fr, pt and sv so the bot translates them.
This commit is contained in:
MacRimi
2026-10-06 19:42:30 +02:00
parent 747b32489f
commit 3f75b94ea1
31 changed files with 185 additions and 163 deletions
+6 -6
View File
@@ -354,7 +354,7 @@ def candidate_contract(record, operation, proposal=None):
raise ValueError(translate('Recreating requires a confirmed proposal'))
if (proposal.get('base_config_sha256') is not None
and proposal['base_config_sha256'] != record['observed']['config_sha256']):
raise ValueError(translate('The instance changed while it was being edited; configure Recreate again'))
raise ValueError(translate('The instance changed while it was being edited; open Modify again'))
candidate = proposal['candidate']
if (candidate.get('vmid') != record['vmid']
or candidate.get('installation_id') != record['installation_id']
@@ -872,7 +872,7 @@ def apply(root, vmid, archive, operation, proposal=None, registry_digest=None, i
if coordinated and backup_compression != 'zstd':
raise ValueError(translate('Coordinated backups require zstd'))
if show:
msg_info(translate('Preparing the update...') if update else translate('Preparing the recreation...'))
msg_info(translate('Preparing the update...') if update else translate('Preparing the changes...'))
record = instances.read(root, vmid)
if coordinated and any(coordinated.get(flag) for flag in
('nextcloud_replay', 'paperless_replay', 'tandoor_replay', 'immich_replay')):
@@ -910,7 +910,7 @@ def apply(root, vmid, archive, operation, proposal=None, registry_digest=None, i
required = {m['container_path'] for m in candidate['deployment'].get('mounts', [])}
if any(not any(p == target or p.startswith(target.rstrip('/') + '/') for target in required)
for p in set(image['defaults'].get('Volumes') or {}) - non_persistent_image_volumes(candidate['template'])):
raise ValueError(translate('The new image requires additional persistent paths; use Recreate'))
raise ValueError(translate('The new image requires additional persistent paths; use Modify'))
directory = instances.location(root, vmid).parent / 'transactions' / uuid.uuid4().hex
private_directory(directory)
open_log(directory)
@@ -956,7 +956,7 @@ def apply(root, vmid, archive, operation, proposal=None, registry_digest=None, i
gpu_devices.verify(original_gpu)
gpu_devices.verify(desired_gpu)
if show:
msg_ok(translate('Update prepared') if update else translate('Recreation prepared'))
msg_ok(translate('Update prepared') if update else translate('Changes prepared'))
msg_info(translate('Stopping the container...'))
stop(vmid)
if show:
@@ -1062,7 +1062,7 @@ def apply(root, vmid, archive, operation, proposal=None, registry_digest=None, i
cleanup_error = exc
log(f'cleanup: {exc}')
msg_ok(translate('Update completed. Data kept.') if update
else translate('Recreation completed. Data kept.'))
else translate('Changes applied. Data kept.'))
if freed:
msg_ok(f"{translate('Unused images removed from the cache:')} {gib(freed)}")
if cleanup_error is not None:
@@ -1275,7 +1275,7 @@ def phase_label(phase):
def show_status(path, state):
operations = {'update': translate('Update'), 'recreate': translate('Recreate')}
operations = {'update': translate('Update'), 'recreate': translate('Modify')}
msg_info2(f"{translate('Interrupted operation:')} {operations.get(state.get('operation'), state.get('operation'))} (CT {state['vmid']})")
msg_info2(f"{translate('Stopped at:')} {phase_label(state.get('phase'))}")
if state.get('stage'):
+2 -2
View File
@@ -254,9 +254,9 @@ def main():
msg_error(translate('Another OCI operation is using the instance registry. Wait for it to finish.'))
return 1
except (OSError, ValueError, KeyError, RuntimeError, StopIteration, subprocess.TimeoutExpired) as error:
msg_error(f"{translate('The application could not be recreated:')} {error}")
msg_error(f"{translate('The application could not be modified:')} {error}")
return 1
msg_ok(translate('The application has been recreated with the new options.'))
msg_ok(translate('The application has been modified with the new options.'))
return 0
+5 -4
View File
@@ -120,6 +120,7 @@ def _apply(path, plan, adapter):
running = {str(vmid): adapter.is_running(vmid) for vmid in plan['start_order']}
if any(type(value) is not bool for value in running.values()):
raise ValueError(translate('Invalid running state'))
recreate = plan['operation'] == 'recreate'
state = {'schema_version': 1, 'id': str(uuid.uuid4()),
'plan': copy.deepcopy(plan), 'running': running,
'prepared': {}, 'backups': {}, 'stop_intent': False,
@@ -152,9 +153,9 @@ def _apply(path, plan, adapter):
state['replacement_intent'] = True
save(path, state, 'replacing')
for vmid in plan['start_order']:
msg_info(f"{translate('Updating')} {member(adapter, vmid)}...")
msg_info(f"{translate('Recreating') if recreate else translate('Updating')} {member(adapter, vmid)}...")
adapter.replace(vmid, state['prepared'][str(vmid)], state['id'])
msg_ok(f"{translate('Updated:')} {member(adapter, vmid)}")
msg_ok(f"{translate('Recreated:') if recreate else translate('Updated:')} {member(adapter, vmid)}")
save(path, state, 'starting')
for vmid in plan['start_order']:
msg_info(f"{translate('Starting')} {member(adapter, vmid)}...")
@@ -162,10 +163,10 @@ def _apply(path, plan, adapter):
adapter.healthcheck(vmid)
msg_ok(f"{translate('Service responding:')} {member(adapter, vmid)}")
save(path, state, 'checking')
msg_info(translate('Checking the updated stack...'))
msg_info(translate('Checking the recreated stack...') if recreate else translate('Checking the updated stack...'))
adapter.validate_candidates(state)
adapter.restore_running_state(running, plan['start_order'])
msg_ok(translate('Updated stack checked'))
msg_ok(translate('Recreated stack checked') if recreate else translate('Updated stack checked'))
save(path, state, 'publishing')
msg_info(translate('Saving the stack records...'))
adapter.publish(state)
+1 -1
View File
@@ -159,7 +159,7 @@ def application_name(record, vmid):
def update(vmid, acknowledge_external_data=False, proposal=None, keep_backup=None):
operation = 'recreate' if proposal is not None else 'update'
msg_info(translate('Checking the container before the update...') if operation == 'update'
else translate('Checking the container before recreating it...'))
else translate('Checking the container before modifying it...'))
with instances.locked(instances.ROOT):
record = instances.read(instances.ROOT, vmid)
if record['status'] != 'installed' or record.get('pending_transaction') or record.get('pending_stack_transaction'):