mirror of
https://github.com/MacRimi/ProxMenux.git
synced 2026-11-02 19:02:31 +00:00
fix(oci): clarify the summary of imported Compose stacks
Each registry line names its image, the variables of a stack are listed without announcing questions that are not asked, and the name given to an imported stack names its containers.
This commit is contained in:
@@ -809,7 +809,9 @@ def describe(template: dict[str, Any]) -> str:
|
|||||||
for volume in volumes]
|
for volume in volumes]
|
||||||
environment = contract.get('environment') or []
|
environment = contract.get('environment') or []
|
||||||
if environment:
|
if environment:
|
||||||
lines += ['', translate('Variables the installation asks for:')]
|
# A stack takes its values from the Compose file; none is asked here.
|
||||||
|
lines += ['', translate('Variables the installation asks for:') if len(services) <= 1 else
|
||||||
|
f"{translate('Variables')} ({template['compose_stack']['main_service']}):"]
|
||||||
lines += [f" {item['name']}"
|
lines += [f" {item['name']}"
|
||||||
+ (f" = {item['example']}" if item.get('example') and not item['sensitive'] and len(services) <= 1 else '')
|
+ (f" = {item['example']}" if item.get('example') and not item['sensitive'] and len(services) <= 1 else '')
|
||||||
+ ('' if item.get('required', True) else f" ({translate('optional')})")
|
+ ('' if item.get('required', True) else f" ({translate('optional')})")
|
||||||
@@ -852,13 +854,17 @@ def _ask_secrets(template: dict[str, Any]) -> list[str]:
|
|||||||
|
|
||||||
|
|
||||||
def _name(ui, template: dict[str, Any]) -> str:
|
def _name(ui, template: dict[str, Any]) -> str:
|
||||||
default = normalize_app_id(source_text(template['catalog_ui'].get('title'))
|
stack = template.get('compose_stack') if len((template.get('compose_stack') or {}).get('services') or []) > 1 else None
|
||||||
|
default = normalize_app_id((stack or {}).get('project_name') or source_text(template['catalog_ui'].get('title'))
|
||||||
or template['container_contract'].get('container_name') or 'oci-app')
|
or template['container_contract'].get('container_name') or 'oci-app')
|
||||||
name = normalize_app_id(ui.ask(translate('Name for this application'), default))
|
name = normalize_app_id(ui.ask(translate('Name for this application'), default))
|
||||||
if not name:
|
if not name:
|
||||||
raise UserCancelled(translate('No name was given'))
|
raise UserCancelled(translate('No name was given'))
|
||||||
template['catalog_ui']['title'] = {'en_US': name}
|
template['catalog_ui']['title'] = {'en_US': name}
|
||||||
template['container_contract']['container_name'] = name
|
template['container_contract']['container_name'] = name
|
||||||
|
if stack:
|
||||||
|
# The containers of the stack are named after it.
|
||||||
|
stack['project_name'] = name
|
||||||
return name
|
return name
|
||||||
|
|
||||||
|
|
||||||
@@ -897,6 +903,8 @@ def _explore(ui) -> None:
|
|||||||
if offer_sign_in(ui, reference, title):
|
if offer_sign_in(ui, reference, title):
|
||||||
accessible, report = registry_report(reference)
|
accessible, report = registry_report(reference)
|
||||||
available = available and accessible
|
available = available and accessible
|
||||||
|
if accessible and len(references) > 1:
|
||||||
|
report = f'{reference}: {report}'
|
||||||
reports.append(report)
|
reports.append(report)
|
||||||
summary += '\n\n' + report
|
summary += '\n\n' + report
|
||||||
if notes:
|
if notes:
|
||||||
|
|||||||
@@ -552,7 +552,8 @@ def build_stack(template, ui, mode='advanced'):
|
|||||||
# A default installation takes the name, the VMID and the settings from the
|
# A default installation takes the name, the VMID and the settings from the
|
||||||
# recipe; it still asks the storage, the address and how the stack starts.
|
# recipe; it still asks the storage, the address and how the stack starts.
|
||||||
quiet = DefaultsUI() if mode == DEFAULT_MODE else ui
|
quiet = DefaultsUI() if mode == DEFAULT_MODE else ui
|
||||||
name = _hostname_default(quiet.ask(translate('Stack name'), template['compose_stack']['project_name']))
|
# An imported Compose file was already named before its installation.
|
||||||
|
name = _hostname_default((DefaultsUI() if custom else quiet).ask(translate('Stack name'), template['compose_stack']['project_name']))
|
||||||
vmid = quiet.ask(translate('Base VMID (empty = next free block)'), '', required=False)
|
vmid = quiet.ask(translate('Base VMID (empty = next free block)'), '', required=False)
|
||||||
from . import host
|
from . import host
|
||||||
from . import network as access
|
from . import network as access
|
||||||
|
|||||||
@@ -109,6 +109,40 @@ class CustomComposeStacks(unittest.TestCase):
|
|||||||
install.assert_not_called()
|
install.assert_not_called()
|
||||||
self.assertIn('app missing', ui.text)
|
self.assertIn('app missing', ui.text)
|
||||||
|
|
||||||
|
def test_each_registry_line_names_its_image(self):
|
||||||
|
class UI:
|
||||||
|
def message(self, text, title):
|
||||||
|
self.text = text
|
||||||
|
ui = UI()
|
||||||
|
with patch.object(custom, 'read_definition', return_value=(COMPOSE, 'Compose')), \
|
||||||
|
patch.object(custom, 'registry_report', side_effect=[(True, 'in registry'), (False, 'app missing')]), \
|
||||||
|
patch.object(custom, '_registry_refused', return_value=False), \
|
||||||
|
patch.object(custom, 'install_template'):
|
||||||
|
custom.explore(ui)
|
||||||
|
self.assertIn('postgres:16: in registry', ui.text)
|
||||||
|
self.assertNotIn('adminer:4: app missing', ui.text)
|
||||||
|
|
||||||
|
@patch('proxmenux_oci.i18n.language', return_value='en')
|
||||||
|
def test_stack_summary_does_not_announce_questions_about_its_variables(self, _):
|
||||||
|
template = custom.template_from_compose(COMPOSE.replace(
|
||||||
|
" ports:", " environment:\n ADMINER_DEFAULT_SERVER: db\n ports:"))
|
||||||
|
summary = custom.describe(template)
|
||||||
|
self.assertNotIn('Variables the installation asks for', summary)
|
||||||
|
self.assertIn('Variables (app):\n ADMINER_DEFAULT_SERVER', summary)
|
||||||
|
single = custom.template_from_compose('services: {app: {image: nginx:1.27, environment: {MODE: x}}}')
|
||||||
|
self.assertIn('Variables the installation asks for', custom.describe(single))
|
||||||
|
|
||||||
|
def test_the_name_given_names_the_stack(self):
|
||||||
|
template = custom.template_from_compose('name: adminer-postgres\n' + COMPOSE)
|
||||||
|
class UI:
|
||||||
|
def ask(self, text, default=None, required=True):
|
||||||
|
self.default = default
|
||||||
|
return 'tools'
|
||||||
|
ui = UI()
|
||||||
|
self.assertEqual(custom._name(ui, template), 'tools')
|
||||||
|
self.assertEqual(ui.default, 'adminer-postgres')
|
||||||
|
self.assertEqual(template['compose_stack']['project_name'], 'tools')
|
||||||
|
|
||||||
def test_single_image_still_uses_single_container_flow(self):
|
def test_single_image_still_uses_single_container_flow(self):
|
||||||
template = custom.template_from_compose('services: {app: {image: nginx:1.27}}')
|
template = custom.template_from_compose('services: {app: {image: nginx:1.27}}')
|
||||||
self.assertNotEqual(template['proxmox'].get('installer_profile', {}).get('stack_driver'), 'generic-multi-lxc-stack')
|
self.assertNotEqual(template['proxmox'].get('installer_profile', {}).get('stack_driver'), 'generic-multi-lxc-stack')
|
||||||
|
|||||||
Reference in New Issue
Block a user