From 9398e7befc483d15c13812e2f6177ed3dc6c7ff2 Mon Sep 17 00:00:00 2001 From: Ammar Ansari Date: Wed, 10 Jan 2018 08:43:22 -0500 Subject: [PATCH] Add job to build Vagrant boxes for Pulp 3 Add a new job called "pulp-3-build-box", which builds Vagrant boxes on an arbitrary host, over SSH, using Packer and Ansible. Also, uploads them to Vagrant cloud with box-name "pulp/pulpcore" for community usage. closes #2908 https://pulp.plan.io/issues/2908 --- AUTHORS | 1 + ci/ansible/pulp_build_box.yml | 4 + ci/ansible/pulp_build_environment.yml | 7 ++ ci/ansible/roles/pulp-build/tasks/main.yml | 20 ++++ .../pulp-galaxy-ansible/defaults/main.yml | 2 + .../roles/pulp-galaxy-ansible/files/motd | 8 ++ .../roles/pulp-galaxy-ansible/tasks/main.yml | 28 +++++ .../templates/pulpcore.json.jj2 | 100 ++++++++++++++++++ .../roles/pulp-libvirtd/files/custom.sh | 1 + ci/ansible/roles/pulp-libvirtd/tasks/main.yml | 67 ++++++++++++ .../roles/pulp-packer/defaults/main.yml | 3 + ci/ansible/roles/pulp-packer/tasks/main.yml | 45 ++++++++ .../roles/pulp-virtualbox/defaults/main.yml | 4 + .../roles/pulp-virtualbox/tasks/main.yml | 88 +++++++++++++++ ci/jjb/jobs/projects.yaml | 10 ++ ci/jjb/jobs/pulp-3-build-box.yml | 59 +++++++++++ ci/jjb/jobs/pulp-3-build-environment.yaml | 52 +++++++++ 17 files changed, 499 insertions(+) create mode 100644 ci/ansible/pulp_build_box.yml create mode 100644 ci/ansible/pulp_build_environment.yml create mode 100644 ci/ansible/roles/pulp-build/tasks/main.yml create mode 100644 ci/ansible/roles/pulp-galaxy-ansible/defaults/main.yml create mode 100644 ci/ansible/roles/pulp-galaxy-ansible/files/motd create mode 100644 ci/ansible/roles/pulp-galaxy-ansible/tasks/main.yml create mode 100644 ci/ansible/roles/pulp-galaxy-ansible/templates/pulpcore.json.jj2 create mode 100644 ci/ansible/roles/pulp-libvirtd/files/custom.sh create mode 100644 ci/ansible/roles/pulp-libvirtd/tasks/main.yml create mode 100644 ci/ansible/roles/pulp-packer/defaults/main.yml create mode 100644 ci/ansible/roles/pulp-packer/tasks/main.yml create mode 100644 ci/ansible/roles/pulp-virtualbox/defaults/main.yml create mode 100644 ci/ansible/roles/pulp-virtualbox/tasks/main.yml create mode 100644 ci/jjb/jobs/pulp-3-build-box.yml create mode 100644 ci/jjb/jobs/pulp-3-build-environment.yaml diff --git a/AUTHORS b/AUTHORS index 2049fc10..dd98e48a 100644 --- a/AUTHORS +++ b/AUTHORS @@ -2,6 +2,7 @@ This is an alphabetical (by last name) list of the authors of the Pulp project. If you submit a pull request to Pulp and your name is not on this list, please add yourself. +Muhammad Ammar Ansari (mansari@redhat.com) Jeremy Cline (jcline@redhat.com) Filip Dobrovolny (fdobrovo@redhat.com) Justin Garrison (justinleegarrison@gmail.com) diff --git a/ci/ansible/pulp_build_box.yml b/ci/ansible/pulp_build_box.yml new file mode 100644 index 00000000..1e6c9007 --- /dev/null +++ b/ci/ansible/pulp_build_box.yml @@ -0,0 +1,4 @@ +--- +- hosts: all + roles: + - role: pulp-build \ No newline at end of file diff --git a/ci/ansible/pulp_build_environment.yml b/ci/ansible/pulp_build_environment.yml new file mode 100644 index 00000000..ff889cff --- /dev/null +++ b/ci/ansible/pulp_build_environment.yml @@ -0,0 +1,7 @@ +--- +- hosts: all + roles: + - role: pulp-packer + - role: pulp-virtualbox + - role: pulp-libvirtd + - role: pulp-galaxy-ansible \ No newline at end of file diff --git a/ci/ansible/roles/pulp-build/tasks/main.yml b/ci/ansible/roles/pulp-build/tasks/main.yml new file mode 100644 index 00000000..1386fd20 --- /dev/null +++ b/ci/ansible/roles/pulp-build/tasks/main.yml @@ -0,0 +1,20 @@ +--- +- name: Update box version + lineinfile: + path: pulpcore.json + regexp: 'version' + line: "\"version\": \"{{ '%Y%m%d' | strftime }}\"" + +- name: Reboot Server + command: /sbin/shutdown -r + async: 0 + poll: 0 + +- name: Wait for remote host to reboot + wait_for_connection: + delay: 60 + +- name: Build image + command: packer build -var 'vagrant_cloud_token'={{ vagrant_cloud_token }} -force -parallel=false {{ ansible_user_dir }}/pulpcore.json + async: 0 + poll: 0 \ No newline at end of file diff --git a/ci/ansible/roles/pulp-galaxy-ansible/defaults/main.yml b/ci/ansible/roles/pulp-galaxy-ansible/defaults/main.yml new file mode 100644 index 00000000..64b7505b --- /dev/null +++ b/ci/ansible/roles/pulp-galaxy-ansible/defaults/main.yml @@ -0,0 +1,2 @@ +--- +box_name: pulp/pulpcore \ No newline at end of file diff --git a/ci/ansible/roles/pulp-galaxy-ansible/files/motd b/ci/ansible/roles/pulp-galaxy-ansible/files/motd new file mode 100644 index 00000000..be4d5aaf --- /dev/null +++ b/ci/ansible/roles/pulp-galaxy-ansible/files/motd @@ -0,0 +1,8 @@ + +Welcome to the Pulp 3 dev environment! + +To get you started, we have built a nice plugin writer's guide for +you - https://docs.pulpproject.org/en/3.0/nightly/plugins/plugin-writer/ and you can +also ask questions in #pulp on Freenode IRC. + +Happy hacking, and thanks for your contribution! \ No newline at end of file diff --git a/ci/ansible/roles/pulp-galaxy-ansible/tasks/main.yml b/ci/ansible/roles/pulp-galaxy-ansible/tasks/main.yml new file mode 100644 index 00000000..17d28959 --- /dev/null +++ b/ci/ansible/roles/pulp-galaxy-ansible/tasks/main.yml @@ -0,0 +1,28 @@ +--- +- name: Download installation playbook + get_url: + url: https://raw.githubusercontent.com/pulp/devel/3.0-dev/ansible/deploy-pulp3.yml + dest: "{{ ansible_user_dir }}" + +- name: Download requirements.yml + get_url: + url: https://raw.githubusercontent.com/pulp/devel/3.0-dev/ansible/requirements.yml + dest: "{{ ansible_user_dir }}" + +- name: Install ansible + package: + name: ansible + state: installed + +- name: Install ansible galaxy roles + command: ansible-galaxy install -r requirements.yml + +- name: Export motd + copy: + src: motd + dest: "{{ ansible_user_dir }}/motd" + +- name: Export packer template + template: + src: pulpcore.json.jj2 + dest: "{{ ansible_user_dir }}/pulpcore.json" \ No newline at end of file diff --git a/ci/ansible/roles/pulp-galaxy-ansible/templates/pulpcore.json.jj2 b/ci/ansible/roles/pulp-galaxy-ansible/templates/pulpcore.json.jj2 new file mode 100644 index 00000000..2bc885e5 --- /dev/null +++ b/ci/ansible/roles/pulp-galaxy-ansible/templates/pulpcore.json.jj2 @@ -0,0 +1,100 @@ +{ + "variables": { + "vagrant_cloud_token": "" + }, + "builders": + [ + { + "type": "virtualbox-ovf", + "source_path": "{{ ovf_path }}", + "ssh_username": "vagrant", + "ssh_password": "vagrant", + "ssh_port": 22, + "ssh_wait_timeout": "60s" , + "headless": true, + "boot_wait": "10s", + {% raw %} + "vboxmanage": [ + ["modifyvm", "{{.Name}}", "--memory", "4096"], + ["modifyvm", "{{.Name}}", "--natdnshostresolver1", "on"] + ], + {% endraw %} + "shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now" + }, + { + "type": "qemu", + "accelerator": "kvm", + "iso_url": "{{ img_path }}", + "iso_checksum_type": "none", + "qemu_binary": "qemu-kvm", + "ssh_username": "vagrant", + "ssh_password": "vagrant", + "ssh_port": 22, + "ssh_wait_timeout": "60s", + "headless": true, + "boot_wait": "10s", + "disk_image": true, + "disk_size": 40960, + "qemuargs": [ + [ "-m", "4096M" ] + ], + "shutdown_command": "echo 'vagrant' | sudo -S shutdown -P now" + } + ], + "provisioners": + [ + { + "type": "file", + "source": "motd", + "destination": "/tmp/motd" + }, + { + "type":"shell", + "only": ["virtualbox-ovf"], + "inline": [ + "sudo mkdir -p /tmp/vboxguest", + "sudo mount -t iso9660 -o loop /home/vagrant/VBoxGuestAdditions.iso /tmp/vboxguest", + "cd /tmp/vboxguest", + "sudo dnf -y install dkms kernel-devel-$(uname -r) gcc", + "sudo ./VBoxLinuxAdditions.run", + "cd /tmp", + "sudo umount /tmp/vboxguest", + "sudo rmdir /tmp/vboxguest", + "rm /home/vagrant/VBoxGuestAdditions.iso" + ] + }, + { + "type":"ansible", + "playbook_file": "deploy-pulp3.yml", + "user": "vagrant" + }, + { + "type":"shell", + "inline": [ + "sudo mv /tmp/motd /etc/motd", + "sudo rm /etc/yum.repos.d/epel.repo", + "sudo dnf -y install git httpie", + "echo 'machine localhost' >> /home/vagrant/.netrc", + "echo 'login admin' >> /home/vagrant/.netrc", + "echo 'password admin' >> /home/vagrant/.netrc", + "sudo sed -i 's/enforcing/permissive/' /etc/selinux/config" + ] + } + ], + "post-processors": + [ + [ + { + "type": "vagrant" + }, + { + "type": "vagrant-cloud", + {% raw %} + "access_token": "{{user `vagrant_cloud_token`}}", + {% endraw %} + "box_tag": "{{ box_name }}", + "version": "{{ '%Y%m%d' | strftime }}" + } + ] + ] +} \ No newline at end of file diff --git a/ci/ansible/roles/pulp-libvirtd/files/custom.sh b/ci/ansible/roles/pulp-libvirtd/files/custom.sh new file mode 100644 index 00000000..e44bf94e --- /dev/null +++ b/ci/ansible/roles/pulp-libvirtd/files/custom.sh @@ -0,0 +1 @@ +PATH=$PATH:/usr/libexec \ No newline at end of file diff --git a/ci/ansible/roles/pulp-libvirtd/tasks/main.yml b/ci/ansible/roles/pulp-libvirtd/tasks/main.yml new file mode 100644 index 00000000..421db722 --- /dev/null +++ b/ci/ansible/roles/pulp-libvirtd/tasks/main.yml @@ -0,0 +1,67 @@ +--- +- name: Install KVM and its dependencies + package: + name: "{{ item }}" + state: present + with_items: + - qemu-kvm + - qemu-img + - virt-manager + - libvirt + - libvirt-python + - libvirt-client + - virt-install + - virt-viewer + - bridge-utils + +- name: Ensure /etc/profile.d/custom.sh exists + file: + path: /etc/profile.d/custom.sh + state: touch + +- name: Add /usr/libexec to $PATH + copy: + dest: /etc/profile.d/custom.sh + content: 'PATH=$PATH:/usr/libexec' + +- name: Add /usr/libexec to $PATH + copy: + dest: /etc/profile.d/ + src: custom.sh + +- name: Start and enable libvirtd service + systemd: + name: libvirtd + state: started + enabled: yes + +- name: Get KVM status + systemd: + name: libvirtd + register: libvirt + +- name: Check if kernel modules are loaded and active + fail: + msg: "The Kernel Modules are inactive or not loaded" + when: (libvirt.status.ActiveState != 'active') or + (libvirt.status.LoadState != 'loaded') + +- name: Add F26 libvirt box + command: vagrant box add fedora/26-cloud-base --provider libvirt --force + register: check_if_added + until: not check_if_added | failed + +- name: Find img file for Fedora box + find: + paths: ~/.vagrant.d/boxes/fedora-VAGRANTSLASH-26-cloud-base + recurse: yes + patterns: 'box.img' + register: results + +- assert: + that: results['matched'] == 1 + msg: "More than one .img files were found for Fedora box" + +- name: Set img file path + set_fact: + img_path: "{{ results['files'][0]['path'] }}" \ No newline at end of file diff --git a/ci/ansible/roles/pulp-packer/defaults/main.yml b/ci/ansible/roles/pulp-packer/defaults/main.yml new file mode 100644 index 00000000..be3f218f --- /dev/null +++ b/ci/ansible/roles/pulp-packer/defaults/main.yml @@ -0,0 +1,3 @@ +--- +packer_install_directory: "/usr/local/bin" +packer_version: 1.1.3 \ No newline at end of file diff --git a/ci/ansible/roles/pulp-packer/tasks/main.yml b/ci/ansible/roles/pulp-packer/tasks/main.yml new file mode 100644 index 00000000..659e6973 --- /dev/null +++ b/ci/ansible/roles/pulp-packer/tasks/main.yml @@ -0,0 +1,45 @@ +--- +- name: Check if packer is already installed + stat: + path: "{{ packer_install_directory }}/packer_{{ packer_version }}/packer" + register: check_existing_packer + +- block: + - name: Create packer version directory + file: + name: "{{ packer_install_directory }}/packer_{{ packer_version }}" + state: directory + + - name: Download packer archive + get_url: + url: "https://releases.hashicorp.com/packer/{{ packer_version }}/packer_{{ packer_version }}_linux_{{ ansible_architecture|regex_replace('x86_64','amd64') }}.zip" + dest: "{{ packer_install_directory }}/packer_{{ packer_version }}/" + timeout: 1000 + register: download_packer_archive + + - name: Install unzip + package: + name: unzip + when: download_packer_archive.changed + + - name: Unarchive packer + unarchive: + src: "{{ packer_install_directory }}/packer_{{ packer_version }}/packer_{{ packer_version }}_linux_{{ ansible_architecture|regex_replace('x86_64','amd64') }}.zip" + dest: "{{ packer_install_directory }}/packer_{{ packer_version }}/" + remote_src: yes + when: download_packer_archive.changed + + - name: Remove packer archive + file: + path: "{{ packer_install_directory }}/packer_{{ packer_version }}/packer_{{ packer_version }}_linux_{{ ansible_architecture|regex_replace('x86_64','amd64') }}.zip" + state: absent + + when: not check_existing_packer.stat.exists + +- name: Symlink packer to correct version + file: + path: "{{ packer_install_directory }}/packer" + src: "{{ packer_install_directory }}/packer_{{ packer_version }}/packer" + state: link + force: yes + mode: 0777 \ No newline at end of file diff --git a/ci/ansible/roles/pulp-virtualbox/defaults/main.yml b/ci/ansible/roles/pulp-virtualbox/defaults/main.yml new file mode 100644 index 00000000..65ba5396 --- /dev/null +++ b/ci/ansible/roles/pulp-virtualbox/defaults/main.yml @@ -0,0 +1,4 @@ +--- +virtualbox_repo: http://download.virtualbox.org/virtualbox/rpm/rhel/virtualbox.repo +virtualbox_key: https://www.virtualbox.org/download/oracle_vbox.asc +vagrant_url: https://releases.hashicorp.com/vagrant/2.0.1/vagrant_2.0.1_x86_64.rpm \ No newline at end of file diff --git a/ci/ansible/roles/pulp-virtualbox/tasks/main.yml b/ci/ansible/roles/pulp-virtualbox/tasks/main.yml new file mode 100644 index 00000000..53a93707 --- /dev/null +++ b/ci/ansible/roles/pulp-virtualbox/tasks/main.yml @@ -0,0 +1,88 @@ +--- +- name: Update + yum: + name: "*" + state: latest + register: updated + +- name: Reboot Server + command: /sbin/shutdown -r + poll: 0 + when: updated | changed + +- name: Wait for remote host to reboot + wait_for_connection: + delay: 60 + when: updated | changed + +- name: Get VirtualBox repo file + get_url: + url: "{{ virtualbox_repo }}" + dest: /etc/yum.repos.d/virtualbox.repo + +- name: Get VirtualBox GPG key + rpm_key: + key: "{{ virtualbox_key }}" + state: present + +- name: Add repository + yum: + name: https://dl.fedoraproject.org/pub/epel/epel-release-latest-{{ ansible_distribution_major_version }}.noarch.rpm + state: present + +- name: Add EPEL GPG key + rpm_key: + key: /etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-{{ ansible_distribution_major_version }} + state: present + +- name: Install VirtualBox and its dependencies + package: + name: "{{ item }}" + state: present + with_items: + - kernel-devel + - dkms + - gcc + - make + - VirtualBox-5.1 + +- name: Compile Kernel modules + command: /sbin/vboxconfig + +- name: Get Virtual Box status + systemd: + name: vboxdrv + register: vbox + +- name: Check if kernel modules are loaded and active + fail: + msg: "The Kernel Modules are inactive or not loaded" + when: (vbox.status.ActiveState != 'active') or + (vbox.status.LoadState != 'loaded') + +- name: Install vagrant + package: + name: "{{ vagrant_url }}" + state: present + register: check_if_installed + until: not check_if_installed | failed + +- name: Add F26 virtualbox + command: vagrant box add fedora/26-cloud-base --provider virtualbox --force + register: check_if_added + until: not check_if_added | failed + +- name: Find ovf file for Fedora box + find: + paths: ~/.vagrant.d/boxes/fedora-VAGRANTSLASH-26-cloud-base + recurse: yes + patterns: 'box.ovf' + register: results + +- assert: + that: results['matched'] == 1 + msg: "More than one .ovf files were found for Fedora box" + +- name: Set ovf file path + set_fact: + ovf_path: "{{ results['files'][0]['path'] }}" \ No newline at end of file diff --git a/ci/jjb/jobs/projects.yaml b/ci/jjb/jobs/projects.yaml index f6b2f30e..876b4f8f 100644 --- a/ci/jjb/jobs/projects.yaml +++ b/ci/jjb/jobs/projects.yaml @@ -108,6 +108,16 @@ jobs: - pulp-3-installer +- project: + name: pulp-3-build-box + jobs: + - pulp-3-build-box + +- project: + name: pulp-3-build-environment + jobs: + - pulp-3-build-environment + - project: name: pulp-upgrade os: diff --git a/ci/jjb/jobs/pulp-3-build-box.yml b/ci/jjb/jobs/pulp-3-build-box.yml new file mode 100644 index 00000000..910b49e9 --- /dev/null +++ b/ci/jjb/jobs/pulp-3-build-box.yml @@ -0,0 +1,59 @@ +- job: + name: pulp-3-build-box + concurrent: true + node: 'fedora-np' + description: | +

+ Build Vagrant box pre-installed with Pulp 3 on the host identified by the job parameter + HOSTNAME. +

+

+ This job requires two hosts: one for use as an Ansible control host, and + one on which to build the Vagrant box. Jenkins is responsible for providing the + control host, and you are responsible for providing the build environment. + When this job is executed, Jenkins will configure the control host, by + doing things like installing Ansible and configuring SSH keys. Then, the + control host will reach out and build a Vagrant box onto the host identified + by HOSTNAME. +

+

+ Ensure the following is in ~/.ssh/authorized_keys on the + Pulp 3 host: +

+
+        ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6DJ8fmd61DWPCMiOEuy96ajI7rL3rWu7C9NQhE9a4SfyaiBcghREHJNCz9LGJ57jtOmNV0+UEDhyvTckZI2YQeDqGCP/xO9B+5gQNlyGZ9gSmFz+68NhYQ0vRekikpb9jNdy6ZZbfZDLp1w7dxqDIKfoyu7QO3Qr3E/9CpiucQif2p+oQOVOCdKEjvGYNkYQks0jVTYNRscgmcezpfLKhqWzAre5+JaMB0kRD5Nqadm2uXKZ4cNYStrpZ4xUrnMvAqjormxW2VJNx+0716Wc2Byhg8Nva+bsOkxp/GewBWHfNPtzQGMsL7oYZPtOd/LrmyYeu/M5Uz7/6QCv4N90P pulp
+      
+

+ In addition, ensure the build environment satisfies the managed + node requirements. +

+ parameters: + - string: + name: HOSTNAME + default: 10.13.129.54 + - string: + name: USER + default: root + properties: + - dev-ownership + scm: + - git: + url: https://github.com/pulp/pulp-ci.git + triggers: + - timed: "H 2 * * *" + wrappers: + - jenkins-ssh-credentials + - credentials-binding: + - text: + credential-id: 3fd73f04-16df-42dc-bbcf-2911d7406f62 + variable: VAGRANT_CLOUD_TOKEN + builders: + - shell: | + sudo dnf -y install ansible + echo "${HOSTNAME} ansible_user=${USER}" > hosts + export ANSIBLE_HOST_KEY_CHECKING=False + ansible-playbook ci/ansible/pulp_build_box.yml --extra-vars "vagrant_cloud_token=${VAGRANT_CLOUD_TOKEN}" -i hosts + publishers: + - email-notify-owners + - mark-node-offline \ No newline at end of file diff --git a/ci/jjb/jobs/pulp-3-build-environment.yaml b/ci/jjb/jobs/pulp-3-build-environment.yaml new file mode 100644 index 00000000..da1b832c --- /dev/null +++ b/ci/jjb/jobs/pulp-3-build-environment.yaml @@ -0,0 +1,52 @@ +- job: + name: pulp-3-build-environment + concurrent: true + node: 'fedora-np' + description: | +

+ Prepare build environment for building Vagrant box pre-installed with Pulp 3 on the host identified by the job parameter + HOSTNAME. +

+

+ This job requires two hosts: one for use as an Ansible control host, and + one on which to configure Packer and other necessary stuff. Jenkins is responsible + for providing the control host, and you are responsible for providing the build environment. + When this job is executed, Jenkins will configure the control host, by doing things + like installing Ansible and configuring SSH keys. Then, the control host will reach out + and configure Packer and other things onto the host identified by HOSTNAME. +

+

+ Ensure the following is in ~/.ssh/authorized_keys on the + Pulp 3 host: +

+
+        ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC6DJ8fmd61DWPCMiOEuy96ajI7rL3rWu7C9NQhE9a4SfyaiBcghREHJNCz9LGJ57jtOmNV0+UEDhyvTckZI2YQeDqGCP/xO9B+5gQNlyGZ9gSmFz+68NhYQ0vRekikpb9jNdy6ZZbfZDLp1w7dxqDIKfoyu7QO3Qr3E/9CpiucQif2p+oQOVOCdKEjvGYNkYQks0jVTYNRscgmcezpfLKhqWzAre5+JaMB0kRD5Nqadm2uXKZ4cNYStrpZ4xUrnMvAqjormxW2VJNx+0716Wc2Byhg8Nva+bsOkxp/GewBWHfNPtzQGMsL7oYZPtOd/LrmyYeu/M5Uz7/6QCv4N90P pulp
+      
+

+ In addition, ensure the build environment satisfies the managed + node requirements. +

+ parameters: + - string: + name: HOSTNAME + default: 10.13.129.54 + - string: + name: USER + default: root + properties: + - dev-ownership + scm: + - git: + url: https://github.com/pulp/pulp-ci.git + wrappers: + - jenkins-ssh-credentials + builders: + - shell: | + sudo dnf -y install ansible + echo "${HOSTNAME} ansible_user=${USER}" > hosts + export ANSIBLE_HOST_KEY_CHECKING=False + ansible-playbook ci/ansible/pulp_build_environment.yml -i hosts + publishers: + - email-notify-owners + - mark-node-offline \ No newline at end of file