Compare commits
12 Commits
e5e4aa1832
...
dev
| Author | SHA1 | Date | |
|---|---|---|---|
| 54dfc77e78 | |||
| 6cdfa56880 | |||
| 45de5696f7 | |||
| 53da333970 | |||
| 8530b93fea | |||
| 130fcb5069 | |||
| 93cee75103 | |||
| 24f34198ff | |||
| f29de42397 | |||
| daa5826573 | |||
| 0696218eb6 | |||
| 4789bbd850 |
@@ -10,70 +10,36 @@
|
||||
ansible_user_passwd_hash: "{{ ansible_password | password_hash('sha512', 's3edscrj45e6r') }}"
|
||||
user_passwd_hash: "{{ user_password | password_hash('sha512', 's3ed6123jhgcr') }}"
|
||||
|
||||
vars_prompt:
|
||||
- name: lxc_hostname
|
||||
prompt: "Hostname for the container (may only contain letters (a-z, A-Z), numbers (0-9), and hyphens)"
|
||||
default: "new-lxc-test"
|
||||
private: false
|
||||
pre_tasks:
|
||||
- name: Include input and validation for hostname
|
||||
ansible.builtin.include_tasks: ../tasks/hostname_validation.yaml
|
||||
|
||||
- name: Include input and validation for LXC root password
|
||||
ansible.builtin.include_tasks: ../tasks/lxc_root_password_validation.yaml
|
||||
|
||||
- name: lxc_root_password
|
||||
prompt: "Root password"
|
||||
default: "new-lxc-test"
|
||||
private: true
|
||||
confirm: true
|
||||
encrypt: sha512_crypt
|
||||
- name: Include input and validation for IP
|
||||
ansible.builtin.include_tasks: ../tasks/ip_validation.yaml
|
||||
|
||||
- name: lxc_ip_address
|
||||
prompt: "IP address for the container (in x.x.x.x/x formant)"
|
||||
default: "192.168.0.90/24"
|
||||
private: false
|
||||
- name: Include input and validation for LXC privilege
|
||||
ansible.builtin.include_tasks: ../tasks/lxc_privileged_validation.yaml
|
||||
|
||||
- name: lxc_is_privileged
|
||||
prompt: "Unprivileged LXC (true/false)?"
|
||||
default: true
|
||||
private: false
|
||||
- name: Include input and validation for OS template
|
||||
ansible.builtin.include_tasks: ../tasks/os_template_validation.yaml
|
||||
|
||||
- name: lxc_create_human_admin_user
|
||||
prompt: "Create human admin user? (true/false)?"
|
||||
default: true
|
||||
private: false
|
||||
- name: Include input and validation for human admin user creation
|
||||
ansible.builtin.include_tasks: ../tasks/human_admin_user_validation.yaml
|
||||
|
||||
pre_tasks:
|
||||
- name: Validate hostname
|
||||
ansible.builtin.fail:
|
||||
msg: |
|
||||
Invalid hostname: "{{ lxc_hostname }}"
|
||||
Hostname may only contain letters (a-z, A-Z), numbers (0-9), and hyphens (-).
|
||||
when: not lxc_hostname is regex('^[a-zA-Z0-9-]+$')
|
||||
run_once: true
|
||||
- name: Include input and validation for storage selection
|
||||
ansible.builtin.include_tasks: ../tasks/storage_validation.yaml
|
||||
|
||||
- name: Validate IP address
|
||||
ansible.builtin.fail:
|
||||
msg: |
|
||||
Invalid IP address: "{{ lxc_ip_address }}"
|
||||
IP address must be in x.x.x.x/x format (e.g., 192.168.0.90/24).
|
||||
when: not lxc_ip_address is regex('^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)(\\/(3[0-2]|[12]?\\d))?$')
|
||||
run_once: true
|
||||
|
||||
roles:
|
||||
- ../roles/deploy_lxc_on_proxmox
|
||||
|
||||
tasks:
|
||||
- name: Make the prompted hostname available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_lxc_hostname: "{{ lxc_hostname }}"
|
||||
|
||||
- name: Make the prompted IP available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_lxc_ip_address: "{{ lxc_ip_address.split('/') | first }}"
|
||||
|
||||
- name: Make the "human admin user" selection available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_lxc_create_human_admin_user: "{{ lxc_create_human_admin_user }}"
|
||||
|
||||
- name: Add the target host to the inventory
|
||||
ansible.builtin.add_host:
|
||||
name: "{{ fact_lxc_ip_address }}"
|
||||
name: "{{ guest_ip_address }}"
|
||||
groups: new_host
|
||||
ansible_user: ansible
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
@@ -98,10 +64,10 @@
|
||||
- name: Include human admin user role
|
||||
ansible.builtin.include_role:
|
||||
name: ../roles/human_admin_user
|
||||
when: "hostvars['localhost']['fact_lxc_create_human_admin_user'] | bool"
|
||||
when: "hostvars['localhost']['create_human_admin_user'] | bool"
|
||||
|
||||
- name: Include update configs role
|
||||
ansible.builtin.include_role:
|
||||
name: ../roles/update_configs
|
||||
when: "hostvars['localhost']['fact_lxc_create_human_admin_user'] | bool"
|
||||
when: "hostvars['localhost']['create_human_admin_user'] | bool"
|
||||
|
||||
|
||||
@@ -10,92 +10,36 @@
|
||||
ansible_user_passwd_hash: "{{ ansible_password | password_hash('sha512', 's3edscrj45e6r') }}"
|
||||
user_passwd_hash: "{{ user_password | password_hash('sha512', 's3ed6123jhgcr') }}"
|
||||
|
||||
vars_prompt:
|
||||
- name: vm_hostname
|
||||
prompt: "Hostname for the VM (may only contain letters (a-z, A-Z), numbers (0-9), and hyphens)"
|
||||
default: "new-vm-test"
|
||||
private: false
|
||||
|
||||
- name: vm_os_template
|
||||
prompt: "Select OS template. Available: debian-13 | alpine"
|
||||
default: "debian-13"
|
||||
private: false
|
||||
|
||||
- name: vm_become_method
|
||||
prompt: "Select become method. Available: sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas | machinectl"
|
||||
default: "sudo"
|
||||
private: false
|
||||
|
||||
- name: vm_create_human_admin_user
|
||||
prompt: "Create human admin user? (true/false)?"
|
||||
default: true
|
||||
private: false
|
||||
|
||||
- name: vm_ip_address
|
||||
prompt: "IP address for the VM (in x.x.x.x/x formant)"
|
||||
default: "192.168.0.89/24"
|
||||
private: false
|
||||
|
||||
pre_tasks:
|
||||
- name: Validate hostname
|
||||
ansible.builtin.fail:
|
||||
msg: |
|
||||
Invalid hostname: "{{ vm_hostname }}"
|
||||
Hostname may only contain letters (a-z, A-Z), numbers (0-9), and hyphens (-).
|
||||
when: not vm_hostname is regex('^[a-zA-Z0-9-]+$')
|
||||
run_once: true
|
||||
|
||||
- name: Validate IP address
|
||||
ansible.builtin.fail:
|
||||
msg: |
|
||||
Invalid IP address: "{{ vm_ip_address }}"
|
||||
IP address must be in x.x.x.x/x format (e.g., 192.168.0.89/24).
|
||||
when: not vm_ip_address is regex('^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)(\\/(3[0-2]|[12]?\\d))?$')
|
||||
run_once: true
|
||||
|
||||
- name: Validate OS template
|
||||
ansible.builtin.fail:
|
||||
msg: |
|
||||
Invalid OS template: "{{ vm_os_template }}"
|
||||
Select from available options: debian-13, alpine
|
||||
when: vm_os_template not in ['debian-13', 'alpine']
|
||||
run_once: true
|
||||
- name: Include input and validation for hostname
|
||||
ansible.builtin.include_tasks: ../tasks/hostname_validation.yaml
|
||||
|
||||
- name: Validate become method
|
||||
ansible.builtin.fail:
|
||||
msg: |
|
||||
Invalid become method: "{{ vm_become_method }}"
|
||||
Select from available options: sudo | su | pbrun | pfexec | doas | dzdo | ksu | runas | machinectl
|
||||
when: vm_become_method not in ['sudo', 'su', 'pbrun', 'pfexec', 'doas', 'dzdo', 'ksu', 'runas', 'machinectl']
|
||||
run_once: true
|
||||
- name: Include input and validation for IP
|
||||
ansible.builtin.include_tasks: ../tasks/ip_validation.yaml
|
||||
|
||||
- name: Include input and validation for human admin user creation
|
||||
ansible.builtin.include_tasks: ../tasks/human_admin_user_validation.yaml
|
||||
|
||||
- name: Include input and validation for OS template
|
||||
ansible.builtin.include_tasks: ../tasks/os_template_validation.yaml
|
||||
|
||||
- name: Include input and validation for become method
|
||||
ansible.builtin.include_tasks: ../tasks/become_method_validation.yaml
|
||||
|
||||
- name: Include input and validation for storage selection
|
||||
ansible.builtin.include_tasks: ../tasks/storage_validation.yaml
|
||||
|
||||
roles:
|
||||
- ../roles/deploy_vm_on_proxmox
|
||||
|
||||
tasks:
|
||||
- name: Make the hostname available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_vm_hostname: "{{ vm_hostname }}"
|
||||
|
||||
- name: Make the OS template available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_vm_os_template: "{{ vm_os_template }}"
|
||||
|
||||
- name: Make the IP available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_vm_ip_address: "{{ vm_ip_address.split('/') | first }}"
|
||||
|
||||
- name: Make the "human admin user" selection available to the whole playbook
|
||||
ansible.builtin.set_fact:
|
||||
fact_vm_create_human_admin_user: "{{ vm_create_human_admin_user }}"
|
||||
|
||||
- name: Add the target host to the inventory
|
||||
ansible.builtin.add_host:
|
||||
name: "{{ fact_vm_ip_address }}"
|
||||
name: "{{ guest_ip_address }}"
|
||||
groups: new_host
|
||||
ansible_user: ansible
|
||||
ansible_become_password: "{{ ansible_become_passwd }}"
|
||||
ansible_become_method: "{{ vm_become_method }}"
|
||||
ansible_become_method: "{{ guest_become_method }}"
|
||||
|
||||
|
||||
- name: Configure VM
|
||||
@@ -117,10 +61,10 @@
|
||||
- name: Include human admin user role
|
||||
ansible.builtin.include_role:
|
||||
name: ../roles/human_admin_user
|
||||
when: "hostvars['localhost']['fact_vm_create_human_admin_user'] | bool"
|
||||
when: "hostvars['localhost']['create_human_admin_user'] | bool"
|
||||
|
||||
- name: Include update configs role
|
||||
ansible.builtin.include_role:
|
||||
name: ../roles/update_configs
|
||||
when: "hostvars['localhost']['fact_vm_create_human_admin_user'] | bool"
|
||||
when: "hostvars['localhost']['create_human_admin_user'] | bool"
|
||||
|
||||
|
||||
@@ -12,9 +12,9 @@
|
||||
|
||||
cmode: "shell"
|
||||
password: "{{ lxc_root_password }}"
|
||||
hostname: "{{ lxc_hostname }}"
|
||||
ostemplate: 'main:vztmpl/debian-13-golden-image.tar.gz'
|
||||
unprivileged: "{{ lxc_is_privileged }}"
|
||||
hostname: "{{ guest_hostname }}"
|
||||
ostemplate: "main:vztmpl/{{ guest_os_template }}-golden-image.tar.gz"
|
||||
unprivileged: "{{ not lxc_privileged | bool }}"
|
||||
memory: 2048
|
||||
cores: 2
|
||||
state: present
|
||||
@@ -22,11 +22,13 @@
|
||||
# This is minimal requirement for rootfs
|
||||
# It might be resized later
|
||||
size: 4 # 4GB rootfs
|
||||
# We put rootfs on fast local storage (NVMe SSD)
|
||||
storage: local
|
||||
# We put rootfs on user-selected sotrage
|
||||
storage: "{{ guest_storage }}"
|
||||
# We need timeout in case a slow storage is used, since it may cause a significant delay
|
||||
timeout: 90
|
||||
pubkey: "{{ lookup('file', lookup('env', 'HOME') + '/.ssh/ansible_key.pub') }}"
|
||||
netif:
|
||||
net0: "name=eth0,gw=192.168.0.1,ip={{ lxc_ip_address }},bridge=vmbr0"
|
||||
net0: "name=eth0,gw=192.168.0.1,ip={{ guest_ip_address }}/{{ guest_netmask }},bridge=vmbr0"
|
||||
|
||||
- name: Make sure the container has started
|
||||
become: false
|
||||
@@ -38,7 +40,7 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
hostname: "{{ lxc_hostname }}"
|
||||
hostname: "{{ guest_hostname }}"
|
||||
state: started
|
||||
retries: 3
|
||||
delay: 15
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
clone: "{{ vm_os_template }}-cloud-init-template"
|
||||
name: "{{ vm_hostname }}"
|
||||
storage: main
|
||||
clone: "{{ guest_os_template }}-cloud-init-template"
|
||||
name: "{{ guest_hostname }}"
|
||||
storage: "{{ guest_storage }}"
|
||||
format: qcow2
|
||||
full: true
|
||||
timeout: 500
|
||||
@@ -33,7 +33,7 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ vm_hostname }}"
|
||||
name: "{{ guest_hostname }}"
|
||||
# Cloud-init parameters
|
||||
update: true
|
||||
ide:
|
||||
@@ -41,7 +41,7 @@
|
||||
ciuser: "ansible"
|
||||
cipassword: "{{ ansible_become_passwd }}"
|
||||
ipconfig:
|
||||
ipconfig0: "ip={{ vm_ip_address }},gw=192.168.0.1"
|
||||
ipconfig0: "ip={{ guest_ip_address }}/{{ guest_netmask }},gw=192.168.0.1"
|
||||
|
||||
- name: Tweak the hardware settings
|
||||
become: false
|
||||
@@ -53,7 +53,7 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ vm_hostname }}"
|
||||
name: "{{ guest_hostname }}"
|
||||
cores: 4
|
||||
memory: 4096 # Minimal value for debian based OS for smooth workflow
|
||||
update: true
|
||||
@@ -68,5 +68,5 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ vm_hostname }}"
|
||||
name: "{{ guest_hostname }}"
|
||||
state: started
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ vm_hostname }}"
|
||||
name: "{{ guest_hostname }}"
|
||||
state: current
|
||||
ignore_errors: true
|
||||
register: vm_status
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
api_token_id: ansible
|
||||
api_token_secret: "{{ proxmox_token_secret }}"
|
||||
|
||||
name: "{{ vm_hostname }}"
|
||||
name: "{{ guest_hostname }}"
|
||||
state: started
|
||||
|
||||
- name: Sleep for 120 seconds to ensure that Proxmox has cloned the VM
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
|
||||
- name: Set default become method
|
||||
ansible.builtin.set_fact:
|
||||
guest_become_method: "sudo"
|
||||
|
||||
- name: Prompt for become method with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Choose become method, available: sudo, su, pbrun, pfexec, doas, dzdo, ksu, runas, machinectl [sudo]"
|
||||
register: become_method_result
|
||||
until: >
|
||||
become_method_result.user_input | length == 0 or
|
||||
(
|
||||
become_method_result.user_input in ['sudo', 'su', 'pbrun', 'pfexec', 'doas', 'dzdo', 'ksu', 'runas', 'machinectl']
|
||||
)
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
guest_become_method: "{{ become_method_result.user_input }}"
|
||||
when: become_method_result.user_input | length > 0
|
||||
@@ -0,0 +1,23 @@
|
||||
---
|
||||
|
||||
- name: Set default hostname
|
||||
ansible.builtin.set_fact:
|
||||
guest_hostname: "test-guest"
|
||||
|
||||
- name: Prompt for hostname with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Enter hostname (letters, digits, hyphens (but not leading and trailing), dots; max 253 chars) [{{ guest_hostname }}]"
|
||||
register: hostname_result
|
||||
until: >
|
||||
hostname_result.user_input | length == 0 or
|
||||
(
|
||||
hostname_result.user_input | length <= 253 and
|
||||
hostname_result.user_input is regex('^[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$')
|
||||
)
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
guest_hostname: "{{ hostname_result.user_input }}"
|
||||
when: hostname_result.user_input | length > 0
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
|
||||
- name: Set default human admin user
|
||||
ansible.builtin.set_fact:
|
||||
create_human_admin_user: true
|
||||
|
||||
- name: Prompt for human admin user creation with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Create human admin user? (true/false) [true]"
|
||||
register: human_admin_user_result
|
||||
until: >
|
||||
human_admin_user_result.user_input | length == 0 or
|
||||
(
|
||||
human_admin_user_result.user_input in ['true', 'false']
|
||||
)
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
create_human_admin_user: "{{ human_admin_user_result.user_input }}"
|
||||
when: human_admin_user_result.user_input | length > 0
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
|
||||
- name: Set default ip
|
||||
ansible.builtin.set_fact:
|
||||
guest_ip_address: "192.168.0.90"
|
||||
|
||||
- name: Set default network mask
|
||||
ansible.builtin.set_fact:
|
||||
guest_netmask: "24"
|
||||
|
||||
- name: Prompt for IP with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Enter ip in x.x.x.x/x format [192.168.0.90/24]"
|
||||
register: ip_result
|
||||
until: >
|
||||
ip_result.user_input | length == 0 or
|
||||
ip_result.user_input is regex('^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)/(3[0-2]|[12]?\\d)$')
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default (IP)
|
||||
ansible.builtin.set_fact:
|
||||
guest_ip_address: "{{ ip_result.user_input.split('/') | first }}"
|
||||
when: ip_result.user_input | length > 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default (netmask)
|
||||
ansible.builtin.set_fact:
|
||||
guest_netmask: "{{ ip_result.user_input.split('/')[1] }}"
|
||||
when: ip_result.user_input | length > 0
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
|
||||
- name: Set default privileged
|
||||
ansible.builtin.set_fact:
|
||||
lxc_privileged: false
|
||||
|
||||
- name: Prompt for privileged with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Privileged LXC? (true/false) [false]"
|
||||
register: privileged_result
|
||||
until: >
|
||||
privileged_result.user_input | length == 0 or
|
||||
(
|
||||
privileged_result.user_input in ['true', 'false']
|
||||
)
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
lxc_privileged: "{{ privileged_result.user_input }}"
|
||||
when: privileged_result.user_input | length > 0
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
|
||||
- name: Set default password
|
||||
ansible.builtin.set_fact:
|
||||
lxc_root_password: "test-guest"
|
||||
|
||||
- name: Prompt for password
|
||||
ansible.builtin.pause:
|
||||
prompt: "Enter your password [{{ lxc_root_password }}]"
|
||||
echo: false
|
||||
register: password_result_1
|
||||
|
||||
- name: Prompt for password confirmation (only if a password was entered)
|
||||
ansible.builtin.pause:
|
||||
prompt: "Confirm your new password"
|
||||
echo: false
|
||||
register: password_result_2
|
||||
when: password_result_1.user_input | length > 0
|
||||
|
||||
- name: Ensure passwords match
|
||||
ansible.builtin.assert:
|
||||
that:
|
||||
- password_result_1.user_input == password_result_2.user_input
|
||||
fail_msg: "Passwords do not match!"
|
||||
success_msg: "Password confirmed."
|
||||
when: password_result_1.user_input | length > 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
lxc_root_password: "{{ password_result_1.user_input }}"
|
||||
when: password_result_1.user_input | length > 0
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
|
||||
- name: Set default OS template
|
||||
ansible.builtin.set_fact:
|
||||
guest_os_template: "debian-13"
|
||||
|
||||
- name: Prompt for OS template with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Choose OS template, available: debian-13, alpine [debian-13]"
|
||||
register: os_template_result
|
||||
until: >
|
||||
os_template_result.user_input | length == 0 or
|
||||
(
|
||||
os_template_result.user_input in ['debian-13', 'alpine']
|
||||
)
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
guest_os_template: "{{ os_template_result.user_input }}"
|
||||
when: os_template_result.user_input | length > 0
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
|
||||
- name: Set default storage
|
||||
ansible.builtin.set_fact:
|
||||
guest_storage: "main"
|
||||
|
||||
- name: Prompt for guest storage with immediate validation
|
||||
ansible.builtin.pause:
|
||||
prompt: "Choose storage for root, available: main (HDD), local (PCIe NVMe SSD) [{{ guest_storage }}]"
|
||||
register: storage_result
|
||||
until: >
|
||||
storage_result.user_input | length == 0 or
|
||||
(
|
||||
storage_result.user_input in ['main', 'local']
|
||||
)
|
||||
retries: 2
|
||||
delay: 0
|
||||
|
||||
- name: Use user input only if provided, otherwise keep the default
|
||||
ansible.builtin.set_fact:
|
||||
guest_storage: "{{ storage_result.user_input }}"
|
||||
when: storage_result.user_input | length > 0
|
||||
Reference in New Issue
Block a user