From d037ba4198838d511e1ddc96d2a3b6cb73683791 Mon Sep 17 00:00:00 2001 From: "Qi (Keira) Zhang" Date: Wed, 27 Sep 2023 17:27:16 +0800 Subject: [PATCH] [Ubuntu 23.10] Fix package installation failure at deploy_vm (#505) Signed-off-by: Qi Zhang --- .../Ubuntu/Desktop/Subiquity/user-data.j2 | 23 ++++++++--- autoinstall/Ubuntu/Server/user-data.j2 | 3 +- common/vm_wait_log_msg.yml | 2 +- .../deploy_vm/create_unattend_install_iso.yml | 2 +- linux/deploy_vm/ubuntu/ubuntu_install_os.yml | 38 ++++++++++++++++--- linux/utils/add_official_online_repo.yml | 6 +-- linux/utils/get_network_config_file.yml | 4 +- linux/utils/set_network_adapter_status.yml | 6 +++ 8 files changed, 65 insertions(+), 19 deletions(-) diff --git a/autoinstall/Ubuntu/Desktop/Subiquity/user-data.j2 b/autoinstall/Ubuntu/Desktop/Subiquity/user-data.j2 index 411f5656b..fc4bcaabb 100644 --- a/autoinstall/Ubuntu/Desktop/Subiquity/user-data.j2 +++ b/autoinstall/Ubuntu/Desktop/Subiquity/user-data.j2 @@ -2,7 +2,8 @@ autoinstall: version: 1 early-commands: - - echo '{{ autoinstall_start_msg }}' >/dev/ttyS0 + - echo 'The network interface name is' $(ip -br link show | grep -v lo | awk '{print $1}') >/dev/ttyS0 + - echo '{{ autoinstall_start_msg }}' $(ip -br -4 addr show | grep -v lo | awk '{print $3}') >/dev/ttyS0 locale: en_US.UTF-8 keyboard: layout: us @@ -17,6 +18,20 @@ autoinstall: realname: ubuntu username: {{ vm_username }} password: {{ vm_password_hash }} + ssh: + install-server: yes + allow-pw: yes + authorized-keys: + - {{ ssh_public_key }} + packages: + - open-vm-tools + - open-vm-tools-desktop + - build-essential + - sg3-utils + - ndctl + - rdma-core + - rdmacm-utils + - ibverbs-utils user-data: users: - name: root @@ -36,12 +51,8 @@ autoinstall: preserve_sources_list: false geoip: true late-commands: - - echo "# apt-get update" >> /dev/ttyS0 - - curtin in-target --target=/target -- apt-get update -y >> /dev/ttyS0 - - echo "# apt-get install build-essential openssh-server open-vm-tools open-vm-tools-desktop cloud-init rdma-core rdmacm-utils ibverbs-utils" >> /dev/ttyS0 - - curtin in-target --target=/target -- apt-get install -y --force-yes build-essential openssh-server open-vm-tools open-vm-tools-desktop cloud-init rdma-core rdmacm-utils ibverbs-utils >> /dev/ttyS0 - rm -f /etc/cloud/cloud.cfg.d/*-installer.cfg 2>/dev/null - sed -i 's/^#PermitRootLogin .*/PermitRootLogin yes/' /target/etc/ssh/sshd_config - sed -i 's/^#PasswordAuthentication .*/PasswordAuthentication yes/' /target/etc/ssh/sshd_config - - echo "{{ autoinstall_complete_msg }}" >> /dev/ttyS0 + - echo "{{ autoinstall_complete_msg }}" > /dev/ttyS0 shutdown: 'poweroff' diff --git a/autoinstall/Ubuntu/Server/user-data.j2 b/autoinstall/Ubuntu/Server/user-data.j2 index dbec0c6f1..7c492ba52 100644 --- a/autoinstall/Ubuntu/Server/user-data.j2 +++ b/autoinstall/Ubuntu/Server/user-data.j2 @@ -2,7 +2,8 @@ autoinstall: version: 1 early-commands: - - echo '{{ autoinstall_start_msg }}' >/dev/ttyS0 + - echo 'The network interface name is' $(ip -br link show | grep -v lo | awk '{print $1}') >/dev/ttyS0 + - echo '{{ autoinstall_start_msg }}' $(ip -br -4 addr show | grep -v lo | awk '{print $3}') >/dev/ttyS0 refresh-installer: update: false locale: en_US.UTF-8 diff --git a/common/vm_wait_log_msg.yml b/common/vm_wait_log_msg.yml index ed72d57a5..adc31327f 100644 --- a/common/vm_wait_log_msg.yml +++ b/common/vm_wait_log_msg.yml @@ -53,7 +53,7 @@ - (get_vm_log_content.content | regex_findall(vm_wait_log_msg) | length) >= (vm_wait_log_msg_times | default(1)) delay: "{{ vm_wait_log_delay | default(5) }}" retries: "{{ vm_wait_log_retries | default(60) }}" - ignore_errors: "{{ vm_wait_log_ignore_errors | default(false) }}" + ignore_errors: true - name: "Set fact of the logs list found for specified log message" ansible.builtin.set_fact: diff --git a/linux/deploy_vm/create_unattend_install_iso.yml b/linux/deploy_vm/create_unattend_install_iso.yml index 5628f7fe3..466852bce 100644 --- a/linux/deploy_vm/create_unattend_install_iso.yml +++ b/linux/deploy_vm/create_unattend_install_iso.yml @@ -85,7 +85,7 @@ - block: - name: "Set fact for autoinstall start message to be printed to VM serial port" ansible.builtin.set_fact: - autoinstall_start_msg: "Ubuntu autoinstall is started at {{ lookup('pipe', 'date +%Y-%m-%d-%H-%M-%S') }}" + autoinstall_start_msg: "Ubuntu autoinstall is started with IPv4 address:" # Create the Ubuntu seed ISO to modify login information - include_tasks: ../utils/create_seed_iso.yml diff --git a/linux/deploy_vm/ubuntu/ubuntu_install_os.yml b/linux/deploy_vm/ubuntu/ubuntu_install_os.yml index 95ab834cd..2cb2f3c0c 100644 --- a/linux/deploy_vm/ubuntu/ubuntu_install_os.yml +++ b/linux/deploy_vm/ubuntu/ubuntu_install_os.yml @@ -6,10 +6,36 @@ when: ubuntu_install_method is defined and ubuntu_install_method == "simulation" # Wait for autoinstall start message in serial port output file -- include_tasks: ../../../common/vm_wait_log_msg.yml - vars: - vm_wait_log_name: "{{ vm_serial_port_output_file | basename }}" - vm_wait_log_msg: "{{ autoinstall_start_msg }}" - vm_wait_log_retries: 150 - vm_wait_log_delay: 5 +- name: "Wait for Ubuntu autoinstall is started successfully" when: ubuntu_install_method is defined and ubuntu_install_method == "cloud-init" + block: + - name: "Wait for autoinstall start message" + include_tasks: ../../../common/vm_wait_log_msg.yml + vars: + vm_wait_log_name: "{{ vm_serial_port_output_file | basename }}" + vm_wait_log_msg: "{{ autoinstall_start_msg }}[^\\r\\n]*" + vm_wait_log_retries: 150 + vm_wait_log_delay: 5 + + # Ubuntu autoinstall with cloud configs requires network connection. + # When autoinstall start message is detected, its must be followed with an IPv4 + # address get at early-commands in the unattend install config file. + # Otherwise, we can stop autoinstall immediately. + - name: "Get the IPv4 address when Ubuntu autoinstall started" + ansible.builtin.set_fact: + ubuntu_autoinstall_start_ipv4: >- + {{ + vm_wait_log_msg_list | + map('replace', autoinstall_start_msg, '') | + map('trim') | + ansible.utils.ipaddr('address') + }} + + - name: "Check VM obtains IPv4 address" + ansible.builtin.assert: + that: + - ubuntu_autoinstall_start_ipv4 + - ubuntu_autoinstall_start_ipv4 | length > 0 + - ubuntu_autoinstall_start_ipv4[0] is ansible.utils.ipv4 + fail_msg: "Ubuntu autoinstall failed to start due to no IPv4 address obtained." + success_msg: "Ubuntu autoinstall is started with IPv4 address {{ ubuntu_autoinstall_start_ipv4 }}" diff --git a/linux/utils/add_official_online_repo.yml b/linux/utils/add_official_online_repo.yml index dbc4d3474..177197f89 100644 --- a/linux/utils/add_official_online_repo.yml +++ b/linux/utils/add_official_online_repo.yml @@ -163,11 +163,11 @@ include_tasks: replace_or_add_line_in_file.yml vars: file: "{{ apt_source_list }}" - reg_exp: "{{ apt_source }}" - line_content: "{{ apt_source }}" + reg_exp: "{{ apt_source_item }}" + line_content: "{{ apt_source_item }}" with_list: "{{ apt_sources }}" loop_control: - loop_var: "apt_source" + loop_var: "apt_source_item" # Remove repositories from universe and multiverse - name: "Remove repositories from universe and multiverse" diff --git a/linux/utils/get_network_config_file.yml b/linux/utils/get_network_config_file.yml index aefea38a1..528d6e617 100644 --- a/linux/utils/get_network_config_file.yml +++ b/linux/utils/get_network_config_file.yml @@ -18,7 +18,9 @@ - name: "Get network config file from NetworkManager" block: - name: "Get network connections" - ansible.builtin.shell: "nmcli -t -f NAME,ACTIVE,FILENAME connection show --active | grep '^{{ network_adapter_name }}:'" + ansible.builtin.shell: | + conn_name=$(nmcli -t -f GENERAL.CONNECTION device show {{ network_adapter_name }} | cut -d ':' -f 2); + nmcli -t -f NAME,ACTIVE,FILENAME connection show --active | grep "$conn_name:" delegate_to: "{{ vm_guest_ip }}" register: "network_conn_result" ignore_errors: true diff --git a/linux/utils/set_network_adapter_status.yml b/linux/utils/set_network_adapter_status.yml index 52a26b9eb..e9e77a344 100644 --- a/linux/utils/set_network_adapter_status.yml +++ b/linux/utils/set_network_adapter_status.yml @@ -19,6 +19,12 @@ - name: "Connect network interface '{{ network_adapter_name }}'" ansible.builtin.shell: "nmcli device connect {{ network_adapter_name }}" delegate_to: "{{ vm_guest_ip }}" + register: nmcli_connect_result + retries: 5 + delay: 5 + until: + - nmcli_connect_result.rc is defined + - nmcli_connect_result.rc == 0 - name: "Set expected network interface status to 'connected'" ansible.builtin.set_fact: