diff options
author | Christian Pointner <equinox@spreadspace.org> | 2022-01-04 14:39:23 +0100 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2022-01-04 14:39:23 +0100 |
commit | c3df634ef65332b68a509c4651a0eb8657642321 (patch) | |
tree | a8555a07e1490f15cbd0b09f03f2f0c9d956f135 | |
parent | sensor: i2c bus detection using regex for name (diff) | |
parent | add some todo docs (diff) |
Merge branch 'topic/openwrt-vm'
-rw-r--r-- | ansible.cfg | 1 | ||||
-rw-r--r-- | chaos-at-home/image-generate.yml | 13 | ||||
-rw-r--r-- | chaos-at-home/vm-deploy.yml | 18 | ||||
-rw-r--r-- | common/vm-deploy.yml | 30 | ||||
-rw-r--r-- | dan/image-generate.yml | 13 | ||||
-rw-r--r-- | dan/vm-deploy.yml | 18 | ||||
-rwxr-xr-x | deploy.sh | 35 | ||||
-rw-r--r-- | inventory/group_vars/chaos-at-home/network.yml | 1 | ||||
-rw-r--r-- | inventory/host_vars/ch-testvm-openwrt.yml | 108 | ||||
-rw-r--r-- | inventory/hosts.ini | 2 | ||||
-rw-r--r-- | library/wait_for_virt.py (renamed from roles/vm/guest/install/library/wait_for_virt.py) | 0 | ||||
-rw-r--r-- | roles/openwrt/image/tasks/main.yml | 5 | ||||
-rw-r--r-- | roles/vm/guest/define/templates/libvirt-domain.xml.j2 | 4 | ||||
-rw-r--r-- | roles/vm/guest/deploy/defaults/main.yml | 7 | ||||
-rw-r--r-- | roles/vm/guest/deploy/tasks/main.yml | 27 | ||||
-rw-r--r-- | roles/vm/guest/install/tasks/main.yml | 2 | ||||
-rw-r--r-- | spreadspace/image-generate.yml | 13 | ||||
-rw-r--r-- | spreadspace/vm-deploy.yml | 18 | ||||
l--------- | vm-deploy.sh | 1 |
19 files changed, 311 insertions, 5 deletions
diff --git a/ansible.cfg b/ansible.cfg index ef74d99c..e3b31768 100644 --- a/ansible.cfg +++ b/ansible.cfg @@ -7,6 +7,7 @@ log_path = ./log remote_tmp = /tmp/.ansible/tmp filter_plugins = ./filter_plugins +library = ./library gathering = smart fact_caching = jsonfile diff --git a/chaos-at-home/image-generate.yml b/chaos-at-home/image-generate.yml index a7d38149..4c2f5fb9 100644 --- a/chaos-at-home/image-generate.yml +++ b/chaos-at-home/image-generate.yml @@ -5,3 +5,16 @@ gather_facts: no roles: - role: "{{ install_distro }}/image" + post_tasks: + - pause: + seconds: 0 + prompt: | + The resulting images can be found here: + + {% for host in play_hosts %} + {{ host }}: + {% for image in hostvars[host].output_images %} + - {{ image }} + {% endfor %} + + {% endfor %} diff --git a/chaos-at-home/vm-deploy.yml b/chaos-at-home/vm-deploy.yml new file mode 100644 index 00000000..33268b6d --- /dev/null +++ b/chaos-at-home/vm-deploy.yml @@ -0,0 +1,18 @@ +--- +- name: generate os image + hosts: "{{ install_hostname }}" + connection: local + gather_facts: no + roles: + - role: "{{ install_distro }}/image" + +- name: cook variables for host + hosts: "{{ install_hostname }}" + gather_facts: no + tasks: + - set_fact: + install: "{{ install | default({}) }}" + network: "{{ network | default({}) }}" + vm_host: "{{ vm_host | default({}) }}" + +- import_playbook: ../common/vm-deploy.yml diff --git a/common/vm-deploy.yml b/common/vm-deploy.yml new file mode 100644 index 00000000..bc2e8039 --- /dev/null +++ b/common/vm-deploy.yml @@ -0,0 +1,30 @@ +--- +- name: preparations and sanity checks + hosts: "{{ install_hostname }}" + connection: local + gather_facts: no + tasks: + - name: check if the installee belongs to the kvmguests group + fail: + msg: "the host '{{ install_hostname }}' does not belong to the group 'kvmguests'" + when: + - "'kvmguests' not in group_names" + + - name: check if the host system belongs to the kvmhosts group + fail: + msg: "the host '{{ vm_host.name }}' does not belong to the group 'kvmhosts'" + when: + - "'kvmhosts' not in hostvars[vm_host.name].group_names" + + - name: check if there is only one output image + fail: + msg: "the output_images variable must only contain a single image" + when: + - (output_images | length) != 1 + + +- name: deploy vm + hosts: "{{ install_hostname }}" + gather_facts: no + roles: + - role: vm/guest/deploy diff --git a/dan/image-generate.yml b/dan/image-generate.yml index a7d38149..4c2f5fb9 100644 --- a/dan/image-generate.yml +++ b/dan/image-generate.yml @@ -5,3 +5,16 @@ gather_facts: no roles: - role: "{{ install_distro }}/image" + post_tasks: + - pause: + seconds: 0 + prompt: | + The resulting images can be found here: + + {% for host in play_hosts %} + {{ host }}: + {% for image in hostvars[host].output_images %} + - {{ image }} + {% endfor %} + + {% endfor %} diff --git a/dan/vm-deploy.yml b/dan/vm-deploy.yml new file mode 100644 index 00000000..33268b6d --- /dev/null +++ b/dan/vm-deploy.yml @@ -0,0 +1,18 @@ +--- +- name: generate os image + hosts: "{{ install_hostname }}" + connection: local + gather_facts: no + roles: + - role: "{{ install_distro }}/image" + +- name: cook variables for host + hosts: "{{ install_hostname }}" + gather_facts: no + tasks: + - set_fact: + install: "{{ install | default({}) }}" + network: "{{ network | default({}) }}" + vm_host: "{{ vm_host | default({}) }}" + +- import_playbook: ../common/vm-deploy.yml diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..c073283f --- /dev/null +++ b/deploy.sh @@ -0,0 +1,35 @@ +#!/bin/bash + +if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then + echo "$0 <hostname> <distro> <codename>" + exit 1 +fi +name=$1 +distro=$2 +codename=$3 +shift 3 + +cd "${BASH_SOURCE%/*}" +source common/utils.sh +ansible_variable__get env_group "$name" || exit 1 +vault_environment__set "$env_group" || exit 1 + +echo "deploying $name with $distro/$codename in environment '$env_group'" +echo "" + +echo "########## clearing old ssh host keys #########" +remove_known_hosts "$name" +echo "" + +echo "########## removing cached facts #########" +rm -f ".cache/facts/$name" +echo "" + +echo "######## running the deploy playbook for $name ########" +declare -a extra_vars +extra_vars+=(-e "install_hostname=$name") +extra_vars+=(-e "install_distro=$distro") +extra_vars+=(-e "install_codename=$codename") +extra_vars+=(-e "install_environment=$env_group") +ansible_variable__get install_playbook "$name" > /dev/null 2>&1 && extra_vars+=(-e "install_playbook=$install_playbook") +exec ansible-playbook ${extra_vars[@]} $@ "$env_group/$(basename "$0" .sh).yml" diff --git a/inventory/group_vars/chaos-at-home/network.yml b/inventory/group_vars/chaos-at-home/network.yml index 2832ec59..86ab6c7a 100644 --- a/inventory/group_vars/chaos-at-home/network.yml +++ b/inventory/group_vars/chaos-at-home/network.yml @@ -70,6 +70,7 @@ network_zones: ch-iot: 30 ch-testvm-prometheus: 42 ch-testvm-phoebe: 43 + ch-testvm-openwrt: 44 ch-nic: 53 __svc_http__: 80 __svc_imap__: 143 diff --git a/inventory/host_vars/ch-testvm-openwrt.yml b/inventory/host_vars/ch-testvm-openwrt.yml new file mode 100644 index 00000000..5a208b55 --- /dev/null +++ b/inventory/host_vars/ch-testvm-openwrt.yml @@ -0,0 +1,108 @@ +--- +install: + vm: + memory: 128M + numcpus: 2 + autostart: false + disks: + primary: /dev/sda + scsi: + sda: + type: image + path: /srv/nvme/ch-testvm-openwrt.img + interfaces: + - bridge: br-svc + name: svc0 + + +openwrt_arch: x86 +openwrt_target: 64 +openwrt_profile: generic +openwrt_output_image_suffixes: + - "{{ openwrt_profile }}-ext4-combined.img.gz" + +openwrt_packages_remove: + - ppp + - ppp-mod-pppoe + - dnsmasq + - firewall + - odhcpd + - odhcpd-ipv6only +openwrt_packages_add: + - rng-tools + - htop + - ip + - less + - nano + - tcpdump-mini + - iperf + - iperf3 + - mtr + +openwrt_mixin: + /etc/dropbear/authorized_keys: + content: "{{ ssh_keys_root | join('\n') }}\n" + + /etc/htoprc: + file: "{{ global_files_dir }}/common/htoprc" + + +openwrt_uci: + system: + - name: system + options: + hostname: '{{ host_name }}' + timezone: 'CET-1CEST,M3.5.0,M10.5.0/3' + ttylogin: '0' + log_size: '64' + urandom_seed: '0' + + - name: timeserver 'ntp' + options: + enabled: '1' + enable_server: '0' + server: + - '0.at.pool.ntp.org' + - '1.at.pool.ntp.org' + - '2.at.pool.ntp.org' + - '3.at.pool.ntp.org' + + - name: rngd + options: + enabled: '1' + device: '/dev/hwrng' + + dropbear: + - name: dropbear + options: + PasswordAuth: 'off' + RootPasswordAuth: 'off' + Port: '{{ ansible_port | default(22) }}' + + network: + - name: globals 'globals' + options: + ula_prefix: "fc{{ '%02x:%04x:%04x' | format((255 | random(seed=inventory_hostname + '0')), (65535 | random(seed=inventory_hostname + '1')), (65535 | random(seed=inventory_hostname + '2'))) }}::/48" + + - name: interface 'loopback' + options: + device: lo + proto: static + ipaddr: 127.0.0.1 + netmask: 255.0.0.0 + + - name: interface 'svc' + options: + device: eth0 + proto: static + ipaddr: "{{ network_zones.svc.prefix | ipaddr(network_zones.svc.offsets[inventory_hostname]) | ipaddr('address') }}" + netmask: "{{ network_zones.svc.prefix | ipaddr('netmask') }}" + gateway: "{{ network_zones.svc.gateway }}" + dns: "{{ network_zones.svc.dns }}" + + - name: route 'lan' + options: + interface: svc + target: "{{ network_zones.lan.prefix | ipaddr('network') }}" + netmask: "{{ network_zones.lan.prefix | ipaddr('netmask') }}" + gateway: "{{ network_zones.svc.prefix | ipaddr(network_zones.svc.offsets['ch-gw-lan']) | ipaddr('address') }}" diff --git a/inventory/hosts.ini b/inventory/hosts.ini index 346ddd49..bed5319e 100644 --- a/inventory/hosts.ini +++ b/inventory/hosts.ini @@ -16,6 +16,7 @@ env_group=chaos-at-home ch-gnocchi host_name=gnocchi ch-phoebe host_name=phoebe ch-testvm-phoebe host_name=testvm-phoebe +ch-testvm-openwrt host_name=testvm-openwrt ch-router host_name=router ch-router-obsd host_name=router ch-gw-lan host_name=gw-lan @@ -336,6 +337,7 @@ vmhost-ch-gnocchi-guests [vmhost-ch-phoebe-guests] ch-testvm-phoebe +ch-testvm-openwrt #ch-router ch-router-obsd #ch-jump diff --git a/roles/vm/guest/install/library/wait_for_virt.py b/library/wait_for_virt.py index 6c49fae1..6c49fae1 100644 --- a/roles/vm/guest/install/library/wait_for_virt.py +++ b/library/wait_for_virt.py diff --git a/roles/openwrt/image/tasks/main.yml b/roles/openwrt/image/tasks/main.yml index e019bf6f..62dcbc9d 100644 --- a/roles/openwrt/image/tasks/main.yml +++ b/roles/openwrt/image/tasks/main.yml @@ -35,10 +35,9 @@ src: "{{ openwrt_imgbuilder_dir }}/{{ openwrt_tarball_basename }}/bin/targets/{{ openwrt_arch }}/{{ openwrt_target }}/{{ openwrt_output_image_name_base }}-{{ item }}" dest: "{{ openwrt_output_dir }}" - ## TODO: make this less ugly.. - name: set output image names set_fact: - openwrt_output_images: "{{ '[\"' + openwrt_output_dir + '/' + openwrt_output_image_name_base + '-' + (openwrt_output_image_suffixes | join('\", \"' + openwrt_output_dir + '/' + openwrt_output_image_name_base + '-')) + '\"]' }}" + output_images: "{{ [(openwrt_output_dir, openwrt_output_image_name_base) | path_join | realpath] | product(openwrt_output_image_suffixes) | map('join', '-') }}" always: - name: save stdout build-log to output directory @@ -53,7 +52,7 @@ content: "{{ openwrt_build.stderr }}\n" dest: "{{ openwrt_output_dir }}/build-stderr.log" - - name: Delete the temporary build directory + - name: delete the temporary build directory when: not openwrt_keep_temporary_build_dir file: path: "{{ openwrt_imgbuilder_dir }}" diff --git a/roles/vm/guest/define/templates/libvirt-domain.xml.j2 b/roles/vm/guest/define/templates/libvirt-domain.xml.j2 index 0430229b..11b1be6e 100644 --- a/roles/vm/guest/define/templates/libvirt-domain.xml.j2 +++ b/roles/vm/guest/define/templates/libvirt-domain.xml.j2 @@ -56,7 +56,7 @@ {% endif %} {% for bus in ['virtio', 'scsi'] %} {% for device, src in (install.disks[bus] | default({})).items() %} - <disk type='block' device='disk'> + <disk type='{{ (src.type == 'image') | ternary('file', 'block') }}' device='disk'> <driver name='qemu' type='raw' cache='none' discard='unmap'/> {% if src.type == 'lvm' %} <source dev='/dev/mapper/{{ src.vg | replace('-', '--') }}-{{ src.lv | replace('-', '--') }}'/> @@ -64,6 +64,8 @@ <source dev='/dev/zvol/{{ vm_host.zfs[src.backend | default('default')].pool }}/{{ vm_host.zfs[src.backend | default('default')].name }}/{{ inventory_hostname }}/{{ src.name }}'/> {% elif src.type == 'blockdev' %} <source dev='{{ src.path }}'/> +{% elif src.type == 'image' %} + <source file='{{ src.path }}'/> {% endif %} <target dev='{{ device }}' bus='{{ bus }}'/> </disk> diff --git a/roles/vm/guest/deploy/defaults/main.yml b/roles/vm/guest/deploy/defaults/main.yml new file mode 100644 index 00000000..c067ecbc --- /dev/null +++ b/roles/vm/guest/deploy/defaults/main.yml @@ -0,0 +1,7 @@ +--- +vm_deploy_decompressors: + "application/octet-stream": cat + "application/gzip": gunzip + "application/zstd": unzstd + "application/x-bzip2": bunzip2 + "application/x-xz": unxz diff --git a/roles/vm/guest/deploy/tasks/main.yml b/roles/vm/guest/deploy/tasks/main.yml new file mode 100644 index 00000000..f22af8af --- /dev/null +++ b/roles/vm/guest/deploy/tasks/main.yml @@ -0,0 +1,27 @@ +--- +- name: fetch infos from image file + delegate_to: localhost + stat: + path: "{{ output_images | first }}" + get_mime: yes + register: output_image_info + + ## TODO: prepare directory for disk images + ## TODO: compute disk path based on install.disks.primary and install.disks.(scsi|virtio) + ## TODO: actually call this directly and make file replacement atomic!! + ## Probably by writing and action plugin based on this: https://github.com/socratesx/Ansible-Decompress +- name: copy disk image + pause: + prompt: | + Please copy the image to the vm-host i.e. by calling this: + + cat {{ output_image_info.stat.path }} | {{ vm_deploy_decompressors[output_image_info.stat.mimetype] }} | ssh {{ vm_host.name }} 'cat > {{ install.disks.scsi.sda.path }}' + + When done press ENTER to continue or CTRL-C then A to abort. + +- name: define vm + vars: + vm_define_installer: no + delegate_to: "{{ vm_host.name }}" + import_role: + name: vm/guest/define diff --git a/roles/vm/guest/install/tasks/main.yml b/roles/vm/guest/install/tasks/main.yml index f2bd5362..d4a31929 100644 --- a/roles/vm/guest/install/tasks/main.yml +++ b/roles/vm/guest/install/tasks/main.yml @@ -10,7 +10,7 @@ size: "{{ item.value.size }}" state: present -- name: create zfs base datasets for vm +- name: create zfs-based datasets for vm loop: "{{ install.disks.virtio | default({}) | combine(install.disks.scsi | default({})) | dict2items | selectattr('value.type', 'eq', 'zfs') | map(attribute='value.backend') | map('default', 'default') | unique | list }}" delegate_to: "{{ vm_host.name }}" zfs: diff --git a/spreadspace/image-generate.yml b/spreadspace/image-generate.yml index a7d38149..4c2f5fb9 100644 --- a/spreadspace/image-generate.yml +++ b/spreadspace/image-generate.yml @@ -5,3 +5,16 @@ gather_facts: no roles: - role: "{{ install_distro }}/image" + post_tasks: + - pause: + seconds: 0 + prompt: | + The resulting images can be found here: + + {% for host in play_hosts %} + {{ host }}: + {% for image in hostvars[host].output_images %} + - {{ image }} + {% endfor %} + + {% endfor %} diff --git a/spreadspace/vm-deploy.yml b/spreadspace/vm-deploy.yml new file mode 100644 index 00000000..33268b6d --- /dev/null +++ b/spreadspace/vm-deploy.yml @@ -0,0 +1,18 @@ +--- +- name: generate os image + hosts: "{{ install_hostname }}" + connection: local + gather_facts: no + roles: + - role: "{{ install_distro }}/image" + +- name: cook variables for host + hosts: "{{ install_hostname }}" + gather_facts: no + tasks: + - set_fact: + install: "{{ install | default({}) }}" + network: "{{ network | default({}) }}" + vm_host: "{{ vm_host | default({}) }}" + +- import_playbook: ../common/vm-deploy.yml diff --git a/vm-deploy.sh b/vm-deploy.sh new file mode 120000 index 00000000..91c11375 --- /dev/null +++ b/vm-deploy.sh @@ -0,0 +1 @@ +deploy.sh
\ No newline at end of file |