From 352c98322771af117a85904d580e1c062062d634 Mon Sep 17 00:00:00 2001
From: binary <me@rgoncalves.se>
Date: Sat, 7 Nov 2020 20:38:07 +0100
Subject: Refactor vmm role with automation

---
 playbooks/vmm.yml                   |  7 ++++++
 roles/vmm/tasks/boot_alpine.yml     | 43 +++++++++++++++++++++++++++++++++++++
 roles/vmm/tasks/debug.yml           |  5 -----
 roles/vmm/tasks/download_iso.yml    | 30 +++++++++++---------------
 roles/vmm/tasks/generate_disk.yml   | 12 +++++------
 roles/vmm/tasks/generate_vmconf.yml | 27 ++++++++++-------------
 roles/vmm/tasks/init_hypervisor.yml | 12 +++++++++++
 roles/vmm/tasks/main.yml            |  9 ++++++++
 roles/vmm/tasks/set_facts.yml       | 19 ++++++++++++++++
 roles/vmm/templates/hostname.j2     |  1 +
 roles/vmm/templates/vm.conf.j2      | 16 +++++++-------
 roles/vmm/vars/main.yml             | 19 ++++++++--------
 12 files changed, 137 insertions(+), 63 deletions(-)
 create mode 100644 playbooks/vmm.yml
 create mode 100644 roles/vmm/tasks/boot_alpine.yml
 delete mode 100644 roles/vmm/tasks/debug.yml
 create mode 100644 roles/vmm/tasks/init_hypervisor.yml
 create mode 100644 roles/vmm/tasks/set_facts.yml
 create mode 100644 roles/vmm/templates/hostname.j2

diff --git a/playbooks/vmm.yml b/playbooks/vmm.yml
new file mode 100644
index 0000000..e0034ef
--- /dev/null
+++ b/playbooks/vmm.yml
@@ -0,0 +1,7 @@
+
+# vmm.yml
+# Init vmm iso for specified host.
+
+- hosts: "{{ host }}"
+  roles:
+    - vmm
diff --git a/roles/vmm/tasks/boot_alpine.yml b/roles/vmm/tasks/boot_alpine.yml
new file mode 100644
index 0000000..da4e91e
--- /dev/null
+++ b/roles/vmm/tasks/boot_alpine.yml
@@ -0,0 +1,43 @@
+
+# vmm ~~ tasks/boot_alpine.yml
+# Boot an alpine image and init its installation set.
+# Required :
+# - guest : vm to be be bootup and initialized
+
+---
+
+- name: Check arguments
+  fail: 
+    msg: "arguments : guest"
+  when: guest is not defined
+
+- set_fact:
+    iso: "{{ hostvars[guest].iso }}"
+    disk_file : "{{ vmm.disk.dir }}/{{ guest }}.{{ vmm.disk.format }}"
+
+- include: set_facts.yml
+
+- name: Start vm
+  shell: |
+    vmctl stop dummy
+    sleep 2
+    vmctl start -d {{ iso_latest | quote }} \
+      -d {{ disk_file | quote }} \
+      -n {{ vmm.config.switch.name | quote }} \
+      -m {{ hostvars[guest].memory | quote }} dummy
+
+    sleep 2
+    tty=$(vmctl show | grep dummy | tr -s " " " " | cut -d " " -f 7)
+    sleep 20
+
+    cat << EOF > /dev/${tty}
+      echo "mkdir /root/.ssh"
+      echo "echo $(cat /root/.ssh/authorized_keys) > /root/.ssh/authorized_keys" > /dev/ttyp1
+      echo "apk add openssh ; rc-update add sshd ; /etc/init.d/sshd start" /dev/${tty}
+    EOF
+
+    exit 0
+
+  args:
+    executable: /bin/sh
+
diff --git a/roles/vmm/tasks/debug.yml b/roles/vmm/tasks/debug.yml
deleted file mode 100644
index c078e11..0000000
--- a/roles/vmm/tasks/debug.yml
+++ /dev/null
@@ -1,5 +0,0 @@
-
-# vmm ~~ debug.yml
-
-- debug:
-    var: vmm.iso.openbsd.version
diff --git a/roles/vmm/tasks/download_iso.yml b/roles/vmm/tasks/download_iso.yml
index c767c05..6f0c5f6 100644
--- a/roles/vmm/tasks/download_iso.yml
+++ b/roles/vmm/tasks/download_iso.yml
@@ -1,34 +1,28 @@
 
 # vmm ~~ tasks/download_iso.yml
+# Download an iso file to hypervisor.
+# Required :
+# - iso : name of an iso file defined in vars/main.yml
 
 ---
 
-- meta: end_play
+- name: Check arguments
+  fail: 
+    msg: "arguments : iso"
   when: iso is not defined
 
-- set_fact:
-    symlink: "{{ vmm.iso.dir }}/{{ vmm.iso[iso].name }}-latest.iso"
-
-- set_fact:
-    dest: "{{ symlink | regex_replace('latest', vmm.iso[iso].version) }}"
-    url: "{{ vmm.iso[iso].url \
-      | regex_replace('VERSIONDIR', vmm.iso[iso].versiondir) \
-      | regex_replace('VERSION', vmm.iso[iso].version) }}"
-
-    sha256: "{{ vmm.iso[iso].sha256 \
-      | regex_replace('VERSIONDIR', vmm.iso[iso].versiondir) \
-      | regex_replace('VERSION', vmm.iso[iso].version) }}"
+- include: set_facts.yml
 
 - name: Get latest iso
   get_url:
-    url: "{{ url }}"
-    dest: "{{ dest }}"
+    url: "{{ iso_url }}"
+    dest: "{{ iso_file }}"
     force: "{{ force | default('no') }}"
-    checksum: "sha256:{{ sha256 }}"
+    checksum: "sha256:{{ iso_checksum }}"
 
 - name: Symlink latest iso
   file:
-    src: "{{ dest }}"
-    dest: "{{ symlink }}"
+    src: "{{ iso_file }}"
+    dest: "{{ iso_latest }}"
     state: link
 
diff --git a/roles/vmm/tasks/generate_disk.yml b/roles/vmm/tasks/generate_disk.yml
index c8ec091..1c44471 100644
--- a/roles/vmm/tasks/generate_disk.yml
+++ b/roles/vmm/tasks/generate_disk.yml
@@ -5,17 +5,17 @@
 
 - name: Check existence of disk directory
   file:
-    path: "{{ vmm.disk.dir }}"
+    path: "{{ vmm.disk_dir }}"
     state: directory
 
 - name: Get existing disk file size
   stat:
-    path: "{{ vmm.disk.dir }}/{{ hostvars[vm].ansible_host }}.{{ vmm.disk.format }}"
+    path: "{{ vmm.disk_dir }}/{{ guest.name }}.{{ vmm.disk_format }}"
   register: st
 
-- name: Generate vm disk
+- name: Generate vm disk for {{ guest.name }}
   shell: |
-    disk="{{ vmm.disk.dir }}/{{ hostvars[vm].ansible_host }}.{{ vmm.disk.format }}"
+    disk="{{ vmm.disk_dir }}/{{ guest.name }}.{{ vmm.disk_format }}"
     rm "${disk}"
-    vmctl create -s {{ hostvars[vm].size }} "${disk}"
-  when: not st.stat.exists or st.stat.size == 0
+    vmctl create -s {{ guest.size }} "${disk}"
+  when: not st.stat.exists or st.stat.size < 32
diff --git a/roles/vmm/tasks/generate_vmconf.yml b/roles/vmm/tasks/generate_vmconf.yml
index 9f120fd..c4e80d8 100644
--- a/roles/vmm/tasks/generate_vmconf.yml
+++ b/roles/vmm/tasks/generate_vmconf.yml
@@ -1,29 +1,24 @@
 
 # vmm ~~ tasks/generate_vmconf.yml
+# Generate vm.conf on hypervisor.
 
 ---
 
+- name: Create network switch
+  template:
+    src: templates/hostname.j2
+    dest: "/etc/hostname.{{ vmm.switch.interface }}"
+
+- name: Start network switch
+  shell: "sh /etc/netstart {{ vmm.switch.interface }}"
+
 - name: Generate vmm configuration
   template:
     src: templates/vm.conf.j2
-    dest: "{{ vmm.config.file }}"
-
-- name: Create empty disk
-  file:
-    path: "{{ vmm.disk.dir }}/{{ hostvars[item].ansible_host }}.{{ vmm.disk.format }}"
-    state: touch
-  loop: "{{ vm.hosts }}"
+    dest: "{{ vmm.config_file }}"
 
-- name: Restart and enable vmd
+- name: Restart vmd
   service:
     name: vmd
     state: restarted
     enabled: true
-  when: vm.enabled
-
-- name: Stop and disable vmd
-  service:
-    name: vmd
-    state: stopped
-    enabled: false
-  when: not vm.enabled
diff --git a/roles/vmm/tasks/init_hypervisor.yml b/roles/vmm/tasks/init_hypervisor.yml
new file mode 100644
index 0000000..c963bbb
--- /dev/null
+++ b/roles/vmm/tasks/init_hypervisor.yml
@@ -0,0 +1,12 @@
+
+# vmm ~~ tasks/init_hypervisor.yml
+
+---
+
+- include_tasks: download_iso.yml 
+  vars:
+    iso="{{ item.name }}"
+  with_items: "{{ vmm.iso }}"
+
+- include: generate_vmconf.yml guest="{{ item }}"
+  loop: "{{ hostvars[ansible_host] }}.vm.hosts"
diff --git a/roles/vmm/tasks/main.yml b/roles/vmm/tasks/main.yml
index 8d5609a..9011497 100644
--- a/roles/vmm/tasks/main.yml
+++ b/roles/vmm/tasks/main.yml
@@ -3,3 +3,12 @@
 
 ---
 
+- name: Download all iso files
+  include: download_iso.yml iso={{ item }}
+  with_items: "{{ vmm.iso }}"
+
+- name: Generate disks for all vms
+  include: generate_disk.yml guest={{ item }}
+  with_items: "{{ vms }}"
+
+- include: generate_vmconf.yml
diff --git a/roles/vmm/tasks/set_facts.yml b/roles/vmm/tasks/set_facts.yml
new file mode 100644
index 0000000..2acc458
--- /dev/null
+++ b/roles/vmm/tasks/set_facts.yml
@@ -0,0 +1,19 @@
+
+# vmm ~~ tasks/set_fact.yml
+
+---
+
+- set_fact:
+    iso_latest: "{{ vmm.iso_dir }}/{{ vmm.iso[iso].name }}-latest.iso"
+  when: iso is defined
+
+- set_fact:
+    iso_file: "{{ iso_latest | regex_replace('latest', vmm.iso[iso].version) }}"
+    iso_url: "{{ vmm.iso[iso].url \
+      | regex_replace('VERSIONDIR', vmm.iso[iso].versiondir) \
+      | regex_replace('VERSION', vmm.iso[iso].version) }}"
+    iso_checksum: "{{ vmm.iso[iso].sha256 \
+      | regex_replace('VERSIONDIR', vmm.iso[iso].versiondir) \
+      | regex_replace('VERSION', vmm.iso[iso].version) }}"
+  when: iso is defined
+
diff --git a/roles/vmm/templates/hostname.j2 b/roles/vmm/templates/hostname.j2
new file mode 100644
index 0000000..68b989a
--- /dev/null
+++ b/roles/vmm/templates/hostname.j2
@@ -0,0 +1 @@
+add {{ vmm.switch.interface_host }}
diff --git a/roles/vmm/templates/vm.conf.j2 b/roles/vmm/templates/vm.conf.j2
index 88be7fb..2665c16 100644
--- a/roles/vmm/templates/vm.conf.j2
+++ b/roles/vmm/templates/vm.conf.j2
@@ -1,22 +1,22 @@
 #jinja2: trim_blocks: True, lstrip_blocks: True
 
-{% for vm in vm.hosts %}
-{% set vm = hostvars[vm] %}
+{% for vm in vms if hostvars[vm.name] is defined %}
+{% set guest = hostvars[vm.name] %}
 
-vm "{{ vm.ansible_host }}" {
-	{% if vm.enabled %}
+vm "{{ guest.ansible_host }}" {
+	{% if vm.enabled and vm.enabled is defined %}
 	enable
 	{% else %}
 	disable
 	{% endif %}
 	memory {{ vm.memory }}
-	disk "{{ vmm.disk.dir }}/{{ vm.ansible_host }}.{{ vmm.disk.format }}"
+	disk "{{ vmm.disk_dir }}/{{ guest.ansible_host }}.{{ vmm.disk_format }}"
 	interface {
-		switch "{{ vmm.config.switch.name }}"
+		switch "{{ vmm.switch.name }}"
 	}
 }
 {% endfor %}
 
-switch "{{ vmm.config.switch.name }}" {
-	interface {{ vmm.config.switch.interface }}
+switch "{{ vmm.switch.name }}" {
+	interface {{ vmm.switch.interface }}
 }
diff --git a/roles/vmm/vars/main.yml b/roles/vmm/vars/main.yml
index 22c59a7..8119c88 100644
--- a/roles/vmm/vars/main.yml
+++ b/roles/vmm/vars/main.yml
@@ -8,20 +8,19 @@ vmm:
   user: "vmm"
   group: "vmm"
 
-  config:
-    file: "/etc/vm.conf"
-    switch:
-      name: "uplink"
-      interface: "bridge0"
+  iso_dir: "/data/vmm/iso.d"
+  disk_dir: "/data/vmm/disk.d"
+  disk_format: "qcow2"
 
-  disk:
-    dir: "/data/vmm/disk.d"
-    format: "qcow2"
+  config_file: "/etc/vm.conf"
+  
+  switch:
+    name: "uplink"
+    interface: "bridge0"
+    interface_host: "bnx0"
 
   iso:
 
-    dir: "/data/vmm/iso.d"
-
     alpine:
       name: "alpine"
       version: "3.12.1"
-- 
cgit v1.2.3