sts-sponsors team mailing list archive
-
sts-sponsors team
-
Mailing list archive
-
Message #08050
[Merge] ~lloydwaltersj/maas-ci/+git/maas-ci-config:fix-external-gh-testers into maas-ci:maas-submodules-sync
Jack Lloyd-Walters has proposed merging ~lloydwaltersj/maas-ci/+git/maas-ci-config:fix-external-gh-testers into maas-ci:maas-submodules-sync.
Commit message:
add missing "JOB_NAME" param to ansible-collection job creator.
Requested reviews:
MAAS Committers (maas-committers)
For more details, see:
https://code.launchpad.net/~lloydwaltersj/maas-ci/+git/maas-ci-config/+merge/442267
--
Your team MAAS Committers is requested to review the proposed merge of ~lloydwaltersj/maas-ci/+git/maas-ci-config:fix-external-gh-testers into maas-ci:maas-submodules-sync.
diff --git a/README.txt b/README.txt
new file mode 100644
index 0000000..8b5ec61
--- /dev/null
+++ b/README.txt
@@ -0,0 +1,52 @@
+This is the configuration for all the MAAS CI jobs running
+on MAAS' CI (see http://goo.gl/Dxz6eW for details).
+
+Installation and configuration
+==============================
+
+Install jenkins-job-builder and jenkins-jobs-mattermost.
+
+ $ pip3 install jenkins-job-builder
+ $ pip3 install git+https://github.com/jovandeginste/jenkins-jobs-mattermost/
+
+
+Job definition generation
+=========================
+
+Once you've made changes to the CI config, you can generate the
+job definition using:
+
+ $ jenkins-jobs --conf jenkins/jobs/config.ini test jenkins/jobs/ \
+ -o /tmp/jobs-definitions/
+
+If you want to compare this with what's actually running on the Jenkins
+instance, you need to compare this output with what's on the Jenkins server.
+
+
+Job definition deployment
+=========================
+
+Once you're happy with the changes, you can deploy your changes to Jenkins:
+
+ $ jenkins-jobs --conf jenkins/jobs/config.ini update jenkins/jobs/
+
+Or you can run the update script in jenkins/jobs/
+
+ $ ./update
+
+
+Generating images
+=================
+
+There's a script, bin/generate-images, that should be used to generate
+the images needed for autopkgtest.
+
+It is meant to be run on the Jenkins slave directly, from within this
+repository
+
+It uses autopkgtest-buildvm-ubuntu-cloud to build the images, and it
+passes in custom user-data in order to configure the networking for the
+autopkgtest VM.
+
+The user-data in etc/ is copied from autopkgtest-buildvm-ubuntu-cloud,
+with the addition that it replaces the network configuration at the end.
diff --git a/bin/generate-images b/bin/generate-images
new file mode 100755
index 0000000..c7fdf66
--- /dev/null
+++ b/bin/generate-images
@@ -0,0 +1,75 @@
+#!/usr/bin/python3
+"""Generate the images needed for the CI jobs.
+
+It goes through the definitions in combined.yml and gets all the
+specified releases. If the structure of the job definitiions changes,
+this script needs to be updated to match.
+
+It is meant to be run on the Jenkins slave when no CI tests are in
+progress. To speed up adding new releases, it will only generate images
+that don't already exist. If you want to regenerate an image, you will
+have to remove it first.
+
+It is assume that this repository lives in ~/maas-ci, and the generated images in ~/images.
+"""
+
+from pathlib import Path
+import shutil
+import subprocess
+import sys
+
+
+import yaml
+
+
+IMAGES_PATH = Path('../other-os-images')
+IMAGE_NAMES = ['windows-win2012hvr2-amd64-root-dd', 'rhel7-amd64-root-tgz']
+
+
+def main():
+ with open('jenkins/jobs/combined.yml', 'r') as yaml_file:
+ job_definitions = yaml.safe_load(yaml_file)
+ releases = set()
+ for item in job_definitions:
+ if 'job-group' in item:
+ job_group = item['job-group']
+ if 'release' in job_group:
+ releases.add(job_group['release'])
+
+ images_dir = Path('..') / 'images'
+ for release in releases:
+ expected_filename = f'autopkgtest-{release}-amd64.img'
+ if not images_dir.joinpath(expected_filename).exists():
+ print(f'Generating {expected_filename}')
+ user_data_path = Path('etc/user-data')
+ release_user_data_path = Path(f'etc/user-data-{release}')
+ if release_user_data_path.exists():
+ user_data_path = release_user_data_path
+ build_vm_cmd = [
+ 'autopkgtest-buildvm-ubuntu-cloud', '-r', release, '-a',
+ 'amd64', '-s', '60G', '-p', 'http://squid.internal:3128',
+ '-o', str(images_dir), '--userdata', str(user_data_path),
+ '--verbose']
+ subprocess.run(build_vm_cmd, check=True)
+ print("Copying other OSes images")
+ ubuntu_image_path = images_dir.joinpath(expected_filename)
+ subprocess.run(
+ ['sudo', 'qemu-nbd', '-c', '/dev/nbd0',
+ str(ubuntu_image_path)], check=True)
+ try:
+ subprocess.run(
+ ['sudo', 'mount', '-t', 'auto', '/dev/nbd0p1', '/mnt'],
+ check=True)
+ for image_name in IMAGE_NAMES:
+ image_path = IMAGES_PATH.joinpath(image_name)
+ shutil.copyfile(
+ str(image_path),
+ Path('/mnt/home/ubuntu').joinpath(image_name))
+ subprocess.run(['sudo', 'umount', '-f', '/mnt'])
+ finally:
+ subprocess.run(
+ ['sudo', 'qemu-nbd', '-d', '/dev/nbd0'], check=True)
+
+
+if __name__ == '__main__':
+ sys.exit(main())
diff --git a/bin/jenkinstrigger.py b/bin/jenkinstrigger.py
new file mode 100755
index 0000000..71dae21
--- /dev/null
+++ b/bin/jenkinstrigger.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+import sys
+import errno
+
+from bzrlib import plugin
+from bzrlib.branch import Branch
+from jenkinsapi.jenkins import Jenkins
+
+# Load plugins so we can use lp: URLs
+plugin.load_plugins()
+
+JENKINS_URL = 'http://162.213.35.104:8080/'
+JENKINS_USER = 'admin'
+JENKINS_PASSWORD = 'Ieg5eipu'
+
+
+def branch_url_to_filename(branch_url):
+ return branch_url.replace('/', '-')
+
+
+def get_current_revno(branch_url):
+ branch = Branch.open(branch_url)
+ return branch.revno()
+
+
+def get_last_revno(branch_url):
+ try:
+ last_revno = open(branch_url_to_filename(branch_url), "rb").read()
+ except IOError as e:
+ if e.errno == errno.ENOENT:
+ # Can't find the file, assume it's the first run.
+ last_revno = 0
+ else:
+ raise
+ return int(last_revno)
+
+
+def save_revno(branch_url, revno):
+ with open(branch_url_to_filename(branch_url), 'wb') as f:
+ f.write(str(revno))
+
+
+def main(argv):
+ # Usage:
+ # jenkinstrigger.py <job-name>
+ job_name = argv[1]
+ jenkins = Jenkins(JENKINS_URL, username=JENKINS_USER, password=JENKINS_PASSWORD)
+ job = jenkins.get_job(job_name)
+ for param in job.get_params():
+ if param.get('name') == 'MAAS_BRANCH':
+ maas_branch_url = param.get('defaultParameterValue')['value']
+ elif param.get('name') == 'PACKAGING_BRANCH':
+ packaging_url = param.get('defaultParameterValue')['value']
+
+ current_maas_revno = get_current_revno(maas_branch_url)
+ current_packaging_revno = get_current_revno(packaging_url)
+ last_maas_revno = get_last_revno(maas_branch_url)
+ last_packaging_revno = get_last_revno(packaging_url)
+
+ if (current_maas_revno > last_maas_revno or
+ current_packaging_revno > last_packaging_revno):
+
+ params = {
+ 'MAAS_BRANCH_REVNO': current_maas_revno,
+ 'PACKAGING_REVNO': current_packaging_revno,
+ 'MAAS_BRANCH': maas_branch_url,
+ 'PACKAGING_BRANCH': packaging_url
+ }
+ print("Building %s with %s" % (job_name, params))
+ job.invoke(build_params=params)
+ save_revno(maas_branch_url, current_maas_revno)
+ save_revno(packaging_url, current_packaging_revno)
+ else:
+ print ("Not running tests because:\n"
+ "%s (revno: %s) <= %s\n"
+ "%s (revno: %s) <= %s\n" % (
+ maas_branch_url, current_maas_revno, last_maas_revno,
+ packaging_url, current_packaging_revno, last_packaging_revno))
+
+
+if __name__ == '__main__':
+ main(sys.argv)
diff --git a/etc/meta-data-orobas b/etc/meta-data-orobas
new file mode 100644
index 0000000..9271c4b
--- /dev/null
+++ b/etc/meta-data-orobas
@@ -0,0 +1,18 @@
+instance-id: nocloud
+package_upgrade: false
+network:
+ version: 2
+ ethernets:
+ ens3:
+ dhcp4: true
+ ens4:
+ addresses:
+ - 10.246.88.6/22
+ - 2001:67c:1562:800a::6/64
+ gateway4: 10.246.88.1
+ gateway6: fe80::1
+ nameservers:
+ addresses:
+ - 10.245.136.1
+ - fe80::1
+local-hostname: autopkgtest-orobas
diff --git a/etc/orobas.cfg b/etc/orobas.cfg
new file mode 100644
index 0000000..9a1bef6
--- /dev/null
+++ b/etc/orobas.cfg
@@ -0,0 +1,24 @@
+# qemu config file
+[net]
+ type = "bridge"
+ vlan = "1"
+ br = "br0"
+ helper = "/usr/lib/qemu-bridge-helper"
+
+[net]
+ type = "nic"
+ model = "virtio"
+ macaddr = "DE:AD:BE:EF:6B:B3"
+ vlan = "1"
+
+# qemu-system-x86_64 -m 512 -nographic -monitor null -netdev bridge,id=hn0,br=br2,helper=/usr/lib/qemu/qemu-bridge-helper -device virtio-net-pci,netdev=hn0,id=nic1 -drive file=/home/andreserl/images/autopkgtest-bionic-amd64.img,if=virtio -enable-kvm
+#[netdev]
+# type = "bridge"
+# id = "hn0"
+# br = "br2"
+# helper = "/usr/lib/qemu-bridge-helper"
+#
+#[device]
+# type = "virtio-net-pci"
+# netdev = "hn0"
+# id = "nic1"
diff --git a/etc/region.cfg b/etc/region.cfg
new file mode 100644
index 0000000..2996469
--- /dev/null
+++ b/etc/region.cfg
@@ -0,0 +1,17 @@
+# qemu config file
+
+# smp-opts match Jenkins host which runs testing
+[smp-opts]
+ cpus = "8"
+ sockets = "1"
+ cores = "8"
+ threads = "1"
+
+[device]
+ driver = "virtio-net-pci"
+ netdev = "br0"
+
+[netdev "br0"]
+ type = "bridge"
+ br = "br0"
+ helper = "/usr/lib/qemu-bridge-helper"
diff --git a/etc/user-data b/etc/user-data
new file mode 100644
index 0000000..c6d181d
--- /dev/null
+++ b/etc/user-data
@@ -0,0 +1,35 @@
+#cloud-config
+locale: en_US.UTF-8
+timezone: Etc/UTC
+password: ubuntu
+chpasswd: { expire: False }
+ssh_pwauth: True
+manage_etc_hosts: True
+apt_proxy: http://squid.internal:3128
+write_files:
+ - path: /etc/netplan/99-maas-networking.yaml
+ content: |
+ network:
+ version: 2
+ ethernets:
+ ens3:
+ dhcp4: false
+
+ ens8:
+ dhcp4: false
+ addresses: [10.245.136.6/21]
+ gateway4: 10.245.136.1
+ nameservers:
+ addresses: [10.245.136.1]
+
+runcmd:
+ - sed -i 's/deb-systemd-invoke/true/' /var/lib/dpkg/info/cloud-init.prerm
+ - mount -r /dev/vdb /mnt
+ - env AUTOPKGTEST_SETUP_VM_UPGRADE=true
+ AUTOPKGTEST_APT_SOURCES_FILE=/mnt/sources.list
+ AUTOPKGTEST_KEEP_APT_SOURCES=no,
+ sh -x /mnt/setup-testbed
+ - if grep -q 'net.ifnames=0' /proc/cmdline; then ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules; update-initramfs -u; fi
+ - umount /mnt
+ - (while [ ! -e /var/lib/cloud/instance/boot-finished ]; do sleep 1; done;
+ rm /etc/netplan/50-cloud-init.yaml; apt-get -y purge cloud-init; shutdown -P now) &
diff --git a/etc/user-data-xenial b/etc/user-data-xenial
new file mode 100644
index 0000000..b130889
--- /dev/null
+++ b/etc/user-data-xenial
@@ -0,0 +1,40 @@
+#cloud-config
+locale: en_US.UTF-8
+timezone: Etc/UTC
+password: ubuntu
+chpasswd: { expire: False }
+ssh_pwauth: True
+manage_etc_hosts: True
+apt_proxy: http://squid.internal:3128
+write_files:
+ - path: /etc/network/interfaces
+ content: |
+ # The loopback network interface
+ auto lo
+ iface lo inet loopback
+
+ # The primary network interface
+ # Don't bring up ens3 automatically as a way to avoid bug 1349891
+ iface ens3 inet manual
+
+ auto ens4
+ iface ens4 inet static
+ address 10.245.136.6
+ netmask 255.255.248.0
+ network 10.245.136.0
+ broadcast 10.245.143.255
+ up route add default gw 10.245.136.1
+ dns-nameservers 10.245.136.1
+
+
+runcmd:
+ - sed -i 's/deb-systemd-invoke/true/' /var/lib/dpkg/info/cloud-init.prerm
+ - mount -r /dev/vdb /mnt
+ - env AUTOPKGTEST_SETUP_VM_UPGRADE=true
+ AUTOPKGTEST_APT_SOURCES_FILE=/mnt/sources.list
+ AUTOPKGTEST_KEEP_APT_SOURCES=no,
+ sh -x /mnt/setup-testbed
+ - if grep -q 'net.ifnames=0' /proc/cmdline; then ln -s /dev/null /etc/udev/rules.d/80-net-setup-link.rules; update-initramfs -u; fi
+ - umount /mnt
+ - (while [ ! -e /var/lib/cloud/instance/boot-finished ]; do sleep 1; done;
+ apt-get -y purge cloud-init; shutdown -P now) &
diff --git a/jenkins-crontab b/jenkins-crontab
new file mode 100644
index 0000000..813c569
--- /dev/null
+++ b/jenkins-crontab
@@ -0,0 +1,29 @@
+# Edit this file to introduce tasks to be run by cron.
+#
+# Each task to run has to be defined through a single line
+# indicating with different fields when the task will be run
+# and what command to run for the task
+#
+# To define the time you can provide concrete values for
+# minute (m), hour (h), day of month (dom), month (mon),
+# and day of week (dow) or use '*' in these fields (for 'any').#
+# Notice that tasks will be started based on the cron's system
+# daemon's notion of time and timezones.
+#
+# Output of the crontab jobs (including errors) is sent through
+# email to the user the crontab file belongs to (unless redirected).
+#
+# For example, you can run a backup of all your user accounts
+# at 5 a.m every week with:
+# 0 5 * * 1 tar -zcf /var/backups/home.tgz /home/
+#
+# For more information see the manual pages of crontab(5) and cron(8)
+#
+# m h dom mon dow command
+#*/6 * * * * $HOME/maas-ci/jenkinstrigger.py maas-utopic-1.7 >> $HOME/maas-ci/maas-utopic-1.7.log
+#*/6 * * * * $HOME/maas-ci/jenkinstrigger.py maas-utopic-1.8 >> $HOME/maas-ci/maas-utopic-1.8.log
+*/3 * * * * $HOME/maas-ci/jenkinstrigger.py maas-trusty-1.7 >> $HOME/maas-ci/maas-trusty-1.7.log
+*/2 * * * * $HOME/maas-ci/jenkinstrigger.py maas-trusty-1.9 >> $HOME/maas-ci/maas-trusty-1.9.log
+*/2 * * * * $HOME/maas-ci/jenkinstrigger.py maas-xenial-2.0 >> $HOME/maas-ci/maas-xenial-2.0.log
+*/2 * * * * $HOME/maas-ci/jenkinstrigger.py maas-xenial-trunk >> $HOME/maas-ci/maas-xenial-trunk.log
+*/2 * * * * $HOME/maas-ci/jenkinstrigger.py maas-yakkety-trunk >> $HOME/maas-ci/maas-yakkety-trunk.log
diff --git a/jenkins/jobs/ansible_collection.groovy b/jenkins/jobs/ansible_collection.groovy
new file mode 100644
index 0000000..be73dc5
--- /dev/null
+++ b/jenkins/jobs/ansible_collection.groovy
@@ -0,0 +1,194 @@
+def updateCommitStatus(repo, commit_sha, state, message) {
+ println "applying ${state} to ${repo} ${commit_sha} with message: ${message}"
+ step([
+ $class: "GitHubCommitStatusSetter",
+ reposSource: [$class: "ManuallyEnteredRepositorySource", url: "${repo}"],
+ commitShaSource: [$class: "ManuallyEnteredShaSource", sha: commit_sha],
+ statusResultSource: [
+ $class: "ConditionalStatusResultSource",
+ results: [[$class: "AnyBuildResult", state: state, message: message]]
+ ]
+ ])
+}
+pipeline {
+ agent {
+ docker {
+ image "ubuntu:${params.SERIES}"
+ args '-u 0:0 -m 4g'
+ label 'ci-lab'
+ registryUrl 'https://maas-ci.internal:5443'
+ registryCredentialsId 'maas-ci-registry'
+ reuseNode true
+ }
+ }
+ options {
+ disableConcurrentBuilds()
+ timeout(time: 6, unit: "HOURS")
+ }
+ stages {
+ stage('Prepare') {
+ steps {
+ withCredentials([
+ sshUserPrivateKey(credentialsId: 'maas-lander-ssh-key', keyFileVariable: 'SSHKEY', usernameVariable: 'SSHUSER')
+ ]) {
+ sh '''
+ if [ ! -z \$http_proxy ]; then
+ echo "Acquire::http::proxy \\"\$http_proxy\\"\\;" > /etc/apt/apt.conf.d/github-ci-proxy
+ echo "Acquire::https::proxy \\"\$http_proxy\\"\\;" >> /etc/apt/apt.conf.d/github-ci-proxy
+
+ mkdir -p ~/.ssh/
+ echo "Host github.com\n HostName ssh.github.com\n Port 443\n ProxyCommand /usr/bin/nc -X connect -x squid.internal %h %p\n" >> ~/.ssh/config
+ fi
+
+ export DEBIAN_FRONTEND=noninteractive
+ apt-get -y update
+ apt install -y git make sudo wget socat netcat python3-pip tox
+
+ useradd ubuntu -d /home/ubuntu
+ mkdir -p /home/ubuntu
+ chown ubuntu:ubuntu /home/ubuntu
+ echo "ubuntu ALL=(ALL) NOPASSWD:ALL" > /etc/sudoers.d/90-docker
+ '''
+ }
+ }
+ }
+ stage('Checkout') {
+ steps{
+ script {
+ currentBuild.description = "${params.GH_REPO}/${params.GH_BRANCH}"
+ }
+ sh '''
+ mkdir -p /opt/ansible_collections/maas
+ git clone ${GH_REPO} --branch ${GH_BRANCH} --depth 1 /opt/ansible_collections/maas/maas
+ env -C /opt/ansible_collections/maas/maas git show --no-patch
+ '''
+ }
+ }
+ stage('Fetch commit sha') {
+ steps {
+ script {
+ env.COMMIT_SHA = sh(script: "git ls-remote ${params.GH_REPO} ${params.GH_BRANCH} | awk \'{print \$1}\'", returnStdout: true).trim()
+ println "commit: ${env.COMMIT_SHA}"
+ }
+ updateCommitStatus(params.TARGET_REPO, env.COMMIT_SHA, "PENDING", "Tests Executing, Awaiting results")
+ }
+ }
+ stage('Install Dependencies') {
+ steps{
+ sh '''
+ sudo -E -u ubuntu pip install git+https://github.com/maas/python-libmaas.git
+ '''
+ }
+ }
+ stage('Setup Env') {
+ steps {
+ withCredentials([string(credentialsId: 'jenkins-maas-token', variable: 'MAAS_API_TOKEN')]){
+ sh '''
+ export no_proxy="${no_proxy:-'localhost'},${MAAS_HOST}"
+ export NO_PROXY="${NO_PROXY:-'localhost'},${MAAS_HOST}"
+ export noproxy="${noproxy:-'localhost'},${MAAS_HOST}"
+ export NOPROXY="${NOPROXY:-'localhost'},${MAAS_HOST}"
+
+ INTEGRATION_CONFIG_PATH="/opt/ansible_collections/maas/maas/tests/integration/integration_config.yaml"
+ MAAS_API_TOKEN_KEY="$(echo $MAAS_API_TOKEN | awk -F: '{print $2}')"
+ MAAS_API_TOKEN_SECRET="$(echo $MAAS_API_TOKEN | awk -F: '{print $3}')"
+ MAAS_API_TOKEN_CLIENT_KEY="$(echo $MAAS_API_TOKEN | awk -F: '{print $1}')"
+
+ sudo ln -s /usr/bin/python3 /usr/bin/python
+
+ cat <<EOF > ${INTEGRATION_CONFIG_PATH}
+ host: "${MAAS_URL}"
+ test_vm_host: "${MAAS_TEST_VMHOST}"
+ test_vm_host_fqdn: "${MAAS_TEST_VMHOST_FQDN}"
+ test_subnet: "${MAAS_TEST_SUBNET}"
+ test_domain: "${MAAS_TEST_DOMAIN}"
+ test_lxd_address: "${MAAS_TEST_LXD_ADDRESS}"
+ test_virsh_host: "${MAAS_TEST_VIRSH_HOST}"
+ token_key: "${MAAS_API_TOKEN_KEY}"
+ token_secret: "${MAAS_API_TOKEN_SECRET}"
+ customer_key: "${MAAS_API_TOKEN_CLIENT_KEY}"
+ EOF
+
+ sudo -E -u ubuntu python3 <<EOF >
+ import os
+
+ from maas.client import connect
+
+
+ maas = connect(os.environ["MAAS_URL"], apikey=os.environ["MAAS_API_TOKEN"])
+
+ rack_controller = maas.rack_controllers.get(system_id=os.environ["PRIMARY_RACK_CONTROLLER"])
+ fabric = maas.fabrics.get(id=0)
+ vlan = fabric.vlans.get_default()
+ vlan.dhcp_on = True
+ vlan.primary_rack = rack_controller
+ vlan.save()
+ EOF
+ '''
+ }
+ }
+ }
+ stage('Test') {
+ steps {
+ withCredentials([string(credentialsId: 'jenkins-maas-token', variable: 'MAAS_API_TOKEN')]) {
+ {% if test_lock is defined and test_lock %}
+ lock('{{ test_lock }}') {
+ sh '''
+ export no_proxy="${no_proxy:-'localhost'},${MAAS_HOST}"
+ export NO_PROXY="${NO_PROXY:-'localhost'},${MAAS_HOST}"
+ export noproxy="${noproxy:-'localhost'},${MAAS_HOST}"
+ export NOPROXY="${NOPROXY:-'localhost'},${MAAS_HOST}"
+ cd /opt/ansible_collections/maas/maas
+ sudo -E -H -u ubuntu tox -e integration
+ '''
+ }
+ {% else %}
+ sh '''
+ export no_proxy="${no_proxy:-'localhost'},${MAAS_HOST}"
+ export NO_PROXY="${NO_PROXY:-'localhost'},${MAAS_HOST}"
+ export noproxy="${noproxy:-'localhost'},${MAAS_HOST}"
+ export NOPROXY="${NOPROXY:-'localhost'},${MAAS_HOST}"
+ cd /opt/ansible_collections/maas/maas
+ sudo -E -H -u ubuntu tox -e integration
+ '''
+ {% endif %}
+ }
+ }
+ }
+ }
+ post {
+ always {
+ withCredentials([
+ string(credentialsId: 'jenkins-maas-token', variable: 'MAAS_API_TOKEN'),
+ sshUserPrivateKey(credentialsId: 'maas-lander-ssh-key', keyFileVariable: 'SSHKEY', usernameVariable: 'SSHUSER')
+ ]) {
+ sh '''
+ sudo -E -u ubuntu python3 <<EOF>
+ import os
+
+ from maas.client import connect
+
+
+ maas = connect(os.environ["MAAS_URL"], apikey=os.environ["MAAS_API_TOKEN"])
+
+ fabric = maas.fabrics.get(id=0)
+ vlan = fabric.vlans.get_default()
+ vlan.dhcp_on = False
+ vlan.save()
+ EOF
+ '''
+ }
+ }
+ success {
+ updateCommitStatus(params.TARGET_REPO, env.COMMIT_SHA, "SUCCESS", "Success")
+ }
+ failure {
+ script {
+ if (params.GITHUB_BRANCH == "main" && currentBuild.getBuildCauses("hudson.triggers.TimerTrigger$TimerTriggerCause")) {
+ mattermostSend (color: 'red', message: "[${env.JOB_NAME} #${env.BUILD_NUMBER}](${env.BUILD_URL}) [${params.GH_BRANCH}](${params.GH_REPO}/commit/${env.COMMIT_SHA}) :fire: failed")
+ }
+ }
+ updateCommitStatus(params.TARGET_REPO, env.COMMIT_SHA, "FAILURE", "Failed")
+ }
+ }
+}
diff --git a/jenkins/jobs/ansible_collection.yaml b/jenkins/jobs/ansible_collection.yaml
new file mode 100644
index 0000000..2487e28
--- /dev/null
+++ b/jenkins/jobs/ansible_collection.yaml
@@ -0,0 +1,87 @@
+---
+- project:
+ name: maas-ansible-collection
+ jobs:
+ - 'gh-maas-ansible-collection-creator'
+ - 'gh-maas-ansible-collection-tester'
+
+- job-template:
+ name: gh-maas-ansible-collection-creator
+ description: |
+ Periodically check Github for open Pull Requests against Main that can be tested.
+ Builds gh-maas-ansible-tester aganst each PR
+ project-type: pipeline
+ parameters:
+ - string:
+ name: TARGET_REPO
+ description: Git repo to merge Ansible Collections into
+ default: https://github.com/maas/ansible-collection
+ - string:
+ name: JOB_NAME
+ description: The testing job to trigger when a PR is found.
+ default: gh-maas-ansible-collection-tester
+ triggers:
+ - timed: "H/15 * * * *"
+ dsl: !include-jinja2: gh_repo_tester.groovy
+
+- job-template:
+ name: gh-maas-ansible-collection-tester
+ description: |
+ Run the Ansible Collection Integration Tests
+ project-type: pipeline
+ parameters:
+ - string:
+ name: GH_REPO
+ description: 'Github repo to clone'
+ default: 'ansible-collection'
+ - string:
+ name: GH_BRANCH
+ description: 'Github branch to clone'
+ default: 'main'
+ - string:
+ name: GH_ORG
+ description: 'Github org that owns the repo to clone'
+ default: 'maas'
+ - string:
+ name: SERIES
+ description: 'The Ubuntu series to build and with'
+ default: '22.04'
+ - string:
+ name: GH_USER_NAME
+ description: 'The name to use to commit results and push them'
+ default: 'MAAS Lander'
+ - string:
+ name: GH_USER_EMAIL
+ description: 'The email to use to commit results and push them'
+ default: 'maas-lander@xxxxxxxxxxxxx'
+ - string:
+ name: MAAS_HOST
+ description: "The IP or Hostname used in the MAAS_URL, to be added to NO_PROXY"
+ default: '10.245.136.7'
+ - string:
+ name: PRIMARY_RACK_CONTROLLER
+ description: "The rack controller to manage the VLAN DHCP to be enabled on"
+ default: "ckbafg"
+ - string:
+ name: MAAS_URL
+ description: "The URL to configure the Ansible Collection to test against"
+ default: "http://10.245.136.7:5240/MAAS"
+ - string:
+ name: MAAS_TEST_VMHOST
+ description: "The existing VM Host to use within the ansible tests"
+ default: "natasha.labmaas"
+ - string:
+ name: MAAS_TEST_DOMAIN
+ description: "The default domain of the MAAS env being tested against"
+ default: "labmaas"
+ - string:
+ name: MAAS_TEST_LXD_ADDRESS
+ description: "The LXD address of a host to be added as a VM Host in the tests"
+ default: "opelt.labmaas:5443"
+ - string:
+ name: MAAS_TEST_VIRSH_HOST
+ description: "The host or address to add as a Virsh host in the tests"
+ default: "arm64.labmaas"
+ triggers:
+ - timed: '@daily'
+ dsl: !include-jinja2: ansible_collection.groovy
diff --git a/jenkins/jobs/ansible_playbook.groovy b/jenkins/jobs/ansible_playbook.groovy
new file mode 100644
index 0000000..cc2a552
--- /dev/null
+++ b/jenkins/jobs/ansible_playbook.groovy
@@ -0,0 +1,91 @@
+def updateCommitStatus(repo, commit_sha, state, message) {
+ println "applying ${state} to ${repo} ${commit_sha} with message: ${message}"
+ step([
+ $class: "GitHubCommitStatusSetter",
+ reposSource: [$class: "ManuallyEnteredRepositorySource", url: "${repo}"],
+ commitShaSource: [$class: "ManuallyEnteredShaSource", sha: commit_sha],
+ statusResultSource: [
+ $class: "ConditionalStatusResultSource",
+ results: [[$class: "AnyBuildResult", state: state, message: message]]
+ ]
+ ])
+}
+pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ timeout(time: 6, unit: "HOURS")
+ }
+ stages {
+ stage('Checkout') {
+ steps {
+ sh """
+ rm -rf system-tests
+ git clone ${params.SYSTEMTEST_REPO} --branch ${params.SYSTEMTEST_BRANCH} --depth 1 system-tests
+ env -C system-tests git show --no-patch
+ """
+ }
+ }
+ stage('Setup') {
+ steps {
+ sh """
+ sudo apt-get install -y tox
+ """
+ }
+ }
+ stage('Fetch commit sha') {
+ steps {
+ script {
+ env.COMMIT_SHA = sh(script: "git ls-remote ${params.GITHUB_REPO} ${params.GITHUB_BRANCH} | awk \'{print \$1}\'", returnStdout: true).trim()
+ println "commit: ${env.COMMIT_SHA}"
+ }
+ updateCommitStatus(params.TARGET_REPO, env.COMMIT_SHA, "PENDING", "Tests Executing, Awaiting results")
+ }
+ }
+ stage('System Tests') {
+ steps {
+ writeFile file: 'system-tests/config.yaml', text: """
+ proxy:
+ http: http://squid.internal:3128
+ containers-image: ${params.CONTAINERS_IMAGE}
+ ansible-playbooks:
+ git-repo: ${params.GITHUB_REPO}
+ git-branch: ${params.GITHUB_BRANCH}
+ verbosity: ${params.DEBUG_LEVEL}
+ """
+ dir("system-tests") {
+ sh """
+ cat config.yaml
+ export http_proxy=http://squid.internal:3128/
+ export https_proxy=http://squid.internal:3128/
+ tox r -e cog
+ tox r -e ansible_tests -- ${params.PYTEST_ARGS}
+ """
+ }
+ }
+ }
+ }
+ post {
+ always {
+ archiveArtifacts artifacts:'system-tests/*.log,system-tests/config.yaml,system-tests/junit*.xml', fingerprint: true
+ junit allowEmptyResults: true, testResults: 'system-tests/junit*.xml'
+ sh """
+ lxc delete ansible-main --force || true
+ lxc delete ansible-host-1 --force || true
+ lxc delete ansible-host-2 --force || true
+ """
+ }
+ success {
+ updateCommitStatus(params.TARGET_REPO, env.COMMIT_SHA, "SUCCESS", "Success")
+ }
+ failure {
+ script {
+ if (params.GITHUB_BRANCH == "main" && currentBuild.getBuildCauses("hudson.triggers.TimerTrigger$TimerTriggerCause")) {
+ mattermostSend (color: 'red', message: "[${env.JOB_NAME} #${env.BUILD_NUMBER}](${env.BUILD_URL}) [${params.GITHUB_BRANCH}](${params.GITHUB_REPO}/commit/${env.COMMIT_SHA}) :fire: failed")
+ }
+ }
+ updateCommitStatus(params.TARGET_REPO, env.COMMIT_SHA, "FAILURE", "Failed")
+ }
+ }
+}
diff --git a/jenkins/jobs/ansible_playbook.yaml b/jenkins/jobs/ansible_playbook.yaml
new file mode 100644
index 0000000..d5f5e67
--- /dev/null
+++ b/jenkins/jobs/ansible_playbook.yaml
@@ -0,0 +1,65 @@
+- project:
+ name: ansible-playbook-tests
+ jobs:
+ - ansible-job-creator
+ - ansible-playbook-tests
+
+- job-template:
+ name: ansible-job-creator
+ description: |
+ Periodically check GitHub for open Pull requests against Main that can be tested. Builds ansible-playbook-tests against each PR.
+ project-type: pipeline
+ parameters:
+ - string:
+ name: TARGET_REPO
+ description: Git repo to merge Ansible playbook into
+ default: https://github.com/maas/maas-ansible-playbook
+ - string:
+ name: JOB_NAME
+ description: The testing job to trigger when a PR is found.
+ default: ansible-playbook-tests
+ triggers:
+ - timed: "H/15 * * * *"
+ dsl: !include-jinja2: gh_repo_tester.groovy
+
+- job-template:
+ name: ansible-playbook-tests
+ description: |
+ Run the Ansible Playbook system tests, report the result back to mattermost and GitHub.
+ project-type: pipeline
+ parameters:
+ - string:
+ name: SYSTEMTEST_REPO
+ description: Git repo to pull system tests from
+ default: https://git.launchpad.net/~maas-committers/maas-ci/+git/system-tests
+ - string:
+ name: SYSTEMTEST_BRANCH
+ description: Branch in the repo to use
+ default: master
+ - string:
+ name: GITHUB_REPO
+ description: Git repo to pull Ansible playbook from
+ default: https://github.com/maas/maas-ansible-playbook
+ - string:
+ name: GITHUB_BRANCH
+ description: Branch in the Ansible playbook repo to use
+ default: main
+ - string:
+ name: TARGET_REPO
+ description: Git repo to merge Ansible playbook into
+ default: https://github.com/maas/maas-ansible-playbook
+ - string:
+ name: PYTEST_ARGS
+ description: Additional args to pytest
+ default: --log-cli-level info
+ - string:
+ name: DEBUG_LEVEL
+ description: Debug Level to use in the ansible playbooks (ie -v)
+ default:
+ - string:
+ name: CONTAINERS_IMAGE
+ description: LXD image for containers used in tests
+ default: ubuntu:22.04
+ triggers:
+ - timed: '@daily'
+ dsl: !include-jinja2: ansible_playbook.groovy
diff --git a/jenkins/jobs/combined.yml b/jenkins/jobs/combined.yml
new file mode 100644
index 0000000..2a6526a
--- /dev/null
+++ b/jenkins/jobs/combined.yml
@@ -0,0 +1,1144 @@
+####################################################################################################
+######################################## MACROS ####################################################
+####################################################################################################
+
+- builder:
+ name: maas_adt_git
+ builders:
+ - shell: |
+ #!/bin/bash -ex
+ # Clean-up testing env
+ rm -Rf *
+ export http_proxy="${HTTP_PROXY_ENV}"
+ export https_proxy="${HTTP_PROXY_ENV}"
+ #
+ # Parameter passed to autopkgtest to perform updates in the
+ # testing environment. This does 'apt upgrade'.
+ UPDATES="-U"
+ #
+ # Parameter that defines the RAM size of the VM where MAAS
+ # runs. If it is not set, it will default to 8192 (8G).
+ if [ ! $VM_RAM_SIZE ]; then
+ VM_RAM_SIZE="8192"
+ fi
+ #
+ # If $TEST_PERFORMANCE env variable doesn't exist, set it
+ # here so it doesn't cause the script to fail.
+ if [ ! $TEST_PERFORMANCE ]; then
+ TEST_PERFORMANCE=0
+ fi
+ #
+ # If $CLOUDINIT_PROPOSED env variable doesn't exist, set it
+ # to 0 to ensure it is not mistakenly used.
+ if [ ! $CLOUDINIT_PROPOSED ]; then
+ CLOUDINIT_PROPOSED=0
+ fi
+ #
+ # Build proposed images
+ # Checkout lp:maas-images if it is defined:
+ TEST_CUSTOM_IMAGES=0
+ if [ $MAAS_IMAGES_REPO ]; then
+ TEST_CUSTOM_IMAGES=1
+ git clone ${MAAS_IMAGES_REPO} maas-images
+ PATH=$PATH:./maas-images/bin
+ # Determine what architectures to create streams for
+ STREAM_ARCHES="amd64"
+ if [ $USE_PPC_NODES -ge 1 ]; then
+ STREAM_ARCHES="$STREAM_ARCHES,ppc64el"
+ fi
+ if [ $USE_ARM64_NODES -ge 1 ]; then
+ STREAM_ARCHES="$STREAM_ARCHES,arm64"
+ fi
+ # Create streams for supported LTSes
+ STREAM_RELEASES="xenial|bionic|focal"
+ # If deployment release is different (e.g., non-LTS) we add it to the
+ # streams creation
+ if [ ! $DEPLOYMENT_RELEASE ]; then
+ DEPLOYMENT_RELEASE="$RELEASE"
+ elif [ $DEPLOYMENT_RELEASE != $RELEASE ]; then
+ STREAM_RELEASES="$STREAM_RELEASES|$DEPLOYMENT_RELEASE"
+ fi
+ # Put the images in $WORKSPACE/../ so that it is a shared dir across jobs
+ workspace_root=$(dirname $WORKSPACE)
+ rm -Rf $workspace_root/www/html/images/*
+ if [ ! -d $workspace_root/www/html/images ]; then
+ mkdir -p $workspace_root/www/html/images
+ # NOTE: This may fail, if it does, we may have to create this manually
+ sudo ln -sf $workspace_root/www/html/images /var/www/html/images || true
+ fi
+ # Create images
+ if [ $CLOUDINIT_PROPOSED -eq 0 ]; then
+ meph2-cloudimg-sync --config ./maas-images/conf/meph-v3.yaml --target=force --arches=${STREAM_ARCHES} --max=1 $workspace_root/www/html/images/ "release~(${STREAM_RELEASES})" || exit $?
+ else
+ meph2-cloudimg-sync --config ./maas-images/conf/meph-v3.yaml --target=force --proposed --arches=${STREAM_ARCHES} --max=1 $workspace_root/www/html/images/ "release~(${STREAM_RELEASES})" || exit $?
+ fi
+ # Create & merge bootloaders
+ meph2-import --proposed --no-sign ./maas-images/conf/bootloaders.yaml ./bootloaders || exit $?
+ meph2-util merge --no-sign ./bootloaders $workspace_root/www/html/images || exit $?
+ # Create & merge CentOS
+ if [ $TEST_CENTOS -ge 1 ]; then
+ meph2-import --no-sign --max=1 ./maas-images/conf/centos.yaml ./centos || exit $?
+ meph2-util merge --no-sign ./centos $workspace_root/www/html/images || exit $?
+ fi
+ fi
+ #
+ # Checkout qa-lab-tests
+ bzr checkout --lightweight ${TESTS_BRANCH} qa-lab-tests
+ #
+ # If TEST_PERFORMANCE >= 1, we enable the test of performance tests.
+ # As such, we need to use the performance suite as the control file
+ # instead of the default.
+ if [ $TEST_PERFORMANCE -ge 1 ]; then
+ mv qa-lab-tests/performance-control qa-lab-tests/control
+ # When testing performance, don't update the environment
+ # to gain speed.
+ UPDATES=""
+ fi
+ #
+ # Checkout maas branches if needed, otherwise use dummy package
+ # MAAS_BRANCH = e.g. https://git.launchpad.net/maas
+ # MAAS_BRANCH_ID = e.g. master, 2.1, 2.2, etc
+ # MAAS_BRANCH_REVNO = e.g. HEAD, 179e609cb112041c661e4dd249ef039709e005c4
+ if [ $MAAS_PROPOSED -eq 1 ] || [ ! $MAAS_BRANCH ] || [ $CURTIN_PROPOSED -eq 1 ] || [ $CLOUDINIT_PROPOSED -eq 1 ]; then
+ mv qa-lab-tests/dummy maas
+ else
+ git clone --depth 100 --single-branch --branch ${MAAS_BRANCH_ID} ${MAAS_BRANCH} maas
+ cd maas/
+ git checkout ${MAAS_BRANCH_ID}
+ git reset --hard ${MAAS_BRANCH_REVNO}
+ git submodule update --init --recursive
+ cd ../
+ fi
+ # MAAS and Curtin unbuilt trees to pass to adt.
+ UNBUILT_MAAS_TREE=${PWD}/maas
+ if grep "^package-tree" ${UNBUILT_MAAS_TREE}/Makefile;
+ then
+ # From 2.7, the source tarball is no longer a clean
+ # export of the git tree.
+ make -C ${UNBUILT_MAAS_TREE} package-tree
+ PACKAGE_BUILD_AREA=${UNBUILT_MAAS_TREE}/../build-area
+ UNBUILT_MAAS_TREE=$(
+ find "$PACKAGE_BUILD_AREA" -mindepth 1 -maxdepth 1 -type d | head -n1)
+ fi
+ #
+ # Move working trees into maas branch.
+ # bzr can't branch inside existing branches without a bit of
+ # pain and merge-into plugin doesn't work with new repo format
+ # (see LP: #486245)
+ mv qa-lab-tests ${UNBUILT_MAAS_TREE}/debian/tests
+ #
+ # Obtain revno count from the git revno.
+ export MAAS_BRANCH_REVNO_COUNT=$(git -C maas rev-list --count $MAAS_BRANCH_REVNO)
+ # Overwrite the MAAS_BRANCH_REVNO var with the short revno.
+ export MAAS_BRANCH_REVNO=$(git -C maas rev-parse --short $MAAS_BRANCH_REVNO)
+ # Obtain the version the packaging will use
+ export VER_FOR_PKG="$MAAS_BRANCH_REVNO_COUNT-g$MAAS_BRANCH_REVNO"
+ # XXX: matsubara For now, branch maas-ci-config branch to be able to
+ # source config files. Once the MAAS CI lab is fully charmed and
+ # maas-ci-config works together with the ci-configurator charm,
+ # this won't be necessary anymore.
+ git clone git+ssh://git.launchpad.net/~maas-committers/maas-ci/+git/maas-ci-config
+ source maas-ci-config/maas-ci-common
+ #
+ # Update changelog entry to easily check in the logs the versions
+ # used to build the package.
+ ${UNBUILT_MAAS_TREE}/debian/tests/update_changelog.py ${UNBUILT_MAAS_TREE}/debian/changelog ${VER_FOR_PKG} ci
+ #
+ SETUP_COMMANDS="export http_proxy=${HTTP_PROXY_ENV}; export https_proxy=${HTTP_PROXY_ENV}"
+ # Configure environment setup commands.
+ if [ ! -z $MAAS_PPA ]; then
+ SETUP_COMMANDS="$SETUP_COMMANDS; add-apt-repository -y ${MAAS_PPA}"
+ fi
+ if [ ! -z $CURTIN_PPA ]; then
+ SETUP_COMMANDS="$SETUP_COMMANDS; add-apt-repository -y ${CURTIN_PPA}"
+ fi
+ if [ ! -z $TEST_JUJU ]; then
+ SETUP_COMMANDS="$SETUP_COMMANDS; add-apt-repository -y ppa:juju/devel"
+ fi
+ SETUP_COMMANDS="$SETUP_COMMANDS; apt-get update"
+ # Configure apt environment for proposed.
+ PACKAGES_FROM_PROPOSED=""
+ if [ $CURTIN_PROPOSED -eq 1 ] && [ $MAAS_PROPOSED -eq 1 ]; then
+ PACKAGES_FROM_PROPOSED="--apt-pocket=proposed=src:maas,src:curtin"
+ elif [ $CURTIN_PROPOSED -eq 1 ] && [ $MAAS_PROPOSED -eq 0 ]; then
+ PACKAGES_FROM_PROPOSED="--apt-pocket=proposed=src:curtin"
+ elif [ $CURTIN_PROPOSED -eq 0 ] && [ $MAAS_PROPOSED -eq 1 ]; then
+ PACKAGES_FROM_PROPOSED="--apt-pocket=proposed=src:maas"
+ fi
+
+ #
+ # Run adt.
+ QEMU_CFG=${WORKSPACE}/maas-ci-config/etc/region.cfg
+ QEMU_IMG=${ADT_IMAGES_ROOT}/autopkgtest-${RELEASE}-amd64.img
+ if [ ${CURTIN_PPA} ]; then
+ echo CURTIN_PPA is set - running with Curtin from ${CURTIN_PPA}
+ ${AUTOPKGTEST_ROOT}/runner/autopkgtest ${UPDATES} -ddd --output-dir ${WORKSPACE}/results \
+ --env DEPLOYMENT_RELEASE=${DEPLOYMENT_RELEASE} \
+ --env TEST_JUJU=${TEST_JUJU} \
+ --env TEST_CENTOS=${TEST_CENTOS} \
+ --env TEST_RHEL=${TEST_RHEL} \
+ --env TEST_WINDOWS=${TEST_WINDOWS} \
+ --env TEST_CUSTOM_IMAGES=${TEST_CUSTOM_IMAGES} \
+ --env USE_PPC_NODES=${USE_PPC_NODES} \
+ --env USE_ARM64_NODES=${USE_ARM64_NODES} \
+ --env KEEP_CI_RUNNING=${KEEP_CI_RUNNING} \
+ --env PAUSE_CI=${PAUSE_CI} \
+ --env TEST_PERFORMANCE=${TEST_PERFORMANCE} \
+ --env DEBUG=${DEBUG} \
+ --env SLAVE_NODE=${NODE_NAME} \
+ --setup-commands="$SETUP_COMMANDS" \
+ --timeout-test=20000 \
+ $UNBUILT_MAAS_TREE \
+ -- ${AUTOPKGTEST_ROOT}/virt/autopkgtest-virt-qemu \
+ -d --show-boot \
+ --ram-size ${VM_RAM_SIZE} \
+ --qemu-options -readconfig\ ${QEMU_CFG} ${QEMU_IMG}
+ else
+ echo running with Curtin from archive
+ ${AUTOPKGTEST_ROOT}/runner/autopkgtest ${UPDATES} -ddd --output-dir ${WORKSPACE}/results \
+ --env DEPLOYMENT_RELEASE=${DEPLOYMENT_RELEASE} \
+ --env TEST_JUJU=${TEST_JUJU} \
+ --env TEST_CENTOS=${TEST_CENTOS} \
+ --env TEST_RHEL=${TEST_RHEL} \
+ --env TEST_WINDOWS=${TEST_WINDOWS} \
+ --env TEST_CUSTOM_IMAGES=${TEST_CUSTOM_IMAGES} \
+ --env USE_PPC_NODES=${USE_PPC_NODES} \
+ --env USE_ARM64_NODES=${USE_ARM64_NODES} \
+ --env KEEP_CI_RUNNING=${KEEP_CI_RUNNING} \
+ --env PAUSE_CI=${PAUSE_CI} \
+ --env TEST_PERFORMANCE=${TEST_PERFORMANCE} \
+ --env DEBUG=${DEBUG} \
+ --env SLAVE_NODE=${NODE_NAME} \
+ --setup-commands="$SETUP_COMMANDS" \
+ --timeout-test=20000 \
+ $PACKAGES_FROM_PROPOSED \
+ $UNBUILT_MAAS_TREE \
+ -- ${AUTOPKGTEST_ROOT}/virt/autopkgtest-virt-qemu \
+ -d --show-boot \
+ --ram-size ${VM_RAM_SIZE} \
+ --qemu-options -readconfig\ ${QEMU_CFG} ${QEMU_IMG}
+ fi
+
+ RET=$?
+
+ # EXIT STATUS
+ # 0 all tests passed
+ # 1 unexpected failure (the python interpreter invents this exit status)
+ # 2 at least one test skipped
+ # 4 at least one test failed
+ # 6 at least one test failed and at least one test skipped
+ # 8 no tests in this package
+ # 12 erroneous package
+ # 16 testbed failure
+ # 20 other unexpected failures including bad usage
+
+ # Return "at least one test skipped" as Passed
+ if [ $RET -eq 2 ]; then
+ RET=0
+ fi
+
+ exit $RET
+
+- builder:
+ name: maas_adt_ea
+ builders:
+ - shell: |
+ #!/bin/bash -ex
+ # Clean-up testing env
+ rm -Rf *
+ export http_proxy="${HTTP_PROXY_ENV}"
+ export https_proxy="${HTTP_PROXY_ENV}"
+ # Checkout maas branches
+ # MAAS_BRANCH = e.g. https://git.launchpad.net/maas
+ # MAAS_BRANCH_ID = e.g. master, 2.1, 2.2, etc
+ # MAAS_BRANCH_REVNO = e.g. HEAD, 179e609cb112041c661e4dd249ef039709e005c4
+ git clone --depth 100 --single-branch --branch ${MAAS_BRANCH_ID} ${MAAS_BRANCH} maas
+ cd maas/
+ git checkout ${MAAS_BRANCH_ID}
+ git reset --hard ${MAAS_BRANCH_REVNO}
+ git submodule update --init --recursive
+ cd ../
+ #
+ # Obtain revno count from the git revno.
+ export MAAS_BRANCH_REVNO_COUNT=$(git -C maas rev-list --count $MAAS_BRANCH_REVNO)
+ # Overwrite the MAAS_BRANCH_REVNO var with the short revno.
+ export MAAS_BRANCH_REVNO=$(git -C maas rev-parse --short $MAAS_BRANCH_REVNO)
+ # Obtain the version the packaging will use
+ export VER_FOR_PKG="$MAAS_BRANCH_REVNO_COUNT-g$MAAS_BRANCH_REVNO"
+ #
+ # Checkout qa-lab-tests
+ bzr checkout --lightweight ${TESTS_BRANCH} qa-lab-tests
+ # XXX: matsubara For now, branch maas-ci-config branch to be able to
+ # source config files. Once the MAAS CI lab is fully charmed and
+ # maas-ci-config works together with the ci-configurator charm,
+ # this won't be necessary anymore.
+ git clone git+ssh://git.launchpad.net/~maas-committers/maas-ci/+git/maas-ci-config
+ source maas-ci-config/maas-ci-common
+
+ SETUP_COMMANDS="export http_proxy=${HTTP_PROXY_ENV}; export https_proxy=${HTTP_PROXY_ENV}"
+ # Configure environment setup commands.
+ if [ ! -z $MAAS_PPA ]; then
+ SETUP_COMMANDS="$SETUP_COMMANDS; add-apt-repository -y ${MAAS_PPA}"
+ fi
+ if [ ! -z $CURTIN_PPA ]; then
+ SETUP_COMMANDS="$SETUP_COMMANDS; add-apt-repository -y ${CURTIN_PPA}"
+ fi
+ SETUP_COMMANDS="$SETUP_COMMANDS; apt-get update"
+ #
+ # Move working trees into maas branch.
+ # bzr can't branch inside existing branches without a bit of
+ # pain and merge-into plugin doesn't work with new repo format
+ # (see LP: #486245)
+ mv qa-lab-tests maas/debian/tests
+ #
+ # Update changelog entry to easily check in the logs the versions
+ # used to build the package.
+ ./maas/debian/tests/update_changelog.py maas/debian/changelog ${VER_FOR_PKG} ci
+ # MAAS and Curtin unbuilt trees to pass to adt.
+ UNBUILT_MAAS_TREE=${PWD}/maas
+ if grep "^package-tree" ${UNBUILT_MAAS_TREE}/Makefile;
+ then
+ # From 2.7, the source tarball is no longer a clean
+ # export of the git tree.
+ make -C ${UNBUILT_MAAS_TREE} package-tree
+ PACKAGE_BUILD_AREA=${UNBUILT_MAAS_TREE}/../build-area
+ UNBUILT_MAAS_TREE=$(
+ find "$PACKAGE_BUILD_AREA" -mindepth 1 -maxdepth 1 -type d | head -n1)
+ fi
+ #
+ # Run adt.
+ QEMU_CFG=${WORKSPACE}/maas-ci-config/etc/region.cfg
+ QEMU_IMG=${ADT_IMAGES_ROOT}/autopkgtest-${RELEASE}-amd64.img
+ if [ ${CURTIN_PPA} ]; then
+ echo CURTIN_PPA is set - running with Curtin from ${CURTIN_PPA}
+ ${AUTOPKGTEST_ROOT}/runner/autopkgtest -U -ddd --output-dir ${WORKSPACE}/results \
+ --env TEST_WINDOWS=1 \
+ --env TEST_CENTOS=1 \
+ --env USE_DELL_R630_SYSTEMS=1 \
+ --env KEEP_CI_RUNNING=${KEEP_CI_RUNNING} \
+ --env PAUSE_CI=${PAUSE_CI} \
+ --env DEBUG=${DEBUG} \
+ --setup-commands="$SETUP_COMMANDS" \
+ $UNBUILT_MAAS_TREE \
+ -- ${AUTOPKGTEST_ROOT}/virt/autopkgtest-virt-qemu \
+ -d --show-boot \
+ --ram-size 3072 \
+ --qemu-options -readconfig\ ${QEMU_CFG} ${QEMU_IMG}
+ else
+ echo running with Curtin from archive
+ ${AUTOPKGTEST_ROOT}/runner/autopkgtest -U -ddd --output-dir ${WORKSPACE}/results \
+ --env TEST_WINDOWS=1 \
+ --env TEST_CENTOS=1 \
+ --env USE_DELL_R630_SYSTEMS=1 \
+ --env KEEP_CI_RUNNING=${KEEP_CI_RUNNING} \
+ --env PAUSE_CI=${PAUSE_CI} \
+ --env DEBUG=${DEBUG} \
+ --setup-commands="$SETUP_COMMANDS" \
+ $UNBUILT_MAAS_TREE \
+ -- ${AUTOPKGTEST_ROOT}/virt/autopkgtest-virt-qemu \
+ -d --show-boot \
+ --ram-size 3072 \
+ --qemu-options -readconfig\ ${QEMU_CFG} ${QEMU_IMG}
+ fi
+
+ RET=$?
+
+ # EXIT STATUS
+ # 0 all tests passed
+ # 1 unexpected failure (the python interpreter invents this exit status)
+ # 2 at least one test skipped
+ # 4 at least one test failed
+ # 6 at least one test failed and at least one test skipped
+ # 8 no tests in this package
+ # 12 erroneous package
+ # 16 testbed failure
+ # 20 other unexpected failures including bad usage
+
+ # Return "at least one test skipped" as Passed
+ if [ $RET -eq 2 ]; then
+ RET=0
+ fi
+
+ exit $RET
+
+- parameter:
+ name: notes
+ parameters:
+ - string:
+ name: Notes
+ description: What and why this build is what it is.
+ default: ''
+
+- parameter:
+ name: debug
+ parameters:
+ - string:
+ name: DEBUG
+ default: '1'
+ description: Whether to enable debug logging in MAAS (0 False, 1 True)
+
+- parameter:
+ name: maas_branch
+ parameters:
+ - string:
+ name: MAAS_BRANCH
+ description: MAAS default git repository (https://git.launchpad.net/maas) or custom (https://git.launchpad.net/~<username>/<repository>)
+ default: '{maas_branch}'
+
+- parameter:
+ name: maas_branch_id
+ parameters:
+ - string:
+ name: MAAS_BRANCH_ID
+ description: Branch inside repository (e.g. master, custom_branch)
+ default: '{maas_branch_id}'
+
+- parameter:
+ name: maas_images_repo
+ parameters:
+ - string:
+ name: MAAS_IMAGES_REPO
+ description: Identifier for the branch MAAS Images will use.
+ default: '{maas_images_repo}'
+
+- parameter:
+ name: maas_repo_url
+ parameters:
+ - string:
+ name: MAAS_REPO_URL
+ description: Identifier for the branch MAAS will use.
+ default: '{maas_repo_url}'
+
+- parameter:
+ name: maas_branch_revno
+ parameters:
+ - string:
+ name: MAAS_BRANCH_REVNO
+ description: Branch revision (e.g. HEAD, c9ad0ba, etc)
+ default: '{maas_branch_revno}'
+
+- parameter:
+ name: tests_branch
+ parameters:
+ - string:
+ name: TESTS_BRANCH
+ description: Which integration tests branch to use.
+ default: '{tests_branch}'
+
+- parameter:
+ name: release
+ parameters:
+ - string:
+ name: RELEASE
+ default: '{release}'
+ description: The release to test MAAS on.
+
+- parameter:
+ name: deployment_release
+ parameters:
+ - string:
+ name: DEPLOYMENT_RELEASE
+ default: '{deployment_release}'
+ description: The release used to deploy with if different from RELEASE (e.g. xenial)
+
+- parameter:
+ name: ppa
+ parameters:
+ - string:
+ name: PPA
+ default: '{ppa}'
+ description: The PPA MAAS will be pulled from.
+
+- parameter:
+ name: architecture
+ parameters:
+ - string:
+ name: ARCH
+ default: amd64
+
+- parameter:
+ name: http_proxy_env
+ parameters:
+ - string:
+ name: HTTP_PROXY_ENV
+ default: http://squid.internal:3128
+ description: Default proxy to use in the lab.
+
+- parameter:
+ name: curtin_ppa
+ parameters:
+ - string:
+ name: CURTIN_PPA
+ default: '{curtin_ppa}'
+ description: PPA to take Curtin from
+
+- parameter:
+ name: curtin_proposed
+ parameters:
+ - string:
+ name: CURTIN_PROPOSED
+ default: '{curtin_proposed}'
+ description: Whether to use curtin from -proposed. 0 False. 1 True.
+
+- parameter:
+ name: cloudinit_proposed
+ parameters:
+ - string:
+ name: CLOUDINIT_PROPOSED
+ default: '{cloudinit_proposed}'
+ description: Whether to use cloudinit from -proposed. 0 False. 1 True.
+
+- parameter:
+ name: maas_proposed
+ parameters:
+ - string:
+ name: MAAS_PROPOSED
+ default: '{maas_proposed}'
+ description: Whether to test MAAS from -proposed. 0 False. 1 True.
+
+- parameter:
+ name: maas_ppa
+ parameters:
+ - string:
+ name: MAAS_PPA
+ default: '{maas_ppa}'
+ description: PPA where to get MAAS from (used to verified releases from PPA).
+
+- parameter:
+ name: test_juju
+ parameters:
+ - string:
+ name: TEST_JUJU
+ default: '{test_juju}'
+ description: Whether to test Juju with this MAAS install
+
+- parameter:
+ name: test_windows
+ parameters:
+ - string:
+ name: TEST_WINDOWS
+ default: '{test_windows}'
+ description: Whether to test Windows with this MAAS install
+
+- parameter:
+ name: use_ppc_nodes
+ parameters:
+ - string:
+ name: USE_PPC_NODES
+ default: '{use_ppc_nodes}'
+ description: Whether to use the PPC nodes in the lab
+
+- parameter:
+ name: use_arm64_nodes
+ parameters:
+ - string:
+ name: USE_ARM64_NODES
+ default: '{use_arm64_nodes}'
+ description: Whether to use the ARM64 nodes in the lab
+
+- parameter:
+ name: keep_ci_running
+ parameters:
+ - string:
+ name: KEEP_CI_RUNNING
+ default: '0'
+ description: Keep the CI running after integration tests have finished (or failed).
+
+- parameter:
+ name: pause_ci
+ parameters:
+ - string:
+ name: PAUSE_CI
+ default: '0'
+ description: Pause CI right after new machines have been powered on for enlistment.
+
+- parameter:
+ name: test_performance
+ parameters:
+ - string:
+ name: TEST_PERFORMANCE
+ default: '{test_performance}'
+ description: Test performance by running pods with VM's per deployed machine.
+
+- parameter:
+ name: vm_ram_size
+ parameters:
+ - string:
+ name: VM_RAM_SIZE
+ default: ''
+ description: RAM size for the VM where MAAS runs on. Defaults to 3072
+
+- parameter:
+ name: test_centos
+ parameters:
+ - string:
+ name: TEST_CENTOS
+ default: '{test_centos}'
+ description: Whether or not to test CentOS
+
+- parameter:
+ name: test_rhel
+ parameters:
+ - string:
+ name: TEST_RHEL
+ default: '{test_rhel}'
+ description: Whether or not to test RHEL
+
+- parameter:
+ name: node_name
+ parameters:
+ - string:
+ name: NODE_NAME
+ default: '{node_name}'
+ description: Define in which node to test
+
+# This is just a parameter that defines a job name when creating a job based on a job group
+# and a template.
+- parameter:
+ name: job_name
+ parameters:
+ - string:
+ name: JOB_NAME
+ default: '{job_name}'
+ description: Just a parameter to define a job name.
+
+
+- publisher:
+ name: archive_build_artifacts
+ publishers:
+ - archive:
+ artifacts: 'results/*stderr,results/*stdout,results/*log,results/log,results/*.crash,results/**/*'
+ - junit:
+ results: 'results/artifacts/nosetests.xml'
+ keep-long-stdio: true
+ allow-empty-results: true
+
+- publisher:
+ name: mattermost_announce
+ publishers:
+ - mattermost:
+ notify-start: false
+ notify-aborted: false
+ notify-success: true
+ notify-notbuilt: false
+ notify-unstable: false
+ notify-failure: true
+ notify-backtonormal: false
+ notify-repeatedfailure: false
+ include-test-summary: false
+ show-commit-list: false
+
+- wrapper:
+ name: build_timeout
+ wrappers:
+ - timeout:
+ timeout: 180
+ fail: true
+ type: absolute
+
+- scm:
+ name: maas-branch
+ scm:
+ - git:
+ url: https://git.launchpad.net/maas
+ branches:
+ - '*/${MAAS_BRANCH_ID}'
+ browser: cgit
+ browser-url: https://git.launchpad.net/maas
+ do-not-fetch-tags: true
+ shallow-clone: true
+ timeout: 15 # bumped from 10 mins to account for PS4½ issues
+
+####################################################################################################
+######################################## JOB TEMPLATES #############################################
+####################################################################################################
+
+- job-template:
+ name: 'proposed-maas-images-manual'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ properties:
+ - build-discarder:
+ days-to-keep: 90
+ artifact-days-to-keep: 30
+ parameters:
+ - release:
+ release: focal
+ - maas_branch:
+ maas_branch: https://git.launchpad.net/maas
+ - maas_branch_id:
+ maas_branch_id: 'master'
+ - maas_branch_revno:
+ maas_branch_revno: 'HEAD'
+ - deployment_release:
+ deployment_release: ''
+ - maas_images_repo:
+ maas_images_repo: 'https://git.launchpad.net/maas-images'
+ - tests_branch:
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ - curtin_proposed:
+ curtin_proposed: '0'
+ - curtin_ppa:
+ curtin_ppa: ''
+ - use_arm64_nodes:
+ use_arm64_nodes: '0'
+ - use_ppc_nodes:
+ use_ppc_nodes: '0'
+ - test_centos:
+ test_centos: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+
+- job-template:
+ name: 'maas-{release}-{maas_branch_id}-git'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ properties:
+ - build-discarder:
+ days-to-keep: 90
+ artifact-days-to-keep: 30
+ parameters:
+ - maas_branch:
+ maas_branch: '{maas_branch}'
+ - maas_branch_id:
+ maas_branch_id: '{maas_branch_id}'
+ - maas_branch_revno:
+ maas_branch_revno: '{maas_branch_revno}'
+ - tests_branch:
+ tests_branch: '{tests_branch}'
+ - maas_ppa:
+ maas_ppa: '{maas_ppa}'
+ - curtin_ppa:
+ curtin_ppa: '{curtin_ppa}'
+ - release:
+ release: '{release}'
+ - test_rhel:
+ test_rhel: '0'
+ - test_centos:
+ test_centos: '1'
+ - use_arm64_nodes:
+ use_arm64_nodes: '{use_arm64_nodes}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '{use_ppc_nodes}'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_git
+ scm:
+ - maas-branch
+ triggers:
+ - pollscm:
+ cron: "*/15 * * * *"
+ ignore-post-commit-hooks: true
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: 'maas-{release}-{maas_branch_id}-git-ea'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ properties:
+ - build-discarder:
+ days-to-keep: 90
+ artifact-days-to-keep: 30
+ parameters:
+ - maas_branch:
+ maas_branch: '{maas_branch}'
+ - maas_branch_id:
+ maas_branch_id: '{maas_branch_id}'
+ - maas_branch_revno:
+ maas_branch_revno: '{maas_branch_revno}'
+ - maas_ppa:
+ maas_ppa: '{maas_ppa}'
+ - tests_branch:
+ tests_branch: '{tests_branch}'
+ - curtin_ppa:
+ curtin_ppa: '{curtin_ppa}'
+ - release:
+ release: '{release}'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_ea
+ triggers:
+ - pollscm:
+ cron: "H/15 * * * *"
+ ignore-post-commit-hooks: true
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: '{job_name}-manual'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ properties:
+ - build-discarder:
+ days-to-keep: 30
+ artifact-days-to-keep: 30
+ parameters:
+ - maas_branch:
+ maas_branch: https://git.launchpad.net/maas
+ - maas_branch_id:
+ maas_branch_id: '{maas_branch_id}'
+ - maas_branch_revno:
+ maas_branch_revno: 'HEAD'
+ - maas_ppa:
+ maas_ppa: '{maas_ppa}'
+ - tests_branch:
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ - curtin_ppa:
+ curtin_ppa: ''
+ - curtin_proposed:
+ curtin_proposed: '{curtin_proposed}'
+ - release:
+ release: focal
+ - use_arm64_nodes:
+ use_arm64_nodes: '{use_arm64_nodes}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '{use_ppc_nodes}'
+ - test_rhel:
+ test_rhel: '0'
+ - test_centos:
+ test_centos: '1'
+ - test_windows:
+ test_windows: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: '{job_name}-curtin-sru-manual'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ parameters:
+ - release:
+ release: '{release}'
+ - use_arm64_nodes:
+ use_arm64_nodes: '{use_arm64_nodes}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '{use_ppc_nodes}'
+ - tests_branch:
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ - curtin_proposed:
+ curtin_proposed: '1'
+ - maas_proposed:
+ maas_proposed: '0'
+ - maas_ppa:
+ maas_ppa: '{maas_ppa}'
+ - test_rhel:
+ test_rhel: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: '{job_name}-cloudinit-sru-manual'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ parameters:
+ - release:
+ release: '{release}'
+ - tests_branch:
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ - maas_images_repo:
+ maas_images_repo: 'https://git.launchpad.net/maas-images'
+ - use_arm64_nodes:
+ use_arm64_nodes: '{use_arm64_nodes}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '{use_ppc_nodes}'
+ - cloudinit_proposed:
+ cloudinit_proposed: '1'
+ - test_centos:
+ test_centos: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ # - test_rhel:
+ # test_rhel: '0'
+ # - debug
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: '{job_name}-maas-sru-manual'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ parameters:
+ - release:
+ release: '{release}'
+ - use_arm64_nodes:
+ use_arm64_nodes: '{use_arm64_nodes}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '{use_ppc_nodes}'
+ - tests_branch:
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ - maas_proposed:
+ maas_proposed: '1'
+ - maas_ppa:
+ maas_ppa: '{maas_ppa}'
+ - curtin_proposed:
+ curtin_proposed: '0'
+ - test_rhel:
+ test_rhel: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: 'maas-{release}-{maas_branch_id}-performance-suite'
+ node: ci-lab
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ parameters:
+ - test_performance:
+ test_performance: '1'
+ - maas_branch:
+ maas_branch: '{maas_branch}'
+ - maas_branch_id:
+ maas_branch_id: '{maas_branch_id}'
+ - maas_branch_revno:
+ maas_branch_revno: '{maas_branch_revno}'
+ - tests_branch:
+ tests_branch: '{tests_branch}'
+ - release:
+ release: '{release}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '0'
+ - use_arm64_nodes:
+ use_arm64_nodes: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ - vm_ram_size
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+ - mattermost_announce
+
+- job-template:
+ name: '{job_name}-manual-ipv6'
+ node: '{node_name}'
+ auth-token: '5b52a610'
+ wrappers:
+ - build_timeout
+ parameters:
+ - maas_branch:
+ maas_branch: https://git.launchpad.net/maas
+ - maas_branch_id:
+ maas_branch_id: '{maas_branch_id}'
+ - maas_branch_revno:
+ maas_branch_revno: 'HEAD'
+ - tests_branch:
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ - curtin_ppa:
+ curtin_ppa: ''
+ - curtin_proposed:
+ curtin_proposed: '{curtin_proposed}'
+ - release:
+ release: focal
+ - use_arm64_nodes:
+ use_arm64_nodes: '{use_arm64_nodes}'
+ - use_ppc_nodes:
+ use_ppc_nodes: '{use_ppc_nodes}'
+ - test_rhel:
+ test_rhel: '0'
+ - http_proxy_env
+ - keep_ci_running
+ - pause_ci
+ - debug
+ builders:
+ - maas_adt_git
+ publishers:
+ - archive_build_artifacts
+
+###############################################################################################
+
+- job-group:
+ name: focal-2.9-jobs-git
+ release: focal
+ maas_branch: https://git.launchpad.net/maas
+ maas_branch_id: '2.9'
+ maas_branch_revno: HEAD
+ maas_ppa: 'ppa:maas/2.9'
+ curtin_ppa: ''
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ use_arm64_nodes: '1'
+ use_ppc_nodes: '1'
+ jobs:
+ - 'maas-{release}-{maas_branch_id}-git'
+ - 'maas-{release}-{maas_branch_id}-git-ea'
+
+- job-group:
+ name: focal-3.0-jobs-git
+ release: focal
+ maas_branch: https://git.launchpad.net/maas
+ maas_branch_id: '3.0'
+ maas_branch_revno: HEAD
+ maas_ppa: 'ppa:maas/3.0'
+ curtin_ppa: ''
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ use_arm64_nodes: '1'
+ use_ppc_nodes: '1'
+ jobs:
+ - 'maas-{release}-{maas_branch_id}-git'
+ - 'maas-{release}-{maas_branch_id}-git-ea'
+
+- job-group:
+ name: focal-3.1-jobs-git
+ release: focal
+ maas_branch: https://git.launchpad.net/maas
+ maas_branch_id: '3.1'
+ maas_branch_revno: HEAD
+ maas_ppa: 'ppa:maas/3.1'
+ curtin_ppa: ''
+ tests_branch: lp:~maas-maintainers/maas/qa-lab-tests
+ use_arm64_nodes: '1'
+ use_ppc_nodes: '1'
+ jobs:
+ - 'maas-{release}-{maas_branch_id}-git'
+ - 'maas-{release}-{maas_branch_id}-git-ea'
+
+- job-group:
+ name: proposed-sru-manual
+ job_name: SRU-proposed
+ release: bionic
+ use_arm64_nodes: '0'
+ use_ppc_nodes: '0'
+ maas_ppa: ''
+ jobs:
+ - '{job_name}-curtin-sru-manual'
+ - '{job_name}-cloudinit-sru-manual'
+ - '{job_name}-maas-sru-manual'
+
+####################################################################################################
+######################################## PROJECTS ##################################################
+####################################################################################################
+
+# TODO:
+# - Add jobs for Windows
+# - Add jobs for Ubuntu Core
+# - Add jobs for ESXi
+- project:
+ name: maas-qa-lab
+ jobs:
+ - focal-2.9-jobs-git # job group (creates -git, -ea)
+ - focal-3.0-jobs-git # job group (creates -git, -ea)
+ - focal-3.1-jobs-git # job group (creates -git, -ea)
+ - proposed-sru-manual # job group (creates jobs for SRU testing: -curtin-sru-manual, -maas-sru-manual)
+ - proposed-maas-images-manual
+ # maas-git-manual-ipv6 # configuration for IPv6
+
+- job:
+ name: enable-global-maas-pxe
+ description: |
+ This job enables DHCP for the PXE network on the global MAAS
+ at http://10.245.136.7:5240/MAAS.
+
+ The PXE network is shared between the CI tests and the global
+ MAAS, and this job ensures that DHCP is only enabled for one MAAS
+ at a time. No CI tests will be run while this job is running.
+
+ When you're done using the global MAAS, either disable DHCP for
+ the PXE VLAN in MAAS, or abort this job.
+
+ After the given timeout, this job will be automatically aborted,
+ and DHCP disabled, so that the CI tests my run again.
+
+ NEVER ENABLE DHCP IN THE GLOBAL MAAS MANUALLY, ALWAYS USE THIS JOB
+ project-type: pipeline
+ parameters:
+ - string:
+ name: TIMEOUT
+ default: '60'
+ description: 'Timeout in minutes'
+ dsl: |
+ pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ stages {
+ stage('Enable DHCP') {
+ steps {
+ script {
+ env.PATH += ":/snap/bin"
+ }
+ withCredentials([string(credentialsId: 'jenkins-maas-token', variable: 'API_TOKEN')]) {
+ sh "echo \$PATH"
+ sh "ls /snap/bin"
+ sh "maas login jenkins http://10.245.136.7:5240/MAAS ${API_TOKEN}"
+ }
+ sh "maas jenkins vlan update 0 0 dhcp_on=true primary_rack=ckbafg"
+ }
+ }
+ stage('Wait for DHCP to be disabled') {
+ steps {
+ timeout(time: "${TIMEOUT}" as Integer, unit: 'MINUTES') {
+ sh """
+ DHCP_VLAN=''
+ while [ -z "\$DHCP_VLAN" ];
+ do
+ sleep 30;
+ DHCP_VLAN=\$(maas jenkins vlan read 0 0 | jq -c 'select( .dhcp_on == false)')
+ done
+ """
+ }
+ }
+ }
+ }
+ post {
+ always {
+ sh "maas jenkins vlan update 0 0 dhcp_on=false"
+ sh "maas logout jenkins"
+ }
+ }
+ }
diff --git a/jenkins/jobs/config.ini b/jenkins/jobs/config.ini
new file mode 100644
index 0000000..fa1e4ab
--- /dev/null
+++ b/jenkins/jobs/config.ini
@@ -0,0 +1,6 @@
+[jenkins]
+user=admin
+password=c4n0n1c4l
+url=http://maas-integration-ci.internal:8080/
+#password=472af6c7184dd6d96a87b4f9ab6aea68
+#url=http://162.213.35.104:8080/
diff --git a/jenkins/jobs/gh_repo_tester.groovy b/jenkins/jobs/gh_repo_tester.groovy
new file mode 100644
index 0000000..e1b044c
--- /dev/null
+++ b/jenkins/jobs/gh_repo_tester.groovy
@@ -0,0 +1,139 @@
+import groovy.json.JsonSlurper
+
+MAAS_GH_USER = "maas"
+
+def parseJobs(repoName, jsonString) {
+ parsed_jobs = new JsonSlurper().parseText(jsonString)
+ println("Jobs to parse: ${parsed_jobs}")
+ jobs = []
+
+ if (parsed_jobs.size() > 0) {
+ for(parsed_job in parsed_jobs) {
+ job = [:]
+
+ source_repo = parsed_job["head"]["repo"]["html_url"]
+ source_branch = parsed_job["head"]["ref"]
+ source_latest_commit = sh(script: "git ls-remote ${source_repo} ${source_branch} | awk \'{print \$1}\'", returnStdout: true).trim()
+
+ target_repo = parsed_job["base"]["repo"]["html_url"]
+ target_branch = parsed_job["base"]["ref"]
+
+ pr_updated = Date.parse("yyyy-MM-dd'T'HH:mm:ss'Z'", parsed_job["updated_at"])
+
+ // Don't test PRs that aren't targeting the main branch
+ target_repo_name = parsed_job["base"]["repo"]["full_name"]
+ default_branch = parsed_job["base"]["repo"]["default_branch"]
+ correct_repo = (
+ target_branch==default_branch && target_repo_name=="${MAAS_GH_USER}/${repoName}"
+ )
+
+ // Don't test PRs that have the WIP label applied
+ parsed_pr_labels = parsed_job["labels"]
+ wip = false
+ if (parsed_pr_labels.size() > 0) {
+ for (label in parsed_pr_labels) {
+ if (label["name"]=="WIP") {
+ wip = true
+ }
+ }
+ }
+
+ // Don't test PRs that have already been tested (ie: they have a status applied to the commit)
+ commit_status_out = sh(script: "curl -s https://api.github.com/repos/${MAAS_GH_USER}/${repoName}/commits/${source_latest_commit}/statuses", returnStdout: true).trim()
+ commit_status = new JsonSlurper().parseText(commit_status_out)
+ tested = (commit_status.size() > 0)
+
+ // Reset the tested status if we have left a comment after a test has been run
+ comment_url = parsed_job["comments_url"]
+ comment_out = sh(script: "curl -s ${comment_url}", returnStdout: true).trim()
+ comments = new JsonSlurper().parseText(comment_out)
+ if (tested && comments.size() > 0) {
+ println("Tested PR has comments, checking for retest requests")
+ def latest_status_time = Date.parse("yyyy-MM-dd hh:mm:ss", "2000-01-01 00:00:00")
+ latest_status = ""
+ for (status in commit_status) {
+ status_time = Date.parse("yyyy-MM-dd'T'HH:mm:ss'Z'", status["updated_at"])
+ if (status_time > latest_status_time) {
+ latest_status_time = status_time
+ latest_status = status["state"]
+ }
+ }
+ println("Most recent status ${latest_status} at ${latest_status_time}")
+ // if the latest test has been completed, and the comment was left after that
+ if (latest_status != "pending") {
+ for (comment in comments) {
+ if (Date.parse("yyyy-MM-dd'T'HH:mm:ss'Z'", comment["created_at"]) > latest_status_time && comment["body"].toLowerCase() == "jenkins: !test") {
+ println("Retest request made after most recent test result")
+ tested = false
+ }
+ }
+ }
+ }
+
+ // add this commit to be tested
+ if (correct_repo && !wip && !tested) {
+ job["updated"] = pr_updated
+ // The repo and branch to build a job for
+ job["GITHUB_REPO"] = source_repo
+ job["GITHUB_BRANCH"] = source_branch
+ jobs.add(job)
+ println("Job candidate ${job} created")
+ }
+ }
+ }
+ return jobs
+}
+
+def makeBuild(job_name, job) {
+ println("Running job for ${job.GITHUB_REPO} ${job.GITHUB_BRANCH}")
+ return build(
+ job: job_name,
+ parameters: [
+ [$class: 'StringParameterValue', name: 'GITHUB_REPO', value: job.GITHUB_REPO],
+ [$class: 'StringParameterValue', name: 'GITHUB_BRANCH', value: job.GITHUB_BRANCH],
+ ],
+ propagate: false,
+ wait: false,
+ waitForStart: false,
+ )
+}
+
+pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ disableConcurrentBuilds()
+ }
+ stages {
+ stage("Fetch Pull Requests") {
+ steps {
+ script {
+ split_repo_url = params.TARGET_REPO.split("/")
+ repo_name = split_repo_url[split_repo_url.length-1]
+ user_name = split_repo_url[split_repo_url.length-2]
+ output = sh(script: "curl -s https://api.github.com/repos/${user_name}/${repo_name}/pulls?state=open", returnStdout: true).trim()
+ if (!output.contains("API rate limit exceeded")) {
+ env._pr_to_review = output
+ } else {
+ println("API Limit exceeded, cannot parse jobs")
+ env._pr_to_review = "[]"
+ }
+ env._gh_repo_name = repo_name
+ }
+ }
+ }
+ stage("Test PRs") {
+ when { not { environment name: "_pr_to_review", value: "[]" }}
+ steps {
+ script {
+ jobs = parseJobs(env._gh_repo_name, env._pr_to_review)
+ if (jobs) {
+ // Only parse one job for now
+ makeBuild(params.JOB_NAME, jobs[0])
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/jenkins/jobs/labmaas_base_config.inc b/jenkins/jobs/labmaas_base_config.inc
new file mode 100644
index 0000000..a68786a
--- /dev/null
+++ b/jenkins/jobs/labmaas_base_config.inc
@@ -0,0 +1,194 @@
+proxy:
+ use_internal: true
+ http: http://squid.internal:3128
+networks:
+ pxe:
+ cidr: 10.245.136.0/21
+ bridge: br0
+ dynamic:
+ start: 10.245.136.21
+ end: 10.245.136.200
+ reserved:
+ - start: 10.245.136.1
+ end: 10.245.136.19
+ comment: Reserved
+ - start: 10.245.143.100
+ end: 10.245.143.200
+ comment: BMCs
+maas:
+ networks:
+ pxe: 10.245.136.20
+ config:
+ # This values will set with `maas set-config` command
+ upstream_dns: 10.245.136.1
+ dnssec_validation: "no"
+ domain_name: systemtestsmaas
+
+windows_image_file_path: /home/ubuntu/other-os-images/windows-win2012hvr2-amd64-root-dd
+
+o11y:
+ grafana_agent_file_path: >
+ /home/ubuntu/system_tests_assets/agent-linux-amd64_0_28_0
+ o11y_ip: 10.245.136.5
+
+tls:
+ cacerts: ssl-cert-snakeoil.pem
+
+containers-image: ${params.CONTAINERS_IMAGE}
+
+machines:
+ hardware:
+ opelt:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.121
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:6d:fb:3c
+ stunky:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.127
+ power_username: landscape
+ power_password: insecure
+ mac_address: ec:b1:d7:7f:ef:34
+ natasha:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.120
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:75:6b:ee
+ osystem: windows
+ arm64:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.114
+ power_username: admin
+ power_password: password
+ mac_address: 1c:1b:0d:0d:52:7c
+ architecture: arm64
+ ppc64le:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.113
+ power_username: ""
+ power_password: admin
+ mac_address: 98:be:94:02:6a:c8
+ architecture: ppc64el
+ vms:
+ instances:
+ vm1:
+ mac_address: 00:16:3e:d6:36:18
+ devices:
+ disk1:
+ type: disk
+ source: /home/ubuntu/diego/test_block_device.img
+ #size: 1MB
+ path: /mnt/ext2
+ iface1:
+ type: nic
+ nictype: bridged
+ parent: br0
+ name: eth1
+ hwaddr: 00:16:3e:4a:19:6f
+ # usb1:
+ # type: usb
+ # productid: "0016"
+ # pci1:
+ # type: pci
+ # address: '02:00.1'
+ lxd_profile: prof-maas-test
+ vm2:
+ mac_address: 00:16:3e:d0:54:9f
+ lxd_profile: prof-maas-test
+ power_type: lxd
+ power_parameters:
+ power_address: https://10.157.204.1:8443
+ project: default
+ certificate: |
+ -----BEGIN CERTIFICATE-----
+ MIIElzCCAn8CEQD+6NBHtM1z951J2HwbtZwnMA0GCSqGSIb3DQEBDQUAMAAwHhcN
+ MjIwMjA4MTMwNDI4WhcNMzIwMjA2MTMwNDI4WjATMREwDwYDVQQDDAh0ZXN0aG9z
+ dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANRvcoT8dofRU2A0ICm0
+ JzZPJr9C7oQmJhxd/I8Fwzt1Jzom0mhg+8oSFXPI7jzx8kpFexJZHBF8WBUII+0v
+ RnZx8oeIRtvrL22tKEqeH2dwZxHIpcmoPbj2jMCFR1IFhFGBJD1uDUvkBAYFnguM
+ tJml5yh+BhhPGc8Ehds/kstq032rWlDjx0Cne+5mebSniz+TW5+uc/7Vy4mIDm3P
+ IGgytRXDseryvJ0kuLkNZGT38tHTva22skz0K0mRImNgCdjbacsS85DQymANJtP/
+ TbAZnZ2VGLGJ2jXVBEKcXDRdrT5jusQTdRseciXqbSBuvCcsd+4R85ZZNO4ARDqI
+ XNWEEinspXfJtBuvx2dtZ1S8K233kz1ds5n3vLirw6LIeNW1b8a200JeDovBzUmt
+ fu9qSgw+fS2H7k/TnQDzd1AqhcKQpZqZd2eY1d4AbM9L9oEPFPesISNko7U0NpPC
+ 5RfejxL+IMhshKDPWCo50I4Ty80gSPbzRBJUXE4Qq3ZiiqiK8EW0VRobz6ZfDF1A
+ /2oR6C6QvNd30lzdP1laLLHKBh2A3TTWL4UE+N6eH38LdO2isbh/8ux068sclxzX
+ Ba34D5ICzjHd4FpBHiNpyTnb8QAaKcOFLr2QGHogRCQI2QygPyB6jaVTTVwkJbKS
+ kuJBcUjBNmkEnx1VFIqnzDr5AgMBAAEwDQYJKoZIhvcNAQENBQADggIBAL7aLr6Z
+ Hfqlefng/JMr+ojDJWmdtHTqwa9MviEzHTlzhvTw3JRCMFlIlIrK7wpd7kr9Jmhz
+ HI3atc1NtrEsMeUsvNmopnlqKWPwcyCYX0juKvoMeTqFDLN7yWPBHEc4NNhXJQte
+ pee7P02e8+C0g4UXlQ8Hry1LfwhlwHok0LijEbBkX4x0m7RlqqprMfJJsU6wL613
+ WOcfTEiHkZYB/a/yeIAhdqSi3jMH3m+jbG9Tjfn62pPheSzRpH28A5mvZVP39RUO
+ JdpEHT7F5pMmauygWBxXT/VCU0TriCMYrexjA1cWOlrT0+VU5Im3+u0l3vUE+2Wc
+ zKNpt3l3wG3KmLHeJr9/7QyFLMHhEYr4xpMoikIhq75iLz6GqGkgho7Xy7Iz2WZP
+ YW39eNAYdW8UEnSpdlmsA0gIHeWDVWZFebMk8Jw5AtIr6qTUGRMp4jFzwaQX4Oc2
+ kf2jqICMKz3nQjT5b5+/w6OKuz1POrzA9hRkp85fDdeD/zwO9v+65qwHk9T+FOM4
+ xC/VQcoSp5lJmGN6NGCleLhpUbIwX381rCk7pvOPQ5PLWW2gPB61njsdbJ97fWpy
+ 5b7QD4Pcq+eQ2Xy1+F4ToCmW8E6XorUFPUKTInTl4McHbJiuGwmXAkGqLzgJd+Q1
+ opB3iqj1W36wgZQK6lRoN7X/zugt9m+MZX/6
+ -----END CERTIFICATE-----
+ key: |
+ -----BEGIN PRIVATE KEY-----
+ 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
+ Xwjk99gnvag+HswBDB7A7DCTEqhkUQ==
+ -----END PRIVATE KEY-----
diff --git a/jenkins/jobs/orobas.ini b/jenkins/jobs/orobas.ini
new file mode 100644
index 0000000..38c8dcb
--- /dev/null
+++ b/jenkins/jobs/orobas.ini
@@ -0,0 +1,4 @@
+[jenkins]
+user=admin
+password=admin
+url=http://10.246.88.13:8080/
diff --git a/jenkins/jobs/systemtests.yaml b/jenkins/jobs/systemtests.yaml
new file mode 100644
index 0000000..2193032
--- /dev/null
+++ b/jenkins/jobs/systemtests.yaml
@@ -0,0 +1,301 @@
+- job:
+ name: maas-system-tests
+ description: |
+ Run the MAAS system tests
+ project-type: pipeline
+ triggers:
+ - timed: '@daily'
+ dsl: |
+ pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ timeout(time: 6, unit: "HOURS")
+ }
+ parameters {
+ string(name: 'GIT_REPO', defaultValue: 'https://git.launchpad.net/~maas-committers/maas-ci/+git/system-tests', description: 'Git repo to pull system tests from')
+ string(name: 'GIT_BRANCH', defaultValue: 'master', description: 'Branch in the repo to use')
+ string(name: 'PYTEST_ARGS', defaultValue: '--log-cli-level info', description: 'Additional args to pytest')
+ string(name: 'MAAS_GIT_BRANCH', defaultValue: 'master', description: 'branch of maas project to build from.')
+ string(name: 'MAAS_PPA', defaultValue: 'ppa:maas-committers/latest-deps', description: 'maas ppa for dependencies.')
+ string(name: 'CONTAINERS_IMAGE', defaultValue: 'ubuntu:22.04', description: 'LXD image for containers used in tests')
+ booleanParam(name: 'REMOVE_CONTAINERS', defaultValue: true, description: 'Should existing containers be torn down before we run?')
+ }
+ stages {
+ stage('Checkout') {
+ steps {
+ sh """
+ lxc list
+ pgrep -a qemu || true
+ rm -rf system-tests
+ git clone ${params.GIT_REPO} --branch ${params.GIT_BRANCH} --depth 10 system-tests
+ env -C system-tests git show --no-patch
+ """
+ }
+ }
+ stage('Clean') {
+ when {
+ expression {
+ return params.REMOVE_CONTAINERS
+ }
+ }
+ steps {
+ sh """
+ lxc delete maas-system-build --force || true
+ lxc delete maas-system-maas --force || true
+ lxc delete maas-client --force || true
+ """
+ }
+ }
+ stage('Setup') {
+ steps {
+ sh """
+ sudo apt-get install -y tox
+ """
+ }
+ }
+ stage('System Tests') {
+ steps {
+ writeFile file: 'system-tests/config.yaml', text: """
+ proxy:
+ use_internal: true
+ http: http://squid.internal:3128
+ networks:
+ pxe:
+ cidr: 10.245.136.0/21
+ bridge: br0
+ dynamic:
+ start: 10.245.136.21
+ end: 10.245.136.200
+ reserved:
+ - start: 10.245.136.1
+ end: 10.245.136.19
+ comment: Reserved
+ - start: 10.245.143.100
+ end: 10.245.143.200
+ comment: BMCs
+ maas:
+ networks:
+ pxe: 10.245.136.20
+ config:
+ # This values will set with `maas set-config` command
+ upstream_dns: 10.245.136.1
+ dnssec_validation: "no"
+ domain_name: systemtestsmaas
+
+ windows_image_file_path: /home/ubuntu/other-os-images/windows-win2012hvr2-amd64-root-dd
+
+ tls:
+ cacerts: ssl-cert-snakeoil.pem
+
+ vault:
+ snap-channel: 1.11/stable
+
+ containers-image: ${params.CONTAINERS_IMAGE}
+
+ deb:
+ ppa:
+ - ${params.MAAS_PPA}
+ git_branch: ${params.MAAS_GIT_BRANCH}
+
+ machines:
+ hardware:
+ opelt:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.121
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:6d:fb:3c
+ stunky:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.127
+ power_username: landscape
+ power_password: insecure
+ mac_address: ec:b1:d7:7f:ef:34
+ natasha:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.120
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:75:6b:ee
+ osystem: windows
+ arm64:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.114
+ power_username: admin
+ power_password: password
+ mac_address: 1c:1b:0d:0d:52:7c
+ architecture: arm64
+ ppc64le:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.113
+ power_username: ""
+ power_password: admin
+ mac_address: 98:be:94:02:6a:c8
+ architecture: ppc64el
+ vms:
+ instances:
+ vm1:
+ mac_address: 00:16:3e:d6:36:18
+ devices:
+ disk1:
+ type: disk
+ source: /home/ubuntu/diego/test_block_device.img
+ #size: 1MB
+ path: /mnt/ext2
+ iface1:
+ type: nic
+ nictype: bridged
+ parent: br0
+ name: eth1
+ hwaddr: 00:16:3e:4a:19:6f
+ # usb1:
+ # type: usb
+ # productid: "0016"
+ # pci1:
+ # type: pci
+ # address: '02:00.1'
+ lxd_profile: prof-maas-test
+ vm2:
+ mac_address: 00:16:3e:d0:54:9f
+ lxd_profile: prof-maas-test
+ power_type: lxd
+ power_parameters:
+ power_address: https://10.157.204.1:8443
+ project: default
+ certificate: |
+ -----BEGIN CERTIFICATE-----
+ MIIElzCCAn8CEQD+6NBHtM1z951J2HwbtZwnMA0GCSqGSIb3DQEBDQUAMAAwHhcN
+ MjIwMjA4MTMwNDI4WhcNMzIwMjA2MTMwNDI4WjATMREwDwYDVQQDDAh0ZXN0aG9z
+ dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANRvcoT8dofRU2A0ICm0
+ JzZPJr9C7oQmJhxd/I8Fwzt1Jzom0mhg+8oSFXPI7jzx8kpFexJZHBF8WBUII+0v
+ RnZx8oeIRtvrL22tKEqeH2dwZxHIpcmoPbj2jMCFR1IFhFGBJD1uDUvkBAYFnguM
+ tJml5yh+BhhPGc8Ehds/kstq032rWlDjx0Cne+5mebSniz+TW5+uc/7Vy4mIDm3P
+ IGgytRXDseryvJ0kuLkNZGT38tHTva22skz0K0mRImNgCdjbacsS85DQymANJtP/
+ TbAZnZ2VGLGJ2jXVBEKcXDRdrT5jusQTdRseciXqbSBuvCcsd+4R85ZZNO4ARDqI
+ XNWEEinspXfJtBuvx2dtZ1S8K233kz1ds5n3vLirw6LIeNW1b8a200JeDovBzUmt
+ fu9qSgw+fS2H7k/TnQDzd1AqhcKQpZqZd2eY1d4AbM9L9oEPFPesISNko7U0NpPC
+ 5RfejxL+IMhshKDPWCo50I4Ty80gSPbzRBJUXE4Qq3ZiiqiK8EW0VRobz6ZfDF1A
+ /2oR6C6QvNd30lzdP1laLLHKBh2A3TTWL4UE+N6eH38LdO2isbh/8ux068sclxzX
+ Ba34D5ICzjHd4FpBHiNpyTnb8QAaKcOFLr2QGHogRCQI2QygPyB6jaVTTVwkJbKS
+ kuJBcUjBNmkEnx1VFIqnzDr5AgMBAAEwDQYJKoZIhvcNAQENBQADggIBAL7aLr6Z
+ Hfqlefng/JMr+ojDJWmdtHTqwa9MviEzHTlzhvTw3JRCMFlIlIrK7wpd7kr9Jmhz
+ HI3atc1NtrEsMeUsvNmopnlqKWPwcyCYX0juKvoMeTqFDLN7yWPBHEc4NNhXJQte
+ pee7P02e8+C0g4UXlQ8Hry1LfwhlwHok0LijEbBkX4x0m7RlqqprMfJJsU6wL613
+ WOcfTEiHkZYB/a/yeIAhdqSi3jMH3m+jbG9Tjfn62pPheSzRpH28A5mvZVP39RUO
+ JdpEHT7F5pMmauygWBxXT/VCU0TriCMYrexjA1cWOlrT0+VU5Im3+u0l3vUE+2Wc
+ zKNpt3l3wG3KmLHeJr9/7QyFLMHhEYr4xpMoikIhq75iLz6GqGkgho7Xy7Iz2WZP
+ YW39eNAYdW8UEnSpdlmsA0gIHeWDVWZFebMk8Jw5AtIr6qTUGRMp4jFzwaQX4Oc2
+ kf2jqICMKz3nQjT5b5+/w6OKuz1POrzA9hRkp85fDdeD/zwO9v+65qwHk9T+FOM4
+ xC/VQcoSp5lJmGN6NGCleLhpUbIwX381rCk7pvOPQ5PLWW2gPB61njsdbJ97fWpy
+ 5b7QD4Pcq+eQ2Xy1+F4ToCmW8E6XorUFPUKTInTl4McHbJiuGwmXAkGqLzgJd+Q1
+ opB3iqj1W36wgZQK6lRoN7X/zugt9m+MZX/6
+ -----END CERTIFICATE-----
+ key: |
+ -----BEGIN PRIVATE KEY-----
+ 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
+ Xwjk99gnvag+HswBDB7A7DCTEqhkUQ==
+ -----END PRIVATE KEY-----
+ """
+ dir("system-tests") {
+ sh """
+ cat config.yaml
+ export http_proxy=http://squid.internal:3128/
+ export https_proxy=http://squid.internal:3128/
+ export TOX_PARALLEL_NO_SPINNER=1
+ tox -e cog
+ tox -e env_builder -- ${params.PYTEST_ARGS} | tee env_builder.out
+ tox -e general_tests --
+ tox -p all -e vm1,natasha -- ${params.PYTEST_ARGS}
+ tox -p all -e opelt,arm64,ppc64le,vm2 -- ${params.PYTEST_ARGS}
+ """
+ }
+ }
+ }
+ }
+ post {
+ always {
+ script {
+ buildInfo = sh (returnStdout: true, script: "awk '/BEGIN_SYSTEMTESTS_META/{ f = 1; next } /END_SYSTEMTESTS_META/ { f = 0 } f' system-tests/env_builder.out")
+ currentBuild.description = "$buildInfo"
+ }
+ sh """
+ export http_proxy=http://squid.internal:3128/
+ export https_proxy=http://squid.internal:3128/
+ env -C system-tests tox -e collect_sos_report
+ """
+ archiveArtifacts artifacts: 'system-tests/sosreport/*,system-tests/*.log,system-tests/config.yaml,system-tests/junit*.xml', fingerprint: true
+ junit allowEmptyResults: true, testResults: 'system-tests/junit*.xml'
+ sh """
+ lxc delete --force maas-system-build || true
+ lxc delete --force maas-system-maas || true
+ lxc delete --force maas-client || true
+ """
+ }
+ success {
+ mattermostSend (color: 'green', message: "[${env.JOB_NAME} #${env.BUILD_NUMBER}](${env.BUILD_URL}) :success: was successful")
+ }
+ failure {
+ mattermostSend (color: 'red', message: "[${env.JOB_NAME} #${env.BUILD_NUMBER}](${env.BUILD_URL}) :fire: failed")
+ }
+ }
+ }
diff --git a/jenkins/jobs/systemtests_config_generator.groovy b/jenkins/jobs/systemtests_config_generator.groovy
new file mode 100644
index 0000000..6d7d210
--- /dev/null
+++ b/jenkins/jobs/systemtests_config_generator.groovy
@@ -0,0 +1,92 @@
+def gen_config_cmd = 'tox -e generate_config --'
+pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ timeout(time: 6, unit: "HOURS")
+ }
+ environment {
+ TOX_PARALLEL_NO_SPINNER = '1'
+ }
+ stages {
+ stage('Checkout') {
+ steps {
+ script {
+ sh """
+ rm -rf system-tests;
+ git clone ${params.SYSTEMTESTS_GIT_REPO} --branch ${params.SYSTEMTESTS_GIT_BRANCH} --depth 1 system-tests;
+ cd system-tests && git show --no-patch;
+ """
+ }
+ }
+ }
+ stage('Setup') {
+ steps {
+ script {
+ sh '''
+ sudo apt-get install -y tox;
+ '''
+ }
+ script {
+ sh '''
+ cd system-tests
+ tox -e cog
+ '''
+ }
+ script {
+ writeFile file: 'system-tests/base_config.yaml', text: """
+{{ labmaas_base_config.format() }}
+"""
+ }
+ }
+ }
+ stage('Generate configuration') {
+ steps {
+ script {
+ if (params.INSTALLATION_METHOD == 'SNAP') {
+ gen_config_cmd = "${gen_config_cmd} --snap --snap-channel ${params.MAAS_SNAP_CHANNEL} --test-db-channel ${params.TEST_DB_SNAP_CHANNEL}"
+ } else {
+ gen_config_cmd = "${gen_config_cmd} --deb --git-repo ${params.MAAS_GIT_REPO} --git-branch ${params.MAAS_GIT_BRANCH} --ppa ${params.MAAS_PPA}"
+ }
+ if (params.ENABLE_TLS) {
+ gen_config_cmd = "${gen_config_cmd} --tls"
+ }
+ if (params.ENABLE_OBSERVABILITY) {
+ gen_config_cmd = "${gen_config_cmd} --o11y"
+ }
+ if (params.ENABLE_HW_SYNC_TEST) {
+ gen_config_cmd = "${gen_config_cmd} --hw-sync"
+ }
+ if (params.GEN_CONFIG_ARGS) {
+ gen_config_cmd = "${gen_config_cmd} ${params.GEN_CONFIG_ARGS}"
+ }
+
+ sh """
+ cd system-tests
+ cat base_config.yaml
+ ${gen_config_cmd} --containers-image=${params.CONTAINERS_IMAGE} base_config.yaml config.yaml
+ """
+
+ archiveArtifacts artifacts: 'system-tests/config.yaml', fingerprint: true
+ }
+ }
+ }
+ stage('Launch System Tests') {
+ steps {
+ script {
+ build(job: 'maas-system-tests-executor',
+ wait: false,
+ parameters: [
+ string(name:'SYSTEMTESTS_GIT_REPO', value:"${params.SYSTEMTESTS_GIT_REPO}"),
+ string(name:'SYSTEMTESTS_GIT_BRANCH', value:"${params.SYSTEMTESTS_GIT_BRANCH}"),
+ string(name:'PYTEST_ARGS', value:"${params.PYTEST_ARGS}"),
+ booleanParam(name:'REMOVE_CONTAINERS', value:"${params.REMOVE_CONTAINERS}"),
+ ],
+ )
+ }
+ }
+ }
+ }
+}
+
diff --git a/jenkins/jobs/systemtests_config_generator.yaml b/jenkins/jobs/systemtests_config_generator.yaml
new file mode 100644
index 0000000..f8ee769
--- /dev/null
+++ b/jenkins/jobs/systemtests_config_generator.yaml
@@ -0,0 +1,82 @@
+- project:
+ name: maas-system-tests-config-generator
+ jobs:
+ - maas-system-tests-config-generator
+
+- job-template:
+ name: maas-system-tests-config-generator
+ description: |
+ Generate config for MAAS system tests
+ project-type: pipeline
+ parameters:
+ - string:
+ description: Git repo to pull system tests from.
+ name: SYSTEMTESTS_GIT_REPO
+ default: https://git.launchpad.net/~maas-committers/maas-ci/+git/system-tests
+ - string:
+ description: Branch in the repo to use.
+ name: SYSTEMTESTS_GIT_BRANCH
+ default: master
+ - choice:
+ name: INSTALLATION_METHOD
+ choices:
+ - SNAP
+ - DEB
+ description: Which MAAS installation method use for this execution.
+ - string:
+ description: Git repo to pull MAAS from.
+ name: MAAS_GIT_REPO
+ default: https://git.launchpad.net/maas
+ - string:
+ description: Branch in the repo to build from.
+ name: MAAS_GIT_BRANCH
+ default: master
+ - string:
+ description: MAAS PPA for dependencies.
+ name: MAAS_PPA
+ default: ppa:maas-committers/latest-deps
+ - string:
+ description: Channel to use to install MAAS snap.
+ name: MAAS_SNAP_CHANNEL
+ default: latest/edge
+ - string:
+ description: Channel for maas-test-db snap. Leave empty to use the same channel as MAAS snap.
+ name: TEST_DB_SNAP_CHANNEL
+ default: latest/edge
+ - string:
+ description: LXD image for containers used in tests
+ name: CONTAINERS_IMAGE
+ default: ubuntu:22.04
+ - bool:
+ description: Enable TLS when testing.
+ name: ENABLE_TLS
+ default: false
+ - bool:
+ description: Enable telemetry when testing.
+ name: ENABLE_OBSERVABILITY
+ default: false
+ - bool:
+ description: Execute hardware sync feature tests
+ name: ENABLE_HW_SYNC_TEST
+ default: false
+ - bool:
+ description: Should existing containers be torn down before we run?
+ name: REMOVE_CONTAINERS
+ default: true
+ - string:
+ description: Additional args to gen_config (--ppa --architecture --machine etc)
+ name: GEN_CONFIG_ARGS
+ default: ""
+ - string:
+ description: Additional args to pytest
+ name: PYTEST_ARGS
+ default: --log-cli-level info
+
+ triggers:
+ - timed: '@daily'
+ properties:
+ - copyartifact:
+ projects: "maas-system-tests-executor*"
+ dsl: !include-jinja2: systemtests_config_generator.groovy
+
+ labmaas_base_config: !include-jinja2: labmaas_base_config.inc
diff --git a/jenkins/jobs/systemtests_executor.groovy b/jenkins/jobs/systemtests_executor.groovy
new file mode 100644
index 0000000..3638f8f
--- /dev/null
+++ b/jenkins/jobs/systemtests_executor.groovy
@@ -0,0 +1,113 @@
+pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ timeout(time: 6, unit: "HOURS")
+ }
+
+ environment {
+ TOX_PARALLEL_NO_SPINNER = '1'
+ }
+
+ stages {
+ stage('Clean') {
+ when {
+ expression {
+ return params.REMOVE_CONTAINERS
+ }
+ }
+ steps {
+ script {
+ sh '''
+ lxc delete maas-system-build --force || true;
+ lxc delete maas-system-maas --force || true;
+ lxc delete maas-client --force || true;
+ '''
+ }
+ }
+ }
+ stage('Checkout') {
+ steps {
+ script {
+ sh """
+ lxc list;
+ pgrep -a qemu || true;
+ rm -rf system-tests;
+ git clone ${params.SYSTEMTESTS_GIT_REPO} --branch ${params.SYSTEMTESTS_GIT_BRANCH} --depth 10 system-tests;
+ cd system-tests && git show --no-patch;
+ """
+ }
+ }
+ }
+ stage('Copy config.yaml') {
+ steps {
+ script {
+ copyArtifacts(projectName: currentBuild.upstreamBuilds[0].fullProjectName,
+ selector: upstream(),
+ filter: 'system-tests/config.yaml',
+ )
+ }
+ }
+ }
+ stage('Cog') {
+ steps {
+ script {
+ sh 'env -C system-tests tox run -e cog'
+ }
+ }
+ }
+ stage('Filter envs') {
+ steps {
+ script {
+ sh 'env -C system-tests tox run -e filter_envs -- --output-file=envs1 vm1,natasha'
+ sh 'env -C system-tests tox run -e filter_envs -- --output-file=envs2 opelt,arm64,ppc64le,vm2'
+ }
+ }
+ }
+ stage('System Tests') {
+ steps {
+ script {
+ sh """
+ cd system-tests
+ cat config.yaml
+ tox run -e env_builder -- ${params.PYTEST_ARGS} | tee env_builder.out
+ tox run -e general_tests -- ${params.PYTEST_ARGS}
+ """
+ status1 = sh(script:"""
+ cd system-tests
+ if test -s envs1; then tox run-parallel -e \$(cat envs1) -- ${params.PYTEST_ARGS}; else true; fi
+ """, returnStatus: true)
+ status2 = sh(script:"""
+ cd system-tests
+ if test -s envs2; then tox run-parallel -e \$(cat envs2) -- ${params.PYTEST_ARGS}; else true; fi
+ """, returnStatus: true)
+ if (status1 || status2) {
+ sh 'exit 1'
+ }
+ }
+ }
+ }
+ }
+ post {
+ always {
+ script {
+ buildInfo = sh (returnStdout: true, script: "awk '/BEGIN_SYSTEMTESTS_META/{ f = 1; next } /END_SYSTEMTESTS_META/ { f = 0 } f' system-tests/env_builder.out")
+ currentBuild.description = "$buildInfo"
+ }
+ sh 'env -C system-tests tox run -e collect_sos_report || true'
+ archiveArtifacts(
+ artifacts:'system-tests/sosreport/*,' +
+ 'system-tests/*.log,' +
+ 'system-tests/config.yaml' +
+ 'system-tests/junit*.xml',
+ fingerprint: true
+ )
+ junit allowEmptyResults: true, testResults: 'system-tests/junit*.xml'
+ sh(script:'lxc delete --force maas-system-build;' +
+ 'lxc delete --force maas-system-maas;' +
+ 'lxc delete --force maas-client',
+ returnStatus: true)
+ }
+ }
+}
diff --git a/jenkins/jobs/systemtests_executor.yaml b/jenkins/jobs/systemtests_executor.yaml
new file mode 100644
index 0000000..87500bb
--- /dev/null
+++ b/jenkins/jobs/systemtests_executor.yaml
@@ -0,0 +1,29 @@
+- project:
+ name: maas-system-tests-executor
+ jobs:
+ - maas-system-tests-executor
+
+- job-template:
+ name: maas-system-tests-executor
+ description: |
+ Exexcute MAAS system tests
+ project-type: pipeline
+ parameters:
+ - string:
+ description: Git repo to pull system tests from
+ name: SYSTEMTESTS_GIT_REPO
+ default: https://git.launchpad.net/~maas-committers/maas-ci/+git/system-tests
+ - string:
+ description: Branch in the repo to use
+ name: SYSTEMTESTS_GIT_BRANCH
+ default: master
+ - string:
+ description: Additional args to pytest
+ name: PYTEST_ARGS
+ default: --log-cli-level info
+ - bool:
+ description: Should existing containers be torn down before we run?
+ name: REMOVE_CONTAINERS
+ default: true
+
+ dsl: !include-jinja2: systemtests_executor.groovy
diff --git a/jenkins/jobs/systemtests_snap.yaml b/jenkins/jobs/systemtests_snap.yaml
new file mode 100644
index 0000000..1f5edcf
--- /dev/null
+++ b/jenkins/jobs/systemtests_snap.yaml
@@ -0,0 +1,300 @@
+- job:
+ name: maas-system-tests-snap
+ description: |
+ Run the MAAS system tests, installed from snap
+ project-type: pipeline
+ triggers:
+ - timed: '@daily'
+ dsl: |
+ pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ timeout(time: 6, unit: "HOURS")
+ }
+ parameters {
+ string(name: 'GIT_REPO', defaultValue: 'https://git.launchpad.net/~maas-committers/maas-ci/+git/system-tests', description: 'Git repo to pull system tests from')
+ string(name: 'GIT_BRANCH', defaultValue: 'master', description: 'Branch in the repo to use')
+ string(name: 'PYTEST_ARGS', defaultValue: '--log-cli-level info', description: 'Additional args to pytest')
+ string(name: 'MAAS_SNAP_CHANNEL', defaultValue: 'latest/edge', description: 'Channel of maas snap.')
+ string(name: 'TEST_DB_SNAP_CHANNEL', defaultValue: '', description: 'Channel of maas-test-db snap. Leave empty to use same channel of maas snap.')
+ string(name: 'CONTAINERS_IMAGE', defaultValue: 'ubuntu:22.04', description: 'LXD image for containers used in tests')
+ booleanParam(name: 'REMOVE_CONTAINERS', defaultValue: true, description: 'Should existing containers be torn down before we run?')
+ }
+ stages {
+ stage('Checkout') {
+ steps {
+ sh """
+ lxc list
+ pgrep -a qemu || true
+ rm -rf system-tests
+ git clone ${params.GIT_REPO} --branch ${params.GIT_BRANCH} --depth 10 system-tests
+ env -C system-tests git show --no-patch
+ """
+ }
+ }
+ stage('Clean') {
+ when {
+ expression {
+ return params.REMOVE_CONTAINERS
+ }
+ }
+ steps {
+ sh """
+ lxc delete maas-system-build --force || true
+ lxc delete maas-system-maas --force || true
+ lxc delete maas-client --force || true
+ """
+ }
+ }
+ stage('Setup') {
+ steps {
+ sh """
+ sudo apt-get install -y tox
+ """
+ }
+ }
+ stage('System Tests') {
+ steps {
+ writeFile file: 'system-tests/config.yaml', text: """
+ proxy:
+ use_internal: true
+ http: http://squid.internal:3128
+ networks:
+ pxe:
+ cidr: 10.245.136.0/21
+ bridge: br0
+ dynamic:
+ start: 10.245.136.21
+ end: 10.245.136.200
+ reserved:
+ - start: 10.245.136.1
+ end: 10.245.136.19
+ comment: Reserved
+ - start: 10.245.143.100
+ end: 10.245.143.200
+ comment: BMCs
+ maas:
+ networks:
+ pxe: 10.245.136.20
+ config:
+ # This values will set with `maas set-config` command
+ upstream_dns: 10.245.136.1
+ dnssec_validation: "no"
+ domain_name: systemtestsmaas
+
+ windows_image_file_path: /home/ubuntu/other-os-images/windows-win2012hvr2-amd64-root-dd
+
+ tls:
+ cacerts: ssl-cert-snakeoil.pem
+
+ vault:
+ snap-channel: 1.11/stable
+
+ containers-image: ${params.CONTAINERS_IMAGE}
+
+ machines:
+ hardware:
+ opelt:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.121
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:6d:fb:3c
+ stunky:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.127
+ power_username: landscape
+ power_password: insecure
+ mac_address: ec:b1:d7:7f:ef:34
+ natasha:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.120
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:75:6b:ee
+ osystem: windows
+ arm64:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.114
+ power_username: admin
+ power_password: password
+ mac_address: 1c:1b:0d:0d:52:7c
+ architecture: arm64
+ ppc64le:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.113
+ power_username: ""
+ power_password: admin
+ mac_address: 98:be:94:02:6a:c8
+ architecture: ppc64el
+ vms:
+ instances:
+ vm1:
+ mac_address: 00:16:3e:d6:36:18
+ devices:
+ disk1:
+ type: disk
+ source: /home/ubuntu/diego/test_block_device.img
+ #size: 1MB
+ path: /mnt/ext2
+ iface1:
+ type: nic
+ nictype: bridged
+ parent: br0
+ name: eth1
+ hwaddr: 00:16:3e:4a:19:6f
+ # usb1:
+ # type: usb
+ # productid: "0016"
+ # pci1:
+ # type: pci
+ # address: '02:00.1'
+ lxd_profile: prof-maas-test
+ vm2:
+ mac_address: 00:16:3e:d0:54:9f
+ lxd_profile: prof-maas-test
+ power_type: lxd
+ power_parameters:
+ power_address: https://10.157.204.1:8443
+ project: default
+ certificate: |
+ -----BEGIN CERTIFICATE-----
+ MIIElzCCAn8CEQD+6NBHtM1z951J2HwbtZwnMA0GCSqGSIb3DQEBDQUAMAAwHhcN
+ MjIwMjA4MTMwNDI4WhcNMzIwMjA2MTMwNDI4WjATMREwDwYDVQQDDAh0ZXN0aG9z
+ dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANRvcoT8dofRU2A0ICm0
+ JzZPJr9C7oQmJhxd/I8Fwzt1Jzom0mhg+8oSFXPI7jzx8kpFexJZHBF8WBUII+0v
+ RnZx8oeIRtvrL22tKEqeH2dwZxHIpcmoPbj2jMCFR1IFhFGBJD1uDUvkBAYFnguM
+ tJml5yh+BhhPGc8Ehds/kstq032rWlDjx0Cne+5mebSniz+TW5+uc/7Vy4mIDm3P
+ IGgytRXDseryvJ0kuLkNZGT38tHTva22skz0K0mRImNgCdjbacsS85DQymANJtP/
+ TbAZnZ2VGLGJ2jXVBEKcXDRdrT5jusQTdRseciXqbSBuvCcsd+4R85ZZNO4ARDqI
+ XNWEEinspXfJtBuvx2dtZ1S8K233kz1ds5n3vLirw6LIeNW1b8a200JeDovBzUmt
+ fu9qSgw+fS2H7k/TnQDzd1AqhcKQpZqZd2eY1d4AbM9L9oEPFPesISNko7U0NpPC
+ 5RfejxL+IMhshKDPWCo50I4Ty80gSPbzRBJUXE4Qq3ZiiqiK8EW0VRobz6ZfDF1A
+ /2oR6C6QvNd30lzdP1laLLHKBh2A3TTWL4UE+N6eH38LdO2isbh/8ux068sclxzX
+ Ba34D5ICzjHd4FpBHiNpyTnb8QAaKcOFLr2QGHogRCQI2QygPyB6jaVTTVwkJbKS
+ kuJBcUjBNmkEnx1VFIqnzDr5AgMBAAEwDQYJKoZIhvcNAQENBQADggIBAL7aLr6Z
+ Hfqlefng/JMr+ojDJWmdtHTqwa9MviEzHTlzhvTw3JRCMFlIlIrK7wpd7kr9Jmhz
+ HI3atc1NtrEsMeUsvNmopnlqKWPwcyCYX0juKvoMeTqFDLN7yWPBHEc4NNhXJQte
+ pee7P02e8+C0g4UXlQ8Hry1LfwhlwHok0LijEbBkX4x0m7RlqqprMfJJsU6wL613
+ WOcfTEiHkZYB/a/yeIAhdqSi3jMH3m+jbG9Tjfn62pPheSzRpH28A5mvZVP39RUO
+ JdpEHT7F5pMmauygWBxXT/VCU0TriCMYrexjA1cWOlrT0+VU5Im3+u0l3vUE+2Wc
+ zKNpt3l3wG3KmLHeJr9/7QyFLMHhEYr4xpMoikIhq75iLz6GqGkgho7Xy7Iz2WZP
+ YW39eNAYdW8UEnSpdlmsA0gIHeWDVWZFebMk8Jw5AtIr6qTUGRMp4jFzwaQX4Oc2
+ kf2jqICMKz3nQjT5b5+/w6OKuz1POrzA9hRkp85fDdeD/zwO9v+65qwHk9T+FOM4
+ xC/VQcoSp5lJmGN6NGCleLhpUbIwX381rCk7pvOPQ5PLWW2gPB61njsdbJ97fWpy
+ 5b7QD4Pcq+eQ2Xy1+F4ToCmW8E6XorUFPUKTInTl4McHbJiuGwmXAkGqLzgJd+Q1
+ opB3iqj1W36wgZQK6lRoN7X/zugt9m+MZX/6
+ -----END CERTIFICATE-----
+ key: |
+ -----BEGIN PRIVATE KEY-----
+ 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
+ Xwjk99gnvag+HswBDB7A7DCTEqhkUQ==
+ -----END PRIVATE KEY-----
+
+ snap:
+ maas_channel: ${params.MAAS_SNAP_CHANNEL}
+ test_db_channel: ${params.TEST_DB_SNAP_CHANNEL}
+ """
+ dir("system-tests") {
+ sh """
+ cat config.yaml
+ export http_proxy=http://squid.internal:3128/
+ export https_proxy=http://squid.internal:3128/
+ export TOX_PARALLEL_NO_SPINNER=1
+ tox -e cog
+ tox -e env_builder -- ${params.PYTEST_ARGS} | tee env_builder.out
+ tox -e general_tests -- ${params.PYTEST_ARGS}
+ tox -p all -e vm1,natasha -- ${params.PYTEST_ARGS}
+ tox -p all -e opelt,arm64,ppc64le,vm2 -- ${params.PYTEST_ARGS}
+ """
+ }
+ }
+ }
+ }
+ post {
+ always {
+ script {
+ buildInfo = sh (returnStdout: true, script: "awk '/BEGIN_SYSTEMTESTS_META/{ f = 1; next } /END_SYSTEMTESTS_META/ { f = 0 } f' system-tests/env_builder.out")
+ currentBuild.description = "$buildInfo"
+ }
+ sh """
+ export http_proxy=http://squid.internal:3128/
+ export https_proxy=http://squid.internal:3128/
+ env -C system-tests tox -e collect_sos_report
+ """
+ archiveArtifacts artifacts: 'system-tests/sosreport/*,system-tests/*.log,system-tests/config.yaml,system-tests/junit*.xml', fingerprint: true
+ junit allowEmptyResults: true, testResults: 'system-tests/junit*.xml'
+ sh """
+ lxc delete maas-system-build --force || true
+ lxc delete maas-system-maas --force || true
+ lxc delete maas-client --force || true
+ """
+ }
+ success {
+ mattermostSend (color: 'green', message: "[${env.JOB_NAME} #${env.BUILD_NUMBER}](${env.BUILD_URL}) :success: was successful")
+ }
+ failure {
+ mattermostSend (color: 'red', message: "[${env.JOB_NAME} #${env.BUILD_NUMBER}](${env.BUILD_URL}) :fire: failed")
+ }
+ }
+ }
diff --git a/jenkins/jobs/systemtests_v3.yaml b/jenkins/jobs/systemtests_v3.yaml
new file mode 100644
index 0000000..4c03c02
--- /dev/null
+++ b/jenkins/jobs/systemtests_v3.yaml
@@ -0,0 +1,340 @@
+- job:
+ name: maas-system-tests-wip
+ description: |
+ Run the MAAS system tests
+ project-type: pipeline
+ triggers:
+ - timed: '@daily'
+ dsl: |
+ def cd_tox = "env -C system-tests tox"
+ def gen_config_cmd = "${cd_tox} -e generate_config --"
+ pipeline {
+ agent {
+ label 'ci-lab'
+ }
+ options {
+ timeout(time: 6, unit: "HOURS")
+ }
+ parameters {
+ string(name: 'SYSTEMTESTS_GIT_REPO', defaultValue: 'https://git.launchpad.net/~maas-committers/maas-ci/+git/system-tests', description: 'Git repo to pull system tests from')
+ string(name: 'SYSTEMTESTS_GIT_BRANCH', defaultValue: 'master', description: 'Branch in the repo to use')
+
+ choice(name: 'INSTALLATION_METTHOD', choices: ['SNAP', 'DEB'], description: 'Which MAAS installation method use for this execution.')
+ string(name: 'MAAS_GIT_REPO', defaultValue: 'https://git.launchpad.net/maas', description: 'Git repo to pull MAAS of.')
+ string(name: 'MAAS_GIT_BRANCH', defaultValue: 'master', description: 'branch of MAAS project to build from.')
+ string(name: 'MAAS_PPA', defaultValue: 'ppa:maas-committers/latest-deps', description: 'MAAS ppa for dependencies.')
+
+ string(name: 'MAAS_SNAP_CHANNEL', defaultValue: 'latest/edge', description: 'Channel of MAAS snap.')
+ string(name: 'TEST_DB_SNAP_CHANNEL', defaultValue: '', description: 'Channel of maas-test-db snap. Leave empty to use same channel of MAAS snap.')
+
+ string(name: 'CONTAINERS_IMAGE', defaultValue: 'ubuntu:22.04', description: 'LXD image for containers used in tests')
+ booleanParam(name: 'ENABLE_TLS', defaultValue: false, description: 'During MAAS installation enable TLS.')
+ booleanParam(name: 'ENABLE_OBSERVABILITY', defaultValue: false, description: 'During MAAS installation enable telemtry and send it to our O11y stack.')
+ booleanParam(name: 'ENABLE_HW_SYNC_TEST', defaultValue: false, description: 'Execute HW SYNC feature tests')
+
+ string(name: 'GEN_CONFIG_ARGS', defaultValue: '', description: 'Additional args to gen_onfig (--ppa --architecture --machine etc)')
+ string(name: 'PYTEST_ARGS', defaultValue: '--log-cli-level info', description: 'Additional args to pytest')
+
+ booleanParam(name: 'REMOVE_CONTAINERS', defaultValue: true, description: 'Should existing containers be torn down before we run?')
+ }
+ environment {
+ http_proxy ='http://squid.internal:3128/'
+ https_proxy='http://squid.internal:3128/'
+ TOX_PARALLEL_NO_SPINNER='1'
+ }
+ stages {
+ stage('Checkout') {
+ steps {
+ sh """
+ lxc list
+ pgrep -a qemu || true
+ rm -rf system-tests
+ git clone ${params.SYSTEMTESTS_GIT_REPO} --branch ${params.SYSTEMTESTS_GIT_BRANCH} --depth 10 system-tests
+ cd system-tests && git show --no-patch
+ """
+ }
+ }
+ stage('Clean') {
+ when {
+ expression {
+ return params.REMOVE_CONTAINERS
+ }
+ }
+ steps {
+ sh """
+ lxc delete maas-system-build --force || true
+ lxc delete maas-system-maas --force || true
+ lxc delete maas-client --force || true
+ """
+ }
+ }
+ stage('Setup') {
+ steps {
+ sh """
+ sudo apt-get install -y tox
+ """
+ writeFile file: 'system-tests/base_config.yaml', text: """
+ proxy:
+ use_internal: true
+ http: http://squid.internal:3128
+ networks:
+ pxe:
+ cidr: 10.245.136.0/21
+ bridge: br0
+ dynamic:
+ start: 10.245.136.21
+ end: 10.245.136.200
+ reserved:
+ - start: 10.245.136.1
+ end: 10.245.136.19
+ comment: Reserved
+ - start: 10.245.143.100
+ end: 10.245.143.200
+ comment: BMCs
+ maas:
+ networks:
+ pxe: 10.245.136.20
+ config:
+ # This values will set with `maas set-config` command
+ upstream_dns: 10.245.136.1
+ dnssec_validation: "no"
+ domain_name: systemtestsmaas
+
+ windows_image_file_path: /home/ubuntu/other-os-images/windows-win2012hvr2-amd64-root-dd
+
+ tls:
+ cacerts: ssl-cert-snakeoil.pem
+
+ vault:
+ snap-channel: 1.11/stable
+
+ containers-image: ${params.CONTAINERS_IMAGE}
+
+ machines:
+ hardware:
+ opelt:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.121
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:6d:fb:3c
+ stunky:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.127
+ power_username: landscape
+ power_password: insecure
+ mac_address: ec:b1:d7:7f:ef:34
+ natasha:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.120
+ power_username: root
+ power_password: calvin
+ mac_address: 18:66:da:75:6b:ee
+ osystem: windows
+ arm64:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.114
+ power_username: admin
+ power_password: password
+ mac_address: 1c:1b:0d:0d:52:7c
+ architecture: arm64
+ ppc64le:
+ power_type: ipmi
+ power_parameters:
+ power_driver: LAN_2_0
+ power_address: 10.245.143.113
+ power_username: ""
+ power_password: admin
+ mac_address: 98:be:94:02:6a:c8
+ architecture: ppc64el
+ vms:
+ instances:
+ vm1:
+ mac_address: 00:16:3e:d6:36:18
+ devices:
+ disk1:
+ type: disk
+ source: /home/ubuntu/diego/test_block_device.img
+ #size: 1MB
+ path: /mnt/ext2
+ iface1:
+ type: nic
+ nictype: bridged
+ parent: br0
+ name: eth1
+ hwaddr: 00:16:3e:4a:19:6f
+ # usb1:
+ # type: usb
+ # productid: "0016"
+ # pci1:
+ # type: pci
+ # address: '02:00.1'
+ lxd_profile: prof-maas-test
+ vm2:
+ mac_address: 00:16:3e:d0:54:9f
+ lxd_profile: prof-maas-test
+ power_type: lxd
+ power_parameters:
+ power_address: https://10.157.204.1:8443
+ project: default
+ certificate: |
+ -----BEGIN CERTIFICATE-----
+ MIIElzCCAn8CEQD+6NBHtM1z951J2HwbtZwnMA0GCSqGSIb3DQEBDQUAMAAwHhcN
+ MjIwMjA4MTMwNDI4WhcNMzIwMjA2MTMwNDI4WjATMREwDwYDVQQDDAh0ZXN0aG9z
+ dDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANRvcoT8dofRU2A0ICm0
+ JzZPJr9C7oQmJhxd/I8Fwzt1Jzom0mhg+8oSFXPI7jzx8kpFexJZHBF8WBUII+0v
+ RnZx8oeIRtvrL22tKEqeH2dwZxHIpcmoPbj2jMCFR1IFhFGBJD1uDUvkBAYFnguM
+ tJml5yh+BhhPGc8Ehds/kstq032rWlDjx0Cne+5mebSniz+TW5+uc/7Vy4mIDm3P
+ IGgytRXDseryvJ0kuLkNZGT38tHTva22skz0K0mRImNgCdjbacsS85DQymANJtP/
+ TbAZnZ2VGLGJ2jXVBEKcXDRdrT5jusQTdRseciXqbSBuvCcsd+4R85ZZNO4ARDqI
+ XNWEEinspXfJtBuvx2dtZ1S8K233kz1ds5n3vLirw6LIeNW1b8a200JeDovBzUmt
+ fu9qSgw+fS2H7k/TnQDzd1AqhcKQpZqZd2eY1d4AbM9L9oEPFPesISNko7U0NpPC
+ 5RfejxL+IMhshKDPWCo50I4Ty80gSPbzRBJUXE4Qq3ZiiqiK8EW0VRobz6ZfDF1A
+ /2oR6C6QvNd30lzdP1laLLHKBh2A3TTWL4UE+N6eH38LdO2isbh/8ux068sclxzX
+ Ba34D5ICzjHd4FpBHiNpyTnb8QAaKcOFLr2QGHogRCQI2QygPyB6jaVTTVwkJbKS
+ kuJBcUjBNmkEnx1VFIqnzDr5AgMBAAEwDQYJKoZIhvcNAQENBQADggIBAL7aLr6Z
+ Hfqlefng/JMr+ojDJWmdtHTqwa9MviEzHTlzhvTw3JRCMFlIlIrK7wpd7kr9Jmhz
+ HI3atc1NtrEsMeUsvNmopnlqKWPwcyCYX0juKvoMeTqFDLN7yWPBHEc4NNhXJQte
+ pee7P02e8+C0g4UXlQ8Hry1LfwhlwHok0LijEbBkX4x0m7RlqqprMfJJsU6wL613
+ WOcfTEiHkZYB/a/yeIAhdqSi3jMH3m+jbG9Tjfn62pPheSzRpH28A5mvZVP39RUO
+ JdpEHT7F5pMmauygWBxXT/VCU0TriCMYrexjA1cWOlrT0+VU5Im3+u0l3vUE+2Wc
+ zKNpt3l3wG3KmLHeJr9/7QyFLMHhEYr4xpMoikIhq75iLz6GqGkgho7Xy7Iz2WZP
+ YW39eNAYdW8UEnSpdlmsA0gIHeWDVWZFebMk8Jw5AtIr6qTUGRMp4jFzwaQX4Oc2
+ kf2jqICMKz3nQjT5b5+/w6OKuz1POrzA9hRkp85fDdeD/zwO9v+65qwHk9T+FOM4
+ xC/VQcoSp5lJmGN6NGCleLhpUbIwX381rCk7pvOPQ5PLWW2gPB61njsdbJ97fWpy
+ 5b7QD4Pcq+eQ2Xy1+F4ToCmW8E6XorUFPUKTInTl4McHbJiuGwmXAkGqLzgJd+Q1
+ opB3iqj1W36wgZQK6lRoN7X/zugt9m+MZX/6
+ -----END CERTIFICATE-----
+ key: |
+ -----BEGIN PRIVATE KEY-----
+ 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
+ Xwjk99gnvag+HswBDB7A7DCTEqhkUQ==
+ -----END PRIVATE KEY-----
+ """
+ }
+ }
+ stage('Generate configuration') {
+ steps {
+ if (params.INSTALLATION_METTHOD == 'SNAP') {
+ gen_config_cmd = "${gen_config_cmd} --snap --snap-channel ${params.MAAS_SNAP_CHANNEL}"
+ if (params.TEST_DB_SNAP_CHANNEL) {
+ gen_config_cmd ="${gen_config_cmd} --test-db-channel ${params.TEST_DB_SNAP_CHANNEL}"
+ }
+ } else {
+ gen_config_cmd = "${gen_config_cmd} --deb --git-repo ${params.MAAS_GIT_REPO} --git-branch ${params.MAAS_GIT_BRANCH} --ppa ${params.MAAS_PPA}"
+ }
+ if (params.ENABLE_TLS) {
+ gen_config_cmd = "${gen_config_cmd} --tls"
+ }
+ if (params.ENABLE_OBSERVABILITY) {
+ gen_config_cmd = "${gen_config_cmd} --o11y"
+ }
+ if (params.ENABLE_HW_SYNC_TEST) {
+ gen_config_cmd = "${gen_config_cmd} --hw-sync"
+ }
+ if (params.GEN_CONFIG_ARGS) {
+ gen_config_cmd = "${gen_config_cmd} ${params.GEN_CONFIG_ARGS}"
+ }
+
+ sh """
+ ${gen_config_cmd} --containers-image=${params.CONTAINERS_IMAGE} base_config.yaml config.yaml
+ """
+ }
+ }
+ stage('System Tests') {
+ environment {
+ COG = sh (returnStdout: true, script:"${cd_tox} -e cog").trim()
+ ENVS1 = sh (returnStdout: true, script: "${cd_tox} -q -e filter_envs vm1,natasha | head -1").trim()
+ ENVS2 = sh (returnStdout: true, script: "${cd_tox} -q -e filter_envs opelt,arm64,ppc64le,vm2 | head -1").trim()
+ }
+
+ steps {
+ sh """
+ cd system-tests
+ cat config.yaml
+ tox -e env_builder,general_tests -- ${params.PYTEST_ARGS}
+ """
+ if (ENVS1) {
+ sh """
+ ${cd_tox} -p all -e ${ENVS1} -- ${params.PYTEST_ARGS}
+ """
+ }
+ if (ENVS2) {
+ sh """
+ ${cd_tox} -p all -e ${ENVS2} -- ${params.PYTEST_ARGS}
+ """
+ }
+ }
+ }
+ }
+ post {
+ always {
+ sh """
+ ${cd_tox} -e collect_sos_report
+ """
+ archiveArtifacts artifacts: 'system-tests/sosreport/*,system-tests/*.log,system-tests/config.yaml,system-tests/junit*.xml', fingerprint: true
+ junit allowEmptyResults: true, testResults: 'system-tests/junit*.xml'
+ sh """
+ lxc delete --force maas-system-build || true
+ lxc delete --force maas-system-maas || true
+ lxc delete --force maas-client || true
+ """
+ }
+ }
+ }
diff --git a/jenkins/jobs/update b/jenkins/jobs/update
new file mode 100755
index 0000000..d286ac6
--- /dev/null
+++ b/jenkins/jobs/update
@@ -0,0 +1,10 @@
+#!/bin/bash -e
+case $1 in
+ orobas)
+ config="orobas.ini"
+ ;;
+ *)
+ config="config.ini"
+ ;;
+esac
+jenkins-jobs --conf $config --ignore-cache update .
diff --git a/maas-ci-common b/maas-ci-common
new file mode 100644
index 0000000..1023ead
--- /dev/null
+++ b/maas-ci-common
@@ -0,0 +1,7 @@
+#!/bin/bash
+# Common environment variables used to configure jenkins and jenkins-slave for
+# MAAS CI.
+
+AUTOPKGTEST_ROOT=${JENKINS_HOME}/autopkgtest
+MAAS_CI_ROOT=${JENKINS_HOME}/maas-ci
+ADT_IMAGES_ROOT=${JENKINS_HOME}/images
diff --git a/prometheus-setup.md b/prometheus-setup.md
new file mode 100644
index 0000000..cce73af
--- /dev/null
+++ b/prometheus-setup.md
@@ -0,0 +1,126 @@
+# Configuring Prometheus and Grafana for collecting MAAS CI runs metrics
+
+The following should be run from the `jenkins-slave-2` CI machine.
+
+## Setting up the container
+
+- Create a container
+
+ ```
+ lxc init ubuntu-daily:b maas-performance
+ lxc edit maas-performance
+ ```
+
+- Set the following in the `devices` section:
+
+ ```
+ devices:
+ eth0:
+ nictype: bridged
+ parent: br0
+ type: nic
+ ```
+
+ to have the container access the host bridge. Then start the container and
+ connect to it:
+
+ ```
+ lxc start maas-performance
+ lxc shell maas-performance
+ ```
+
+- Create a `/etc/netplan/eth0.yaml` file to configure the static interface,
+ with the following content:
+
+ ```
+ network:
+ version: 2
+ ethernets:
+ eth0:
+ dhcp4: false
+ addresses: [10.245.136.203/21]
+ gateway4: 10.245.136.1
+ nameservers:
+ addresses: [10.245.136.1]
+ ```
+
+ and run `netplan apply`. The specified IP address is reserved in the CI
+ config so that the deployed MAAS won't use it.
+
+- Edit `/etc/environment` and add the following:
+
+ ```
+ http_proxy=http://squid.internal:3128
+ https_proxy=http://squid.internal:3128
+ no_proxy="10.157.204.9,10.157.204.52,10.157.204.227,10.157.204.239,10.245.136.6"
+ ```
+
+
+## Installing and configuring Prometheus and Grafana
+
+- Install the snaps:
+
+ ```
+ snap install prometheus
+ snap install promreg
+ snap install grafana --edge
+ snap connect prometheus:content promreg:content
+ ```
+
+- Edit `/var/snap/promreg/common/promreg.yaml` changing `AuthToken: promreg`
+ and `ListenAddress: 0.0.0.0`.
+
+- Run `snap restart promreg`.
+
+- Edit `/var/snap/prometheus/current/prometheus.yml` and add the following job
+ definition:
+
+ ```
+ - job_name: 'prometheus-registration'
+ file_sd_configs:
+ - files:
+ - /var/snap/prometheus/current/promreg/targets.yaml
+
+ - job_name: 'maas'
+ static_configs:
+ - targets:
+ - 10.245.136.6:5239
+ - 10.245.136.6:5249
+
+ - job_name: 'maas-stats'
+ metrics_path: /MAAS/metrics
+ static_configs:
+ - targets:
+ - 10.245.136.6:5240
+ ```
+
+- Edit `/var/snap/prometheus/current/daemon_arguments` and set `ARGS` to the following:
+
+ ```
+ ARGS="--web.listen-address=:9093"
+ ```
+
+- Run `snap restart prometheus`. Make sure it's working via `curl http://localhost:9093`
+
+- Create `/var/snap/grafana/current/conf/grafana.ini` with the following content:
+
+ ```
+ [server]
+ http_port = 3003
+
+ [sercurity]
+ admin_user = admin
+ ```
+
+- Run `snap restart grafana`. Make sure it's working via `curl http://localhost:3003`
+
+
+## Setting up the dashboards
+
+- Log in to Grafana with `admin/admin` credentials.
+- Add a Prometheus source with URL `http://localhost:9093`.
+- Import the dashboards from the [MAAS performance][maas-performance]
+ repo. They're located under `grafana/dashboards`.
+
+
+[maas-performance]: https://code.launchpad.net/~maas-committers/maas/+git/maas-performance
diff --git a/rebuild-ci.sh b/rebuild-ci.sh
new file mode 100755
index 0000000..428e350
--- /dev/null
+++ b/rebuild-ci.sh
@@ -0,0 +1,210 @@
+#!/bin/bash
+
+PROFILE="jenkins"
+CONTAINER="jenkins"
+PROXY="http://squid.internal:3128"
+# config for orobas. Temporary
+#IP_CIDR="10.246.88.13/22"
+#GATEWAY="10.246.88.1"
+#DNS="10.246.88.1"
+#LXD_STORAGE_POOL="default"
+#LXD_BRIDGE="br0"
+IP_CIDR="10.245.136.4/21"
+GATEWAY="10.245.136.1"
+DNS="10.245.136.1"
+LXD_STORAGE_POOL="sdb"
+LXD_BRIDGE="br0"
+
+function info (){
+ echo "INFO: $1"
+}
+
+function configure_lxd_profile() {
+ # define
+ # TODO:
+ # - we could create a storage pool on another disk to host the containers.
+ # - lxc storage create sdb zfs source=/dev/sdb
+ # create profile
+ lxc profile create $PROFILE
+ # configure profile
+ cat << EOF | lxc profile edit $PROFILE
+ config: {}
+ description: Profile for Jenkins Master
+ devices:
+ eth0:
+ name: eth0
+ nictype: bridged
+ parent: "$LXD_BRIDGE"
+ type: nic
+ root:
+ path: /
+ pool: $LXD_STORAGE_POOL
+ type: disk
+ name: $PROFILE
+ config:
+ environment.http_proxy: "$PROXY"
+ environment.https_proxy: "$PROXY"
+ user.vendor-data: |
+ #cloud-config
+ apt:
+ proxy: "$PROXY"
+ apt_proxy: "$PROXY"
+EOF
+}
+
+function configure_lxd_container() {
+ info "Configuring $CONTAINER"
+ lxc launch --profile $PROFILE ubuntu-daily:bionic $CONTAINER
+ sleep 2
+
+ info "configuring networking"
+ lxc exec $CONTAINER -- /bin/bash -c "cat <<EOF > /etc/netplan/50-cloud-init.yaml
+# Not really setup by cloud-init
+network:
+ version: 2
+ ethernets:
+ eth0:
+ addresses:
+ - $IP_CIDR
+ gateway4: $GATEWAY
+ nameservers:
+ addresses:
+ - $DNS
+EOF"
+ lxc exec $CONTAINER -- netplan apply
+}
+
+function configure_lxd_container_jenkins() {
+ info "configuring & installing jenkins"
+ lxc exec $CONTAINER -- /bin/bash -c "wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -"
+ lxc exec $CONTAINER -- /bin/bash -c "echo 'deb https://pkg.jenkins.io/debian binary/' | tee -a /etc/apt/sources.list.d/jenkins.list"
+ lxc exec $CONTAINER -- apt-get update
+ lxc exec $CONTAINER -- apt-get install openjdk-8-jdk -y
+ lxc exec $CONTAINER -- apt-get install jenkins -y
+}
+
+function configure_slave_maas_lander() {
+ info "Configure slave to access LP as 'maas-lander'"
+ mkdir -p ~/.ssh/
+ cat << EOF > ~/.ssh/id_rsa-maas-lander
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpAIBAAKCAQEA145HSiczzCZ42x8DMrjcNLyu2ViD5b9Bb6KXC4D3CTZTXfUl
+xEv92o976xvANObajsdUHHByyG26hy09e1AYq/o1aDvsKsZlgxlIVowo3qFkrxlY
+Mv8T3YBPLJxsLItw3yZ3qUFc+kiPjL1VsJZ8nWYEf6CLs0zHpnVKXVOoO1618GQr
+XgT4VaO7le1KaK/cy09haGDnUFSoceYYKIGZvhb9xUJLptQZE6NByjPIQhT75ODI
+YRvNF8x5iYIl9j4BtByPdKqudpr6/g7mqmIrpLHMakl5+XC6blDsnZ8D2dN3alkv
+kukfUKgJe9YX248hsJEnRpCn/hRoRfsMgiJePQIDAQABAoIBAHu6bW1BB1hdlO2h
+5YIN3khfLbYQOtV7bKIZn724rxQYnM3H03/TZsk3pxeS/EbhY/6kp8ETQq+NXI4P
+B8Vqel7s5g8Ipkz/SHFx57XWCfeQiGyBjcDn7Y0tA0VGHEmNWKKeP/1lSWtYjx1n
+6HHOT4VBc7+WddnbbpY7qQ3c4SoB6wrXii6MvtLojqYvOVAbaQyQJJyRapz5S6zK
+nOk3bfxrHQvt+ZQAcqDlQ9e2xBchYDQVeBNp8tR/b8xuEPzUUfewJLINgWKjJiW9
+mdSgPsu2GncrBpznpf84pW+X1aIvSYb092+UFm2a95S8bNkKU8Tu2HZBlUbea8PH
+o2jJlXkCgYEA+p8ScYgsdGHw9fLI5AqyfxIpdCaDjRBZQhyGoNQw6n/Q0s5QPoIy
+aE5XVWcUcRpp65vVz3QbwxDEc/N5R+vdxds0P3ylh7+ojamJTu6DOrBpOKL07ule
+vCcT4YfO51iCqshUtc9g+cRXZs0R22nr01PD8c7ALI+0uia68z0lgBsCgYEA3C6N
+1ih+/WMhulXjy1IhSjuxJ33mgR5uyQJR1Jb2qA7VgPLeeBuz85bRQq9L2R9UH84S
+/OTf4DoAOJJqSB1eBgELSeyna2RsP9Z6BtW69YAcmbs75WVrhFzxXUqBERlylSQk
+6CQrbo6UFMEdDChPZE7D1djC/1BZ3ToGvGbwcIcCgYEApV/D/tB5bQ6XvuNGtlts
+rzbfzboAQlwQWfSSzZtW79YJiKEFCEpHUtanAD61mXBxhjvdWTfnfc8Zot19IP09
+6OodTutEGxBX+6psZX4zb82qkOnOr7ukfIlYsBA6ciPQjTsF0raV6hoqBja5WsxJ
+BbiXan8gBgeJnPAjmo+1qBMCgYA8obk/MxGdNzIvfL1o3On75ionhNz3y2iYg8IC
+97telg8nHjoy+vX36x0e7uTFGoJw66+A4onf1jj/WxpXV3bv0lPIfJmx0gqZHbem
+sC52slut3chlqCMOZQW2OfEGw2oxNa3QGz22iR6wBGm6UlNifOoitjkkU30blYIL
+WZF2ewKBgQDRKCcar4lxSw1uq3xXrXk5c9BGrcq5/8/Fg1qGEMLsB/Q+i6GiSCcv
+gyXemK+Daiuku6l8g/IXJKoDhX4gxuzZCtYgA6Q3AKV+RSESw3So85wjZUCpfTzj
+WbBVbnDC4rgeyR82y2AagpvSGAERE6IjJ90QXDwxl6lFhS8TwactjQ==
+-----END RSA PRIVATE KEY-----
+EOF
+ chmod 0400 ~/.ssh/id_rsa-maas-lander
+
+ cat << EOF > ~/.ssh/config
+Host bazaar.launchpad.net
+ IdentityFile /home/ubuntu/.ssh/id_rsa-maas-lander
+ User maas-lander
+EOF
+
+ mkdir -p ~/.bazaar
+ cat << EOF > ~/.bazaar/authentication.conf
+[Launchpad]
+host = .launchpad.net
+scheme = ssh
+user = maas-lander
+EOF
+
+ cat << EOF > ~/.bazaar/bazaar.conf
+[DEFAULT]
+launchpad_username = maas-lander
+EOF
+}
+
+function configure_slave_kvm() {
+ sudo apt-get install qemu-kvm libvirt-bin bridge-utils openjdk-8-jre-headless -y
+ mkdir -p /etc/qemu
+ sudo bash -c 'echo "allow br0" >> /etc/qemu/bridge.conf'
+ sudo chmod u+s /usr/lib/qemu/qemu-bridge-helper
+ sudo ln -sf /usr/lib/qemu/qemu-bridge-helper /usr/lib/qemu-bridge-helper
+}
+
+function configure_slave_download_autopkgtest() {
+ cd ~/
+ git clone https://anonscm.debian.org/git/autopkgtest/autopkgtest.git
+}
+
+function configure_slave_images() {
+ bzr branch lp:~maas-maintainers/maas/maas-ci-config
+ mkdir -p ~/images/
+ ./autopkgtest/tools/autopkgtest-buildvm-ubuntu-cloud \
+ -v -r bionic -s 20G -a amd64 \
+ -o ./images/ -p $PROXY \
+ --metadata ~/maas-ci-config/etc/meta-data-orobas
+
+}
+
+function configure_lxd_container_candid() {
+ info "Configuring and installing Candid"
+ lxc exec $CONTAINER -- git clone http://git.launchpad.net/maas
+ lxc exec $CONTAINER -- /bin/bash -c "echo $CONTAINER.maasci > /etc/hostname"
+ lxc exec $CONTAINER -- /bin/bash -c "echo $IP $CONTAINER.maasci $CONTAINER >> /etc/hosts"
+ lxc exec $CONTAINER -- cp ./maas/utilities/ldap-setup.sh ./
+ lxc exec $CONTAINER -- cp ./maas/utilities/candid-setup.sh ./
+ lxc exec $CONTAINER -- /bin/bash ./ldap-setup.sh
+ lxc exec $CONTAINER -- /bin/bash -c "no_proxy=$CONTAINER.maasci ./candid-setup.sh"
+}
+
+case "$1" in
+ master)
+ configure_lxd_profile
+ configure_lxd_container
+ configure_lxd_container_jenkins
+ info "Jenkins is installed. Now configure jenkins"
+ info " - use proxy: $PROXY"
+ info " - Install extra plugins: Git, Global Variable String Parameter, Rebuilder, Build with parameters, IRC"
+ info " - Add a slave node"
+ ;;
+ slave)
+ configure_slave_maas_lander
+ configure_slave_kvm
+ configure_slave_download_autopkgtest
+ configure_slave_images
+ ;;
+ candid)
+ CONTAINER="candid"
+ IP_CIDR="10.245.136.5/21"
+ IP="10.245.136.5"
+ configure_lxd_container
+ configure_lxd_container_candid
+ info "###### Please do the following items manually ######"
+ info "# There are some steps that need to be done manually so that the"
+ info "# MAAS istance can actually authenticate via candid:"
+ info "# - Branch lp:~maas-maintainers/maas/qa-lab-tests"
+ info "# - Update config.py:CANDID_MAAS_AGENT with candid's maas.agent"
+ info "# - Update config.py:CANDID_CA_CERT with candid's ~/cert/ca.crt"
+ info "# Once updated, please commit changes and submit them."
+ ;;
+ *)
+ info "###### No argument passed. Please pass:"
+ info "# candid - to re-install candid container"
+ info "# master - to re-install jenkins master inside a container"
+ info "# slave - to configure the host as a slave"
+ # TODO: Create jobs
+esac
diff --git a/ssh/config b/ssh/config
new file mode 100644
index 0000000..6ddd9e5
--- /dev/null
+++ b/ssh/config
@@ -0,0 +1,30 @@
+# Replace $HOME with the Jenkins home directory as SSH config
+# does not support environment variables
+Host localhost
+ IdentityFile $HOME/.ssh/id_rsa.pub
+ CheckHostIP no
+ UserKnownHostsFile /dev/null
+ StrictHostKeyChecking no
+ User ubuntu
+
+Host bazaar.launchpad.net
+ IdentityFile $HOME/.ssh/id_rsa_maas-lander
+ User maas-lander
+
+Host region
+ HostName localhost
+ IdentityFile /var/tmp/adt/disks/adtkey
+ CheckHostIP no
+ UserKnownHostsFile /dev/null
+ StrictHostKeyChecking no
+ Port 54323
+ User ubuntu
+
+Host cluster
+ HostName localhost
+ IdentityFile /var/tmp/adt/disks/adtkey
+ CheckHostIP no
+ UserKnownHostsFile /dev/null
+ StrictHostKeyChecking no
+ Port 54324
+ User ubuntu