From f30938ed59f4f9bdaf2e8d425a1f309260a2efee Mon Sep 17 00:00:00 2001 From: Josh Patterson Date: Thu, 6 Mar 2025 15:26:08 -0500 Subject: [PATCH] hypervisor annotation show if base domain is initialized or not --- salt/_runners/setup_hypervisor.py | 4 +-- salt/libvirt/images/init.sls | 11 ++++++ salt/orch/dyanno_hypervisor.sls | 34 ++++++++++++------ salt/salt/minion.sls | 5 --- salt/soc/dyanno/hypervisor/init.sls | 2 +- .../hypervisor/soc_hypervisor.yaml.example | 36 ------------------- .../hypervisor/soc_hypervisor.yaml.jinja | 26 ++++++++------ 7 files changed, 53 insertions(+), 65 deletions(-) delete mode 100644 salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.example diff --git a/salt/_runners/setup_hypervisor.py b/salt/_runners/setup_hypervisor.py index 782419d27..6b3f289e8 100644 --- a/salt/_runners/setup_hypervisor.py +++ b/salt/_runners/setup_hypervisor.py @@ -430,9 +430,9 @@ def _apply_dyanno_hypervisor_state(): # Initialize the LocalClient local = salt.client.LocalClient() - # Target the salt master (localhost) to apply the soc.dyanno.hypervisor state + # Target the salt master to apply the soc.dyanno.hypervisor state target = MANAGER_HOSTNAME + '_*' - state_result = local.cmd(target, 'state.apply', ['soc.dyanno.hypervisor'], tgt_type='glob', concurrent=True) + state_result = local.cmd(target, 'state.apply', ['soc.dyanno.hypervisor', "pillar={'baseDomain': {'status': 'PreInit'}}", 'concurrent=True'], tgt_type='glob') log.debug(f"DYANNO: state_result: {state_result}") # Check if state was applied successfully if state_result: diff --git a/salt/libvirt/images/init.sls b/salt/libvirt/images/init.sls index 70e668ffb..91350de42 100644 --- a/salt/libvirt/images/init.sls +++ b/salt/libvirt/images/init.sls @@ -157,6 +157,17 @@ configure_network_predictable_sool9: - onchanges: - cmd: create_vm_sool9 +# Fire event here that causes soc.dyanno.hypervisor state to be applied +base_domain_ready: + event.send: + - name: soc/dyanno/hypervisor/baseDomain + - data: + status: 'Initialized' + - require: + - cmd: configure_network_predictable_sool9 + - onchanges: + - cmd: create_vm_sool9 + {% else %} {{sls}}_no_license_detected: test.fail_without_changes: diff --git a/salt/orch/dyanno_hypervisor.sls b/salt/orch/dyanno_hypervisor.sls index c9ba20115..fa6a2f2ff 100644 --- a/salt/orch/dyanno_hypervisor.sls +++ b/salt/orch/dyanno_hypervisor.sls @@ -11,6 +11,16 @@ {% if 'hvn' in salt['pillar.get']('features', []) %} +{% do salt.log.info('dyanno_hypervisor_orch: Running') %} +{% set vm_name = None %} +{% set hypervisor = None %} +{% set status = None %} +{% set data = pillar.get('data', {}) %} +{% set tag = pillar.get('tag', '') %} +{% set timestamp = data.get('_stamp') %} +{% do salt.log.debug('dyanno_hypervisor_orch: tag: ' ~ tag) %} +{% do salt.log.debug('dyanno_hypervisor_orch: Received data: ' ~ data|json|string) %} + {# Macro to find hypervisor name from VM status file #} {% macro find_hypervisor_from_status(vm_name) -%} {%- set path = salt['file.find']('/opt/so/saltstack/local/salt/hypervisor/hosts/',type='f', name=vm_name ~ '.status') -%} @@ -28,22 +38,17 @@ {%- endif -%} {%- endmacro %} -{% do salt.log.info('dyanno_hypervisor_orch: Running') %} - -{% set data = pillar.get('data', {}) %} -{% set tag = pillar.get('tag', '') %} -{% set timestamp = data.get('_stamp') %} -{% do salt.log.debug('dyanno_hypervisor_orch: tag: ' ~ tag) %} -{% do salt.log.debug('dyanno_hypervisor_orch: Received data: ' ~ data|json|string) %} - {# Our custom tag #} {% if tag.startswith('soc/dyanno/hypervisor') %} {% set status_data = data.get('data')%} {% do salt.log.debug('dyanno_hypervisor_orch: Received data: ' ~ status_data|json|string) %} -{% do salt.log.debug('dyanno_hypervisor_orch: Setting vm_name, hypervisor and status') %} -{% set vm_name = status_data.get('vm_name') %} -{% set hypervisor = status_data.get('hypervisor') %} +{% if not tag.endswith('/baseDomain') %} +{% do salt.log.debug('dyanno_hypervisor_orch: Setting vm_name, hypervisor and status') %} +{% set vm_name = status_data.get('vm_name') %} +{% set hypervisor = status_data.get('hypervisor') %} +{% endif %} {% set status = status_data.get('status') %} +{% set hypervisor = data.get('id') %} {% endif %} {# setup/so-minion tag #} @@ -80,6 +85,7 @@ {% do salt.log.info('dyanno_hypervisor_orch: vm_name: ' ~ vm_name ~ ' hypervisor: ' ~ hypervisor ~ ' status: ' ~ status) %} +{% if vm_name and hypervisor and timestamp and status and tag %} write_vm_status: salt.state: - tgt: 'G@role:so-manager or G@role:so-managersearch or G@role:so-standalone or G@role:so-eval' @@ -94,6 +100,7 @@ write_vm_status: timestamp: {{ timestamp }} status: {{ status }} event_tag: {{ tag }} +{% endif %} {# Check if the base domain exists / is ready for VMs #} {#% set file_exists = False %} @@ -113,6 +120,11 @@ update_hypervisor_annotation: - sls: - soc.dyanno.hypervisor - concurrent: True +{% if tag == ('soc/dyanno/hypervisor/baseDomain') %} + - pillar: + baseDomain: + status: {{ status }} +{% endif %} {% do salt.log.info('dyanno_hypervisor_orch: Completed') %} diff --git a/salt/salt/minion.sls b/salt/salt/minion.sls index de0f35c50..1402bea5e 100644 --- a/salt/salt/minion.sls +++ b/salt/salt/minion.sls @@ -83,11 +83,6 @@ enable_startup_states: - regex: '^startup_states: highstate$' - unless: pgrep so-setup -# manager with hypervisors with need this beacon added to the minion config -#beacons: -# add_virtual_node_beacon: -# - base_path: /opt/so/saltstack/local/salt/hypervisor/hosts/*/add_* - # prior to 2.4.30 this managed file would restart the salt-minion service when updated # since this file is currently only adding a sleep timer on service start # it is not required to restart the service diff --git a/salt/soc/dyanno/hypervisor/init.sls b/salt/soc/dyanno/hypervisor/init.sls index 5d3e3ae45..e4ce3b47c 100644 --- a/salt/soc/dyanno/hypervisor/init.sls +++ b/salt/soc/dyanno/hypervisor/init.sls @@ -22,7 +22,7 @@ hypervisor_annotation: - group: socore - defaults: HYPERVISORS: {{ HYPERVISORS }} - base_domain_ready: {{ salt['pillar.get']('base_domain_ready', False) }} + baseDomainStatus: {{ salt['pillar.get']('baseDomain:status', 'Initialized') }} {% for role in HYPERVISORS %} {% for hypervisor in HYPERVISORS[role].keys() %} diff --git a/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.example b/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.example deleted file mode 100644 index 902d9b1b1..000000000 --- a/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.example +++ /dev/null @@ -1,36 +0,0 @@ -# This is the start of an example of what this file will look like. It will be generated by Salt, so this yaml file is not used by Salt. -hypervisor: - hosts: - jpphype1VMs: - description: Hypervisor Configuration - file: true - global: true - syntax: json - title: jpphype1 - uiElements: - - field: hostname - label: Enter the hostname - - field: role - label: sensor or searchnode - - field: network_mode - label: Choose static4 or dhcp4. If static4, populate IP details below. - - field: ip4 - label: IP Address with netmask. ex. 192.168.1.10/24 - - field: gw4 - label: Gateway - - field: dns4 - label: DNS. Comma separated list. ex. 192.168.1.1,8.8.8.8 - - field: search4 - label: Search domain - - field: cpu - label: 'CPU cores to assign. Free: 120 | Total: 128' - - field: memory - label: 'Memory to assign, in GB. Free: 112 | Total: 128' - - field: disk - label: 'Disk(s) for passthrough. Comma separated list. Free: 2 | Total: 1,2' - - field: copper - label: 'Copper port(s) for passthrough. Comma separated list. Free: 3,4 | - Total: 1,2,3,4' - - field: sfp - label: 'SFP port(s) for passthrough. Comma separated list. Free: 5,6,7,8 | - Total: 5,6,7,8' diff --git a/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.jinja b/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.jinja index f90e3b579..17603ab9d 100644 --- a/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.jinja +++ b/salt/soc/dyanno/hypervisor/soc_hypervisor.yaml.jinja @@ -24,26 +24,32 @@ | Available | {{ cpu_free }} | {{ mem_free }} | {{ disk_free | replace('\n', ',') if disk_free else 'None' }} | {{ copper_free | replace('\n', ',') if copper_free else 'None' }} | {{ sfp_free | replace('\n', ',') if sfp_free else 'None' }} | | Total | {{ cpu_total }} | {{ mem_total }} | {{ disk_total | replace('\n', ',') }} | {{ copper_total | replace('\n', ',') }} | {{ sfp_total | replace('\n', ',') }} | -{%- if vm_list %} +{%- if baseDomainStatus == 'Initialized' %} +{%- if vm_list %} #### Virtual Machines Status values: {% for step in PROCESS_STEPS %}{{ step }}{% if not loop.last %}, {% endif %}{% endfor %}. "Last Updated" shows when status changed. After "Highstate Triggered", only "Destroyed Instance" updates the timestamp. | Name | Status | CPU Cores | Memory (GB)| Disk | Copper | SFP | Last Updated | |--------------------|--------------------|-----------|------------|------|--------|------|---------------------| -{%- for hostname, vm_data in vm_list.items() %} -{%- set vm_status = vm_data.get('status', {}).get('status', 'Unknown') %} -{%- set is_destroyed = vm_status == 'Destroyed Instance' %} -{%- if is_destroyed %} +{%- for hostname, vm_data in vm_list.items() %} +{%- set vm_status = vm_data.get('status', {}).get('status', 'Unknown') %} +{%- set is_destroyed = vm_status == 'Destroyed Instance' %} +{%- if is_destroyed %} | {{ hostname }} | {{ vm_status }} | - | - | - | - | - | {{ vm_data.get('status', {}).get('timestamp', 'Never') | replace('T', ' ') | regex_replace('\\.[0-9]+', '') }} | -{%- else %} +{%- else %} | {{ hostname }} | {{ vm_status }} | {{ vm_data.get('config', {}).get('cpu', 'N/A') }} | {{ vm_data.get('config', {}).get('memory', 'N/A') }} | {{ vm_data.get('config', {}).get('disk', []) | join(',') if vm_data.get('config', {}).get('disk') else '-' }} | {{ vm_data.get('config', {}).get('copper', []) | join(',') if vm_data.get('config', {}).get('copper') else '-' }} | {{ vm_data.get('config', {}).get('sfp', []) | join(',') if vm_data.get('config', {}).get('sfp') else '-' }} | {{ vm_data.get('status', {}).get('timestamp', 'Never') | replace('T', ' ') | regex_replace('\\.[0-9]+', '') }} | -{%- endif %} -{%- endfor %} -{%- else %} +{%- endif %} +{%- endfor %} +{%- else %} #### Virtual Machines Status values: {% for step in PROCESS_STEPS %}{{ step }}{% if not loop.last %}, {% endif %}{% endfor %}. "Last Updated" shows when status changed. After "Highstate Triggered", only "Destroyed Instance" updates the timestamp. No Virtual Machines Found +{%- endif %} +{%- else %} +#### WARNING + +Base domain has not been initialized. {%- endif %} {%- endmacro -%} @@ -174,7 +180,7 @@ No Virtual Machines Found {%- endif -%} {%- do updated_elements.append(updated_field) -%} {%- endfor -%} -{%- if base_domain_ready -%} +{%- if baseDomainStatus == 'Initialized' %} {%- do updated_template.update({'uiElements': updated_elements}) -%} {%- else -%} {%- do updated_template.pop('uiElements') -%}