From 9f0e2a07848cd1e315af997fa62a2b2c176b7ea5 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 29 Jun 2021 15:00:08 +0200 Subject: add ubuntu insaller fetch and base --- roles/installer/debian/base/tasks/main.yml | 2 +- roles/installer/ubuntu/base/tasks/main.yml | 15 ++++++++ roles/installer/ubuntu/fetch/defaults/main.yml | 7 ++++ .../installer/ubuntu/fetch/tasks/fetch-latest.yml | 13 +++++++ .../installer/ubuntu/fetch/tasks/fetch-version.yml | 41 +++++++++++++++++++++ roles/installer/ubuntu/fetch/tasks/main.yml | 43 ++++++++++++++++++++++ roles/installer/ubuntu/fetch/vars/main.yml | 2 + 7 files changed, 122 insertions(+), 1 deletion(-) create mode 100644 roles/installer/ubuntu/base/tasks/main.yml create mode 100644 roles/installer/ubuntu/fetch/defaults/main.yml create mode 100644 roles/installer/ubuntu/fetch/tasks/fetch-latest.yml create mode 100644 roles/installer/ubuntu/fetch/tasks/fetch-version.yml create mode 100644 roles/installer/ubuntu/fetch/tasks/main.yml create mode 100644 roles/installer/ubuntu/fetch/vars/main.yml (limited to 'roles') diff --git a/roles/installer/debian/base/tasks/main.yml b/roles/installer/debian/base/tasks/main.yml index 662b8acb..56ca7dc0 100644 --- a/roles/installer/debian/base/tasks/main.yml +++ b/roles/installer/debian/base/tasks/main.yml @@ -17,7 +17,7 @@ src: "{{ item }}" dest: "{{ installer_base_path }}/keyrings/{{ item | basename }}" -- name: copy ubuntu keyring file +- name: copy ubuntu archive keyring file copy: src: "{{ global_files_dir }}/common/keyrings/ubuntu-archive.gpg" dest: "{{ installer_base_path }}/keyrings/ubuntu-archive.gpg" diff --git a/roles/installer/ubuntu/base/tasks/main.yml b/roles/installer/ubuntu/base/tasks/main.yml new file mode 100644 index 00000000..c48ed4b5 --- /dev/null +++ b/roles/installer/ubuntu/base/tasks/main.yml @@ -0,0 +1,15 @@ +--- +- name: install gpgv + apt: + name: gpgv + state: present + +- name: prepare directory keyrings + file: + name: "{{ installer_base_path }}/keyrings" + state: directory + +- name: copy ubuntu cdimage keyring file + copy: + src: "{{ global_files_dir }}/common/keyrings/ubuntu-cdimage.gpg" + dest: "{{ installer_base_path }}/keyrings/ubuntu-cdimage.gpg" diff --git a/roles/installer/ubuntu/fetch/defaults/main.yml b/roles/installer/ubuntu/fetch/defaults/main.yml new file mode 100644 index 00000000..f6ac2bc0 --- /dev/null +++ b/roles/installer/ubuntu/fetch/defaults/main.yml @@ -0,0 +1,7 @@ +--- +# ubuntu_installer_codename: bionic | focal +ubuntu_installer_arch: amd64 +# ubuntu_installer_variant: live-server | desktop +# ubuntu_installer_version: 20.04.1 + +ubuntu_installer_force_download: no diff --git a/roles/installer/ubuntu/fetch/tasks/fetch-latest.yml b/roles/installer/ubuntu/fetch/tasks/fetch-latest.yml new file mode 100644 index 00000000..9baa6d97 --- /dev/null +++ b/roles/installer/ubuntu/fetch/tasks/fetch-latest.yml @@ -0,0 +1,13 @@ +--- +- name: downloading SHA256SUMS and signature file for latest release + loop: + - SHA256SUMS + - SHA256SUMS.gpg + get_url: + url: "https://releases.ubuntu.com/{{ ubuntu_installer_codename }}/{{ item }}" + dest: "{{ ubuntu_installer_target_dir }}/{{ item }}" + force: "{{ ubuntu_installer_force_download }}" + +- name: set download url to releases.ubuntu.com + set_fact: + ubuntu_installer_base_url: "https://releases.ubuntu.com/{{ ubuntu_installer_codename }}" diff --git a/roles/installer/ubuntu/fetch/tasks/fetch-version.yml b/roles/installer/ubuntu/fetch/tasks/fetch-version.yml new file mode 100644 index 00000000..868adc95 --- /dev/null +++ b/roles/installer/ubuntu/fetch/tasks/fetch-version.yml @@ -0,0 +1,41 @@ +--- +## we need to try old-releases.ubuntu.com first because otherwise it would be impossible to download the initial release +## of any codename release. (i.e. 20.04) +- name: try downloading SHA256SUMS and signature file from old-releases.ubuntu.com + loop: + - SHA256SUMS + - SHA256SUMS.gpg + get_url: + url: "https://old-releases.ubuntu.com/releases/{{ ubuntu_installer_version }}/{{ item }}" + dest: "{{ ubuntu_installer_target_dir }}/{{ item }}" + force: yes + register: ubuntu_installer_old + failed_when: "'status_code' in ubuntu_installer_old and ubuntu_installer_old.status_code not in [200, 404]" + +- when: 404 not in (ubuntu_installer_old.results | selectattr('status_code', 'defined') | map(attribute='status_code') | list) + block: + - name: check if SHA256SUM actually contains the correct iso + command: grep -E '^[0-9a-z]{64}\s+\*ubuntu-{{ ubuntu_installer_version }}-{{ ubuntu_installer_variant }}-{{ ubuntu_installer_arch }}.iso$' "{{ ubuntu_installer_target_dir }}/SHA256SUMS" + changed_when: false + failed_when: false + register: ubuntu_installer_old_sha256sum + + - name: set download url to old-releases.ubuntu.com + when: (ubuntu_installer_old_sha256sum.stdout_lines | length) > 0 + set_fact: + ubuntu_installer_base_url: "https://old-releases.ubuntu.com/releases/{{ ubuntu_installer_version }}" + +- when: ubuntu_installer_base_url is not defined + block: + - name: try downloading SHA256SUMS and signature file from releases.ubuntu.com + loop: + - SHA256SUMS + - SHA256SUMS.gpg + get_url: + url: "https://releases.ubuntu.com/{{ ubuntu_installer_version }}/{{ item }}" + dest: "{{ ubuntu_installer_target_dir }}/{{ item }}" + force: yes + + - name: set download url to releases.ubuntu.com + set_fact: + ubuntu_installer_base_url: "https://releases.ubuntu.com/{{ ubuntu_installer_version }}" diff --git a/roles/installer/ubuntu/fetch/tasks/main.yml b/roles/installer/ubuntu/fetch/tasks/main.yml new file mode 100644 index 00000000..618cfd22 --- /dev/null +++ b/roles/installer/ubuntu/fetch/tasks/main.yml @@ -0,0 +1,43 @@ +--- +- name: prepare directories for installer files + file: + name: "{{ ubuntu_installer_target_dir }}" + state: directory + +- include_tasks: "fetch-{{ (ubuntu_installer_version is defined) | ternary('version', 'latest') }}.yml" + +- name: verfiy signature of SHA256SUMS file + command: >- + gpgv --keyring "{{ installer_keyrings_path | default(installer_base_path+'/keyrings') }}/ubuntu-cdimage.gpg" + "{{ ubuntu_installer_target_dir }}/SHA256SUMS.gpg" "{{ ubuntu_installer_target_dir }}/SHA256SUMS" + changed_when: False + register: ubuntu_installer_gpg_result + +- debug: + var: ubuntu_installer_gpg_result.stderr_lines + + +- name: download and verify installer files + block: + - name: extract file hash from SHA256SUMS + command: grep -E '^[0-9a-z]{64}\s+\*ubuntu-{{ ubuntu_installer_version | default("[0-9.]+") }}-{{ ubuntu_installer_variant }}-{{ ubuntu_installer_arch }}.iso$' "{{ ubuntu_installer_target_dir }}/SHA256SUMS" + changed_when: false + register: ubuntu_installer_sha256sum + + - name: extract filename from SHA256SUM + set_fact: + ubuntu_installer_filename: "{{ (ubuntu_installer_sha256sum.stdout.split(' ') | last)[1:] }}" + + - debug: + msg: "will be downloading: {{ ubuntu_installer_base_url }}/{{ ubuntu_installer_filename }} (this will probably take a while...)" + + - name: download/verify installer file + get_url: + url: "{{ ubuntu_installer_base_url }}/{{ ubuntu_installer_filename }}" + dest: "{{ ubuntu_installer_target_dir }}/{{ ubuntu_installer_filename }}" + checksum: "sha256:{{ ubuntu_installer_sha256sum.stdout.split(' ') | first }}" + force: "{{ ubuntu_installer_force_download }}" + + rescue: + - fail: + msg: "download/verification of installer files failed. Is the cd-image variant '{{ ubuntu_installer_variant }}' available for {{ ubuntu_installer_codename }}?" diff --git a/roles/installer/ubuntu/fetch/vars/main.yml b/roles/installer/ubuntu/fetch/vars/main.yml new file mode 100644 index 00000000..caf1fa67 --- /dev/null +++ b/roles/installer/ubuntu/fetch/vars/main.yml @@ -0,0 +1,2 @@ +--- +ubuntu_installer_target_dir: "{{ installer_base_path }}/{{ ubuntu_installer_codename }}/{{ ubuntu_installer_version | default('latest') }}-{{ ubuntu_installer_variant }}" -- cgit v1.2.3 From 1d7c13b3a4c52278641bd8d20017bef12130fab5 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 29 Jun 2021 17:40:42 +0200 Subject: add autoinstall role for ubuntu/installer --- roles/installer/debian/preseed/defaults/main.yml | 2 +- .../installer/ubuntu/autoinstall/defaults/main.yml | 36 +++++ .../ubuntu/autoinstall/files/early-command.py | 25 +++ roles/installer/ubuntu/autoinstall/tasks/main.yml | 20 +++ .../autoinstall/templates/autoinstall.yml.j2 | 172 +++++++++++++++++++++ 5 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 roles/installer/ubuntu/autoinstall/defaults/main.yml create mode 100644 roles/installer/ubuntu/autoinstall/files/early-command.py create mode 100644 roles/installer/ubuntu/autoinstall/tasks/main.yml create mode 100644 roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 (limited to 'roles') diff --git a/roles/installer/debian/preseed/defaults/main.yml b/roles/installer/debian/preseed/defaults/main.yml index b8d22ea6..a0646b3b 100644 --- a/roles/installer/debian/preseed/defaults/main.yml +++ b/roles/installer/debian/preseed/defaults/main.yml @@ -1,5 +1,5 @@ --- -# preseed_initrd +# preseed_initrd: # preseed_tmpdir: preseed_language: en diff --git a/roles/installer/ubuntu/autoinstall/defaults/main.yml b/roles/installer/ubuntu/autoinstall/defaults/main.yml new file mode 100644 index 00000000..1a4fd3ed --- /dev/null +++ b/roles/installer/ubuntu/autoinstall/defaults/main.yml @@ -0,0 +1,36 @@ +--- +# ubuntu_autoinstall_tmpdir: + +ubuntu_autoinstall_locale: en_US + +ubuntu_autoinstall_keyboard_layout: de +ubuntu_autoinstall_keyboard_variant: nodeadkeys + +ubuntu_autoinstall_timezone: Europe/Vienna + +# ubuntu_autoinstall_kernel_image: +ubuntu_autoinstall_virtual_machine: no + +ubuntu_autoinstall_efi_esp_size: 128M + +ubuntu_autoinstall_system_lvm_size_default: all +ubuntu_autoinstall_system_lvm_volumes_default: + - name: root + size: 2.5G + filesystem: ext4 + mountpoint: / + - name: var + size: 1280M + filesystem: ext4 + mountpoint: /var + - name: var+log + size: 768M + filesystem: ext4 + mountpoint: /var/log + mount_options: + - nodev + - noatime + - noexec + + +ubuntu_autoinstall_install_tasks: [] diff --git a/roles/installer/ubuntu/autoinstall/files/early-command.py b/roles/installer/ubuntu/autoinstall/files/early-command.py new file mode 100644 index 00000000..93d72b2d --- /dev/null +++ b/roles/installer/ubuntu/autoinstall/files/early-command.py @@ -0,0 +1,25 @@ +#!/usr/bin/env python3 + +import os +from shutil import copyfile +import yaml + +os.umask(0o077) +copyfile('/autoinstall.yaml', '/autoinstall.yaml_before-early-command') + +config = {} +with open('/autoinstall.yaml', 'r') as file: + config = yaml.safe_load(file) + +try: + for c in config['storage']['config']: + if 'type' not in c or c['type'] != 'disk' or 'path' not in c: + continue + + c['path'] = os.path.realpath(c['path']) + + with open('/autoinstall.yaml', 'w') as file: + yaml.dump(config, file, default_flow_style=False) + +except KeyError: + pass diff --git a/roles/installer/ubuntu/autoinstall/tasks/main.yml b/roles/installer/ubuntu/autoinstall/tasks/main.yml new file mode 100644 index 00000000..4a3034d0 --- /dev/null +++ b/roles/installer/ubuntu/autoinstall/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: create autoinstall sub-directory + file: + path: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall" + state: directory + +- name: create empty meta-data file + copy: + content: "" + dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/meta-data" + +- name: copy early-command script + copy: + src: early-command.py + dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/early-command.py" + +- name: generate autoinstall.yml as user-data + template: + src: autoinstall.yml.j2 + dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/user-data" diff --git a/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 b/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 new file mode 100644 index 00000000..97b54b0a --- /dev/null +++ b/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 @@ -0,0 +1,172 @@ +#cloud-config +autoinstall: + version: 1 + early-commands: + - python3 /cdrom/autoinstall/early-command.py + + locale: "{{ ubuntu_autoinstall_locale }}" + keyboard: + layout: "{{ ubuntu_autoinstall_keyboard_layout }}" + variant: "{{ ubuntu_autoinstall_keyboard_variant }}" + toggle: null + + network: + version: 2 + ethernets: + {{ install_interface | default(network_cooked.primary.name) }}: +{% if install_dhcp | default(false) %} + dhcp4: yes +{% else %} + addresses: + - {{ network_cooked.primary.address }} + gateway4: {{ network_cooked.primary.gateway }} +{% if (network_cooked.nameservers | default([]) | length) > 0 %} + nameservers: + search: [ {{ host_domain }} ] + addresses: [ {{ network_cooked.nameservers | join(', ') }} ] +{% endif %} +{% endif %} + + storage: + config: + - id: disk-primary + type: disk + path: {{ install_cooked.disks.primary }} +{% if install_cooked.efi | default(false) %} + ptable: gpt +{% else %} + ptable: msdos + grub_device: true +{% endif %} + wipe: superblock-recursive + +{% if install_cooked.efi | default(false) %} +{% set part_offset = 1 %} + - id: partition-esp + type: partition + device: disk-primary + flag: boot + number: 1 + size: {{ ubuntu_autoinstall_efi_esp_size | human_to_bytes }} + grub_device: true + - id: format-esp + type: format + volume: partition-esp + label: efi + fstype: fat32 + - id: mount-esp + type: mount + device: format-esp + path: /boot/efi + +{% else %} +{% set part_offset = 0 %} + +{% endif %} +{% set system_lvm_size = install_cooked.system_lvm.size | default(ubuntu_autoinstall_system_lvm_size_default) %} +{% set system_lvm_volumes = install_cooked.system_lvm.volumes | default(ubuntu_autoinstall_system_lvm_volumes_default) %} + - id: partition-lvm + type: partition + device: disk-primary + flag: linux + number: {{ part_offset + 1 }} +{% if system_lvm_size != 'all' %} + size: {{ system_lvm_size | human_to_bytes }} + - id: partition-unused + type: partition + device: disk-primary + flag: linux + number: {{ part_offset + 2 }} +{% endif %} + size: -1 + + - id: lvm-vg-system + type: lvm_volgroup + devices: + - partition-lvm + name: {{ host_name }} + +{% for volume in system_lvm_volumes %} + - id: lvm-lv-{{ volume.name }} + type: lvm_partition + volgroup: lvm-vg-system + name: {{ volume.name }} + size: {{ volume.size | human_to_bytes }} + - id: format-{{ volume.name }} + type: format + fstype: {{ volume.filesystem }} + volume: lvm-lv-{{ volume.name }} + - id: mount-{{ volume.name }} + type: mount + device: format-{{ volume.name }} + path: {{ volume.mountpoint }} +{% if 'mount_options' in volume and (volume.mount_options | length) > 0 %} + options: '{{ volume.mount_options | join(",") }}' +{% endif %} + +{% endfor %} + apt: + primary: + - uri: http://{{ apt_repo_providers[apt_repo_provider].ubuntu.host }}{{ apt_repo_providers[apt_repo_provider].ubuntu.path }} + arches: + - amd64 + + user-data: + hostname: "{{ host_name }}" + timezone: "{{ ubuntu_autoinstall_timezone }}" + disable_root: false + users: + - name: root + ssh_authorized_keys: +{% for key in ssh_keys_root %} + - {{ key }} +{% endfor %} + runcmd: + - [ apt-get, -y, -q, purge, snapd, cloud-init, cloud-guest-utils, cloud-initramfs-copymods, cloud-initramfs-dyn-netconf, python3-cryptography, gpg, sosreport, update-notifier-common, ssh-import-id ] + - [ rm, -rf, /etc/cloud, /var/lib/cloud ] + - [ apt-get, -y, -q, auto-remove ] + - [ bash, -c, 'dpkg -l | grep "^rc" | awk "{ print(\$2) }" | xargs dpkg -P' ] +{% if ubuntu_autoinstall_virtual_machine %} + - [ poweroff ] +{% endif %} + + ssh: + install-server: true + + packages: + - python3 + - python3-apt +{% for task in ubuntu_autoinstall_install_tasks %} + - {{ task }}^ +{% endfor %} + + late-commands: + - curtin in-target --target=/target -- swapoff -a; sed -e '/^\/swapfile/d' -i /etc/fstab; rm -f /swapfile +{% if ansible_port is defined %} + - curtin in-target --target=/target -- sed -e 's/^\(\s*#*\s*Port.*\)/Port {{ ansible_port }}/' -i /etc/ssh/sshd_config +{% endif %} + - curtin in-target --target=/target -- apt-mark manual iputils-ping isc-dhcp-client netcat-openbsd netplan.io sudo + - curtin in-target --target=/target -- apt-get -y -q purge policykit-1 multipath-tools ubuntu-minimal unattended-upgrades sound-theme-freedesktop thin-provisioning-tools cryptsetup mdadm byobu open-iscsi btrfs-progs pollinate lxd-agent-loader +{% if not ubuntu_autoinstall_virtual_machine %} + - curtin in-target --target=/target -- apt-get -y -q purge open-vm-tools +{% endif %} + - curtin in-target --target=/target -- env SUDO_FORCE_REMOVE=yes apt-get -y -q purge sudo + - curtin in-target --target=/target -- apt-get -y -q autoremove + - curtin in-target --target=/target -- bash -c 'dpkg -l | grep "^rc" | awk "{ print(\$2) }" | xargs dpkg -P' +{# purging the snapd package here would trigger a bug in den postrm script because some filesystems in /run/ can not be unmounted... #} +{# to workadound this issue we only remove the package here and rely on cloud-init to fully purge it on first boot (see user-data: above) #} + - curtin in-target --target=/target -- apt-get -y -q remove snapd + - curtin in-target --target=/target -- bash -c 'apt-get update -q && apt-get full-upgrade -y -q' +{% if ubuntu_autoinstall_kernel_image is defined or ubuntu_autoinstall_virtual_machine %} + +write_files: + - path: /run/kernel-meta-package + content: | +{% if ubuntu_autoinstall_kernel_image is defined %} + {{ ubuntu_autoinstall_kernel_image }} +{% else %} + linux-virtual +{% endif %} + owner: root:root + permissions: "0644" +{% endif %} -- cgit v1.2.3 From eb12569ed4284345cf2f574ec5e081ac767b5f29 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Tue, 29 Jun 2021 21:00:37 +0200 Subject: first workin version of the subiquity based ubuntu installer --- roles/installer/debian/iso/tasks/main.yml | 2 +- roles/installer/debian/usb/tasks/main.yml | 2 +- roles/installer/ubuntu/iso/defaults/main.yml | 5 ++ roles/installer/ubuntu/iso/tasks/main.yml | 55 ++++++++++++++++++++++ roles/installer/ubuntu/iso/templates/grub.cfg.j2 | 18 +++++++ .../installer/ubuntu/iso/templates/isolinux.cfg.j2 | 15 ++++++ 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 roles/installer/ubuntu/iso/defaults/main.yml create mode 100644 roles/installer/ubuntu/iso/tasks/main.yml create mode 100644 roles/installer/ubuntu/iso/templates/grub.cfg.j2 create mode 100644 roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 (limited to 'roles') diff --git a/roles/installer/debian/iso/tasks/main.yml b/roles/installer/debian/iso/tasks/main.yml index 3170c7b5..04d913c3 100644 --- a/roles/installer/debian/iso/tasks/main.yml +++ b/roles/installer/debian/iso/tasks/main.yml @@ -4,7 +4,7 @@ vars: debian_installer_distro: "{{ install_distro }}" debian_installer_codename: "{{ install_codename }}" - debian_installer_arch: "{{ install.arch | default('amd64') }}" + debian_installer_arch: "{{ install_cooked.arch | default('amd64') }}" debian_installer_variant: mini-iso import_role: role: installer/debian/fetch diff --git a/roles/installer/debian/usb/tasks/main.yml b/roles/installer/debian/usb/tasks/main.yml index e02f38e6..88da49c8 100644 --- a/roles/installer/debian/usb/tasks/main.yml +++ b/roles/installer/debian/usb/tasks/main.yml @@ -16,7 +16,7 @@ vars: debian_installer_distro: "{{ install_distro }}" debian_installer_codename: "{{ install_codename }}" - debian_installer_arch: "{{ install.arch | default('amd64') }}" + debian_installer_arch: "{{ install_cooked.arch | default('amd64') }}" debian_installer_variant: netboot import_role: role: installer/debian/fetch diff --git a/roles/installer/ubuntu/iso/defaults/main.yml b/roles/installer/ubuntu/iso/defaults/main.yml new file mode 100644 index 00000000..cf498757 --- /dev/null +++ b/roles/installer/ubuntu/iso/defaults/main.yml @@ -0,0 +1,5 @@ +--- +ubuntu_installer_iso_variant: live-server +# ubuntu_installer_iso_variant: desktop + +iso_install_target_dir: "{{ global_artifacts_dir }}/{{ inventory_hostname }}/ubuntu-installer" diff --git a/roles/installer/ubuntu/iso/tasks/main.yml b/roles/installer/ubuntu/iso/tasks/main.yml new file mode 100644 index 00000000..ecfc2265 --- /dev/null +++ b/roles/installer/ubuntu/iso/tasks/main.yml @@ -0,0 +1,55 @@ +--- +- name: download installer + run_once: true + vars: + ubuntu_installer_codename: "{{ install_codename }}" + ubuntu_installer_arch: "{{ install_cooked.arch | default('amd64') }}" + ubuntu_installer_variant: "{{ ubuntu_installer_iso_variant }}" + import_role: + role: installer/ubuntu/fetch + +- block: + - name: create temporary workdir + tempfile: + prefix: "iso-install.{{ inventory_hostname }}." + state: directory + register: tmpdir + + - name: generate autoinstall files + vars: + ubuntu_autoinstall_tmpdir: "{{ tmpdir.path }}" + import_role: + name: installer/ubuntu/autoinstall + + - name: generate isolinux configuration for BIOS boot + template: + src: isolinux.cfg.j2 + dest: "{{ tmpdir.path }}/isolinux.cfg" + + - name: generate grub configuration for UEFI boot + template: + src: grub.cfg.j2 + dest: "{{ tmpdir.path }}/grub.cfg" + + + - name: create destination directory + file: + path: "{{ iso_install_target_dir }}" + state: directory + + - name: make sure target image does not exist + file: + path: "{{ iso_install_target_dir }}/{{ inventory_hostname }}.iso" + state: absent + + - name: generate target iso image + command: xorriso -indev "{{ ubuntu_installer_target_dir }}/{{ ubuntu_installer_filename }}" -outdev "{{ iso_install_target_dir }}/{{ inventory_hostname }}.iso" -pathspecs on -boot_image any replay -update isolinux.cfg /isolinux/isolinux.cfg -update grub.cfg /boot/grub/grub.cfg -add /autoinstall=autoinstall + args: + chdir: "{{ tmpdir.path }}" + + always: + - name: cleanup temporary workdir + when: tmpdir.path is defined + file: + path: "{{ tmpdir.path }}" + state: absent diff --git a/roles/installer/ubuntu/iso/templates/grub.cfg.j2 b/roles/installer/ubuntu/iso/templates/grub.cfg.j2 new file mode 100644 index 00000000..6ba4e6be --- /dev/null +++ b/roles/installer/ubuntu/iso/templates/grub.cfg.j2 @@ -0,0 +1,18 @@ +if loadfont $prefix/font.pf2 ; then + set gfxmode=auto + insmod efi_gop + insmod efi_uga + insmod gfxterm + terminal_output gfxterm +fi + +set menu_color_normal=white/black +set menu_color_highlight=black/light-gray +set timeout=10 +set default=0 + +menuentry "automated installer for {{ inventory_hostname }}" { + set gfxpayload=keep + linux /casper/vmlinuz quiet autoinstall "ds=nocloud;s=/cdrom/autoinstall/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + initrd /casper/initrd +} diff --git a/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 b/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 new file mode 100644 index 00000000..68269dfc --- /dev/null +++ b/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 @@ -0,0 +1,15 @@ +DEFAULT {{ inventory_hostname }} +TIMEOUT 100 +PROMPT 1 +SAY ***************************************** +SAY ** +SAY ** Distro: {{ install_distro }} +SAY ** Codename: {{ install_codename }} +SAY ** +SAY ** will be booting automated installer for {{ inventory_hostname }} in 10s ... +SAY ** + +LABEL {{ inventory_hostname }} + KERNEL /casper/vmlinuz + INITRD /casper/initrd + APPEND quiet autoinstall ds=nocloud;s=/cdrom/autoinstall/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} -- cgit v1.2.3 From ed2ea315f6b48700373087e259223e5761069fac Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 30 Jun 2021 00:13:57 +0200 Subject: ubuntu installer: add support for software raid (WIP) --- .../debian/preseed/templates/partman_config.j2 | 4 +- .../installer/ubuntu/autoinstall/defaults/main.yml | 2 + .../autoinstall/templates/autoinstall.yml.j2 | 100 +++++++++++++++++++-- 3 files changed, 97 insertions(+), 9 deletions(-) (limited to 'roles') diff --git a/roles/installer/debian/preseed/templates/partman_config.j2 b/roles/installer/debian/preseed/templates/partman_config.j2 index 9f8c7dcd..39003864 100644 --- a/roles/installer/debian/preseed/templates/partman_config.j2 +++ b/roles/installer/debian/preseed/templates/partman_config.j2 @@ -48,14 +48,14 @@ d-i partman-auto/method string lvm d-i partman-auto/expert_recipe string \ ansible :: \ {% if (install_cooked.efi | default(false)) %} -{% set efi_esp_size_mb = (((preseed_efi_esp_size | default(preseed_efi_esp_size)) | human_to_bytes) / (1024*1024)) | int %} +{% set efi_esp_size_mb = ((preseed_efi_esp_size | human_to_bytes) / (1024*1024)) | int %} {{ efi_esp_size_mb }} {{ efi_esp_size_mb }} {{ efi_esp_size_mb }} fat16 \ $primary{ } $bootable{ } \ method{ efi } format{ } \ . \ {% endif %} {% if install_cooked.disks.primary == "software-raid" %} -{% set swraid_boot_size_mb = (((preseed_swraid_boot_size | default(preseed_swraid_boot_size)) | human_to_bytes) / (1024*1024)) | int %} +{% set swraid_boot_size_mb = ((preseed_swraid_boot_size | human_to_bytes) / (1024*1024)) | int %} {{ swraid_boot_size_mb }} {{ swraid_boot_size_mb }} {{ swraid_boot_size_mb }} raid \ $lvmignore{ } $primary{ } $bootable{ } \ method{ raid } \ diff --git a/roles/installer/ubuntu/autoinstall/defaults/main.yml b/roles/installer/ubuntu/autoinstall/defaults/main.yml index 1a4fd3ed..4af5a42d 100644 --- a/roles/installer/ubuntu/autoinstall/defaults/main.yml +++ b/roles/installer/ubuntu/autoinstall/defaults/main.yml @@ -11,7 +11,9 @@ ubuntu_autoinstall_timezone: Europe/Vienna # ubuntu_autoinstall_kernel_image: ubuntu_autoinstall_virtual_machine: no + ubuntu_autoinstall_efi_esp_size: 128M +ubuntu_autoinstall_swraid_boot_size: 256M ubuntu_autoinstall_system_lvm_size_default: all ubuntu_autoinstall_system_lvm_volumes_default: diff --git a/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 b/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 index 97b54b0a..52eb0d44 100644 --- a/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 +++ b/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 @@ -29,19 +29,35 @@ autoinstall: storage: config: +{% if install_cooked.disks.primary != "software-raid" %} - id: disk-primary type: disk path: {{ install_cooked.disks.primary }} -{% if install_cooked.efi | default(false) %} +{% if install_cooked.efi | default(false) %} ptable: gpt +{% else %} + ptable: msdos + grub_device: true +{% endif %} + wipe: superblock-recursive {% else %} +{% for raid_member in install_cooked.disks.raid.members %} + - id: raid-disk{{ loop.index }} + type: disk + path: {{ raid_member }} +{% if install_cooked.efi | default(false) %} + ptable: gpt +{% else %} ptable: msdos grub_device: true -{% endif %} +{% endif %} wipe: superblock-recursive +{% endfor %} +{% endif %} {% if install_cooked.efi | default(false) %} {% set part_offset = 1 %} +{% if install_cooked.disks.primary != "software-raid" %} - id: partition-esp type: partition device: disk-primary @@ -49,6 +65,25 @@ autoinstall: number: 1 size: {{ ubuntu_autoinstall_efi_esp_size | human_to_bytes }} grub_device: true +{% else %} +{% for raid_member in install_cooked.disks.raid.members %} + - id: raid-partition-esp{{ loop.index }} + type: partition + device: raid-disk{{ loop.index }} + flag: boot + number: 1 + size: {{ ubuntu_autoinstall_efi_esp_size | human_to_bytes }} + grub_device: true +{% endfor %} + - id: partition-esp + type: raid + raidlevel: {{ install_cooked.disks.raid.level }} + metadata: 0.90 + devices: +{% for raid_member in install_cooked.disks.raid.members %} + - raid-partition-esp{{ loop.index }} +{% endfor %} +{% endif %} - id: format-esp type: format volume: partition-esp @@ -61,25 +96,76 @@ autoinstall: {% else %} {% set part_offset = 0 %} +{% endif %} +{% if install_cooked.disks.primary == "software-raid" %} +{% for raid_member in install_cooked.disks.raid.members %} + - id: raid-partition-boot{{ loop.index }} + type: partition + device: raid-disk{{ loop.index }} + number: {{ part_offset + 1 }} + size: {{ ubuntu_autoinstall_swraid_boot_size | human_to_bytes }} +{% endfor %} + - id: partition-boot + type: raid + raidlevel: {{ install_cooked.disks.raid.level }} + devices: +{% for raid_member in install_cooked.disks.raid.members %} + - raid-partition-boot{{ loop.index }} +{% endfor %} + - id: format-boot + type: format + volume: partition-boot + fstype: ext4 + - id: mount-boot + type: mount + device: format-boot + path: /boot +{% set part_offset = part_offset + 1 %} {% endif %} {% set system_lvm_size = install_cooked.system_lvm.size | default(ubuntu_autoinstall_system_lvm_size_default) %} {% set system_lvm_volumes = install_cooked.system_lvm.volumes | default(ubuntu_autoinstall_system_lvm_volumes_default) %} +{% if install_cooked.disks.primary != "software-raid" %} - id: partition-lvm type: partition device: disk-primary flag: linux number: {{ part_offset + 1 }} -{% if system_lvm_size != 'all' %} +{% if system_lvm_size != 'all' %} size: {{ system_lvm_size | human_to_bytes }} - id: partition-unused type: partition device: disk-primary flag: linux number: {{ part_offset + 2 }} -{% endif %} +{% endif %} size: -1 +{% else %} +{% for raid_member in install_cooked.disks.raid.members %} + - id: raid-partition-lvm{{ loop.index }} + type: partition + device: raid-disk{{ loop.index }} + number: {{ part_offset + 1 }} +{% if system_lvm_size != 'all' %} + size: {{ system_lvm_size | human_to_bytes }} + - id: raid-partition-unused{{ loop.index }} + type: partition + device: raid-disk{{ loop.index }} + flag: linux + number: {{ part_offset + 2 }} +{% endif %} + size: -1 +{% endfor %} + - id: partition-lvm + type: raid + raidlevel: {{ install_cooked.disks.raid.level }} + devices: +{% for raid_member in install_cooked.disks.raid.members %} + - raid-partition-lvm{{ loop.index }} +{% endfor %} + +{% endif %} - id: lvm-vg-system type: lvm_volgroup devices: @@ -146,9 +232,9 @@ autoinstall: - curtin in-target --target=/target -- sed -e 's/^\(\s*#*\s*Port.*\)/Port {{ ansible_port }}/' -i /etc/ssh/sshd_config {% endif %} - curtin in-target --target=/target -- apt-mark manual iputils-ping isc-dhcp-client netcat-openbsd netplan.io sudo - - curtin in-target --target=/target -- apt-get -y -q purge policykit-1 multipath-tools ubuntu-minimal unattended-upgrades sound-theme-freedesktop thin-provisioning-tools cryptsetup mdadm byobu open-iscsi btrfs-progs pollinate lxd-agent-loader -{% if not ubuntu_autoinstall_virtual_machine %} - - curtin in-target --target=/target -- apt-get -y -q purge open-vm-tools + - curtin in-target --target=/target -- apt-get -y -q purge policykit-1 multipath-tools ubuntu-minimal unattended-upgrades sound-theme-freedesktop thin-provisioning-tools cryptsetup byobu open-iscsi btrfs-progs pollinate lxd-agent-loader open-vm-tools +{% if install_cooked.disks.primary != "software-raid" %} + - curtin in-target --target=/target -- apt-get -y -q purge mdadm {% endif %} - curtin in-target --target=/target -- env SUDO_FORCE_REMOVE=yes apt-get -y -q purge sudo - curtin in-target --target=/target -- apt-get -y -q autoremove -- cgit v1.2.3 From f8a7983a5fa4f6f1e583838ec0de82af08bbe340 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 30 Jun 2021 20:07:53 +0200 Subject: fix some issues with ubuntu autoinstall and add preliminary ubuntu/usb installer role --- common/iso-generate.yml | 6 ++- common/usb-generate.yml | 9 ++-- roles/installer/debian/usb/tasks/main.yml | 4 +- .../autoinstall/templates/autoinstall.yml.j2 | 33 ++++++++------- roles/installer/ubuntu/usb/defaults/main.yml | 3 ++ roles/installer/ubuntu/usb/tasks/main.yml | 48 ++++++++++++++++++++++ roles/installer/ubuntu/usb/templates/grub.cfg.j2 | 18 ++++++++ .../installer/ubuntu/usb/templates/isolinux.cfg.j2 | 15 +++++++ 8 files changed, 113 insertions(+), 23 deletions(-) create mode 100644 roles/installer/ubuntu/usb/defaults/main.yml create mode 100644 roles/installer/ubuntu/usb/tasks/main.yml create mode 100644 roles/installer/ubuntu/usb/templates/grub.cfg.j2 create mode 100644 roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 (limited to 'roles') diff --git a/common/iso-generate.yml b/common/iso-generate.yml index 504d91ae..78047e13 100644 --- a/common/iso-generate.yml +++ b/common/iso-generate.yml @@ -3,7 +3,9 @@ hosts: "{{ install_hostnames }}" connection: local gather_facts: no + vars: + installer_variant: debian roles: - - role: installer/debian/iso - installer_base_path: "{{ global_cache_dir }}/debian-installer" + - role: "installer/{{ installer_variant }}/iso" + installer_base_path: "{{ global_cache_dir }}/{{ installer_variant }}-installer" installer_keyrings_path: "{{ global_files_dir }}/common/keyrings" diff --git a/common/usb-generate.yml b/common/usb-generate.yml index 30b0f190..7031839c 100644 --- a/common/usb-generate.yml +++ b/common/usb-generate.yml @@ -3,12 +3,13 @@ hosts: "{{ install_hostnames }}" connection: local gather_facts: no + vars: + installer_variant: debian vars_prompt: - name: usb_install_path - prompt: Where is the USB installation medium mounted to? + prompt: "Path to the the USB installation mountpoint or device" private: no - roles: - - role: installer/debian/usb - installer_base_path: "{{ global_cache_dir }}/debian-installer" + - role: "installer/{{ installer_variant }}/usb" + installer_base_path: "{{ global_cache_dir }}/{{ installer_variant }}-installer" installer_keyrings_path: "{{ global_files_dir }}/common/keyrings" diff --git a/roles/installer/debian/usb/tasks/main.yml b/roles/installer/debian/usb/tasks/main.yml index 88da49c8..acc003a2 100644 --- a/roles/installer/debian/usb/tasks/main.yml +++ b/roles/installer/debian/usb/tasks/main.yml @@ -8,8 +8,8 @@ - name: fail if usb drive mountpoint does not exist run_once: true assert: - that: usb_install_mountpoint.stat.exists - msg: the path to the usb drive does not exist + that: usb_install_mountpoint.stat.exists and usb_install_mountpoint.stat.isdir + msg: the path to the usb drive does not exist or is not a directory - name: download installer run_once: true diff --git a/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 b/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 index 52eb0d44..e166a78f 100644 --- a/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 +++ b/roles/installer/ubuntu/autoinstall/templates/autoinstall.yml.j2 @@ -65,34 +65,35 @@ autoinstall: number: 1 size: {{ ubuntu_autoinstall_efi_esp_size | human_to_bytes }} grub_device: true + - id: format-esp + type: format + volume: partition-esp + label: efi + fstype: fat32 + - id: mount-esp + type: mount + device: format-esp + path: /boot/efi {% else %} {% for raid_member in install_cooked.disks.raid.members %} - - id: raid-partition-esp{{ loop.index }} + - id: partition-esp{{ loop.index }} type: partition device: raid-disk{{ loop.index }} flag: boot number: 1 size: {{ ubuntu_autoinstall_efi_esp_size | human_to_bytes }} grub_device: true -{% endfor %} - - id: partition-esp - type: raid - raidlevel: {{ install_cooked.disks.raid.level }} - metadata: 0.90 - devices: -{% for raid_member in install_cooked.disks.raid.members %} - - raid-partition-esp{{ loop.index }} -{% endfor %} -{% endif %} - - id: format-esp + - id: format-esp{{ loop.index }} type: format - volume: partition-esp + volume: partition-esp{{ loop.index }} label: efi fstype: fat32 - - id: mount-esp + - id: mount-esp{{ loop.index }} type: mount - device: format-esp + device: format-esp{{ loop.index }} path: /boot/efi +{% endfor %} +{% endif %} {% else %} {% set part_offset = 0 %} @@ -107,6 +108,7 @@ autoinstall: {% endfor %} - id: partition-boot type: raid + name: md-boot raidlevel: {{ install_cooked.disks.raid.level }} devices: {% for raid_member in install_cooked.disks.raid.members %} @@ -159,6 +161,7 @@ autoinstall: {% endfor %} - id: partition-lvm type: raid + name: md-lvm raidlevel: {{ install_cooked.disks.raid.level }} devices: {% for raid_member in install_cooked.disks.raid.members %} diff --git a/roles/installer/ubuntu/usb/defaults/main.yml b/roles/installer/ubuntu/usb/defaults/main.yml new file mode 100644 index 00000000..8afdb9f0 --- /dev/null +++ b/roles/installer/ubuntu/usb/defaults/main.yml @@ -0,0 +1,3 @@ +--- +### path to the unmounted usb drive (/dev/...) +# installer_ubuntu_usb_devicepath diff --git a/roles/installer/ubuntu/usb/tasks/main.yml b/roles/installer/ubuntu/usb/tasks/main.yml new file mode 100644 index 00000000..26df154d --- /dev/null +++ b/roles/installer/ubuntu/usb/tasks/main.yml @@ -0,0 +1,48 @@ +--- +- name: check if usb drive device exists + run_once: true + stat: + path: "{{ usb_install_path }}" + register: usb_install_device + +- name: fail if usb drive path is not a device + run_once: true + assert: + that: usb_install_device.stat.exists and usb_install_device.stat.isblk + msg: the path to the usb drive does not exist or is not a block device + +- block: + - name: create temporary workdir + tempfile: + prefix: "usb-install.{{ inventory_hostname }}." + state: directory + register: tmpdir + + - name: generate autoinstall files + vars: + ubuntu_autoinstall_tmpdir: "{{ tmpdir.path }}" + import_role: + name: installer/ubuntu/autoinstall + + - name: generate isolinux configuration for BIOS boot + template: + src: isolinux.cfg.j2 + dest: "{{ tmpdir.path }}/isolinux.cfg" + + - name: generate grub configuration for UEFI boot + template: + src: grub.cfg.j2 + dest: "{{ tmpdir.path }}/grub.cfg" + + - name: update iso9660 filesystem on installer usb drive + become: yes + command: xorriso -dev "stdio:{{ usb_install_path }}" -pathspecs on -boot_image any replay -update isolinux.cfg /isolinux/isolinux.cfg -update grub.cfg /boot/grub/grub.cfg -find / -disk_name autoinstall -type d -exec rm_r -- -add /autoinstall=autoinstall + args: + chdir: "{{ tmpdir.path }}" + + always: + - name: cleanup temporary workdir + when: tmpdir.path is defined + file: + path: "{{ tmpdir.path }}" + state: absent diff --git a/roles/installer/ubuntu/usb/templates/grub.cfg.j2 b/roles/installer/ubuntu/usb/templates/grub.cfg.j2 new file mode 100644 index 00000000..6ba4e6be --- /dev/null +++ b/roles/installer/ubuntu/usb/templates/grub.cfg.j2 @@ -0,0 +1,18 @@ +if loadfont $prefix/font.pf2 ; then + set gfxmode=auto + insmod efi_gop + insmod efi_uga + insmod gfxterm + terminal_output gfxterm +fi + +set menu_color_normal=white/black +set menu_color_highlight=black/light-gray +set timeout=10 +set default=0 + +menuentry "automated installer for {{ inventory_hostname }}" { + set gfxpayload=keep + linux /casper/vmlinuz quiet autoinstall "ds=nocloud;s=/cdrom/autoinstall/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + initrd /casper/initrd +} diff --git a/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 b/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 new file mode 100644 index 00000000..68269dfc --- /dev/null +++ b/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 @@ -0,0 +1,15 @@ +DEFAULT {{ inventory_hostname }} +TIMEOUT 100 +PROMPT 1 +SAY ***************************************** +SAY ** +SAY ** Distro: {{ install_distro }} +SAY ** Codename: {{ install_codename }} +SAY ** +SAY ** will be booting automated installer for {{ inventory_hostname }} in 10s ... +SAY ** + +LABEL {{ inventory_hostname }} + KERNEL /casper/vmlinuz + INITRD /casper/initrd + APPEND quiet autoinstall ds=nocloud;s=/cdrom/autoinstall/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} -- cgit v1.2.3 From 9936c3c9053c470bfa09de300ba46359906c84b3 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Wed, 30 Jun 2021 21:52:28 +0200 Subject: fix reusability of subiquity based usb installer --- roles/installer/ubuntu/usb/templates/grub.cfg.j2 | 2 +- roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'roles') diff --git a/roles/installer/ubuntu/usb/templates/grub.cfg.j2 b/roles/installer/ubuntu/usb/templates/grub.cfg.j2 index 6ba4e6be..a9a1761c 100644 --- a/roles/installer/ubuntu/usb/templates/grub.cfg.j2 +++ b/roles/installer/ubuntu/usb/templates/grub.cfg.j2 @@ -13,6 +13,6 @@ set default=0 menuentry "automated installer for {{ inventory_hostname }}" { set gfxpayload=keep - linux /casper/vmlinuz quiet autoinstall "ds=nocloud;s=/cdrom/autoinstall/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + linux /casper/vmlinuz quiet nopersistent autoinstall "ds=nocloud;s=/cdrom/autoinstall/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} initrd /casper/initrd } diff --git a/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 b/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 index 68269dfc..4c84dd45 100644 --- a/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 +++ b/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 @@ -12,4 +12,4 @@ SAY ** LABEL {{ inventory_hostname }} KERNEL /casper/vmlinuz INITRD /casper/initrd - APPEND quiet autoinstall ds=nocloud;s=/cdrom/autoinstall/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + APPEND quiet nopersistent autoinstall ds=nocloud;s=/cdrom/autoinstall/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} -- cgit v1.2.3 From 8ef2f52313f5affce1614c9eee27d6466fc6f46d Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 1 Jul 2021 01:21:02 +0200 Subject: ubuntu usb installer can now install multiple hosts from same drive --- roles/installer/ubuntu/autoinstall/tasks/main.yml | 7 ++++--- roles/installer/ubuntu/iso/templates/grub.cfg.j2 | 2 +- .../installer/ubuntu/iso/templates/isolinux.cfg.j2 | 2 +- roles/installer/ubuntu/usb/defaults/main.yml | 3 +++ roles/installer/ubuntu/usb/tasks/main.yml | 23 ++++++++++++++++++++++ roles/installer/ubuntu/usb/templates/grub.cfg.j2 | 8 ++++++-- .../installer/ubuntu/usb/templates/isolinux.cfg.j2 | 14 +++++++++++-- 7 files changed, 50 insertions(+), 9 deletions(-) (limited to 'roles') diff --git a/roles/installer/ubuntu/autoinstall/tasks/main.yml b/roles/installer/ubuntu/autoinstall/tasks/main.yml index 4a3034d0..a7ea67ba 100644 --- a/roles/installer/ubuntu/autoinstall/tasks/main.yml +++ b/roles/installer/ubuntu/autoinstall/tasks/main.yml @@ -1,15 +1,16 @@ --- - name: create autoinstall sub-directory file: - path: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall" + path: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/{{ inventory_hostname }}" state: directory - name: create empty meta-data file copy: content: "" - dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/meta-data" + dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/{{ inventory_hostname }}/meta-data" - name: copy early-command script + run_once: yes copy: src: early-command.py dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/early-command.py" @@ -17,4 +18,4 @@ - name: generate autoinstall.yml as user-data template: src: autoinstall.yml.j2 - dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/user-data" + dest: "{{ ubuntu_autoinstall_tmpdir }}/autoinstall/{{ inventory_hostname }}/user-data" diff --git a/roles/installer/ubuntu/iso/templates/grub.cfg.j2 b/roles/installer/ubuntu/iso/templates/grub.cfg.j2 index 6ba4e6be..0b598c2e 100644 --- a/roles/installer/ubuntu/iso/templates/grub.cfg.j2 +++ b/roles/installer/ubuntu/iso/templates/grub.cfg.j2 @@ -13,6 +13,6 @@ set default=0 menuentry "automated installer for {{ inventory_hostname }}" { set gfxpayload=keep - linux /casper/vmlinuz quiet autoinstall "ds=nocloud;s=/cdrom/autoinstall/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + linux /casper/vmlinuz quiet autoinstall "ds=nocloud;s=/cdrom/autoinstall/{{ inventory_hostname }}/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} initrd /casper/initrd } diff --git a/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 b/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 index 68269dfc..ac94ac00 100644 --- a/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 +++ b/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 @@ -12,4 +12,4 @@ SAY ** LABEL {{ inventory_hostname }} KERNEL /casper/vmlinuz INITRD /casper/initrd - APPEND quiet autoinstall ds=nocloud;s=/cdrom/autoinstall/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + APPEND quiet autoinstall ds=nocloud;s=/cdrom/autoinstall/{{ inventory_hostname }}/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} diff --git a/roles/installer/ubuntu/usb/defaults/main.yml b/roles/installer/ubuntu/usb/defaults/main.yml index 8afdb9f0..5467946d 100644 --- a/roles/installer/ubuntu/usb/defaults/main.yml +++ b/roles/installer/ubuntu/usb/defaults/main.yml @@ -1,3 +1,6 @@ --- +ubuntu_installer_usb_variant: live-server +# ubuntu_installer_usb_variant: desktop + ### path to the unmounted usb drive (/dev/...) # installer_ubuntu_usb_devicepath diff --git a/roles/installer/ubuntu/usb/tasks/main.yml b/roles/installer/ubuntu/usb/tasks/main.yml index 26df154d..c29fe2f8 100644 --- a/roles/installer/ubuntu/usb/tasks/main.yml +++ b/roles/installer/ubuntu/usb/tasks/main.yml @@ -11,8 +11,27 @@ that: usb_install_device.stat.exists and usb_install_device.stat.isblk msg: the path to the usb drive does not exist or is not a block device +- name: download installer + run_once: true + vars: + ubuntu_installer_codename: "{{ install_codename }}" + ubuntu_installer_arch: "{{ install_cooked.arch | default('amd64') }}" + ubuntu_installer_variant: "{{ ubuntu_installer_usb_variant }}" + import_role: + role: installer/ubuntu/fetch + +- name: write ISO image to usb stick + pause: + prompt: | + Please write the image to the USB drive using something like this: + + $ sudo ddrescue {{ ubuntu_installer_target_dir }}/{{ ubuntu_installer_filename }} {{ usb_install_path }} -D --force + + This will NOT be done automatically. + - block: - name: create temporary workdir + run_once: true tempfile: prefix: "usb-install.{{ inventory_hostname }}." state: directory @@ -25,16 +44,19 @@ name: installer/ubuntu/autoinstall - name: generate isolinux configuration for BIOS boot + run_once: true template: src: isolinux.cfg.j2 dest: "{{ tmpdir.path }}/isolinux.cfg" - name: generate grub configuration for UEFI boot + run_once: true template: src: grub.cfg.j2 dest: "{{ tmpdir.path }}/grub.cfg" - name: update iso9660 filesystem on installer usb drive + run_once: true become: yes command: xorriso -dev "stdio:{{ usb_install_path }}" -pathspecs on -boot_image any replay -update isolinux.cfg /isolinux/isolinux.cfg -update grub.cfg /boot/grub/grub.cfg -find / -disk_name autoinstall -type d -exec rm_r -- -add /autoinstall=autoinstall args: @@ -42,6 +64,7 @@ always: - name: cleanup temporary workdir + run_once: true when: tmpdir.path is defined file: path: "{{ tmpdir.path }}" diff --git a/roles/installer/ubuntu/usb/templates/grub.cfg.j2 b/roles/installer/ubuntu/usb/templates/grub.cfg.j2 index a9a1761c..1f97113a 100644 --- a/roles/installer/ubuntu/usb/templates/grub.cfg.j2 +++ b/roles/installer/ubuntu/usb/templates/grub.cfg.j2 @@ -8,11 +8,15 @@ fi set menu_color_normal=white/black set menu_color_highlight=black/light-gray +{% if (ansible_play_hosts_all | length) == 1 %} set timeout=10 set default=0 +{% endif %} +{% for host in ansible_play_hosts_all %} -menuentry "automated installer for {{ inventory_hostname }}" { +menuentry "automated installer for {{ host }}" { set gfxpayload=keep - linux /casper/vmlinuz quiet nopersistent autoinstall "ds=nocloud;s=/cdrom/autoinstall/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + linux /casper/vmlinuz quiet nopersistent autoinstall "ds=nocloud;s=/cdrom/autoinstall/{{ host }}/" {{ (hostvars[host].install_cooked.kernel_cmdline | default([])) | join(' ') }} initrd /casper/initrd } +{% endfor %} diff --git a/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 b/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 index 4c84dd45..8360c057 100644 --- a/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 +++ b/roles/installer/ubuntu/usb/templates/isolinux.cfg.j2 @@ -1,3 +1,4 @@ +{% if (ansible_play_hosts_all | length) == 1 %} DEFAULT {{ inventory_hostname }} TIMEOUT 100 PROMPT 1 @@ -8,8 +9,17 @@ SAY ** Codename: {{ install_codename }} SAY ** SAY ** will be booting automated installer for {{ inventory_hostname }} in 10s ... SAY ** +{% else %} +DEFAULT menu.c32 +TIMEOUT 0 +PROMPT 0 +MENU TITLE {{ install_distro }} / {{ install_codename }} +{% endif %} +{% for host in ansible_play_hosts_all %} -LABEL {{ inventory_hostname }} +LABEL {{ host }} + MENU LABEL automatic installer for {{ host }} KERNEL /casper/vmlinuz INITRD /casper/initrd - APPEND quiet nopersistent autoinstall ds=nocloud;s=/cdrom/autoinstall/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + APPEND quiet nopersistent autoinstall ds=nocloud;s=/cdrom/autoinstall/{{ host }}/ {{ (hostvars[host].install_cooked.kernel_cmdline | default([])) | join(' ') }} +{% endfor %} -- cgit v1.2.3 From 1834f5bd9e3aeb6787475e3705146aec238014e7 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 1 Jul 2021 11:12:50 +0200 Subject: use nopersistent kernel command line at ubunut/iso installer as well --- roles/installer/ubuntu/iso/templates/grub.cfg.j2 | 2 +- roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'roles') diff --git a/roles/installer/ubuntu/iso/templates/grub.cfg.j2 b/roles/installer/ubuntu/iso/templates/grub.cfg.j2 index 0b598c2e..f49d7f40 100644 --- a/roles/installer/ubuntu/iso/templates/grub.cfg.j2 +++ b/roles/installer/ubuntu/iso/templates/grub.cfg.j2 @@ -13,6 +13,6 @@ set default=0 menuentry "automated installer for {{ inventory_hostname }}" { set gfxpayload=keep - linux /casper/vmlinuz quiet autoinstall "ds=nocloud;s=/cdrom/autoinstall/{{ inventory_hostname }}/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + linux /casper/vmlinuz quiet nopersistent autoinstall "ds=nocloud;s=/cdrom/autoinstall/{{ inventory_hostname }}/" {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} initrd /casper/initrd } diff --git a/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 b/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 index ac94ac00..99401b8b 100644 --- a/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 +++ b/roles/installer/ubuntu/iso/templates/isolinux.cfg.j2 @@ -12,4 +12,4 @@ SAY ** LABEL {{ inventory_hostname }} KERNEL /casper/vmlinuz INITRD /casper/initrd - APPEND quiet autoinstall ds=nocloud;s=/cdrom/autoinstall/{{ inventory_hostname }}/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} + APPEND quiet nopersistent autoinstall ds=nocloud;s=/cdrom/autoinstall/{{ inventory_hostname }}/ {{ (install_cooked.kernel_cmdline | default([])) | join(' ') }} -- cgit v1.2.3 From c05e1ca70925e9e68788718f05fca0f13a13bb44 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 1 Jul 2021 13:23:12 +0200 Subject: make new ubuntu-installer selectable by (usb|iso)-install.yml playbooks --- common/iso-install.yml | 21 ++++++++++++--------- common/usb-install.yml | 24 +++++++++++++----------- roles/installer/ubuntu/usb/tasks/main.yml | 2 +- 3 files changed, 26 insertions(+), 21 deletions(-) (limited to 'roles') diff --git a/common/iso-install.yml b/common/iso-install.yml index ea132d4e..810761d2 100644 --- a/common/iso-install.yml +++ b/common/iso-install.yml @@ -1,26 +1,23 @@ --- -- name: preparations and sanity checks +- name: preparations, sanity checks and basic installation hosts: "{{ install_hostname }}" connection: local gather_facts: no + vars: + installer_variant: debian roles: - - role: installer/debian/iso - installer_base_path: "{{ global_cache_dir }}/debian-installer" + - role: "installer/{{ installer_variant }}/iso" + installer_base_path: "{{ global_cache_dir }}/{{ installer_variant }}-installer" installer_keyrings_path: "{{ global_files_dir }}/common/keyrings" post_tasks: - set_fact: iso_install_image_path: "{{ iso_install_target_dir }}/{{ install_hostname }}.iso" - -- name: basic installation - hosts: "{{ install_hostname }}" - gather_facts: no - tasks: - pause: prompt: | The generated image can be found at: - {{ iso_install_image_path }} + {{ iso_install_image_path | realpath }} Please load the image into the machine and boot from it. {% if install_distro == "debian" and install_cooked.efi is defined and install_cooked.efi %} @@ -33,6 +30,12 @@ {% endif %} Once the installation is done press ENTER to continue or CTRL-C then A to abort. + {% if installer_variant == 'ubuntu' %} + + Hint: You are using the ubuntu installer, this means the final system initialization and + cleanup is done by cloud-init on first boot. These steps need to be finished before the + playbook can continue. + {% endif %} - name: wait for new machine to start up, apply early roles and reboot diff --git a/common/usb-install.yml b/common/usb-install.yml index 81fe239a..a7bbe012 100644 --- a/common/usb-install.yml +++ b/common/usb-install.yml @@ -1,28 +1,30 @@ --- -- name: preparations and sanity checks +- name: preparations, sanity checks and basic installation hosts: "{{ install_hostname }}" connection: local gather_facts: no + vars: + installer_variant: debian vars_prompt: - name: usb_install_path - prompt: Where is the USB installation medium mounted to? + prompt: "Path to the the USB installation mountpoint or device" private: no - roles: - - role: installer/debian/usb - installer_base_path: "{{ global_cache_dir }}/debian-installer" + - role: "installer/{{ installer_variant }}/usb" + installer_base_path: "{{ global_cache_dir }}/{{ installer_variant }}-installer" installer_keyrings_path: "{{ global_files_dir }}/common/keyrings" - - -- name: basic installation - hosts: "{{ install_hostname }}" - gather_facts: no - tasks: + post_tasks: - pause: prompt: | Please unmount the USB the stick, plug it into the machine and boot from it. Once the installation is done press ENTER to continue or CTRL-C then A to abort. + {% if installer_variant == 'ubuntu' %} + + Hint: You are using the ubuntu installer, this means the final system initialization and + cleanup is done by cloud-init on first boot. These steps need to be finished before the + playbook can continue. + {% endif %} - name: wait for new machine to start up, apply early roles and reboot diff --git a/roles/installer/ubuntu/usb/tasks/main.yml b/roles/installer/ubuntu/usb/tasks/main.yml index c29fe2f8..c7eb9e41 100644 --- a/roles/installer/ubuntu/usb/tasks/main.yml +++ b/roles/installer/ubuntu/usb/tasks/main.yml @@ -25,7 +25,7 @@ prompt: | Please write the image to the USB drive using something like this: - $ sudo ddrescue {{ ubuntu_installer_target_dir }}/{{ ubuntu_installer_filename }} {{ usb_install_path }} -D --force + $ sudo ddrescue {{ (ubuntu_installer_target_dir, ubuntu_installer_filename) | path_join | realpath }} {{ usb_install_path }} -D --force This will NOT be done automatically. -- cgit v1.2.3 From 833c613e4083384e9395e7ce4ec910b09cf1e2fe Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Thu, 1 Jul 2021 20:24:50 +0200 Subject: cosmetic changes --- roles/installer/debian/usb/tasks/main.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'roles') diff --git a/roles/installer/debian/usb/tasks/main.yml b/roles/installer/debian/usb/tasks/main.yml index acc003a2..62bfced7 100644 --- a/roles/installer/debian/usb/tasks/main.yml +++ b/roles/installer/debian/usb/tasks/main.yml @@ -109,12 +109,12 @@ $ sudo syslinux -i /dev/CHANGEME1 -d bios $ sudo fdisk /dev/CHANGEME [Here, make sure partition 1 is marked bootable.] - $ cp /usr/lib/syslinux/modules/bios/* {{ usb_install_path }}/bios/ + $ cp /usr/lib/syslinux/modules/bios/* {{ (usb_install_path, 'bios/') | path_join }} for UEFI these steps need to be done $ sudo apt install syslinux-efi - $ cp /usr/lib/syslinux/modules/efi64/* {{ usb_install_path }}/EFI/boot/ - $ cp /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi {{ usb_install_path }}/EFI/boot/bootx64.efi + $ cp /usr/lib/syslinux/modules/efi64/* {{ (usb_install_path, 'EFI/boot/') | path_join }} + $ cp /usr/lib/SYSLINUX.EFI/efi64/syslinux.efi {{ (usb_install_path, 'EFI/boot/bootx64.efi') | path_join }} This will NOT be done automatically. -- cgit v1.2.3