summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYuya Kusakabe <yuya.kusakabe@gmail.com>2018-06-21 22:49:37 +0900
committerYuya Kusakabe <yuya.kusakabe@gmail.com>2018-06-21 22:49:37 +0900
commite7e91bb0b34568cc3244950739cc207a43009ff3 (patch)
tree54a428879bc90474f949ab565a3db62af0f658ea
parentdae52d73f6a83eb799aab095952d51439026f3bf (diff)
downloadvyos-vm-images-e7e91bb0b34568cc3244950739cc207a43009ff3.tar.gz
vyos-vm-images-e7e91bb0b34568cc3244950739cc207a43009ff3.zip
Initial vagrant-libvirt support
-rw-r--r--.gitignore1
-rw-r--r--README.md30
-rw-r--r--hosts3
-rw-r--r--roles/vagrant-libvirt/files/Vagrantfile12
-rw-r--r--roles/vagrant-libvirt/files/config.boot41
-rw-r--r--roles/vagrant-libvirt/files/metadata.json1
-rw-r--r--roles/vagrant-libvirt/files/persistence.conf1
-rw-r--r--roles/vagrant-libvirt/tasks/build_image.yml122
-rw-r--r--roles/vagrant-libvirt/tasks/convert.yml24
-rw-r--r--roles/vagrant-libvirt/tasks/install_packages.yml10
-rw-r--r--roles/vagrant-libvirt/tasks/load_modules.yml2
-rw-r--r--roles/vagrant-libvirt/tasks/main.yml7
-rw-r--r--roles/vagrant-libvirt/tasks/setup_iso.yml57
-rw-r--r--roles/vagrant-libvirt/tasks/unmount.yml66
-rw-r--r--roles/vagrant-libvirt/templates/boot/grub/device.map.j21
-rw-r--r--roles/vagrant-libvirt/templates/boot/grub/grub.cfg.j27
-rw-r--r--roles/vagrant-libvirt/vars/main.yml7
-rw-r--r--vagrant-libvirt.yml8
18 files changed, 400 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 6e5983f..8d39285 100644
--- a/.gitignore
+++ b/.gitignore
@@ -6,6 +6,7 @@
*.qcow2
*.ova
*.vhd
+*.box
# Python
.python-version
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..af08f34
--- /dev/null
+++ b/README.md
@@ -0,0 +1,30 @@
+# vyos-vm-images
+
+[Ansible](https://www.ansible.com/) playbooks to build VyOS VM images.
+
+## Supported Platforms
+
+- QEMU
+
+ ```
+ ansible-playbook -i hosts qemu.yml
+ ```
+
+- VMware
+
+ ```
+ ansible-playbook -i hosts vmware.yml
+ ansible-playbook -i hosts vmware.yml -e vyos_vmware_private_key_path=path_to_private_key
+ ```
+
+- Microsoft Hyper-V
+
+ ```
+ ansible-playbook -i hosts hyperv.yml
+ ```
+
+- Vagrant libvirt
+
+ ```
+ ansible-playbook -i hosts vagrant-libvirt.yml
+ ```
diff --git a/hosts b/hosts
index 3a30fe0..3fcf34c 100644
--- a/hosts
+++ b/hosts
@@ -9,3 +9,6 @@ localhost
[hyperv]
localhost
+
+[vagrant-libvirt]
+localhost
diff --git a/roles/vagrant-libvirt/files/Vagrantfile b/roles/vagrant-libvirt/files/Vagrantfile
new file mode 100644
index 0000000..7c89422
--- /dev/null
+++ b/roles/vagrant-libvirt/files/Vagrantfile
@@ -0,0 +1,12 @@
+Vagrant.configure("2") do |config|
+ config.vm.synced_folder './', '/vagrant',
+ type: "rsync",
+ owner: 'vyos',
+ group: 'users',
+ mount_options: ['dmode=775,fmode=775']
+ config.ssh.username = "vyos"
+ config.ssh.password = "vyos"
+ config.vm.provider :libvirt do |libvirt|
+ libvirt.driver = "kvm"
+ end
+end
diff --git a/roles/vagrant-libvirt/files/config.boot b/roles/vagrant-libvirt/files/config.boot
new file mode 100644
index 0000000..f1ec4f5
--- /dev/null
+++ b/roles/vagrant-libvirt/files/config.boot
@@ -0,0 +1,41 @@
+service {
+ ssh {
+ port 22
+ }
+}
+system {
+ host-name vyos
+ login {
+ user vyos {
+ authentication {
+ encrypted-password "$6$MjV2YvKQ56q$QbL562qhRoyUu8OaqrXagicvcsNpF1HssCY06ZxxghDJkBCfSfTE/4FlFB41xZcd/HqYyVBuRt8Zyq3ozJ0dc."
+ plaintext-password ""
+ }
+ level admin
+ }
+ }
+ syslog {
+ global {
+ facility all {
+ level notice
+ }
+ facility protocols {
+ level debug
+ }
+ }
+ }
+ ntp {
+ server "0.pool.ntp.org"
+ server "1.pool.ntp.org"
+ server "2.pool.ntp.org"
+ }
+ config-management {
+ commit-revisions 100
+ }
+}
+interfaces {
+ ethernet eth0 {
+ address dhcp
+ }
+ loopback lo
+}
diff --git a/roles/vagrant-libvirt/files/metadata.json b/roles/vagrant-libvirt/files/metadata.json
new file mode 100644
index 0000000..a502c63
--- /dev/null
+++ b/roles/vagrant-libvirt/files/metadata.json
@@ -0,0 +1 @@
+{"format":"qcow2","provider":"libvirt","virtual_size":1}
diff --git a/roles/vagrant-libvirt/files/persistence.conf b/roles/vagrant-libvirt/files/persistence.conf
new file mode 100644
index 0000000..f500aef
--- /dev/null
+++ b/roles/vagrant-libvirt/files/persistence.conf
@@ -0,0 +1 @@
+/ union
diff --git a/roles/vagrant-libvirt/tasks/build_image.yml b/roles/vagrant-libvirt/tasks/build_image.yml
new file mode 100644
index 0000000..7cfdadc
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/build_image.yml
@@ -0,0 +1,122 @@
+- name: Create the target disk image
+ command: qemu-img create -f raw "{{ vyos_raw_img }}" 1G
+
+- name: Find loopback
+ shell: losetup -f
+ register: loopback
+
+- name: Loopback attach
+ command: "losetup {{ loopback.stdout }} {{ vyos_raw_img }}"
+
+- name: Partition the target drive
+ parted:
+ device: "{{ loopback.stdout }}"
+ state: present
+ label: msdos
+ number: 1
+ part_type: primary
+ part_start: 0%
+ part_end: 100%
+ align: optimal
+ flags: [boot]
+
+- name: Create a filesystem on root partition
+ filesystem:
+ fstype: "{{ ROOT_FSTYPE }}"
+ device: "{{ loopback.stdout }}"
+ opts: "-L persistence"
+
+- name: Mount root partition
+ mount:
+ name: "{{ WRITE_ROOT }}"
+ src: "{{ loopback.stdout }}"
+ fstype: "{{ ROOT_FSTYPE }}"
+ state: mounted
+
+# ---- Install image from ISO ----
+- name: Create {{ WRITE_ROOT }} directories
+ file:
+ path: "{{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/rw"
+ state: directory
+ register: RW_DIR
+
+- name: Create the work directory
+ file:
+ path: "{{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/work/work"
+ state: directory
+
+- name: Copy squashfs image from ISO to root partition
+ command: cp -p {{ SQUASHFS_IMAGE }} {{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/{{ version_string.stdout }}.squashfs
+ args:
+ creates: "{{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/{{ version_string.stdout }}.squashfs"
+
+- name: Copy boot files (kernel and initrd images) from ISO to root partition
+ shell: find {{ CD_SQUASH_ROOT }}/boot -maxdepth 1 \( -type f -o -type l \) -print -exec cp -dp {} {{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/ \;
+ args:
+ creates: "{{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/vmlinuz"
+
+- name: Mount squashfs image from root partition
+ mount:
+ name: "{{ READ_ROOT }}"
+ src: "{{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/{{ version_string.stdout }}.squashfs"
+ fstype: squashfs
+ opts: loop,ro
+ state: mounted
+
+- name: Set up union root for post installation tasks
+ mount:
+ name: "{{ INSTALL_ROOT }}"
+ src: none
+ fstype: aufs
+ opts: "noatime,dirs={{ RW_DIR.path }}=rw:{{ READ_ROOT }}=rr"
+ state: mounted
+
+# ---- Post image installation tasks ----
+
+## ---- VyOS configuration ----
+- name: Make sure that config partition marker exists
+ file:
+ path: "{{ INSTALL_ROOT }}/opt/vyatta/etc/config/.vyatta_config"
+ state: touch
+
+- name: Copy the default config for QEMU to the installed image
+ template:
+ src: files/config.boot
+ dest: "{{ INSTALL_ROOT }}/opt/vyatta/etc/config/config.boot"
+ mode: 0755
+
+## ---- Install GRUB boot loader ----
+- name: Create GRUB directory
+ file:
+ path: "{{ WRITE_ROOT }}/boot/grub"
+ state: directory
+
+# It is necessary to mount and bind /dev, /proc, /sys and /boot in order to execute grub-install
+# and install GRUB correctly within the {{ volume_drive }} using chroot
+
+# XXX: ansible mount module requires fstype so it cannot be used for binding an already
+# mounted location, we get to use mount directly at least for /boot
+- name: Mount and bind /dev /proc /sys and {{ WRITE_ROOT }}/boot to {{ INSTALL_ROOT }}
+ shell: mount --bind /dev {{ INSTALL_ROOT }}/dev &&
+ mount --bind /proc {{ INSTALL_ROOT }}/proc &&
+ mount --bind /sys {{ INSTALL_ROOT }}/sys &&
+ mount --bind {{ WRITE_ROOT }} {{ INSTALL_ROOT }}/boot
+ args:
+ warn: no
+
+- name: Install GRUB in the boot sector of {{ loopback.stdout }}
+ command: chroot {{ INSTALL_ROOT }} grub-install --no-floppy --root-directory=/boot {{ loopback.stdout }} --force
+ args:
+ creates: "{{ INSTALL_ROOT }}/boot/grub/grubenv"
+
+- name: Configure GRUB
+ template:
+ src: templates/boot/grub/grub.cfg.j2
+ dest: "{{ WRITE_ROOT }}/boot/grub/grub.cfg"
+ mode: 0644
+
+- name: Create the persistence config
+ template:
+ src: files/persistence.conf
+ dest: "{{ WRITE_ROOT }}/persistence.conf"
+ mode: 0644
diff --git a/roles/vagrant-libvirt/tasks/convert.yml b/roles/vagrant-libvirt/tasks/convert.yml
new file mode 100644
index 0000000..d6de82f
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/convert.yml
@@ -0,0 +1,24 @@
+- name: Convert raw to qcow2
+ command: qemu-img convert -f raw "{{ vyos_raw_img }}" -O qcow2 "{{ vyos_vagrant_libvirt_box_img }}"
+- name: Copy metadata.json
+ become: false
+ copy:
+ src: "{{ vyos_vagrant_libvirt_metadata }}"
+ dest: "{{ vyos_vagrant_libvirt_tmp_metadata }}"
+- name: Copy Vagrantfile
+ become: false
+ copy:
+ src: "{{ vyos_vagrant_libvirt_vagrantfile }}"
+ dest: "{{ vyos_vagrant_libvirt_tmp_vagrantfile }}"
+- name: Create OVA with private key
+ become: false
+ archive:
+ path:
+ - "{{ vyos_vagrant_libvirt_box_img }}"
+ - "{{ vyos_vagrant_libvirt_tmp_metadata }}"
+ - "{{ vyos_vagrant_libvirt_tmp_vagrantfile }}"
+ dest: "{{ vyos_vagrant_libvirt_box }}"
+ format: tar
+- name: Copy image
+ become: false
+ command: cp "{{ vyos_vagrant_libvirt_box }}" .
diff --git a/roles/vagrant-libvirt/tasks/install_packages.yml b/roles/vagrant-libvirt/tasks/install_packages.yml
new file mode 100644
index 0000000..b60241e
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/install_packages.yml
@@ -0,0 +1,10 @@
+- name: Install required packages
+ become: yes
+ apt:
+ update_cache: yes
+ name:
+ - parted
+ - e2fsprogs
+ - gnupg
+ - qemu-utils
+ state: present
diff --git a/roles/vagrant-libvirt/tasks/load_modules.yml b/roles/vagrant-libvirt/tasks/load_modules.yml
new file mode 100644
index 0000000..44295fe
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/load_modules.yml
@@ -0,0 +1,2 @@
+- name: Load aufs module
+ shell: modprobe aufs
diff --git a/roles/vagrant-libvirt/tasks/main.yml b/roles/vagrant-libvirt/tasks/main.yml
new file mode 100644
index 0000000..611a6d3
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/main.yml
@@ -0,0 +1,7 @@
+- include_tasks: install_packages.yml
+- include_tasks: load_modules.yml
+- include_tasks: setup_iso.yml
+- include_tasks: build_image.yml
+- include_tasks: unmount.yml
+- include_tasks: convert.yml
+
diff --git a/roles/vagrant-libvirt/tasks/setup_iso.yml b/roles/vagrant-libvirt/tasks/setup_iso.yml
new file mode 100644
index 0000000..18f1f5e
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/setup_iso.yml
@@ -0,0 +1,57 @@
+- name: Fetch VyOS ISO GPG signature
+ uri:
+ url: "{{ vyos_iso_url }}.asc"
+ dest: "{{ vyos_iso_local }}.asc"
+ status_code: 200,404,403
+ tags: verify
+ register: gpg_uri
+
+- name: Download VyOS ISO release
+ get_url:
+ url: "{{ vyos_iso_url }}"
+ dest: "{{ vyos_iso_local }}"
+
+- name: Fetch the VyOS release GPG key
+ get_url:
+ url: "{{ vyos_key_url}}"
+ dest: "{{ vyos_key_local }}"
+ tags: verify
+
+- name: Install the VyOS release GPG key
+ command: gpg --import {{ vyos_key_local }}
+ when: gpg_uri.status == 200
+ tags: verify
+
+- name: Validate ISO GPG signature
+ command: gpg --verify {{ vyos_iso_local }}.asc {{ vyos_iso_local }}
+ when: gpg_uri.status == 200
+ tags: verify
+
+- name: Mount ISO
+ mount:
+ name: "{{ CD_ROOT }}"
+ src: "{{ vyos_iso_local }}"
+ fstype: iso9660
+ opts: loop,ro
+ state: mounted
+
+- name: Verify checksums of all the files in the ISO image
+ command: md5sum -c md5sum.txt
+ args:
+ chdir: "{{ CD_ROOT }}"
+ changed_when: False
+
+- name: Mount squashfs image from ISO
+ mount:
+ name: "{{ CD_SQUASH_ROOT }}"
+ src: "{{ SQUASHFS_IMAGE }}"
+ fstype: squashfs
+ opts: loop,ro
+ state: mounted
+
+- name: Read version string from iso packages
+ shell: cat {{ CD_SQUASH_ROOT }}/opt/vyatta/etc/version | awk '{print $2}' | tr + -
+ register: version_string
+
+- name: Debug version string as read from ISO
+ debug: msg="This is version {{ version_string.stdout }}"
diff --git a/roles/vagrant-libvirt/tasks/unmount.yml b/roles/vagrant-libvirt/tasks/unmount.yml
new file mode 100644
index 0000000..39c3d52
--- /dev/null
+++ b/roles/vagrant-libvirt/tasks/unmount.yml
@@ -0,0 +1,66 @@
+# Unmount all mounts
+# If remove unmounted before absent, cannot unmount INSTALL_ROOT...
+- name: Unmount {{ INSTALL_ROOT }}/boot
+ mount:
+ name: "{{ INSTALL_ROOT }}/boot"
+ src: "{{ WRITE_ROOT }}"
+ fstype: none
+ state: unmounted
+
+- name: Unmount {{ INSTALL_ROOT }}/boot
+ mount:
+ name: "{{ INSTALL_ROOT }}/boot"
+ src: "{{ WRITE_ROOT }}"
+ fstype: none
+ state: absent
+
+- name: Unmount {{ INSTALL_ROOT }}/sys, {{ INSTALL_ROOT }}/proc, {{ INSTALL_ROOT }}/dev
+ mount:
+ name: "{{ INSTALL_ROOT }}/{{ item }}"
+ src: "/{{ item }}"
+ fstype: none
+ state: unmounted
+ with_items: [ 'sys', 'proc', 'dev' ]
+
+- name: Unmount {{ INSTALL_ROOT }}/sys, {{ INSTALL_ROOT }}/proc, {{ INSTALL_ROOT }}/dev
+ mount:
+ name: "{{ INSTALL_ROOT }}/{{ item }}"
+ src: "/{{ item }}"
+ fstype: none
+ state: absent
+ with_items: [ 'sys', 'proc', 'dev' ]
+
+- name: Unmount {{ INSTALL_ROOT }}
+ mount:
+ name: "{{ INSTALL_ROOT }}"
+ src: overlayfs
+ fstype: overlayfs
+ state: absent
+
+- name: Unmount {{ READ_ROOT }}
+ mount:
+ name: "{{ READ_ROOT }}"
+ src: "{{ WRITE_ROOT }}/boot/{{ version_string.stdout }}/{{ version_string.stdout }}.squashfs"
+ fstype: squashfs
+ state: absent
+
+- name: Unmount {{ WRITE_ROOT }}
+ mount:
+ name: "{{ WRITE_ROOT }}"
+ src: "{{ loopback.stdout }}"
+ fstype: "{{ ROOT_FSTYPE }}"
+ state: absent
+
+- name: Unmount {{ CD_SQUASH_ROOT }}
+ mount:
+ name: "{{ CD_SQUASH_ROOT }}"
+ src: "{{ SQUASHFS_IMAGE }}"
+ fstype: squashfs
+ state: absent
+
+- name: Unmount {{ CD_ROOT }}
+ mount:
+ name: "{{ CD_ROOT }}"
+ src: "{{ vyos_iso_local }}"
+ fstype: iso9660
+ state: absent
diff --git a/roles/vagrant-libvirt/templates/boot/grub/device.map.j2 b/roles/vagrant-libvirt/templates/boot/grub/device.map.j2
new file mode 100644
index 0000000..e14205e
--- /dev/null
+++ b/roles/vagrant-libvirt/templates/boot/grub/device.map.j2
@@ -0,0 +1 @@
+(hd0) /dev/sda
diff --git a/roles/vagrant-libvirt/templates/boot/grub/grub.cfg.j2 b/roles/vagrant-libvirt/templates/boot/grub/grub.cfg.j2
new file mode 100644
index 0000000..cf126ab
--- /dev/null
+++ b/roles/vagrant-libvirt/templates/boot/grub/grub.cfg.j2
@@ -0,0 +1,7 @@
+set default=0
+set timeout=0
+
+menuentry "VyOS VM Image {{ version_string.stdout }}" {
+ linux /boot/{{ version_string.stdout }}/vmlinuz boot=live selinux=0 vyos-union=/boot/{{ version_string.stdout }} console=tty1
+ initrd /boot/{{ version_string.stdout }}/initrd.img
+}
diff --git a/roles/vagrant-libvirt/vars/main.yml b/roles/vagrant-libvirt/vars/main.yml
new file mode 100644
index 0000000..e5c1712
--- /dev/null
+++ b/roles/vagrant-libvirt/vars/main.yml
@@ -0,0 +1,7 @@
+vyos_raw_img: /tmp/vyos_raw_image.img
+vyos_vagrant_libvirt_box_img: /tmp/box.img
+vyos_vagrant_libvirt_box: /tmp/vyos_vagrant_libvirt_image.box
+vyos_vagrant_libvirt_metadata: files/metadata.json
+vyos_vagrant_libvirt_vagrantfile: files/Vagrantfile
+vyos_vagrant_libvirt_tmp_metadata: /tmp/metadata.json
+vyos_vagrant_libvirt_tmp_vagrantfile: /tmp/Vagrantfile
diff --git a/vagrant-libvirt.yml b/vagrant-libvirt.yml
new file mode 100644
index 0000000..d20d98d
--- /dev/null
+++ b/vagrant-libvirt.yml
@@ -0,0 +1,8 @@
+---
+- hosts: vagrant-libvirt
+ become: True
+ gather_facts: False
+ connection: local
+ roles:
+ - common
+ - vagrant-libvirt