Merge pull request #20 from realraum/vm-improvements
authorChristian Pointner <equinox@spreadspace.org>
Sun, 17 Jun 2018 10:32:35 +0000 (12:32 +0200)
committerGitHub <noreply@github.com>
Sun, 17 Jun 2018 10:32:35 +0000 (12:32 +0200)
Improvements in VM handling

17 files changed:
ansible/host_playbooks/testvm.yml
ansible/hosts.ini
ansible/remove-known-host.sh [deleted file]
ansible/remove_known_hosts.sh [new file with mode: 0755]
ansible/remove_known_hosts.yml [new file with mode: 0644]
ansible/roles/base/tasks/main.yml
ansible/roles/localconfig/defaults/main.yml
ansible/roles/localconfig/templates/ssh/10r3.conf.j2
ansible/roles/vm/grub/tasks/main.yml
ansible/roles/vm/guest/tasks/main.yml
ansible/roles/vm/host/handlers/main.yml
ansible/roles/vm/host/tasks/main.yml
ansible/roles/vm/install/tasks/main.yml
ansible/roles/vm/install/templates/libvirt-domain.xml.j2
ansible/roles/vm/install/templates/preseed_debian-stretch.cfg.j2
ansible/vm-install.sh
ansible/vm-install.yml

index 58a4868..0ed84eb 100644 (file)
@@ -3,6 +3,3 @@
   hosts: testvm
   roles:
   - role: base
-  - role: vm/grub
-  - role: vm/network
-  - role: vm/guest
index d67f69e..c165125 100644 (file)
@@ -2,6 +2,8 @@
 host_domain=realraum.at
 ansible_host={{ inventory_hostname }}.{{ host_domain }}
 ansible_user=root
+ansible_port=22000
+
 
 [net-zone-mgmt]
 torwaechter
diff --git a/ansible/remove-known-host.sh b/ansible/remove-known-host.sh
deleted file mode 100755 (executable)
index 2c5fd7f..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-#!/bin/bash
-
-if [ -z "$1" ]; then
-  echo "$0 <host>"
-  exit 1
-fi
-
-SHORT="r3-${1%%.*}"
-SSH_HOST=$(ssh -G "$SHORT" | grep "^hostname " | awk '{ print($2) }' )
-
-for name in $SHORT $SSH_HOST; do
-  ssh-keygen -f "$HOME/.ssh/known_hosts" -R "[$name]:22000"
-done
-
-exit 0
diff --git a/ansible/remove_known_hosts.sh b/ansible/remove_known_hosts.sh
new file mode 100755 (executable)
index 0000000..ee4a0fb
--- /dev/null
@@ -0,0 +1,13 @@
+#!/bin/sh
+set -eu
+
+if [ $# -eq 0 ]; then
+    echo "Usage: $0 vmname [vmname ...]" >&2
+    exit 1
+fi
+
+cd "$(dirname "$0")"
+
+for vmname in "$@"; do
+    ansible-playbook -e vmname="${vmname}" remove_known_hosts.yml
+done
diff --git a/ansible/remove_known_hosts.yml b/ansible/remove_known_hosts.yml
new file mode 100644 (file)
index 0000000..5491342
--- /dev/null
@@ -0,0 +1,11 @@
+- name: Purge host from known hosts
+  hosts: localhost
+  gather_facts: no
+  tasks:
+    - command: ssh-keygen -f ~/.ssh/known_hosts -R [{{ item }}]:{{ hostvars[vmname].ansible_port }}
+      with_items:
+        - "{{ hostvars[vmname].ansible_host }}"
+        - r3-{{ vmname }}
+        - r3g-{{ vmname }}
+        - r3e-{{ vmname }}
+        - "{{ hostvars[vmname].vm_network_cooked.primary.ip }}"
index 92218ba..919b2aa 100644 (file)
     shell: /bin/zsh
 
 - name: set default shell for adduser
-  with_items:
-    - regexp: "^DSHELL"
-      line: "DSHELL=/bin/zsh"
+  with_dict:
+    DSHELL: /bin/zsh
   lineinfile:
     dest: /etc/adduser.conf
-    regexp: "{{ item.regexp }}"
-    line: "{{ item.line }}"
+    regexp: "^#?{{ item.key }}="
+    line: "{{ item.key }}={{ item.value }}"
index ae14b0c..285c37f 100644 (file)
@@ -10,4 +10,4 @@ localconfig_ssh_ids:
 ### to be set inhost_vars and group_vars
 # localconfig_ssh_config_proxycommand:
 # localconfig_ssh_config_user:
-# localconfig_ssh_config_port:
+# ansible_port
index e133de8..294af58 100644 (file)
@@ -13,8 +13,8 @@ Host {{ hostvars[host].ansible_host }} r3-{{ host }} r3g-{{ host }} r3e-{{ host
 {% if 'localconfig_ssh_config_user' in hostvars[host] %}
     User {{ hostvars[host].localconfig_ssh_config_user }}
 {% endif %}
-{% if 'localconfig_ssh_config_port' in hostvars[host] %}
-    Port {{ hostvars[host].localconfig_ssh_config_port }}
+{% if hostvars[host].ansible_port != 22000 %}
+    Port {{ hostvars[host].ansible_port }}
 {% endif %}
 
 {% endfor %}
index f751243..eb868d3 100644 (file)
@@ -1,16 +1,15 @@
 ---
 - name: enable serial console in grub and for kernel
-  with_items:
-    - regexp: '^GRUB_TIMEOUT='
-      line: 'GRUB_TIMEOUT=2'
-    - regexp: '^GRUB_CMDLINE_LINUX='
-      line: 'GRUB_CMDLINE_LINUX="console=ttyS0,115200n8"'
-    - regexp: '^GRUB_TERMINAL='
-      line: 'GRUB_TERMINAL=serial'
-    - regexp: '^GRUB_SERIAL_COMMAND='
-      line: 'GRUB_SERIAL_COMMAND="serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"'
+  with_dict:
+    GRUB_TIMEOUT: 2
+    GRUB_CMDLINE_LINUX: '"console=ttyS0,115200n8"'
+    GRUB_TERMINAL: serial
+    GRUB_SERIAL_COMMAND: >-
+      "serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1"
   lineinfile:
     dest: /etc/default/grub
-    regexp: "{{ item.regexp }}"
-    line: "{{ item.line }}"
+    regexp: "^{{ item.key }}="
+    line: "{{ item.key }}={{ item.value }}"
   notify: update grub
+  loop_control:
+    label: "{{ item.key }}"
index 780a276..17c1a53 100644 (file)
   loop_control:
     label: "{{ item.key }}"
   notify: restart rngd
+
+- name: Provide a root shell on the VM console [1/2]
+  file:
+    path: /etc/systemd/system/serial-getty@ttyS0.service.d/
+    state: directory
+
+- name: Provide a root shell on the VM console [2/2]
+  copy:
+    dest: /etc/systemd/system/serial-getty@ttyS0.service.d/autologon.conf
+    content: |
+      [Service]
+      ExecStart=
+      ExecStart=-/sbin/agetty --keep-baud 115200,38400,9600 --noclear --autologin root --login-pause --host {{ vm_install_host }} %I $TERM
index f6b5f80..6541dd8 100644 (file)
@@ -1,9 +1,4 @@
 ---
-- name: restart inetd
-  service:
-    name: openbsd-inetd
-    state: restarted
-
 - name: restart haveged
   service:
     name: haveged
index a7b018c..dc9a0a3 100644 (file)
@@ -2,8 +2,6 @@
 - name: install dependencies
   apt:
     name:
-      - atftpd
-      - openbsd-inetd
       - qemu-kvm
       - libvirt-bin
       - python-libvirt
     path: /etc/default/haveged
   notify: restart haveged
 
-- name: configure tftpd via inetd
-  lineinfile:
-    regexp: "^#?({{ vm_host.network.ip }}:)?tftp"
-    line: "{{ vm_host.network.ip }}:tftp               dgram   udp4    wait    nobody /usr/sbin/tcpd /usr/sbin/in.tftpd --tftpd-timeout 300 --retry-timeout 5 --maxthread 10 --verbose=5 {{ vm_host.installer.preseed_path }}"
-    path: /etc/inetd.conf
-  notify: restart inetd
-
 - name: make sure installer directories exists
   with_items:
     - "{{ vm_host.installer.path }}"
index 1603483..aaa881e 100644 (file)
@@ -1,8 +1,43 @@
 ---
-- name: generate preseed file
-  template:
-    src: "preseed_{{ vmdistro }}-{{ vmdistcodename }}.cfg.j2"
-    dest: "{{ vm_host.installer.preseed_path }}/vm-{{ vmname }}-{{ vmdistro }}-{{ vmdistcodename }}.cfg"
+- block:
+    - name: Make a temporary directory
+      command: mktemp -d
+      register: tmpdir
+
+    - set_fact:
+        tmpdir: "{{ tmpdir.stdout }}"
+        initramfs: "{{ vm_host.installer.preseed_path }}/vm-{{ vmname }}-{{ vmdistro }}-{{ vmdistcodename }}.initrd.gz"
+
+    - name: Copy initramfs into position
+      copy:
+        remote_src: yes
+        src: "{{ vm_host.installer.path }}/{{ vmdistro }}-{{ vmdistcodename }}/{{ hostvars[vmname].vm_install_cooked.arch | default('amd64') }}/initrd.gz"
+        dest: "{{ initramfs }}"
+
+    - name: generate preseed file
+      template:
+        src: "preseed_{{ vmdistro }}-{{ vmdistcodename }}.cfg.j2"
+        dest: "{{ tmpdir }}/preseed.cfg"
+
+    - name: generate authorized_keys file
+      authorized_key:
+        user: root
+        path: "{{ tmpdir }}/authorized_keys"
+        key: "{{ hostvars[vmname].ssh_keys | default(noc_ssh_keys) | join('\n') }}"
+
+    - name: Inject files into initramfs
+      shell: cpio -H newc -o | gzip -9 >> {{ initramfs }}
+      args:
+        chdir: "{{ tmpdir }}"
+        stdin: |
+          preseed.cfg
+          authorized_keys
+
+  always:
+    - name: Delete temporary directory
+      file:
+        path: "{{ tmpdir }}"
+        state: absent
 
 - name: create disks for vm
   with_dict: "{{ hostvars[vmname].vm_install_cooked.disks.virtio | default({}) | combine(hostvars[vmname].vm_install_cooked.disks.scsi | default({})) }}"
     command: info
   register: vmhost_info
 
-- name: destroy exisiting vm
-  virt:
-    name: "{{ vmname }}"
-    state: destroyed
-  when: vmname in vmhost_info
+- block:
+    - name: destroy exisiting vm
+      virt:
+        name: "{{ vmname }}"
+        state: destroyed
 
-- name: wait for vm to be destroyed
-  wait_for_virt:
-    name: "{{ vmname }}"
-    states: shutdown,crashed
-    timeout: 5
-  when: vmname in vmhost_info
+    - name: wait for vm to be destroyed
+      wait_for_virt:
+        name: "{{ vmname }}"
+        states: shutdown,crashed
+        timeout: 5
+
+    - name: undefining exisiting vm
+      virt:
+        name: "{{ vmname }}"
+        command: undefine
 
-- name: undefining exisiting vm
-  virt:
-    name: "{{ vmname }}"
-    command: undefine
   when: vmname in vmhost_info
 
 - name: enable installer in VM config
index c8a2d95..c39b904 100644 (file)
@@ -7,8 +7,8 @@
     <type arch='x86_64' machine='pc-0.12'>hvm</type>
 {% if run_installer %}
     <kernel>{{ vm_host.installer.path }}/{{ vmdistro }}-{{ vmdistcodename }}/{{ hostvars[vmname].vm_install_cooked.arch | default('amd64') }}/linux</kernel>
-    <initrd>{{ vm_host.installer.path }}/{{ vmdistro }}-{{ vmdistcodename }}/{{ hostvars[vmname].vm_install_cooked.arch | default('amd64') }}/initrd.gz</initrd>
-    <cmdline>console=ttyS0,115200n8 auto=true interface=auto url=tftp://{{ hostvars[inventory_hostname]['ansible_' + (vm_host.installer.net_if | replace('-', '_'))].ipv4.address }}/vm-{{ vmname }}-{{ vmdistro }}-{{ vmdistcodename }}.cfg netcfg/choose_interface=enp1s1 netcfg/disable_autoconfig=true netcfg/get_ipaddress={{ hostvars[vmname].vm_network_cooked.primary.ip }} netcfg/get_netmask={{ hostvars[vmname].vm_network_cooked.primary.mask }} netcfg/get_gateway={{ hostvars[vmname].vm_network_cooked.primary.gateway }} netcfg/get_nameservers="{{ hostvars[vmname].vm_network_cooked.nameservers | join(' ') }}" netcfg/confirm_static=true netcfg/get_hostname={{ vmname }} netcfg/get_domain={{ hostvars[vmname].vm_network_cooked.domain }}</cmdline>
+    <initrd>{{ vm_host.installer.preseed_path }}/vm-{{ vmname }}-{{ vmdistro }}-{{ vmdistcodename }}.initrd.gz</initrd>
+    <cmdline>console=ttyS0,115200n8</cmdline>
 {% endif %}
     <boot dev='hd'/>
   </os>
index 5b1b3f8..d802418 100644 (file)
@@ -7,14 +7,14 @@ d-i debian-installer/country string AT
 d-i debian-installer/locale string en_US.UTF-8
 d-i keyboard-configuration/xkb-keymap select us
 
-
-#d-i netcfg/choose_interface select enp1s1
-#d-i netcfg/disable_autoconfig boolean false
-#d-i netcfg/get_ipaddress string {{ hostvars[vmname].vm_network_cooked.primary.ip }}
-#d-i netcfg/get_netmask string {{ hostvars[vmname].vm_network_cooked.primary.mask }}
-#d-i netcfg/get_gateway string {{ hostvars[vmname].vm_network_cooked.primary.gateway }}
-#d-i netcfg/get_nameservers string {{ hostvars[vmname].vm_network_cooked.nameservers | join(' ') }}
-#d-i netcfg/confirm_static boolean true
+d-i netcfg/disable_dhcp boolean true
+d-i netcfg/choose_interface select enp1s1
+d-i netcfg/disable_autoconfig boolean false
+d-i netcfg/get_ipaddress string {{ hostvars[vmname].vm_network_cooked.primary.ip }}
+d-i netcfg/get_netmask string {{ hostvars[vmname].vm_network_cooked.primary.mask }}
+d-i netcfg/get_gateway string {{ hostvars[vmname].vm_network_cooked.primary.gateway }}
+d-i netcfg/get_nameservers string {{ hostvars[vmname].vm_network_cooked.nameservers | join(' ') }}
+d-i netcfg/confirm_static boolean true
 
 d-i netcfg/get_hostname string {{ vmname }}
 d-i netcfg/get_domain string {{ hostvars[vmname].vm_network_cooked.domain }}
@@ -102,5 +102,9 @@ d-i finish-install/reboot_in_progress note
 d-i preseed/late_command string \
     lvremove -f {{ vmname }}/dummy; \
     in-target bash -c "apt-get update -q && apt-get full-upgrade -y -q"; \
-    in-target bash -c "passwd -d root; passwd -l root; umask 077; mkdir -p /root/.ssh/; echo -e '{{ noc_ssh_keys | join('\\n') }}' > /root/.ssh/authorized_keys"; \
-    in-target bash -c "sed -e 's/^\(\s*#*\s*Port.*\)/Port 22000/' -i /etc/ssh/sshd_config"
+    in-target bash -c "passwd -d root && passwd -l root"; \
+    mkdir -p -m 0700 /target/root/.ssh; \
+    cp /authorized_keys /target/root/.ssh/; \
+{% if hostvars[vmname].ansible_port is defined %}
+    in-target bash -c "sed -e 's/^\(\s*#*\s*Port.*\)/Port {{ hostvars[vmname].ansible_port }}/' -i /etc/ssh/sshd_config"
+{% endif %}
index 0cc0be4..49d3e16 100755 (executable)
@@ -15,9 +15,5 @@ shift
 echo "installing vm: $name with $distro/$codename"
 echo ""
 
-echo "########## clearing old ssh host keys #########"
-./remove-known-host.sh "$name"
-echo ""
-
 echo "######## running the install playbook ########"
 exec ansible-playbook -e "vmname=$name" -e "vmdistro=$distro" -e "vmdistcodename=$codename" $@ vm-install.yml
index e0685f9..507906f 100644 (file)
@@ -14,6 +14,8 @@
       group: _vmhost_
   # TODO: add some sanity checks
 
+- import_playbook: remove_known_hosts.yml
+
 - name: basic installation
   hosts: _vmhost_
   roles:
     set_fact:
       ansible_ssh_extra_args: ""
 
+- name: Apply VM configuration roles
+  hosts: "{{ vmname }}"
+  roles:
+  - role: vm/grub
+  - role: vm/network
+  - role: vm/guest
+
 - import_playbook: "host_playbooks/{{ vmname }}.yml"
 
 - name: reboot and wait for VM come back