Initialize config repository
diff --git a/nodepool/virt_images/README.md b/nodepool/virt_images/README.md
new file mode 100644
index 0000000..3fed60e
--- /dev/null
+++ b/nodepool/virt_images/README.md
@@ -0,0 +1,12 @@
+# Virt-customize based nodepool image
+
+This directory contains nodepool image built using virt-customize-dib elements.
+
+To use a playbook, add this to a nodepool yaml file:
+
+```yaml
+diskimages:
+ - name: cloud-fedora-rawhide
+ python-path: /usr/bin/python3
+ dib-cmd: /usr/bin/dib-virt-customize /etc/nodepool/virt_images/cloud-fedora-rawhide.yaml
+```
diff --git a/nodepool/virt_images/cloud-fedora-rawhide.yaml b/nodepool/virt_images/cloud-fedora-rawhide.yaml
new file mode 100644
index 0000000..07d2ecc
--- /dev/null
+++ b/nodepool/virt_images/cloud-fedora-rawhide.yaml
@@ -0,0 +1,38 @@
+---
+- name: Build a fedora cloud image suitable for Zuul
+ hosts: localhost
+ vars:
+ image: Fedora-Cloud-Base-Rawhide.x86_64.qcow2
+ extra_packages:
+ # Extra system tools
+ - pigz
+ - bridge-utils
+ - wget
+ - unzip
+ # Basic CI tools
+ - make
+ - gcc
+ - patch
+ tasks:
+ - block:
+ - import_role:
+ name: discover-rawhide
+ - import_role:
+ name: base-appliance
+ - import_role:
+ name: base
+ - import_role:
+ name: sshd-config
+ - import_role:
+ name: network-config
+ - import_role:
+ name: zuul-user
+ - import_role:
+ name: base-install-packages
+ - import_role:
+ name: base-customize
+ - import_role:
+ name: base-finalize
+ always:
+ - import_role:
+ name: base-cleanup
diff --git a/nodepool/virt_images/roles/base-appliance/tasks/main.yaml b/nodepool/virt_images/roles/base-appliance/tasks/main.yaml
new file mode 100644
index 0000000..e5e83fd
--- /dev/null
+++ b/nodepool/virt_images/roles/base-appliance/tasks/main.yaml
@@ -0,0 +1,12 @@
+- name: Download appliance
+ unarchive:
+ src: http://download.libguestfs.org/binaries/appliance/appliance-1.46.0.tar.xz
+ remote_src: yes
+ dest: /tmp
+ args:
+ creates: /tmp/appliance
+
+- set_fact:
+ virt_customize_env:
+ LIBGUESTFS_PATH: '/tmp/appliance'
+ LIBGUESTFS_BACKEND: 'direct'
diff --git a/nodepool/virt_images/roles/base-cleanup/defaults/main.yaml b/nodepool/virt_images/roles/base-cleanup/defaults/main.yaml
new file mode 100644
index 0000000..dd9240b
--- /dev/null
+++ b/nodepool/virt_images/roles/base-cleanup/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+image_tmp_dir: "/var/tmp/{{ image_output | basename }}"
diff --git a/nodepool/virt_images/roles/base-cleanup/tasks/main.yaml b/nodepool/virt_images/roles/base-cleanup/tasks/main.yaml
new file mode 100644
index 0000000..29c01ea
--- /dev/null
+++ b/nodepool/virt_images/roles/base-cleanup/tasks/main.yaml
@@ -0,0 +1,5 @@
+---
+- name: Remove tmp directory
+ file:
+ path: "{{ image_tmp_dir }}"
+ state: absent
diff --git a/nodepool/virt_images/roles/base-customize/defaults/main.yaml b/nodepool/virt_images/roles/base-customize/defaults/main.yaml
new file mode 100644
index 0000000..ed97d53
--- /dev/null
+++ b/nodepool/virt_images/roles/base-customize/defaults/main.yaml
@@ -0,0 +1 @@
+---
diff --git a/nodepool/virt_images/roles/base-customize/tasks/main.yaml b/nodepool/virt_images/roles/base-customize/tasks/main.yaml
new file mode 100644
index 0000000..c1d397d
--- /dev/null
+++ b/nodepool/virt_images/roles/base-customize/tasks/main.yaml
@@ -0,0 +1,7 @@
+---
+- debug:
+ msg: "Running: {{ ' '.join(virt_customize_cmd) }}"
+
+- name: Run virt-customize
+ command: "{{ ' '.join(virt_customize_cmd) }}"
+ environment: "{{ virt_customize_env|default({}) }}"
diff --git a/nodepool/virt_images/roles/base-finalize/defaults/main.yaml b/nodepool/virt_images/roles/base-finalize/defaults/main.yaml
new file mode 100644
index 0000000..ed97d53
--- /dev/null
+++ b/nodepool/virt_images/roles/base-finalize/defaults/main.yaml
@@ -0,0 +1 @@
+---
diff --git a/nodepool/virt_images/roles/base-finalize/tasks/main.yaml b/nodepool/virt_images/roles/base-finalize/tasks/main.yaml
new file mode 100644
index 0000000..9fb8968
--- /dev/null
+++ b/nodepool/virt_images/roles/base-finalize/tasks/main.yaml
@@ -0,0 +1,8 @@
+---
+- name: Create raw file
+ command: "qemu-img convert -O raw {{ image_file }} {{ image_output }}.raw"
+ when: raw_type | default(False) | bool
+
+- name: Create qcow file
+ command: "mv {{ image_file }} {{ image_output }}.qcow2"
+ when: qcow2_type | default(False) | bool
diff --git a/nodepool/virt_images/roles/base-install-packages/defaults/main.yaml b/nodepool/virt_images/roles/base-install-packages/defaults/main.yaml
new file mode 100644
index 0000000..ed97d53
--- /dev/null
+++ b/nodepool/virt_images/roles/base-install-packages/defaults/main.yaml
@@ -0,0 +1 @@
+---
diff --git a/nodepool/virt_images/roles/base-install-packages/tasks/main.yaml b/nodepool/virt_images/roles/base-install-packages/tasks/main.yaml
new file mode 100644
index 0000000..588de54
--- /dev/null
+++ b/nodepool/virt_images/roles/base-install-packages/tasks/main.yaml
@@ -0,0 +1,7 @@
+---
+- set_fact:
+ cmd:
+ - "--install '{{ extra_packages | join(',') }}'"
+
+- set_fact:
+ virt_customize_cmd: "{{ virt_customize_cmd + cmd }}"
diff --git a/nodepool/virt_images/roles/base/defaults/main.yaml b/nodepool/virt_images/roles/base/defaults/main.yaml
new file mode 100644
index 0000000..a1cdfac
--- /dev/null
+++ b/nodepool/virt_images/roles/base/defaults/main.yaml
@@ -0,0 +1,10 @@
+---
+image_cache_dir: "/var/cache/nodepool"
+image_wipe_cache: False
+memsize: 1024
+base_packages:
+ - traceroute
+ - iproute
+ - git
+ - rsync
+extra_packages: []
diff --git a/nodepool/virt_images/roles/base/tasks/main.yaml b/nodepool/virt_images/roles/base/tasks/main.yaml
new file mode 100644
index 0000000..88f8799
--- /dev/null
+++ b/nodepool/virt_images/roles/base/tasks/main.yaml
@@ -0,0 +1,70 @@
+---
+- assert:
+ that:
+ - image_url is defined
+ - image_checksum is defined
+ - image is defined
+ - image_url != ''
+ - image_checksum != ''
+ - image != ''
+
+- name: Set some runtime facts
+ set_fact:
+ image_cache_file: "{{ image_cache_dir }}/{{ image }}"
+ image_tmp_dir: "/var/tmp/{{ image_output | basename }}"
+
+- name: Make sure cache directory exist
+ file:
+ path: "{{ image_cache_dir }}"
+ state: directory
+
+- name: Delete previous image cache
+ file:
+ path: "{{ image_cache_file }}"
+ state: absent
+ when: image_wipe_cache
+
+- name: Check if image is already downloaded
+ stat:
+ path: "{{ image_cache_file }}"
+ register: _image_cache_file_stat
+
+- name: Download if checksum doesn't match
+ get_url:
+ url: "{{ image_url }}"
+ dest: "{{ image_cache_file }}"
+ checksum: "{{ image_checksum }}"
+ when: not _image_cache_file_stat.stat.exists
+
+- name: Extract the image if necessary
+ command: "xz -k -d {{ image_cache_file }}.xz"
+ args:
+ chdir: "{{ image_cache_dir }}"
+ creates: "{{ image_cache_file }}"
+
+- name: Update the cache
+ command: "virt-customize -m {{ memsize }} -a {{ image_cache_file }} --update"
+ environment: "{{ virt_customize_env|default({}) }}"
+
+- name: Create tmp directory
+ file:
+ path: "{{ image_tmp_dir }}"
+ state: directory
+ mode: '0755'
+
+- name: Set filename copy fact
+ set_fact:
+ image_file: "{{ image_tmp_dir }}/{{ image_cache_file | basename }}"
+
+- name: Copy the image
+ copy:
+ src: "{{ image_cache_file }}"
+ dest: "{{ image_file }}"
+ remote_src: true
+ mode: '0644'
+
+- set_fact:
+ virt_customize_cmd:
+ - "virt-customize -m {{ memsize }} -a {{ image_file }}"
+ - "--selinux-relabel"
+ - "--install '{{ base_packages | join(',') }}'"
diff --git a/nodepool/virt_images/roles/discover-rawhide/defaults/main.yaml b/nodepool/virt_images/roles/discover-rawhide/defaults/main.yaml
new file mode 100644
index 0000000..e87cb9c
--- /dev/null
+++ b/nodepool/virt_images/roles/discover-rawhide/defaults/main.yaml
@@ -0,0 +1 @@
+base_url: https://dl.fedoraproject.org/pub/fedora/linux/development/rawhide/Cloud/x86_64/images/
diff --git a/nodepool/virt_images/roles/discover-rawhide/tasks/main.yaml b/nodepool/virt_images/roles/discover-rawhide/tasks/main.yaml
new file mode 100644
index 0000000..51e47c8
--- /dev/null
+++ b/nodepool/virt_images/roles/discover-rawhide/tasks/main.yaml
@@ -0,0 +1,45 @@
+- tempfile:
+ state: file
+ register: tempfile
+
+- file:
+ path: "{{ tempfile.path }}"
+ state: absent
+
+- name: Fetch publication page
+ get_url:
+ url: "{{ base_url }}"
+ dest: "{{ tempfile.path }}"
+
+- name: Find rawhide qcow2 url
+ command: sed -n "/qcow2/ s/.*\(Fedora-Cloud-Base-Rawhide-.*\)<\/a>.*/\1/p" {{ tempfile.path }}
+ register: get_qcow_image_name
+
+- name: Find checksum file url
+ command: sed -n "/CHECKSUM/ s/.*\(Fedora-Cloud-Rawhide-.*\)<\/a>.*/\1/p" {{ tempfile.path }}
+ register: get_checksum_name
+
+- set_fact:
+ checksums_url: "{{ base_url }}{{ get_checksum_name.stdout }}"
+
+- file:
+ path: "{{ tempfile.path }}"
+ state: absent
+
+- name: Fetch checksum file
+ get_url:
+ url: "{{ checksums_url }}"
+ dest: "{{ tempfile.path }}"
+
+- name: Find checksum
+ command: sed -n "/SHA256 ({{ get_qcow_image_name.stdout }}) = / s/.* = \(.*\)/\1/p" {{ tempfile.path }}
+ register: get_checksum
+
+- set_fact:
+ image_url: "{{ base_url }}{{ get_qcow_image_name.stdout }}"
+ image_checksum: "sha256:{{ get_checksum.stdout }}"
+
+- debug:
+ msg: |
+ Discovered image_url: {{ image_url }}
+ Discovered image_checksum: {{ image_checksum }}
diff --git a/nodepool/virt_images/roles/network-config/defaults/main.yaml b/nodepool/virt_images/roles/network-config/defaults/main.yaml
new file mode 100644
index 0000000..dd9240b
--- /dev/null
+++ b/nodepool/virt_images/roles/network-config/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+image_tmp_dir: "/var/tmp/{{ image_output | basename }}"
diff --git a/nodepool/virt_images/roles/network-config/tasks/main.yaml b/nodepool/virt_images/roles/network-config/tasks/main.yaml
new file mode 100644
index 0000000..5d49314
--- /dev/null
+++ b/nodepool/virt_images/roles/network-config/tasks/main.yaml
@@ -0,0 +1,12 @@
+---
+- set_fact:
+ cmd:
+ - "--append-line '/etc/sysctl.conf:net.ipv6.conf.all.disable_ipv6 = 1'"
+ - "--append-line '/etc/sysctl.conf:net.ipv6.conf.default.disable_ipv6 = 1'"
+ - "--append-line '/etc/sysconfig/network:IPV6INIT=no'"
+ - "--append-line '/etc/sysconfig/network:IPV6_AUTOCONF=no'"
+ - "--append-line '/etc/sysconfig/network:IPV6_DEFROUTE=no'"
+ - "--append-line '/etc/yum.conf:ip_resolve=4'"
+
+- set_fact:
+ virt_customize_cmd: "{{ virt_customize_cmd + cmd }}"
diff --git a/nodepool/virt_images/roles/sshd-config/defaults/main.yaml b/nodepool/virt_images/roles/sshd-config/defaults/main.yaml
new file mode 100644
index 0000000..dd9240b
--- /dev/null
+++ b/nodepool/virt_images/roles/sshd-config/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+image_tmp_dir: "/var/tmp/{{ image_output | basename }}"
diff --git a/nodepool/virt_images/roles/sshd-config/files/sshd_config b/nodepool/virt_images/roles/sshd-config/files/sshd_config
new file mode 100644
index 0000000..df17bfa
--- /dev/null
+++ b/nodepool/virt_images/roles/sshd-config/files/sshd_config
@@ -0,0 +1,20 @@
+HostKey /etc/ssh/ssh_host_rsa_key
+HostKey /etc/ssh/ssh_host_ecdsa_key
+HostKey /etc/ssh/ssh_host_ed25519_key
+KexAlgorithms curve25519-sha256@libssh.org,ecdh-sha2-nistp521,ecdh-sha2-nistp384,ecdh-sha2-nistp256,diffie-hellman-group-exchange-sha256
+Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr
+MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com,hmac-sha2-512,hmac-sha2-256,umac-128@openssh.com
+SyslogFacility AUTHPRIV
+AuthorizedKeysFile .ssh/authorized_keys
+PasswordAuthentication no
+ChallengeResponseAuthentication no
+GSSAPIAuthentication no
+GSSAPICleanupCredentials no
+UsePAM yes
+X11Forwarding no
+UseDNS no
+AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES
+AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT
+AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE
+AcceptEnv XMODIFIERS
+Subsystem sftp /usr/libexec/openssh/sftp-server
diff --git a/nodepool/virt_images/roles/sshd-config/tasks/main.yaml b/nodepool/virt_images/roles/sshd-config/tasks/main.yaml
new file mode 100644
index 0000000..ff62665
--- /dev/null
+++ b/nodepool/virt_images/roles/sshd-config/tasks/main.yaml
@@ -0,0 +1,13 @@
+---
+- name: Prepare sshd_config file
+ copy:
+ src: files/sshd_config
+ dest: "{{ image_tmp_dir }}/sshd_config"
+
+- set_fact:
+ cmd:
+ - "--copy-in '{{ image_tmp_dir }}/sshd_config:/etc/ssh/'"
+ - "--chmod '0600:/etc/ssh/sshd_config'"
+
+- set_fact:
+ virt_customize_cmd: "{{ virt_customize_cmd + cmd }}"
diff --git a/nodepool/virt_images/roles/zuul-user/defaults/main.yaml b/nodepool/virt_images/roles/zuul-user/defaults/main.yaml
new file mode 100644
index 0000000..dd9240b
--- /dev/null
+++ b/nodepool/virt_images/roles/zuul-user/defaults/main.yaml
@@ -0,0 +1,2 @@
+---
+image_tmp_dir: "/var/tmp/{{ image_output | basename }}"
diff --git a/nodepool/virt_images/roles/zuul-user/tasks/main.yaml b/nodepool/virt_images/roles/zuul-user/tasks/main.yaml
new file mode 100644
index 0000000..2382ba4
--- /dev/null
+++ b/nodepool/virt_images/roles/zuul-user/tasks/main.yaml
@@ -0,0 +1,27 @@
+---
+- name: Prepare the sudoers file
+ copy:
+ content: |
+ Defaults !requiretty
+ zuul-worker ALL=(ALL) NOPASSWD:ALL
+ dest: "{{ image_tmp_dir }}/zuul-worker"
+
+- name: Prepare the authorized_keys file
+ copy:
+ src: /var/lib/nodepool/.ssh/zuul_rsa.pub
+ dest: "{{ image_tmp_dir }}/authorized_keys"
+ remote_src: true
+
+- set_fact:
+ cmd:
+ - "--run-command 'adduser -m zuul-worker'"
+ - "--mkdir '/home/zuul-worker/.ssh'"
+ - "--chmod '0700:/home/zuul-worker/.ssh'"
+ - "--copy-in '{{ image_tmp_dir }}/authorized_keys:/home/zuul-worker/.ssh/'"
+ - "--chmod '0600:/home/zuul-worker/.ssh/authorized_keys'"
+ - "--run-command 'chown -R zuul-worker:zuul-worker /home/zuul-worker/.ssh/'"
+ - "--copy-in '{{ image_tmp_dir }}/zuul-worker:/etc/sudoers.d/'"
+ - "--chmod '0440:/etc/sudoers.d/zuul-worker'"
+
+- set_fact:
+ virt_customize_cmd: "{{ virt_customize_cmd + cmd }}"