pytest-html report for tcib container builds
Consolidate tcib build results in a html report running pytest to check if the containers were built. For each container image, a test is run to check if the image exists and a link to the logs is attached to the report. As part of the container build simplification and usability improvements, the kolla and tripleo building methods have been split into separate templates. This change also removes the dry-runs in the build script that were supposed to get the list of expected containers. Instead, we replace the dry-runs with the tripleo_containers.yaml file. This avoids confusion in counting expected containers vs the actual built ones. Change-Id: I1bb9353c2b5c79f55ab39d9cfcaa8f9617c28a34
This commit is contained in:
parent
318df84d54
commit
d227115b1d
|
@ -0,0 +1,63 @@
|
|||
# Copyright 2020 Red Hat Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import glob
|
||||
import pytest
|
||||
import subprocess
|
||||
|
||||
|
||||
def _get_build_log(image):
|
||||
"""
|
||||
Retrieve the inidividual log filename for a given image
|
||||
e.g. ./logs/container-builds/**/<image>-build.log
|
||||
"""
|
||||
# compose the log filename
|
||||
log = f"{ image }-build.log"
|
||||
# glob search in ./logs/container-builds/**/<image>-build.log
|
||||
logfile = f"./{ pytest.logs_dir }/{ pytest.build_dir }/**/{ log }"
|
||||
for f in glob.glob(logfile, recursive=True):
|
||||
# return only first match
|
||||
return f
|
||||
# log not found, return glob string
|
||||
return logfile
|
||||
|
||||
|
||||
def test_container_is_built(image):
|
||||
"""
|
||||
Test if container image is built
|
||||
"""
|
||||
# image in skip list, skip the build check
|
||||
if image in pytest.excluded_containers:
|
||||
pytest.skip("container image excluded: {}".format(image))
|
||||
|
||||
# [TEST 1]: check if image exists
|
||||
cmd = ['buildah', 'images', image]
|
||||
proc = subprocess.run(
|
||||
cmd, universal_newlines=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
# buildah images <image> should return 0 and image should be in stdout
|
||||
assert image in proc.stdout and proc.returncode == 0, proc.stderr
|
||||
print(proc.stdout)
|
||||
|
||||
# [TEST 2]: check if build log has errors
|
||||
try:
|
||||
# read log file
|
||||
with open(_get_build_log(image), 'r') as build_log:
|
||||
log = build_log.read()
|
||||
# test if any error is found in the log
|
||||
assert 'Error:' not in log, f"Image failed to build: { image }"
|
||||
except IOError as err:
|
||||
print(f"Warning: Build log not found: { err }")
|
||||
|
||||
# [TEST N+1]: additional tests can be added here
|
|
@ -0,0 +1,93 @@
|
|||
# Copyright 2020 Red Hat Inc.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||
# not use this file except in compliance with the License. You may obtain
|
||||
# a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import glob
|
||||
import pytest
|
||||
from py.xml import html
|
||||
|
||||
BUILD_DIR = 'container-builds'
|
||||
LOGS_DIR = 'logs'
|
||||
EXCLUDE_CONTAINERS = 'containers-excluded.log'
|
||||
|
||||
|
||||
def _get_build_link(funcargs):
|
||||
"""
|
||||
Retrieves the link of the build log for a given container
|
||||
"""
|
||||
# compose logfile to glob search
|
||||
log = f"{ funcargs.get('image') }-build.log"
|
||||
logfile = f"./{ LOGS_DIR }/{ BUILD_DIR }/**/{ log }"
|
||||
for f in glob.glob(logfile, recursive=True):
|
||||
# remove parent 'logs/' dir from the path
|
||||
# link will be like ./container-builds/**/<image>-build.log
|
||||
link = "./" + "/".join(f.split("/")[2:])
|
||||
# return first log file as href link
|
||||
return html.a(log, href=link)
|
||||
# log file not found
|
||||
return ""
|
||||
|
||||
|
||||
def _get_excluded_containers_list():
|
||||
"""
|
||||
Retrieves the list of excluded images to skip the build
|
||||
"""
|
||||
try:
|
||||
with open(EXCLUDE_CONTAINERS) as f:
|
||||
excluded_containers_list = [line.strip() for line in f]
|
||||
except IOError:
|
||||
excluded_containers_list = []
|
||||
return excluded_containers_list
|
||||
|
||||
|
||||
def pytest_addoption(parser):
|
||||
parser.addoption(
|
||||
"--image",
|
||||
action="append",
|
||||
default=[],
|
||||
help="list of container images to pass to test functions",
|
||||
)
|
||||
|
||||
|
||||
def pytest_generate_tests(metafunc):
|
||||
if "image" in metafunc.fixturenames:
|
||||
metafunc.parametrize("image", metafunc.config.getoption("image"))
|
||||
|
||||
|
||||
def pytest_configure():
|
||||
# these vars are visible from build-report.py functions
|
||||
pytest.excluded_containers = _get_excluded_containers_list()
|
||||
pytest.build_dir = BUILD_DIR
|
||||
pytest.logs_dir = LOGS_DIR
|
||||
|
||||
|
||||
@pytest.mark.optionalhook
|
||||
def pytest_html_results_table_header(cells):
|
||||
# this replaces the default 'Links' column in position #3
|
||||
cells.insert(3, html.th('Build Log'))
|
||||
cells.pop()
|
||||
|
||||
|
||||
@pytest.mark.optionalhook
|
||||
def pytest_html_results_table_row(report, cells):
|
||||
if hasattr(report, 'build_log'):
|
||||
# report.logs has the link of each build log
|
||||
cells.insert(3, html.td(report.build_log))
|
||||
|
||||
|
||||
@pytest.mark.hookwrapper
|
||||
def pytest_runtest_makereport(item, call):
|
||||
outcome = yield
|
||||
report = outcome.get_result()
|
||||
# get the link for a given image build log
|
||||
report.build_log = _get_build_link(item.funcargs)
|
|
@ -0,0 +1,94 @@
|
|||
- name: Container build report
|
||||
block:
|
||||
|
||||
- name: Move container-builds dir to workspace/logs
|
||||
shell: "mv /tmp/container-* ./logs/"
|
||||
become: true
|
||||
args:
|
||||
chdir: "{{ workspace }}"
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Set ci_branch for building containers check jobs
|
||||
include_tasks: set_ci_branch.yml
|
||||
|
||||
- name: Set branch
|
||||
set_fact:
|
||||
branch: "{{ osp_branch | default(ci_branch) }}"
|
||||
|
||||
- name: fetch tripleo_containers.yaml into ansible controller
|
||||
fetch:
|
||||
src: "{{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images/tripleo_containers.yaml"
|
||||
dest: "{{ zuul.executor.work_root }}/"
|
||||
flat: yes
|
||||
|
||||
- name: Load list of containers expected to build
|
||||
include_vars:
|
||||
file: "{{ zuul.executor.work_root }}/tripleo_containers.yaml"
|
||||
|
||||
- name: build list of expected images w/ prefix
|
||||
set_fact:
|
||||
expected_images: "{{ expected_images|default([]) + [item['imagename'].split(':')[0].split('/')[2]] }}"
|
||||
when: item['image_source'] == "tripleo"
|
||||
with_items: "{{ container_images }}"
|
||||
|
||||
- name: remove prefix from expected containers list
|
||||
vars:
|
||||
prefix: "{{ container_name_prefix }}-"
|
||||
set_fact:
|
||||
expected_containers: "{{ expected_containers|default([]) + [item | replace(prefix, '')] }}"
|
||||
with_items: "{{ expected_images }}"
|
||||
|
||||
- name: Get list of excluded containers
|
||||
shell: |
|
||||
set -eux
|
||||
echo {{ item }} >> {{ workspace }}/containers-excluded.log
|
||||
with_items: "{{ exclude_containers[branch] }}"
|
||||
when: exclude_containers is defined and branch in exclude_containers
|
||||
|
||||
- name: Write containers-expected.log
|
||||
lineinfile:
|
||||
line: "{{ item }}"
|
||||
path: "{{ workspace }}/containers-expected.log"
|
||||
create: yes
|
||||
state: present
|
||||
with_items: "{{ expected_containers }}"
|
||||
|
||||
- name: Get actual built containers
|
||||
shell: |
|
||||
set -eux
|
||||
{{ container_cli | default('buildah') }} images | grep {{ container_name_prefix }} \
|
||||
| tee {{ workspace }}/containers-built.log
|
||||
become: true
|
||||
|
||||
- name: Copy build-report files
|
||||
copy:
|
||||
src: "files/{{ item }}"
|
||||
dest: "{{ workspace }}"
|
||||
with_items:
|
||||
- build-report.py
|
||||
- conftest.py
|
||||
|
||||
- name: construct images args
|
||||
set_fact:
|
||||
images_args: "{{ images_args | default('') + ' --image ' + item }}"
|
||||
with_items: "{{ expected_containers }}"
|
||||
|
||||
- name: Install pytest
|
||||
pip:
|
||||
name: "{{ item }}"
|
||||
virtualenv: "{{ workspace }}/venv_build"
|
||||
virtualenv_python: "{{ virtualenv_python[ansible_distribution_major_version|int] }}"
|
||||
with_items:
|
||||
- pytest
|
||||
- pytest-html
|
||||
|
||||
- name: Execute build-report
|
||||
shell: |
|
||||
source "venv_build/bin/activate"
|
||||
{{ virtualenv_python[ansible_distribution_major_version|int] }} -m pytest \
|
||||
--html=report.html --self-contained-html {{ images_args }} build-report.py
|
||||
args:
|
||||
chdir: "{{ workspace }}"
|
||||
become: true
|
||||
|
||||
ignore_errors: yes
|
|
@ -128,6 +128,7 @@
|
|||
- name: Set container cli
|
||||
set_fact:
|
||||
container_cli: "{% if use_buildah|bool %}buildah{% else %}docker{% endif %}"
|
||||
cacheable: yes
|
||||
|
||||
- name: Set config-file
|
||||
set_fact:
|
||||
|
@ -200,37 +201,48 @@
|
|||
that:
|
||||
- authfile_exist.stat.exists | bool
|
||||
|
||||
- name: Generate building script
|
||||
- name: Generate kolla building script
|
||||
template:
|
||||
src: templates/build.sh.j2
|
||||
src: templates/kolla-build.sh.j2
|
||||
dest: "{{ workspace }}/build_containers.sh"
|
||||
mode: 0777
|
||||
force: yes
|
||||
when: use_kolla | default(true)
|
||||
|
||||
- name: Generate tripleo building script
|
||||
template:
|
||||
src: templates/tripleo-build.sh.j2
|
||||
dest: "{{ workspace }}/build_containers.sh"
|
||||
mode: 0777
|
||||
force: yes
|
||||
when: not use_kolla | default(true)
|
||||
|
||||
- name: "Run image build as ansible user > {{ workspace }}/build.log"
|
||||
args:
|
||||
chdir: '{{ workspace }}'
|
||||
shell: set -o pipefail && bash build_containers.sh 2>&1 {{ timestamper_cmd }} > {{ workspace }}/build.log
|
||||
shell: set -o pipefail && bash build_containers.sh 2>&1 {{ timestamper_cmd }} > {{ workspace }}/logs/build.log
|
||||
when:
|
||||
- ansible_distribution|lower != "redhat"
|
||||
|
||||
- name: "Run image build as root > {{ workspace }}/build.log"
|
||||
args:
|
||||
chdir: '{{ workspace }}'
|
||||
shell: set -o pipefail && bash build_containers.sh 2>&1 {{ timestamper_cmd }} > {{ workspace }}/build.log
|
||||
become: true
|
||||
shell: set -o pipefail && bash build_containers.sh 2>&1 {{ timestamper_cmd }} > {{ workspace }}/logs/build.log
|
||||
when:
|
||||
- ansible_distribution|lower == "redhat"
|
||||
- ansible_distribution|lower == "redhat"
|
||||
become: true
|
||||
|
||||
- name: Retrieve list of built x86_64 images, retag, and push
|
||||
- name: Retrieve built images
|
||||
shell: "{{ container_cli }} images | grep {{ container_name_prefix }} | awk '{ print $1 }'"
|
||||
register: built_images
|
||||
become: true
|
||||
|
||||
- name: Retag and push x86_64 images
|
||||
when:
|
||||
- ansible_architecture == "x86_64"
|
||||
- push_containers | bool
|
||||
- not push_containers_podman | default(false) | bool
|
||||
block:
|
||||
- name: Retrieve built images
|
||||
command: "awk '{ print $1 }' {{ workspace }}/containers-successfully-built.log"
|
||||
register: built_images
|
||||
- name: Disable HTTPS and certificates to access registry (buildah)
|
||||
set_fact:
|
||||
container_cli_opt: '--tls-verify=false'
|
||||
|
@ -243,13 +255,6 @@
|
|||
with_items: "{{ built_images.stdout_lines }}"
|
||||
become: true
|
||||
|
||||
- name: Retrieve built images
|
||||
command: "awk '{ print $1 }' {{ workspace }}/containers-successfully-built.log"
|
||||
register: built_images
|
||||
become: true
|
||||
when:
|
||||
- job.provider_job|default(false)|bool
|
||||
|
||||
- name: Run registry
|
||||
when:
|
||||
- job.provider_job|default(false)|bool
|
||||
|
|
|
@ -1,4 +1,8 @@
|
|||
---
|
||||
- name: Build report
|
||||
include: build-report.yaml
|
||||
when: not use_kolla | default(false)
|
||||
|
||||
- name: Grab job artifacts
|
||||
become: true
|
||||
args:
|
||||
|
@ -11,14 +15,13 @@
|
|||
mkdir -p {{ workspace }}/etc/ansible
|
||||
mkdir -p {{ workspace }}/etc/docker
|
||||
mkdir -p {{ workspace }}/etc/httpd
|
||||
mkdir -p {{ workspace }}/logs/buildah-builds
|
||||
|
||||
mv *.conf {{ workspace }}/conf/
|
||||
mv {{ openstack_git_root }}/tripleo-common/container-images/overcloud_containers.yaml {{ workspace }}/conf/
|
||||
mv {{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images/*_containers.yaml {{ workspace }}/conf/
|
||||
mv *.log {{ workspace }}/logs/
|
||||
mv *.html {{ workspace }}/logs/
|
||||
mv *.sh {{ workspace }}/logs/
|
||||
mv /tmp/kolla-* {{ workspace }}/logs/buildah-builds/ || true
|
||||
mv /tmp/container-* {{ workspace }}/logs/buildah-builds/ || true
|
||||
mv /tmp/kolla-* {{ workspace }}/logs/ || true
|
||||
rsync -var --no-links /var/log/ {{ workspace }}/logs/system/ || true
|
||||
rsync -var --no-links /etc/ansible/ {{ workspace }}/etc/ansible/ || true
|
||||
rsync -var --no-links /etc/docker/ {{ workspace }}/etc/docker/ || true
|
||||
|
|
|
@ -1,176 +0,0 @@
|
|||
#!/bin/bash -eux
|
||||
{% if buildcontainers_venv is defined and buildcontainers_venv %}
|
||||
source {{ workspace }}/venv_build/bin/activate
|
||||
pip install -U decorator
|
||||
TRIPLEO_COMMON_PATH="{{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common"
|
||||
{% else %}
|
||||
TRIPLEO_COMMON_PATH="/usr/share/openstack-tripleo-common"
|
||||
{% endif %}
|
||||
TRIPLEO_CI_PATH="{{ ansible_user_dir }}/src/opendev.org/openstack/tripleo-ci"
|
||||
|
||||
### list containers to build
|
||||
{% if use_kolla | default(true) %}
|
||||
openstack overcloud container image build {{ container_config }}\
|
||||
--kolla-config-file {{ workspace }}/kolla-build.conf \
|
||||
{% if ci_branch not in ['queens', 'rocky'] and ci_branch in exclude_containers %}
|
||||
{% for item in exclude_containers[ci_branch] %}
|
||||
--exclude {{ item }} \
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if ci_branch not in ['queens', 'rocky', 'stein'] %}
|
||||
--work-dir /tmp/container-builds \
|
||||
{% endif %}
|
||||
--list-images > containers-to-build-full.log 2>&1
|
||||
egrep "^- " containers-to-build-full.log | awk '{ print $2 }' > containers-expected-to-build.log
|
||||
|
||||
### build
|
||||
openstack overcloud container image build {{ container_config }}\
|
||||
{% if ci_branch not in ['queens', 'rocky'] and ci_branch in exclude_containers %}
|
||||
{% for item in exclude_containers[ci_branch] %}
|
||||
--exclude {{ item }} \
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if use_buildah is defined and use_buildah %}
|
||||
--use-buildah \
|
||||
{% endif %}
|
||||
{% if ci_branch not in ['queens', 'rocky', 'stein'] %}
|
||||
--work-dir /tmp/container-builds \
|
||||
{% endif %}
|
||||
{% if build_timeout is defined %}
|
||||
--build-timeout {{ build_timeout }} \
|
||||
{% endif %}
|
||||
--kolla-config-file {{ workspace }}/kolla-build.conf
|
||||
{% else %}
|
||||
### build
|
||||
export TRIPLEO_CI_USR_PATH="${VIRTUAL_ENV:-/usr}"
|
||||
export TRIPLEO_ANSIBLE_WORKPATH="${TRIPLEO_CI_USR_PATH}/share/ansible"
|
||||
export ANSIBLE_ACTION_PLUGINS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/action"
|
||||
export ANSIBLE_CALLBACK_PLUGINS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/callback"
|
||||
export ANSIBLE_FILTER_PLUGINS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/filter"
|
||||
export ANSIBLE_LIBRARY="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/modules"
|
||||
export ANSIBLE_MODULE_UTILS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/module_utils"
|
||||
export ANSIBLE_ROLES_PATH="${TRIPLEO_ANSIBLE_WORKPATH}/roles"
|
||||
export ROLE_REPOS="tripleo-common ansible/roles"
|
||||
|
||||
echo "print exported variables"
|
||||
set | grep -i TRIPLEO
|
||||
set | grep -i ANSIBLE
|
||||
|
||||
echo "list files in ansible role path, ${TRIPLEO_ANSIBLE_WORKPATH}/roles"
|
||||
ls -la "${TRIPLEO_ANSIBLE_WORKPATH}/roles"
|
||||
|
||||
|
||||
# Ensure that the roles from tripleo-common and tripleo-ansible installed
|
||||
# from the venv are available in the roles path
|
||||
# The tripleo-common role path can be found here:
|
||||
# https://opendev.org/openstack/tripleo-common/src/branch/master/tripleo_common/actions/ansible.py
|
||||
for ROLE_REPO in $ROLE_REPOS; do
|
||||
if [[ "${TRIPLEO_CI_USR_PATH}" != '/usr' && -d "${TRIPLEO_CI_USR_PATH}/share/${ROLE_REPO}" ]]; then
|
||||
# Check if the target directory exists and is not a symlink
|
||||
if [[ -d "/usr/share/${ROLE_REPO}" && ! -L "/usr/share/${ROLE_REPO}" ]]; then
|
||||
echo "Creating a backup of /usr/share/${ROLE_REPO}.bak"
|
||||
sudo mv /usr/share/${ROLE_REPO} /usr/share/${ROLE_REPO}.bak
|
||||
fi
|
||||
# Link our venv'd ${ROLE_REPO} files into the root path.
|
||||
echo -e "Linking ${TRIPLEO_CI_USR_PATH}/share/${ROLE_REPO} to /usr/share/${ROLE_REPO}"
|
||||
sudo ln -sf ${TRIPLEO_CI_USR_PATH}/share/${ROLE_REPO} /usr/share/${ROLE_REPO}
|
||||
fi
|
||||
done
|
||||
|
||||
openstack tripleo container image build \
|
||||
{% if push_containers|bool %}
|
||||
--push \
|
||||
{% endif %}
|
||||
{% if buildcontainers_authfile_path is defined %}
|
||||
--authfile {{ buildcontainers_authfile_path }} \
|
||||
{% endif %}
|
||||
{% if distro is defined %}
|
||||
--distro {{ distro }} \
|
||||
{% endif %}
|
||||
{% if registry_namespace is defined %}
|
||||
--namespace {{ registry_namespace }} \
|
||||
{% endif%}
|
||||
{% if push_registry is defined %}
|
||||
--registry {{ push_registry }} \
|
||||
{% endif %}
|
||||
{% if rhel_modules is defined %}
|
||||
--rhel-modules {{ rhel_modules | join(",") }} \
|
||||
{% endif %}
|
||||
{% set branch = osp_branch|default(ci_branch) %}
|
||||
{% if branch in exclude_containers %}
|
||||
{% for item in exclude_containers[branch] %}
|
||||
--exclude {{ item }} \
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
--tag {{ version_hash }}{{ arch_tag | default('') }} \
|
||||
--base {{ containers_base_image | default('ubi8') }} \
|
||||
--prefix {{ container_name_prefix }} \
|
||||
--config-file {{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images/tripleo_containers.yaml \
|
||||
--config-path {{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images \
|
||||
--work-dir /tmp/container-builds \
|
||||
{% if build_timeout is defined %}
|
||||
--build-timeout {{ build_timeout }} \
|
||||
{% endif %}
|
||||
--debug 2> containers-build-errors.log
|
||||
{% endif %}
|
||||
RETCODE=$?
|
||||
|
||||
{% if use_kolla | default(true) %}
|
||||
### actual built containers
|
||||
sudo {{ container_cli }} images | grep {{ registry_namespace }}/{{ kolla_base }}-binary > containers-successfully-built.log
|
||||
### grep errors in all build logs
|
||||
sudo egrep "^Error:|No match" /tmp/kolla-*/docker -R > containers-build-errors.log 2>&1 || true
|
||||
sudo egrep "^Error:|No match" /tmp/container-builds/*/docker -R >> containers-build-errors.log 2>&1 || true
|
||||
### not built (failed)
|
||||
for i in `cat containers-expected-to-build.log`; do
|
||||
grep "$i" containers-successfully-built.log || echo "$i" >> containers-failed-to-build.log
|
||||
done
|
||||
|
||||
{% else %}
|
||||
### actual built containers
|
||||
sudo {{ container_cli }} images | grep '{{ registry_namespace }}/{{ container_name_prefix }}' > containers-successfully-built.log
|
||||
(python3 || python) <<EOC
|
||||
import yaml
|
||||
with open('{{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images/tripleo_containers.yaml') as f:
|
||||
x = yaml.safe_load(f)
|
||||
with open('containers-expected-to-build.log', 'w') as f:
|
||||
for i in x['container_images']:
|
||||
if i['image_source'] == 'tripleo':
|
||||
f.write('{}\n'.format(i['imagename']))
|
||||
EOC
|
||||
|
||||
{% endif %}
|
||||
|
||||
echo "================= COMPLETE ===================="
|
||||
logs=$(find /tmp/container-* -iname "*.log")
|
||||
for l in $logs; do
|
||||
printf "\n\n\n"
|
||||
printf "\n[ $l ]" >> containers-consolidated-builds.log
|
||||
printf "\n===========================================================\n" >> containers-consolidated-builds.log
|
||||
sudo cat $l >> containers-consolidated-builds.log
|
||||
printf "\n......................................................[EOF]" >> containers-consolidated-builds.log
|
||||
done
|
||||
|
||||
EXPECTED=$( wc -l containers-expected-to-build.log | awk '{ print $1 }' )
|
||||
BUILT=$( wc -l containers-successfully-built.log | awk '{ print $1 }' )
|
||||
|
||||
printf "\n\n"
|
||||
printf "\n============= SUMMARY ==============="
|
||||
printf "\nExpected................... $EXPECTED"
|
||||
printf "\nBuilt...................... $BUILT"
|
||||
printf "\n====================================="
|
||||
printf "\n\n"
|
||||
printf "\nReturn code: [ $RETCODE ]"
|
||||
printf "\n\n"
|
||||
|
||||
if [ -s "build-errors.log" ]; then
|
||||
printf "\nWarning: Errors found during container builds. See build-errors.log."
|
||||
fi
|
||||
|
||||
if [ $RETCODE -eq 0 ]; then
|
||||
printf "\nSUCCESS: Congratulations! All containers have been built :)"
|
||||
exit 0
|
||||
else
|
||||
printf "\nFAILURE: I'm sorry. One or more containers failed to build :("
|
||||
exit 1
|
||||
fi
|
|
@ -0,0 +1,31 @@
|
|||
#!/bin/bash -eux
|
||||
{% if buildcontainers_venv is defined and buildcontainers_venv %}
|
||||
source {{ workspace }}/venv_build/bin/activate
|
||||
pip install -U decorator
|
||||
TRIPLEO_COMMON_PATH="{{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common"
|
||||
{% else %}
|
||||
TRIPLEO_COMMON_PATH="/usr/share/openstack-tripleo-common"
|
||||
{% endif %}
|
||||
TRIPLEO_CI_PATH="{{ ansible_user_dir }}/src/opendev.org/openstack/tripleo-ci"
|
||||
|
||||
### build
|
||||
openstack overcloud container image build {{ container_config }}\
|
||||
{% if ci_branch not in ['queens', 'rocky'] and ci_branch in exclude_containers %}
|
||||
{% for item in exclude_containers[ci_branch] %}
|
||||
--exclude {{ item }} \
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
{% if use_buildah is defined and use_buildah %}
|
||||
--use-buildah \
|
||||
{% endif %}
|
||||
{% if ci_branch not in ['queens', 'rocky', 'stein'] %}
|
||||
--work-dir /tmp/container-builds \
|
||||
{% endif %}
|
||||
{% if build_timeout is defined %}
|
||||
--build-timeout {{ build_timeout }} \
|
||||
{% endif %}
|
||||
--kolla-config-file {{ workspace }}/kolla-build.conf
|
||||
|
||||
### grep errors in all build logs
|
||||
sudo egrep "^Error:|No match" /tmp/kolla-*/docker -R > containers-build-errors.log 2>&1 || true
|
||||
sudo egrep "^Error:|No match" /tmp/container-builds/*/docker -R >> containers-build-errors.log 2>&1 || true
|
|
@ -0,0 +1,81 @@
|
|||
#!/bin/bash -eux
|
||||
|
||||
{% if buildcontainers_venv is defined and buildcontainers_venv %}
|
||||
source {{ workspace }}/venv_build/bin/activate
|
||||
pip install -U decorator
|
||||
TRIPLEO_COMMON_PATH="{{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common"
|
||||
{% else %}
|
||||
TRIPLEO_COMMON_PATH="/usr/share/openstack-tripleo-common"
|
||||
{% endif %}
|
||||
TRIPLEO_CI_PATH="{{ ansible_user_dir }}/src/opendev.org/openstack/tripleo-ci"
|
||||
|
||||
export TRIPLEO_CI_USR_PATH="${VIRTUAL_ENV:-/usr}"
|
||||
export TRIPLEO_ANSIBLE_WORKPATH="${TRIPLEO_CI_USR_PATH}/share/ansible"
|
||||
export ANSIBLE_ACTION_PLUGINS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/action"
|
||||
export ANSIBLE_CALLBACK_PLUGINS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/callback"
|
||||
export ANSIBLE_FILTER_PLUGINS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/filter"
|
||||
export ANSIBLE_LIBRARY="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/modules"
|
||||
export ANSIBLE_MODULE_UTILS="${TRIPLEO_ANSIBLE_WORKPATH}/plugins/module_utils"
|
||||
export ANSIBLE_ROLES_PATH="${TRIPLEO_ANSIBLE_WORKPATH}/roles"
|
||||
export ROLE_REPOS="tripleo-common ansible/roles"
|
||||
|
||||
echo "print exported variables"
|
||||
set | grep -i TRIPLEO
|
||||
set | grep -i ANSIBLE
|
||||
|
||||
echo "list files in ansible role path, ${TRIPLEO_ANSIBLE_WORKPATH}/roles"
|
||||
ls -la "${TRIPLEO_ANSIBLE_WORKPATH}/roles"
|
||||
|
||||
# Ensure that the roles from tripleo-common and tripleo-ansible installed
|
||||
# from the venv are available in the roles path
|
||||
# The tripleo-common role path can be found here:
|
||||
# https://opendev.org/openstack/tripleo-common/src/branch/master/tripleo_common/actions/ansible.py
|
||||
for ROLE_REPO in $ROLE_REPOS; do
|
||||
if [[ "${TRIPLEO_CI_USR_PATH}" != '/usr' && -d "${TRIPLEO_CI_USR_PATH}/share/${ROLE_REPO}" ]]; then
|
||||
# Check if the target directory exists and is not a symlink
|
||||
if [[ -d "/usr/share/${ROLE_REPO}" && ! -L "/usr/share/${ROLE_REPO}" ]]; then
|
||||
echo "Creating a backup of /usr/share/${ROLE_REPO}.bak"
|
||||
sudo mv /usr/share/${ROLE_REPO} /usr/share/${ROLE_REPO}.bak
|
||||
fi
|
||||
# Link our venv'd ${ROLE_REPO} files into the root path.
|
||||
echo -e "Linking ${TRIPLEO_CI_USR_PATH}/share/${ROLE_REPO} to /usr/share/${ROLE_REPO}"
|
||||
sudo ln -sf ${TRIPLEO_CI_USR_PATH}/share/${ROLE_REPO} /usr/share/${ROLE_REPO}
|
||||
fi
|
||||
done
|
||||
|
||||
### build
|
||||
openstack tripleo container image build \
|
||||
{% if push_containers|bool %}
|
||||
--push \
|
||||
{% endif %}
|
||||
{% if buildcontainers_authfile_path is defined %}
|
||||
--authfile {{ buildcontainers_authfile_path }} \
|
||||
{% endif %}
|
||||
{% if distro is defined %}
|
||||
--distro {{ distro }} \
|
||||
{% endif %}
|
||||
{% if registry_namespace is defined %}
|
||||
--namespace {{ registry_namespace }} \
|
||||
{% endif%}
|
||||
{% if push_registry is defined %}
|
||||
--registry {{ push_registry }} \
|
||||
{% endif %}
|
||||
{% if rhel_modules is defined %}
|
||||
--rhel-modules {{ rhel_modules | join(",") }} \
|
||||
{% endif %}
|
||||
{% set branch = osp_branch|default(ci_branch) %}
|
||||
{% if branch in exclude_containers %}
|
||||
{% for item in exclude_containers[branch] %}
|
||||
--exclude {{ item }} \
|
||||
{% endfor %}
|
||||
{% endif %}
|
||||
--tag {{ version_hash }}{{ arch_tag | default('') }}\
|
||||
--base {{ containers_base_image | default('ubi8') }} \
|
||||
--prefix {{ container_name_prefix }} \
|
||||
--config-file {{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images/tripleo_containers.yaml \
|
||||
--config-path {{ openstack_git_root }}/{% if zuul_internal is defined %}openstack-{% endif %}tripleo-common/container-images \
|
||||
--work-dir /tmp/container-builds \
|
||||
{% if build_timeout is defined %}
|
||||
--build-timeout {{ build_timeout }} \
|
||||
{% endif %}
|
||||
--debug
|
2
tox.ini
2
tox.ini
|
@ -19,7 +19,7 @@ setenv =
|
|||
PYTHONWARNINGS=ignore:DEPRECATION::pip._internal.cli.base_command
|
||||
PIP_DISABLE_PIP_VERSION_CHECK=1
|
||||
TEST_PARAMS=--cov=emit_releases_file -k "not molecule"
|
||||
molecule: TEST_PARAMS=-ra -k molecule
|
||||
molecule: TEST_PARAMS=-ra -k molecule --ignore=roles/build-containers/files
|
||||
passenv =
|
||||
ANSIBLE_*
|
||||
CURL_CA_BUNDLE
|
||||
|
|
Loading…
Reference in New Issue