diff options
| author | Zuul <zuul@review.opendev.org> | 2026-07-08 16:33:45 +0000 |
|---|---|---|
| committer | Gerrit Code Review <review@openstack.org> | 2026-07-08 16:33:45 +0000 |
| commit | 44b4d81399792f539716618953f2cafa64086a5c (patch) | |
| tree | 4699d7e068e6dd842a9f1f247ca2f150d60d5e27 /kolla | |
| parent | b3803eb9f951acd63018ab8ba69bcbd1a2de5c93 (diff) | |
| parent | db35ac8d793506bc43b62e7e39d27a75de1043ed (diff) | |
| download | kolla-44b4d81399792f539716618953f2cafa64086a5c.tar.gz kolla-44b4d81399792f539716618953f2cafa64086a5c.zip | |
Merge "Migrate to pyproject.toml"
Diffstat (limited to 'kolla')
371 files changed, 10882 insertions, 0 deletions
diff --git a/kolla/docker/aodh/aodh-api/Dockerfile.j2 b/kolla/docker/aodh/aodh-api/Dockerfile.j2 new file mode 100644 index 000000000..b420df814 --- /dev/null +++ b/kolla/docker/aodh/aodh-api/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}aodh-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block aodh_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_aodh_extend_start +RUN chmod 644 /usr/local/bin/kolla_aodh_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block aodh_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/aodh/aodh-api/extend_start.sh b/kolla/docker/aodh/aodh-api/extend_start.sh new file mode 100644 index 000000000..575b0e584 --- /dev/null +++ b/kolla/docker/aodh/aodh-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + aodh-dbsync + exit 0 +fi diff --git a/kolla/docker/aodh/aodh-base/Dockerfile.j2 b/kolla/docker/aodh/aodh-base/Dockerfile.j2 new file mode 100644 index 000000000..519537468 --- /dev/null +++ b/kolla/docker/aodh/aodh-base/Dockerfile.j2 @@ -0,0 +1,38 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block aodh_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='aodh') }} + +{% set aodh_base_packages = [ +] %} + +{{ macros.install_packages(aodh_base_packages | customizable("packages")) }} + +ADD aodh-base-archive /aodh-base-source + +{% set aodh_base_pip_packages = [ + '/aodh', +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY aodh_sudoers /etc/sudoers.d/kolla_aodh_sudoers + +RUN ln -s aodh-base-source/* aodh \ + && {{ macros.install_pip(aodh_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/aodh \ + && cp /aodh/aodh/api/api-paste.ini /etc/aodh/ \ + && chmod 644 /etc/aodh/api-paste.ini \ + && chmod 750 /etc/sudoers.d \ + && chmod 640 /etc/sudoers.d/kolla_aodh_sudoers \ + && touch /usr/local/bin/kolla_aodh_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_aodh_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block aodh_base_footer %}{% endblock %} diff --git a/kolla/docker/aodh/aodh-base/aodh_sudoers b/kolla/docker/aodh/aodh-base/aodh_sudoers new file mode 100644 index 000000000..2ec268c9d --- /dev/null +++ b/kolla/docker/aodh/aodh-base/aodh_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown -R aodh\: /var/lib/aodh/, /bin/chown -R aodh\: /var/lib/aodh/ diff --git a/kolla/docker/aodh/aodh-base/extend_start.sh b/kolla/docker/aodh/aodh-base/extend_start.sh new file mode 100755 index 000000000..f3b1d2d49 --- /dev/null +++ b/kolla/docker/aodh/aodh-base/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Create log dir for Aodh logs +AODH_LOG_DIR="/var/log/kolla/aodh" +if [[ ! -d "${AODH_LOG_DIR}" ]]; then + mkdir -p ${AODH_LOG_DIR} +fi +if [[ $(stat -c %U:%G ${AODH_LOG_DIR}) != "aodh:kolla" ]]; then + chown aodh:kolla ${AODH_LOG_DIR} +fi +if [[ $(stat -c %a ${AODH_LOG_DIR}) != "755" ]]; then + chmod 755 ${AODH_LOG_DIR} +fi + +. /usr/local/bin/kolla_aodh_extend_start diff --git a/kolla/docker/aodh/aodh-evaluator/Dockerfile.j2 b/kolla/docker/aodh/aodh-evaluator/Dockerfile.j2 new file mode 100644 index 000000000..3d1f6a8b4 --- /dev/null +++ b/kolla/docker/aodh/aodh-evaluator/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}aodh-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block aodh_evaluator_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block aodh_evaluator_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER aodh diff --git a/kolla/docker/aodh/aodh-expirer/Dockerfile.j2 b/kolla/docker/aodh/aodh-expirer/Dockerfile.j2 new file mode 100644 index 000000000..9c426f82c --- /dev/null +++ b/kolla/docker/aodh/aodh-expirer/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}aodh-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block aodh_expirer_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block aodh_expirer_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER aodh diff --git a/kolla/docker/aodh/aodh-listener/Dockerfile.j2 b/kolla/docker/aodh/aodh-listener/Dockerfile.j2 new file mode 100644 index 000000000..a6f4f3c0e --- /dev/null +++ b/kolla/docker/aodh/aodh-listener/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}aodh-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block aodh_listener_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block aodh_listener_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER aodh diff --git a/kolla/docker/aodh/aodh-notifier/Dockerfile.j2 b/kolla/docker/aodh/aodh-notifier/Dockerfile.j2 new file mode 100644 index 000000000..c49f37441 --- /dev/null +++ b/kolla/docker/aodh/aodh-notifier/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}aodh-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block aodh_notifier_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block aodh_notifier_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER aodh diff --git a/kolla/docker/barbican/barbican-api/Dockerfile.j2 b/kolla/docker/barbican/barbican-api/Dockerfile.j2 new file mode 100644 index 000000000..e78f3ea63 --- /dev/null +++ b/kolla/docker/barbican/barbican-api/Dockerfile.j2 @@ -0,0 +1,19 @@ +FROM {{ namespace }}/{{ image_prefix }}barbican-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block barbican_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_barbican_extend_start + +RUN chmod 644 /usr/local/bin/kolla_barbican_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block barbican_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER barbican diff --git a/kolla/docker/barbican/barbican-api/extend_start.sh b/kolla/docker/barbican/barbican-api/extend_start.sh new file mode 100755 index 000000000..c541d0343 --- /dev/null +++ b/kolla/docker/barbican/barbican-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + barbican-db-manage upgrade + exit 0 +fi diff --git a/kolla/docker/barbican/barbican-base/Dockerfile.j2 b/kolla/docker/barbican/barbican-base/Dockerfile.j2 new file mode 100644 index 000000000..89c44ef9a --- /dev/null +++ b/kolla/docker/barbican/barbican-base/Dockerfile.j2 @@ -0,0 +1,36 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block barbican_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='barbican', groups='nfast,hsmusers') }} + +{{ macros.install_packages(barbican_base_packages | customizable("packages")) }} + +{% set barbican_base_pip_packages = [ + '/barbican', + 'pastedeploy', + 'python-barbicanclient', +] %} + +ADD barbican-base-archive /barbican-base-source + +COPY barbican_sudoers /etc/sudoers.d/kolla_barbican_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s barbican-base-source/* barbican \ + && {{ macros.install_pip(barbican_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/barbican \ + && cp -r /barbican/etc/barbican/* /etc/barbican/ \ + && chmod 750 /etc/sudoers.d \ + && chmod 640 /etc/sudoers.d/kolla_barbican_sudoers \ + && touch /usr/local/bin/kolla_barbican_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_barbican_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block barbican_base_footer %}{% endblock %} diff --git a/kolla/docker/barbican/barbican-base/barbican_sudoers b/kolla/docker/barbican/barbican-base/barbican_sudoers new file mode 100644 index 000000000..26ae4710e --- /dev/null +++ b/kolla/docker/barbican/barbican-base/barbican_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown -R barbican\: /var/lib/barbican/, /bin/chown -R barbican\: /var/lib/barbican/ diff --git a/kolla/docker/barbican/barbican-base/extend_start.sh b/kolla/docker/barbican/barbican-base/extend_start.sh new file mode 100755 index 000000000..16b41ad09 --- /dev/null +++ b/kolla/docker/barbican/barbican-base/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Create log dir for Barbican logs +LOG_DIR="/var/log/kolla/barbican" +if [[ ! -d "${LOG_DIR}" ]]; then + mkdir -p ${LOG_DIR} +fi +if [[ $(stat -c %U:%G ${LOG_DIR}) != "barbican:kolla" ]]; then + chown barbican:kolla ${LOG_DIR} +fi +if [[ $(stat -c %a ${LOG_DIR}) != "755" ]]; then + chmod 755 ${LOG_DIR} +fi + +. /usr/local/bin/kolla_barbican_extend_start diff --git a/kolla/docker/barbican/barbican-keystone-listener/Dockerfile.j2 b/kolla/docker/barbican/barbican-keystone-listener/Dockerfile.j2 new file mode 100644 index 000000000..3329aed1b --- /dev/null +++ b/kolla/docker/barbican/barbican-keystone-listener/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}barbican-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block barbican_keystone_listener_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block barbican_keystone_listener_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER barbican diff --git a/kolla/docker/barbican/barbican-worker/Dockerfile.j2 b/kolla/docker/barbican/barbican-worker/Dockerfile.j2 new file mode 100644 index 000000000..9cba55b6b --- /dev/null +++ b/kolla/docker/barbican/barbican-worker/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}barbican-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block barbican_worker_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block barbican_worker_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER barbican diff --git a/kolla/docker/base/Dockerfile.j2 b/kolla/docker/base/Dockerfile.j2 new file mode 100644 index 000000000..0e2f3c1ab --- /dev/null +++ b/kolla/docker/base/Dockerfile.j2 @@ -0,0 +1,346 @@ +FROM {{ base_image }}:{{ base_distro_tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +RUN . /etc/os-release;\ + if [ "${PRETTY_NAME#{{ supported_distro_name }}}" = "$PRETTY_NAME" ]; then \ + echo "Only releases \"{{ supported_distro_name }}\" are supported on {{ base_distro }}"; false; \ + fi + +# We use curl in this dockerfile so let configure it before first use +COPY curlrc /root/.curlrc + +{% block base_lang %} +# NOTE(yoctozepto): use a UTF-8 (Unicode) locale like standard image installs do +# fixes issues arising from ascii fallback usage +ENV LANG en_US.UTF-8 +{% endblock %} + +LABEL kolla_version="{{ kolla_version }}" + +{% import "macros.j2" as macros with context %} +{% block base_header %}{% endblock %} + +ENV KOLLA_BASE_DISTRO={{ base_distro }} \ + KOLLA_BASE_ARCH={{ base_arch }} + +#### Customize PS1 to be used with bash shell +COPY kolla_bashrc /tmp/ +RUN cat /tmp/kolla_bashrc >> /etc/skel/.bashrc \ + && cat /tmp/kolla_bashrc >> /root/.bashrc + +# PS1 var when used /bin/sh shell +ENV PS1="$(tput bold)($(printenv KOLLA_SERVICE_NAME))$(tput sgr0)[$(id -un)@$(hostname -s) $(pwd)]$ " + +{% if base_package_type == 'rpm' %} +# For RPM Variants, enable the correct repositories - this should all be done +# in the base image so repos are consistent throughout the system. This also +# enables to provide repo overrides at a later date in a simple fashion if we +# desire such functionality. I think we will :) + +ENV KOLLA_RPM_OVS_VERSION=3.5 \ + KOLLA_RPM_OVN_VERSION=26.03 + +RUN cat /tmp/kolla_bashrc >> /etc/bashrc \ + && sed -i 's|^\(override_install_langs=.*\)|# \1|' /etc/dnf/dnf.conf + +{% block base_dnf_conf %} +{% block base_yum_conf %} + +COPY dnf.conf /etc/dnf/dnf.conf + +{% endblock %} +{% endblock %} + +#### BEGIN REPO ENABLEMENT +{% set base_yum_url_packages = [ +] %} + +{% set base_yum_repo_keys = [ +] %} + +{% block base_centos_repo_overrides_post_copy %}{% endblock %} + +# Install what is needed for en_US.UTF-8 +{% block base_centos_distro_sync_and_languages %} + +{% set base_centos_language_packages = [ + 'langpacks-en', + 'glibc-all-langpacks' +] %} + +# NOTE(hrw): this macro file drops all languages other than C.UTF-8 so horizon fails +# https://bugzilla.redhat.com/show_bug.cgi?id=1729770 +RUN rm -f /etc/rpm/macros.image-language-conf \ + && {{ macros.install_packages(base_centos_language_packages | customizable("centos_language_packages"), chain=True, clean=False) }} \ + && {{ macros.rpm_security_update(clean_package_cache) }} + +{% endblock %} + +{{ macros.install_packages(base_yum_url_packages | customizable("yum_url_packages")) }} + +{% for key in base_yum_repo_keys | customizable('yum_repo_keys') %} +{%- if loop.first %}RUN {% else %} && {% endif -%} + rpm --import {{ key }} +{%- if not loop.last %} \{% endif %} +{% endfor -%} + +{% for cmd in rpm_setup %} +{{ cmd }} +{% endfor %} + +{% block base_centos_repo_overrides_post_rpm %}{% endblock %} + +{% block base_centos_gpg_key_import %} +{% endblock %} + +{% set base_centos_yum_repo_keys = [ +] %} + +{% set base_centos_yum_repo_packages = [ + 'centos-release-ceph-squid', + 'centos-release-nfv-openvswitch', + 'epel-release', +] %} + +# We need 'dnf-plugins-core' for 'dnf config-manager' +{% set base_centos_yum_repo_packages = base_centos_yum_repo_packages + [ + 'dnf-plugins-core' +] %} + +RUN {{ macros.install_packages(base_centos_yum_repo_packages | customizable("centos_yum_repo_packages"), chain=True, clean=False) }} + +{%- for key in base_centos_yum_repo_keys | customizable('centos_yum_repo_keys') %} && rpm --import {{ key }} {% endfor %} \ +{% block base_centos_repo_overrides_post_yum %}{% endblock -%} + && {{ macros.rpm_security_update(clean_package_cache) }} + +#### END REPO ENABLEMENT + +{# We are back to the basic if conditional here which is: + if base_package_type == 'rpm' #} + +{% block base_redhat_binary_versionlock %}{% endblock %} + +{# NOTE(hrw): CentOS Stream 9 has curl-minimal, Rocky Linux 9 has curl so we do not install any #} +{% set base_centos_packages = [ + 'ca-certificates', + 'crypto-policies-scripts', + 'dumb-init', + 'findutils', + 'hostname', + 'iproute', + 'iscsi-initiator-utils', + 'lsof', + 'lvm2', + 'ncurses', + 'openssl', + 'procps-ng', + 'python3', + 'python3-pip', + 'python3-pyyaml', + 'socat', + 'sudo', + 'tar', + 'util-linux', + 'util-linux-user', + 'which', + 'patch' +] %} + +# Install base packages +{{ macros.enable_extra_repos(['epel']) }} +{{ macros.install_packages(base_centos_packages | customizable("centos_packages") | customizable("centos_binary_packages") | customizable("centos_source_packages")) }} + +{# endif for base_package_type rpm #} +{% elif base_package_type == 'deb' %} +# This will prevent questions from being asked during the install +ENV DEBIAN_FRONTEND noninteractive + +# Reducing disk footprint +COPY dpkg_reducing_disk_footprint /etc/dpkg/dpkg.cfg.d/dpkg_reducing_disk_footprint + +{% block base_ubuntu_package_pre %} +# curl and ca-certificates to fetch remote keys via http +# gnupg to fetch keys directly from keyserver +{% set base_ubuntu_package_pre_packages = [ + 'adduser', + 'ca-certificates', + 'curl', + 'gnupg' +] %} +# ubuntu-cloud-keyring to install UCA packages +{% if base_distro == 'ubuntu' %} +{% set base_ubuntu_package_pre_packages = base_ubuntu_package_pre_packages + [ + 'ubuntu-cloud-keyring' +] %} +{% endif %} +{{ macros.install_packages(base_ubuntu_package_pre_packages | customizable("base_ubuntu_package_pre_packages")) }} +{% endblock %} + +# Customize PS1 bash shell +# - enlarge 'system users' range so 'haproxy' package will not complain +# see https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=939470 +# - enlarge 'system groups' range so 'hacluster' user added in +# https://review.opendev.org/c/openstack/kolla/+/802671 +# can be in 'haclient' group with same high uid +RUN cat /tmp/kolla_bashrc >> /etc/bash.bashrc \ + && sed -i -e s/#*LAST_SYSTEM_UID=999/LAST_SYSTEM_UID=59999/g \ + -e s/#*LAST_SYSTEM_GID=999/LAST_SYSTEM_GID=59999/g /etc/adduser.conf + +{# NOTE(mnasiadka): Ubuntu arm64 uses ports.ubuntu.com #} +{% block base_ubuntu_package_sources_list %} +{% if base_distro == "ubuntu" and base_arch == 'aarch64' %} +COPY {{ base_distro }}.sources.arm64 /etc/apt/sources.list.d/{{ base_distro }}.sources +{% else %} +COPY {{ base_distro }}.sources /etc/apt/sources.list.d/ +{% endif %} +COPY sources.list /etc/apt/sources.list.d/kolla-custom.list +{% endblock %} + +{% block base_debian_after_sources_list %}{% endblock %} + +{# install Debian Openstack repos - they are not mirrored on CI #} +{% if base_distro == 'debian' %} + +RUN apt update \ + && apt install -y --no-install-recommends extrepo \ + && extrepo enable openstack_{{ openstack_release_codename | lower }} \ + && apt purge -y extrepo \ + && apt --purge autoremove -y \ + && apt clean + +{% endif %} + +{% block base_ubuntu_package_apt_preferences %} +COPY apt_preferences.{{ base_distro }} /etc/apt/preferences +COPY apt_preferences /etc/apt/preferences.d/kolla-custom +{% endblock %} + +{% set base_apt_packages = [ + 'apt-utils', + 'dumb-init', + 'systemd-standalone-sysusers', + 'gawk', + 'iproute2', + 'kmod', + 'lsof', + 'lvm2', + 'netbase', + 'open-iscsi', + 'procps', + 'python3', + 'python3-pip', + 'python3-yaml', + 'socat', + 'sudo', + 'tgt', + 'patch' +] %} + +{% set base_apt_keys = [ + {'name': 'erlang-ppa', 'keyid': 'F77F1EDA57EBB1CC'}, + {'name': 'rabbitmq', 'keyid': '6B73A36E6026DFCA'}, + {'name': 'haproxy', 'keyid': 'CFFB779AADC995E4F350A060505D97A41C61B9CD'}, +] %} + +{# NOTE(hrw): type field defaults to 'asc' which is used for single keys #} +{% set base_remote_apt_keys = [ + {'name': 'docker-ce', 'url': 'https://download.docker.com/linux/debian/gpg'}, + {'name': 'fluentd', 'url': 'https://fluentd.cdn.cncf.io/GPG-KEY-fluent-package'}, + {'name': 'grafana', 'url': 'https://rpm.grafana.com/gpg.key'}, + {'name': 'mariadb', 'url': 'https://downloads.mariadb.com/MariaDB/mariadb-keyring-2019.gpg', 'type': 'gpg'}, + {'name': 'opensearch', 'url': 'https://artifacts.opensearch.org/publickeys/opensearch-release.pgp'}, + {'name': 'proxysql', 'url': 'https://repo.proxysql.com/ProxySQL/proxysql-3.0.x/repo_pub_key'}, +] %} + +{% block base_ubuntu_package_installation %} + {%- block base_ubuntu_package_key_installation %} + {% for key in base_apt_keys | customizable('apt_keys') %} + {%- if loop.first %}RUN mkdir -p /etc/kolla/apt-keys/{% endif %} \ + && gpg --keyserver hkp://keyserver.ubuntu.com:80 \ + {% if env.http_proxy %} --keyserver-options "http-proxy={{ env.http_proxy }}" {% endif %}\ + --recv-keys {{ key.keyid }} \ + && gpg --export {{ key.keyid }} >/etc/kolla/apt-keys/{{ key.name }}.gpg + {%- if not loop.last %} \ + {% endif -%} + {% endfor %} + {% for key in base_remote_apt_keys | customizable('remote_apt_keys') %} + {%- if loop.first %} RUN mkdir -p /etc/kolla/apt-keys/ {% endif %} \ + && curl {{ key.url }} -o /etc/kolla/apt-keys/{{ key.name }}.{{ key.type | default('asc') }} + {%- if not loop.last %} \ + {% endif -%} + {% endfor %} + {% endblock %} +RUN apt-get --error-on=any update \ + && apt-get -y install locales \ + && sed -e "s/# $LANG UTF-8/$LANG UTF-8/g" /etc/locale.gen -i \ + && locale-gen "$LANG" \ + && apt-get -y upgrade \ + && apt-get -y dist-upgrade \ + && {{ macros.install_packages(base_apt_packages | customizable('apt_packages'), True) }} \ + # NOTE: python3-pip installs dependent tzdata package and blocks mount in docker - 2091161 + && unlink /etc/localtime + +{% endblock %} + +{# endif base_package_type deb #} +{% endif %} + +{# NOTE(SamYaple): Avoid uid/gid conflicts by creating each user/group up front. #} +{# Specifics required such as homedir or shell are configured within the service specific image #} +{%- for name, user in users | dictsort() %} +{% if loop.first -%}RUN {% else %} && {% endif -%} + groupadd --gid {{ user.gid }} {{ user.group }} \ + && useradd -l -M --shell /usr/sbin/nologin --uid {{ user.uid }} --gid {{ user.gid }} {{ name }} + {%- if not loop.last %} \{% endif -%} +{%- endfor %} + +{% if base_distro == 'centos' %} +RUN sed -ri '/-session(\s+)optional(\s+)pam_systemd.so/d' /etc/pam.d/system-auth \ + && sed -ri '/^[^#]/ s/systemd//g' /etc/nsswitch.conf +{% endif %} + +COPY set_configs.py /usr/local/bin/kolla_set_configs +COPY start.sh /usr/local/bin/kolla_start +COPY copy_cacerts.sh /usr/local/bin/kolla_copy_cacerts +COPY install_projects.sh /usr/local/bin/kolla_install_projects +COPY kolla_patch.sh /usr/local/bin/kolla_patch +COPY sudoers /etc/sudoers + +{% if use_dumb_init %} +ENTRYPOINT ["dumb-init", "--single-child", "--"] +{% endif %} + +{% if docker_healthchecks %} +{% block healthcheck_installation %} + +COPY healthcheck_curl healthcheck_filemod healthcheck_listen healthcheck_port healthcheck_socket /usr/local/bin/ +RUN chmod 755 /usr/local/bin/healthcheck_* + +{% endblock %} +{% endif %} + +RUN touch /usr/local/bin/kolla_extend_start \ + && chmod 755 /usr/local/bin/kolla_start \ + /usr/local/bin/kolla_set_configs \ + /usr/local/bin/kolla_copy_cacerts \ + /usr/local/bin/kolla_install_projects \ + /usr/local/bin/kolla_patch \ + && chmod 644 /usr/local/bin/kolla_extend_start \ + && chmod 440 /etc/sudoers \ + && mkdir -p /var/log/kolla \ + && chown :kolla /var/log/kolla \ + && chmod 2775 /var/log/kolla \ + && rm -f /tmp/kolla_bashrc + +{% block base_pip_conf %} +# the variables like PIP_INDEX_URL, PIP_EXTRA_INDEX_URL, PIP_TRUSTED_HOST etc. should be defined here. +# ENV PIP_INDEX_URL=https://pypi.python.org/simple +# ENV PIP_TRUSTED_HOST=pypi.python.org +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block base_footer %}{% endblock %} +CMD ["kolla_start"] diff --git a/kolla/docker/base/apt_preferences b/kolla/docker/base/apt_preferences new file mode 100644 index 000000000..dc5b993f1 --- /dev/null +++ b/kolla/docker/base/apt_preferences @@ -0,0 +1 @@ +# used for adding custom options by 'apt_preferences' option of kolla-build.conf diff --git a/kolla/docker/base/apt_preferences.debian b/kolla/docker/base/apt_preferences.debian new file mode 100644 index 000000000..08e21ff22 --- /dev/null +++ b/kolla/docker/base/apt_preferences.debian @@ -0,0 +1,4 @@ +# NOTE(hrw): we do not want backports unless requested +Package: * +Pin: release n=trixie-backports +Pin-Priority: -1000 diff --git a/kolla/docker/base/apt_preferences.ubuntu b/kolla/docker/base/apt_preferences.ubuntu new file mode 100644 index 000000000..7cc49b4ad --- /dev/null +++ b/kolla/docker/base/apt_preferences.ubuntu @@ -0,0 +1,3 @@ +Package: * +Pin: origin dlm.mariadb.com +Pin-Priority: 1000 diff --git a/kolla/docker/base/ci-centos.repo b/kolla/docker/base/ci-centos.repo new file mode 100644 index 000000000..4c08f1fea --- /dev/null +++ b/kolla/docker/base/ci-centos.repo @@ -0,0 +1,75 @@ +[baseos] +name=(OpenDev mirror) CentOS Stream $releasever - BaseOS +baseurl=http://MIRROR/centos-stream/$stream/BaseOS/$basearch/os/ +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial +gpgcheck=1 +repo_gpgcheck=0 +enabled=1 + +[appstream] +name=(OpenDev mirror) CentOS Stream $releasever - AppStream +baseurl=http://MIRROR/centos-stream/$stream/AppStream/$basearch/os/ +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial +gpgcheck=1 +repo_gpgcheck=0 +enabled=1 + +[extras-common] +name=(OpenDev mirror) CentOS Stream $releasever - Extras packages +baseurl=http://MIRROR/centos-stream/SIGs/$stream/extras/$basearch/extras-common/ +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Extras-SHA512 +gpgcheck=1 +repo_gpgcheck=0 +enabled=1 + +[crb] +name=(OpenDev mirror) CentOS Stream $releasever - CRB +baseurl=http://MIRROR/centos-stream/$stream/CRB/$basearch/os/ +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial +gpgcheck=1 +repo_gpgcheck=0 +enabled=0 + +[highavailability] +name=(OpenDev mirror) CentOS Stream $releasever - HighAvailability +baseurl=http://MIRROR/centos-stream/$stream/HighAvailability/$basearch/os/ +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-centosofficial +gpgcheck=1 +repo_gpgcheck=0 +enabled=0 + +[centos-ceph-reef] +name=(OpenDev mirror) CentOS-$stream - Ceph Reef +baseurl=http://MIRROR/centos-stream/SIGs/$stream/storage/$basearch/ceph-reef/ +gpgcheck=1 +enabled=0 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Storage + +[centos-nfv-openvswitch] +name=(OpenDev mirror) CentOS Stream $releasever - NFV OpenvSwitch +baseurl=http://MIRROR/centos-stream/SIGs/$stream/nfv/$basearch/openvswitch-2/ +gpgcheck=1 +enabled=0 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-NFV +module_hotfixes=1 + +[centos-opstools] +name=(OpenDev mirror) CentOS Stream $releasever - OpsTools - collectd +baseurl=http://MIRROR/centos-stream/SIGs/$stream/opstools/$basearch/collectd-5/ +gpgcheck=1 +enabled=0 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-OpsTools + +[centos-rabbitmq-38] +name=(OpenDev mirror) CentOS-9 - RabbitMQ 38 +baseurl=http://MIRROR/centos-stream/SIGs/$stream/messaging/$basearch/rabbitmq-38 +gpgcheck=1 +enabled=0 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-CentOS-SIG-Messaging + +[epel] +name=(OpenDev mirror) Extra Packages for Enterprise Linux $releasever - $basearch +baseurl=http://MIRROR/epel/$releasever/Everything/$basearch/ +enabled=0 +gpgcheck=1 +gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-EPEL-$releasever diff --git a/kolla/docker/base/copy_cacerts.sh b/kolla/docker/base/copy_cacerts.sh new file mode 100644 index 000000000..213033c0c --- /dev/null +++ b/kolla/docker/base/copy_cacerts.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +# Copy custom CA certificates to system trusted CA certificates folder +# and run CA update utility + +if [[ -e "/etc/debian_version" ]]; then + ca_dst_path="/usr/local/share/ca-certificates" + update_command="update-ca-certificates" +elif [[ -e "/etc/redhat-release" ]]; then + ca_dst_path="/etc/pki/ca-trust/source/anchors" + update_command="update-ca-trust" +else + echo "Unsupported OS" + exit 1 +fi + +# Initialize update_needed variable +update_needed="false" + +# Remove old certificates +if find /etc/ssl/certs/ \ + /usr/local/share/ca-certificates/ \ + /etc/pki/ca-trust/source/anchors/ \ + -name 'kolla*' -exec rm -f {} + 2>/dev/null; then + update_needed="true" +fi + +# Determine source path for CA certificates +if grep -q '"source": "/var/lib/kolla/share/ca-certificates"' /etc/kolla/defaults/state; then + ca_src_path="/var/lib/kolla/share/ca-certificates" +else + ca_src_path="/var/lib/kolla/config_files/ca-certificates" +fi + +# Check if the source path exists and is not empty +if [[ -d ${ca_src_path} && $(ls -A "${ca_src_path}" 2>/dev/null) ]]; then + # Copy certificates and update CA + for cert in "${ca_src_path}"/*; do + file=$(basename "${cert}") + cp ${cert} ${ca_dst_path}/kolla-customca-${file} + update_needed="true" + done +fi + +# Run the update command if needed +if [[ "${update_needed}" == "true" ]]; then + ${update_command} +fi diff --git a/kolla/docker/base/curlrc b/kolla/docker/base/curlrc new file mode 100644 index 000000000..3b1ecea06 --- /dev/null +++ b/kolla/docker/base/curlrc @@ -0,0 +1,8 @@ +# curl default options +--fail +--location +--retry 5 +--retry-all-errors +--silent +--show-error +--write-out "curl (%{url_effective}): response: %{http_code}, time: %{time_total}, size: %{size_download}\n" diff --git a/kolla/docker/base/debian.sources b/kolla/docker/base/debian.sources new file mode 100644 index 000000000..28c61c81d --- /dev/null +++ b/kolla/docker/base/debian.sources @@ -0,0 +1,13 @@ +Types: deb +# http://snapshot.debian.org/archive/debian/20251020T000000Z +URIs: http://deb.debian.org/debian +Suites: trixie trixie-updates trixie-backports +Components: main +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg + +Types: deb +# http://snapshot.debian.org/archive/debian-security/20251020T000000Z +URIs: http://deb.debian.org/debian-security +Suites: trixie-security +Components: main +Signed-By: /usr/share/keyrings/debian-archive-keyring.gpg diff --git a/kolla/docker/base/dnf.conf b/kolla/docker/base/dnf.conf new file mode 100644 index 000000000..6ca687545 --- /dev/null +++ b/kolla/docker/base/dnf.conf @@ -0,0 +1,12 @@ +[main] +keepcache=0 +logfile=/var/log/dnf.log +exactarch=1 +obsoletes=1 +gpgcheck=1 +plugins=1 +installonly_limit=0 +skip_missing_names_on_install=False +clean_requirements_on_remove=True +tsflags=nodocs +install_weak_deps=False diff --git a/kolla/docker/base/dpkg_reducing_disk_footprint b/kolla/docker/base/dpkg_reducing_disk_footprint new file mode 100644 index 000000000..87b8255f9 --- /dev/null +++ b/kolla/docker/base/dpkg_reducing_disk_footprint @@ -0,0 +1,9 @@ +path-exclude /usr/share/doc/* +path-include /usr/share/doc/*/copyright +path-exclude /usr/share/man/* +path-exclude /usr/share/groff/* +path-exclude /usr/share/info/* +path-exclude /usr/share/lintian/* +path-exclude /usr/share/linda/* +path-exclude /usr/share/locale/* +path-include /usr/share/locale/en* diff --git a/kolla/docker/base/healthcheck_curl b/kolla/docker/base/healthcheck_curl new file mode 100755 index 000000000..6df232fe8 --- /dev/null +++ b/kolla/docker/base/healthcheck_curl @@ -0,0 +1,12 @@ +#!/bin/bash +: ${HEALTHCHECK_CURL_MAX_TIME:=10} +: ${HEALTHCHECK_CURL_USER_AGENT:=curl-healthcheck} +: ${HEALTHCHECK_CURL_WRITE_OUT:='\n%{http_code} %{remote_ip}:%{remote_port} %{time_total} seconds\n'} +: ${HEALTHCHECK_CURL_OUTPUT:='/dev/null'} + +export NSS_SDB_USE_CACHE=no +curl -q -g -k -s -S --fail -o "${HEALTHCHECK_CURL_OUTPUT}" \ + --max-time "${HEALTHCHECK_CURL_MAX_TIME}" \ + --user-agent "${HEALTHCHECK_CURL_USER_AGENT}" \ + --write-out "${HEALTHCHECK_CURL_WRITE_OUT}" \ + "$@" || exit 1 diff --git a/kolla/docker/base/healthcheck_filemod b/kolla/docker/base/healthcheck_filemod new file mode 100755 index 000000000..007643d9b --- /dev/null +++ b/kolla/docker/base/healthcheck_filemod @@ -0,0 +1,15 @@ +#!/bin/bash +file_path=$1 +limit_seconds=$2 + +# if the file doesn't exist, return 1 +if [ ! -f $file_path ]; then + echo "${file_path} does not exist for file modification check" + exit 1 +fi +curr_time=$(date +%s) +last_mod=$(stat -c '%Y' $file_path) +limit_epoch=$(( curr_time-limit_seconds )) +if [ ${limit_epoch} -gt ${last_mod} ]; then + exit 1 +fi diff --git a/kolla/docker/base/healthcheck_listen b/kolla/docker/base/healthcheck_listen new file mode 100755 index 000000000..70273339c --- /dev/null +++ b/kolla/docker/base/healthcheck_listen @@ -0,0 +1,8 @@ +#!/bin/bash +process=$1 + +shift 1 +args=$@ +ports=${args// /|} +pids=$(pgrep -d '|' -f $process) +ss -lnp | grep -qE ":($ports).*,pid=($pids)," diff --git a/kolla/docker/base/healthcheck_port b/kolla/docker/base/healthcheck_port new file mode 100755 index 000000000..9531bd77a --- /dev/null +++ b/kolla/docker/base/healthcheck_port @@ -0,0 +1,8 @@ +#!/bin/bash +process=$1 + +shift 1 +args=$@ +ports=${args// /|} +pids=$(pgrep -d '|' -f $process) +ss -ntp | grep -qE ":($ports).*,pid=($pids)," diff --git a/kolla/docker/base/healthcheck_socket b/kolla/docker/base/healthcheck_socket new file mode 100755 index 000000000..cd65bae69 --- /dev/null +++ b/kolla/docker/base/healthcheck_socket @@ -0,0 +1,10 @@ +#!/bin/bash +process=$1 +socket=$2 + +# lsof truncate command name to 15 characters and this behaviour +# cannot be disabled +if [ ${#process} -gt 15 ] ; then + process=${process:0:15} +fi +lsof -Fc -Ua $socket | grep -q "c$process" diff --git a/kolla/docker/base/install_projects.sh b/kolla/docker/base/install_projects.sh new file mode 100644 index 000000000..c3f7182b5 --- /dev/null +++ b/kolla/docker/base/install_projects.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +# This script finds all projects in /dev-mode folder and +# installs them using pip +# The projects are mounted there when dev mode is enabled for them +# in kolla-ansible + +VENV_PATH="/var/lib/kolla/venv" + +if [ -d "/dev-mode" ] && [ -d "$VENV_PATH" ]; then + for project in /dev-mode/*; do + pip install -U "$project" + done +fi diff --git a/kolla/docker/base/kolla_bashrc b/kolla/docker/base/kolla_bashrc new file mode 100644 index 000000000..09b19cc06 --- /dev/null +++ b/kolla/docker/base/kolla_bashrc @@ -0,0 +1,5 @@ +#### Custom data added by Kolla +_KBOLD="\[$(tput bold)\]" +_KRESET="\[$(tput sgr0)\]" + +PS1="${_KBOLD}(${KOLLA_SERVICE_NAME})${_KRESET}[\u@\h \W]\\$ " diff --git a/kolla/docker/base/kolla_patch.sh b/kolla/docker/base/kolla_patch.sh new file mode 100755 index 000000000..b17a5b61d --- /dev/null +++ b/kolla/docker/base/kolla_patch.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# This script works as debian quilt patch. +# So, patch files included in /patches/series +# are applied and information what was applied +# is stored in /etc/kolla/patched. +# +# No more, no less :) + +cd / + +# If exist /patches/series +# let's try to apply patches +if [ -e "/patches/series" ]; then + # If there is /patches/series.applied + # then it means previous run already applied + # some patches - from another intermediate container + # + # So, let's add patches again to /patches/series + # and let's script to handle it + if [ -e "/patches/series.applied" ]; then + grep -v '^#' /patches/series.applied > /tmp/series.tmp + grep -v '^#' /patches/series >> /tmp/series.tmp + rm -f /patches/series + mv /tmp/series.tmp /patches/series + fi + touch /etc/kolla/patched + for patchfile in $(grep -v '^#' /patches/series); do + # If patch is not applied, try to apply it, otherwise + # inform user that patchfile is already applied + if ! grep -q "$patchfile" /etc/kolla/patched; then + echo "[i] Applying /patches/${patchfile}" + patch -p0 --fuzz=0 --ignore-whitespace < /patches/${i}/${patchfile} + # If apply patch was successful inform user, + # otherwise fail build process and inform user + # to check/fix patch + if [ $? -eq 0 ]; then + echo "[i] Applied /patches/${patchfile}" >> /etc/kolla/patched + else + echo "[i] Patch /patches/${patchfile} failed, please fix your patchfiles." + exit 1 + fi + else + echo "[i] /patches/${patchfile} already applied." + fi + done + # Ignore files which are commented and move + # to /patches/series.applied as /patch/series + # can be potentially replaced by another files + # from different intermediate container + grep -v '^#' /patches/series > /patches/series.applied + rm -f /patches/series +else + echo "[i] No series file found, nothing to patch." +fi diff --git a/kolla/docker/base/set_configs.py b/kolla/docker/base/set_configs.py new file mode 100644 index 000000000..4b025d55a --- /dev/null +++ b/kolla/docker/base/set_configs.py @@ -0,0 +1,759 @@ +#!/usr/bin/env python3 + +# 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 argparse +import glob +import grp +import json +import logging +import os +import pwd +import re +import shutil +import stat +import sys +import yaml + + +# TODO(rhallisey): add docstring. +logging.basicConfig( + format='%(asctime)s.%(msecs)03d %(levelname)s %(message)s', + level=logging.INFO, + datefmt='%Y-%m-%d %H:%M:%S' +) +LOG = logging.getLogger(__name__) +LOG.setLevel(logging.INFO) + +KOLLA_DEFAULTS = "/etc/kolla/defaults" +KOLLA_DEFAULTS_STATE = KOLLA_DEFAULTS + '/' + 'state' + + +class ExitingException(Exception): + def __init__(self, message, exit_code=1): + super(ExitingException, self).__init__(message) + self.exit_code = exit_code + + +class ImmutableConfig(ExitingException): + pass + + +class InvalidConfig(ExitingException): + pass + + +class MissingRequiredSource(ExitingException): + pass + + +class UserNotFound(ExitingException): + pass + + +class ConfigFileBadState(ExitingException): + pass + + +class ConfigFileCommandDiffers(ExitingException): + pass + + +class StateMismatch(ExitingException): + pass + + +class ConfigFile(object): + + def __init__(self, source, dest, owner=None, perm=None, optional=False, + preserve_properties=False, merge=False): + self.source = source + self.dest = dest + self.owner = owner + self.perm = perm + self.optional = optional + self.merge = merge + self.preserve_properties = preserve_properties + + def __str__(self): + return '<ConfigFile source:"{}" dest:"{}">'.format(self.source, + self.dest) + + def _copy_file(self, source, dest): + self._delete_path(dest) + # dest endswith / means copy the <source> to <dest> folder + LOG.info('Copying %s to %s', source, dest) + if self.merge and self.preserve_properties and os.path.islink(source): + link_target = os.readlink(source) + os.symlink(link_target, dest) + else: + shutil.copy(source, dest) + self._set_properties(source, dest) + + def _merge_directories(self, source, dest): + if os.path.isdir(source): + if os.path.lexists(dest) and not os.path.isdir(dest): + self._delete_path(dest) + if not os.path.isdir(dest): + LOG.info('Creating directory %s', dest) + os.makedirs(dest) + self._set_properties(source, dest) + + dir_content = os.listdir(source) + for to_copy in dir_content: + self._merge_directories(os.path.join(source, to_copy), + os.path.join(dest, to_copy)) + else: + self._copy_file(source, dest) + + def _delete_path(self, path): + if not os.path.lexists(path): + return + LOG.info('Deleting %s', path) + if os.path.isdir(path): + shutil.rmtree(path) + else: + os.remove(path) + + def _create_parent_dirs(self, path): + parent_path = os.path.dirname(path) + if not os.path.exists(parent_path): + os.makedirs(parent_path) + + def _set_properties(self, source, dest): + if self.preserve_properties: + self._set_properties_from_file(source, dest) + else: + self._set_properties_from_conf(dest) + + def _set_properties_from_file(self, source, dest): + LOG.info('Copying permissions from %s onto %s', source, dest) + shutil.copystat(source, dest) + stat = os.stat(source) + os.chown(dest, stat.st_uid, stat.st_gid) + + def _set_properties_from_conf(self, path): + config = {'permissions': + [{'owner': self.owner, 'path': path, 'perm': self.perm}]} + handle_permissions(config) + + def copy(self): + + sources = glob.glob(self.source) + + if not self.optional and not sources: + raise MissingRequiredSource('%s file is not found' % self.source) + # skip when there is no sources and optional + elif self.optional and not sources: + return + + for source in sources: + dest = self.dest + # dest endswith / means copy the <source> into <dest> folder, + # otherwise means copy the source to dest + if dest.endswith(os.sep): + dest = os.path.join(dest, os.path.basename(source)) + if not self.merge: + self._delete_path(dest) + self._create_parent_dirs(dest) + try: + self._merge_directories(source, dest) + except OSError: + # If a source is tried to merge with a read-only mount, it + # may throw an OSError. Because we don't print the source or + # dest anywhere, let's catch the exception and log a better + # message to help with tracking down the issue. + LOG.error('Unable to merge %s with %s', source, dest) + raise + + def _cmp_file(self, source, dest): + # check exist + if (os.path.exists(source) and + not os.path.exists(dest)): + return False + if (os.path.exists(dest) and + not os.path.exists(source)): + return False + # check content + with open(source, 'rb') as f1, open(dest, 'rb') as f2: + if f1.read() != f2.read(): + LOG.error('The content of source file(%s) and' + ' dest file(%s) are not equal.', source, dest) + return False + # check perm + file_stat = os.stat(dest) + actual_perm = oct(file_stat.st_mode)[-4:] + if self.perm != actual_perm: + LOG.error('Dest file does not have expected perm: %s, actual: %s', + self.perm, actual_perm) + return False + # check owner + desired_user, desired_group = user_group(self.owner) + actual_user = pwd.getpwuid(file_stat.st_uid) + if actual_user.pw_name != desired_user: + LOG.error('Dest file does not have expected user: %s,' + ' actual: %s ', desired_user, actual_user.pw_name) + return False + actual_group = grp.getgrgid(file_stat.st_gid) + if actual_group.gr_name != desired_group: + LOG.error('Dest file does not have expected group: %s,' + ' actual: %s ', desired_group, actual_group.gr_name) + return False + return True + + def _cmp_dir(self, source, dest): + for root, dirs, files in os.walk(source): + for dir_ in dirs: + full_path = os.path.join(root, dir_) + dest_full_path = os.path.join(dest, os.path.relpath(source, + full_path)) + dir_stat = os.stat(dest_full_path) + actual_perm = oct(dir_stat.st_mode)[-4:] + if self.perm != actual_perm: + LOG.error('Dest dir does not have expected perm: %s,' + ' actual %s', self.perm, actual_perm) + return False + for file_ in files: + full_path = os.path.join(root, file_) + dest_full_path = os.path.join(dest, os.path.relpath(full_path, + source)) + if not self._cmp_file(full_path, dest_full_path): + return False + return True + + def check(self): + bad_state_files = [] + sources = glob.glob(self.source) + + if not sources and not self.optional: + raise MissingRequiredSource('%s file is not found' % self.source) + elif self.optional and not sources: + return + + for source in sources: + dest = self.dest + # dest endswith / means copy the <source> into <dest> folder, + # otherwise means copy the source to dest + if dest.endswith(os.sep): + dest = os.path.join(dest, os.path.basename(source)) + if os.path.isdir(source): + if not self._cmp_dir(source, dest): + bad_state_files.append(source) + elif not self._cmp_file(source, dest): + bad_state_files.append(source) + if len(bad_state_files) != 0: + msg = 'Following files are in bad state: %s' % bad_state_files + raise ConfigFileBadState(msg) + + +def validate_config(config): + required_keys = {'source', 'dest'} + required_path_keys = {'path', 'owner', 'perm'} + + if 'command' not in config: + raise InvalidConfig('Config is missing required "command" key') + + # Validate config sections + for data in config.get('config_files', list()): + # Verify required keys exist. + if not set(data.keys()) >= required_keys: + message = 'Config is missing required keys: %s' % required_keys + raise InvalidConfig(message) + if ('owner' not in data or 'perm' not in data) \ + and not data.get('preserve_properties', False): + raise InvalidConfig( + 'Config needs preserve_properties or owner and perm') + + for section in ('directories', 'files'): + for data in config.get(section, list()): + missing = required_path_keys - set(data.keys()) + if missing: + raise InvalidConfig( + '%s config is missing required keys: %s' + % (section, missing)) + + for key in required_path_keys: + if data.get(key) is None: + raise InvalidConfig( + '%s config key "%s" must not be null' + % (section, key)) + + if glob.has_magic(data['path']): + raise InvalidConfig( + '%s config does not support glob paths: %s' + % (section, data['path'])) + + +def validate_source(data): + source = data.get('source') + + # Only check existence if no wildcard found + if '*' not in source: + if not os.path.exists(source): + if data.get('optional'): + LOG.info("%s does not exist, but is not required", source) + return False + else: + raise MissingRequiredSource( + "The source to copy does not exist: %s" % source) + + return True + + +def load_config(): + def load_from_file(): + yaml_config_file = '/var/lib/kolla/config_files/config.yaml' + json_config_file = '/var/lib/kolla/config_files/config.json' + + if os.path.exists(yaml_config_file): + config_file = yaml_config_file + LOG.info("Loading config file at %s", config_file) + try: + with open(config_file) as f: + config = yaml.safe_load(f) + + if config is None: + raise InvalidConfig( + "Invalid yaml file found at %s: " + "file is empty" % config_file) + return config + except yaml.YAMLError: + raise InvalidConfig( + "Invalid yaml file found at %s" % config_file) + except IOError as e: + raise InvalidConfig( + "Could not read file %s: %r" % (config_file, e)) + else: + config_file = json_config_file + LOG.info("Loading config file at %s", config_file) + try: + with open(config_file) as f: + return json.load(f) + except ValueError: + raise InvalidConfig( + "Invalid json file found at %s" % config_file) + except IOError as e: + raise InvalidConfig( + "Could not read file %s: %r" % (config_file, e)) + + config = load_from_file() + + LOG.info('Validating config file') + validate_config(config) + return config + + +def copy_config(config): + if 'config_files' in config: + LOG.info('Copying service configuration files') + for data in config['config_files']: + config_file = ConfigFile(**data) + config_file.copy() + else: + LOG.debug('No files to copy found in config') + + LOG.info('Writing out command to execute') + LOG.debug("Command is: %s", config['command']) + # The value from the 'command' key will be written to '/run_command' + cmd = '/run_command' + with open(cmd, 'w+') as f: + f.write(config['command']) + # Make sure the generated file is readable by all users + try: + os.chmod(cmd, 0o644) + except OSError: + LOG.exception('Failed to set permission of %s to 0o644', cmd) + + +def create_directories(config): + if 'directories' not in config: + return + LOG.info('Creating directories') + for data in config['directories']: + path = data['path'] + try: + os.makedirs(path, exist_ok=True) + except Exception: + raise OSError("Can't create destination directory (%s)" % (path)) + handle_permissions({'permissions': [data]}) + + +def create_files(config): + if 'files' not in config: + return + LOG.info('Creating files') + for data in config['files']: + path = data['path'] + if os.path.islink(path): + raise OSError( + "Path is a symbolic link, expected regular file (%s)" % path) + if os.path.isdir(path): + raise OSError( + "Path is a directory, expected file (%s)" % path) + parent = os.path.dirname(path) + if parent and not os.path.isdir(parent): + raise OSError( + "Parent directory does not exist (%s)" % parent) + if not os.path.exists(path): + with open(path, 'a'): + pass + handle_permissions({'permissions': [data]}) + + +def user_group(owner): + if ':' in owner: + user, group = owner.split(':', 1) + if not group: + group = user + else: + user, group = owner, owner + return user, group + + +def handle_permissions(config): + for permission in config.get('permissions', list()): + path = permission.get('path') + owner = permission.get('owner') + recurse = permission.get('recurse', False) + perm = permission.get('perm') + exclude = permission.get('exclude', []) + + desired_user, desired_group = user_group(owner) + uid = pwd.getpwnam(desired_user).pw_uid + gid = grp.getgrnam(desired_group).gr_gid + + def set_perms(path, uid, gid, perm): + LOG.info('Setting permission for %s', path) + if not os.path.exists(path): + LOG.warning('%s does not exist', path) + return + + try: + os.chown(path, uid, gid) + except OSError: + LOG.exception('Failed to change ownership of %s to %s:%s', + path, uid, gid) + + if perm: + # Accept valid UNIX permission notation + # (e.g. 644, 0600, 1777, 2755) + # or equivalent Python octal literals + # (e.g. 0o644, 0o1777, 0o2755). + if re.fullmatch(r'[0-7]{3,4}', perm): + perm = int(perm, 8) + elif re.fullmatch(r'0o[0-7]{3,4}', perm): + perm = int(perm, 0) + else: + raise ValueError( + f"Invalid permission '{perm}'. Expected a valid UNIX " + "permission (e.g. 644, 0600, 2755) or a Python octal " + "literal (e.g. 0o644, 0o0600, 0o2755)." + ) + + # Ensure execute bit on directory if read bit is set + if os.path.isdir(path): + if perm & stat.S_IRUSR: + perm |= stat.S_IXUSR + if perm & stat.S_IRGRP: + perm |= stat.S_IXGRP + if perm & stat.S_IROTH: + perm |= stat.S_IXOTH + + try: + os.chmod(path, perm) + except OSError: + LOG.exception('Failed to set permission of %s to %s', + path, perm) + + def handle_exclusion(root, path_suffix): + full_path = os.path.join(root, path_suffix) + LOG.debug("Checking for exclusion: %s" % full_path) + if exclude: + for exclude_ in exclude: + if not re.search(exclude_, full_path): + set_perms(full_path, uid, gid, perm) + else: + set_perms(full_path, uid, gid, perm) + + for dest in glob.glob(path): + set_perms(dest, uid, gid, perm) + if recurse and os.path.isdir(dest): + for root, dirs, files in os.walk(dest): + for dir_ in dirs: + handle_exclusion(root, dir_) + for file_ in files: + handle_exclusion(root, file_) + + +def get_defaults_state(): + """Retrieve the saved default configuration state from default state file. + + This function creates the directory for Kolla defaults if it does not + exist, and then attempts to read the current configuration state from + a JSON file. If the file exists, it reads and returns the content. + If not, it returns an empty dictionary. + + Simply said, when the container starts for the first time, the state file + doesn't exist, and it returns an empty dictionary. + However, if it has already been started before, it will contain the state + as it was when it first ran. + + Returns: + dict: The configuration state stored in the Kolla defaults state file. + + Example: + { + "/etc/cinder/cinder.conf": { + "source": "/etc/cinder/cinder.conf", + "preserve_properties": true, + "dest": null + }, + "/etc/apache2/conf-enabled/cinder-wsgi.conf": { + "source": "/etc/apache2/conf-enabled/cinder-wsgi.conf", + "preserve_properties": true, + "dest": null + }, + "/etc/cinder/cinder_audit_map.conf": { + "source": "/etc/cinder/cinder_audit_map.conf", + "preserve_properties": true, + "dest": "/etc/kolla/defaults/etc/cinder/cinder_audit_map.conf" + } + } + + From above example: + /etc/cinder/cinder.conf didn't exist + /etc/apache2/conf-enabled/cinder-wsgi.conf didn't exist + /etc/cinder/cinder_audit_map.conf exists and saved + """ + os.makedirs(KOLLA_DEFAULTS, exist_ok=True) + if os.path.exists(KOLLA_DEFAULTS_STATE): + with open(KOLLA_DEFAULTS_STATE, 'r') as f: + return json.load(f) + else: + return {} + + +def set_defaults_state(state): + """Save the provided configuration state to the defaults state file. + + This function writes the provided state (a dictionary) to a JSON file at + the specified Kolla defaults state location, ensuring that it is properly + formatted with indentation for readability. + + Args: + state (dict): The configuration state to save to the Kolla defaults + state file. + """ + with open(KOLLA_DEFAULTS_STATE, 'w') as f: + json.dump(state, f, indent=4) + + +def remove_or_restore_configs(state): + """Remove or restore configuration files based on their current state. + + This function iterates over the configuration files in the provided state. + If the destination is `None`, it removes the file or directory. Otherwise, + it swaps the source and destination, restoring the configuration file + by copying it back to its original location. + + Args: + state (dict): The current default state of configuration files, mapping + file paths to their source and destination information. + """ + for k, v in state.items(): + if v['dest'] is None: + if os.path.exists(k): + if os.path.isfile(k): + os.remove(k) + else: + shutil.rmtree(k) + else: + v['source'], v['dest'] = v['dest'], v['source'] + config_file = ConfigFile(**v) + config_file.copy() + + +def backup_configs(config, state): + """Back up new configuration files and update the default state. + + This function processes new configuration files provided in the + input `config`. For each file, it checks if the destination exists in the + current state. If not, it backs up the file by copying it to the default + directory. It then updates the state with the new configuration file's + information. + + Args: + config (dict): The input configuration containing a list of config + files. + state (dict): The current default state to be updated with the new + config files. + """ + if 'config_files' in config: + for data in config['config_files']: + if data['dest'] in state.keys(): + continue + src = data['source'] + if data['dest'].endswith('/'): + dst = data['dest'] + data['source'].split('/')[-1] + else: + dst = data['dest'] + default = KOLLA_DEFAULTS + dst + if os.path.exists(src): + copy = {'source': dst, 'preserve_properties': True} + if os.path.exists(dst): + copy['dest'] = default + if dst not in state: + config_file = ConfigFile(**copy) + config_file.copy() + state[dst] = copy + else: + copy['dest'] = None + if dst not in state: + state[dst] = copy + + +def handle_defaults(config): + """Handle the default config files by copying/removing them as needed. + + This function loads the current default state and manages the configuration + files. It first processes existing configuration files in the default + state, either removing or restoring them based on their destination status. + It then backs up any new configuration files from the input config, + updating the default state accordingly. + + Args: + config (dict): A dictionary containing the list of configuration files + to be handled. + """ + state = get_defaults_state() + remove_or_restore_configs(state) + backup_configs(config, state) + set_defaults_state(state) + + +def execute_config_strategy(config): + config_strategy = os.environ.get("KOLLA_CONFIG_STRATEGY") + LOG.info("Kolla config strategy set to: %s", config_strategy) + if config_strategy == "COPY_ALWAYS": + create_directories(config) + create_files(config) + handle_defaults(config) + copy_config(config) + handle_permissions(config) + elif config_strategy == "COPY_ONCE": + if os.path.exists('/configured'): + raise ImmutableConfig( + "The config strategy prevents copying new configs", + exit_code=0) + else: + create_directories(config) + create_files(config) + handle_defaults(config) + copy_config(config) + handle_permissions(config) + os.mknod('/configured') + else: + raise InvalidConfig('KOLLA_CONFIG_STRATEGY is not set properly') + + +def execute_command_check(config): + cmd = config.get('command') + with open("/run_command", "r") as f: + cmd_running = f.read() + if cmd != cmd_running: + msg = "Running command differs. " + cmd + " != " + cmd_running + raise ConfigFileCommandDiffers(msg) + + +def execute_config_check(config): + """Check configuration state consistency and validate config file entries. + + This function compares the current config file destinations from the + provided config dictionary with those stored in the defaults state file. + If any destinations are found in the state file but not in the config, + a StateMismatch exception is raised. These missing files would otherwise + be restored or removed depending on their backup state. + + After validating consistency, the function performs standard checks on + each declared configuration file, including content, permissions, and + ownership validation. + + Args: + config (dict): The configuration dictionary containing 'config_files' + entries as expected by Kolla. + + Raises: + StateMismatch: If there are entries in the defaults state not present + in the provided config. + """ + state = get_defaults_state() + + # Build a set of all current destination paths from the config + # If the destination is a directory, we append the + # basename of the source + current_dests = { + entry['dest'] if not entry['dest'].endswith('/') else + os.path.join(entry['dest'], os.path.basename(entry['source'])) + for entry in config.get('config_files', []) + if entry.get('dest') + } + + # Detect any paths that are present in the state file but + # missing from the config file. + # These would be either restored (if state[dest] has a backup) + # or removed (if dest is null) + removed_dests = [ + path for path in state.keys() + if path not in current_dests + ] + + if removed_dests: + raise StateMismatch( + f"The following config files are tracked in state but missing " + f"from the config file. " + f"They would be restored or removed: {sorted(removed_dests)}" + ) + + # Perform the regular content, permissions, and ownership + # checks on the declared files + for data in config.get('config_files', []): + config_file = ConfigFile(**data) + config_file.check() + + +def main(): + try: + parser = argparse.ArgumentParser() + parser.add_argument('--check', + action='store_true', + required=False, + help='Check whether the configs changed') + args = parser.parse_args() + config = load_config() + + if args.check: + execute_command_check(config) + execute_config_check(config) + else: + execute_config_strategy(config) + except ExitingException as e: + LOG.error("%s: %s", e.__class__.__name__, e) + return e.exit_code + except Exception: + LOG.exception('Unexpected error:') + return 2 + return 0 + + +if __name__ == "__main__": + sys.exit(main()) diff --git a/kolla/docker/base/sources.list b/kolla/docker/base/sources.list new file mode 100644 index 000000000..1acbbcb59 --- /dev/null +++ b/kolla/docker/base/sources.list @@ -0,0 +1 @@ +# used for adding custom repos by 'apt_sources_list' option of kolla-build.conf diff --git a/kolla/docker/base/start.sh b/kolla/docker/base/start.sh new file mode 100644 index 000000000..7ac505aea --- /dev/null +++ b/kolla/docker/base/start.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +set -o errexit +set -o pipefail +set -o nounset +set -o xtrace + +# Processing /var/lib/kolla/config_files/config.json as root. This is necessary +# to permit certain files to be controlled by the root user which should +# not be writable by the dropped-privileged user, especially /run_command +sudo -E kolla_set_configs +CMD=$(cat /run_command) +ARGS="" + +# Install/remove custom CA certificates +sudo kolla_copy_cacerts + +# Install projects that are in /dev-mode +sudo kolla_install_projects + +if [[ ! "${!KOLLA_SKIP_EXTEND_START[@]}" ]]; then + # Run additional commands if present + . kolla_extend_start +fi + +echo "Running command: '${CMD}${ARGS:+ $ARGS}'" +exec ${CMD} ${ARGS} diff --git a/kolla/docker/base/sudoers b/kolla/docker/base/sudoers new file mode 100644 index 000000000..eb31bc98b --- /dev/null +++ b/kolla/docker/base/sudoers @@ -0,0 +1,26 @@ +# The idea here is a container service adds their UID to the kolla group +# via usermod -a -G kolla <uid>. Then the kolla_start may run +# kolla_set_configs via sudo as the root user which is necessary to protect +# the immutability of the container + +# anyone in the kolla group may sudo -E (set the environment) +Defaults: %kolla setenv + +Defaults secure_path="/var/lib/kolla/venv/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +# root may run any commands via sudo as the network seervice user. This is +# neededfor database migrations of existing services which have not been +# converted to run as a non-root user, but instead do that via sudo -E glance +root ALL=(ALL) ALL + +# anyone in the kolla group may run /usr/local/bin/kolla_set_configs as the +# root user via sudo without password confirmation +%kolla ALL=(root) NOPASSWD: /usr/local/bin/kolla_set_configs + +# Copy custom CA certificates to containers +%kolla ALL=(root) NOPASSWD: /usr/local/bin/kolla_copy_cacerts + +# Install projects in dev-mode +%kolla ALL=(root) NOPASSWD: /usr/local/bin/kolla_install_projects + +#includedir /etc/sudoers.d diff --git a/kolla/docker/base/ubuntu.sources b/kolla/docker/base/ubuntu.sources new file mode 100644 index 000000000..f8f609cee --- /dev/null +++ b/kolla/docker/base/ubuntu.sources @@ -0,0 +1,24 @@ +Types: deb +URIs: http://archive.ubuntu.com/ubuntu/ +Suites: noble noble-updates noble-backports +Components: main universe +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg + +## Ubuntu security updates. Aside from URIs and Suites, +## this should mirror your choices in the previous section. +Types: deb +URIs: http://security.ubuntu.com/ubuntu/ +Suites: noble-security +Components: main universe +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg + +## Ubuntu Cloud Archive +Types: deb +URIs: http://ubuntu-cloud.archive.canonical.com/ubuntu +Suites: noble-updates/gazpacho +Components: main +Signed-By: /usr/share/keyrings/ubuntu-cloud-keyring.gpg + +# NOTE(hrw): extra repositories are added into image when they are needed as +# separate files in /etc/apt/sources.list.d/ directory. For that purpose they +# are defined in kolla/template/repos.yaml file. diff --git a/kolla/docker/base/ubuntu.sources.arm64 b/kolla/docker/base/ubuntu.sources.arm64 new file mode 100644 index 000000000..751af7ccf --- /dev/null +++ b/kolla/docker/base/ubuntu.sources.arm64 @@ -0,0 +1,24 @@ +Types: deb +URIs: http://ports.ubuntu.com/ubuntu-ports/ +Suites: noble noble-updates noble-backports +Components: main universe +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg + +## Ubuntu security updates. Aside from URIs and Suites, +## this should mirror your choices in the previous section. +Types: deb +URIs: http://ports.ubuntu.com/ubuntu-ports/ +Suites: noble-security +Components: main universe +Signed-By: /usr/share/keyrings/ubuntu-archive-keyring.gpg + +## Ubuntu Cloud Archive +Types: deb +URIs: http://ubuntu-cloud.archive.canonical.com/ubuntu +Suites: noble-updates/gazpacho +Components: main +Signed-By: /usr/share/keyrings/ubuntu-cloud-keyring.gpg + +# NOTE(hrw): extra repositories are added into image when they are needed as +# separate files in /etc/apt/sources.list.d/ directory. For that purpose they +# are defined in kolla/template/repos.yaml file. diff --git a/kolla/docker/bifrost/bifrost-base/Dockerfile.j2 b/kolla/docker/bifrost/bifrost-base/Dockerfile.j2 new file mode 100644 index 000000000..3e82a9fd3 --- /dev/null +++ b/kolla/docker/bifrost/bifrost-base/Dockerfile.j2 @@ -0,0 +1,76 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block bifrost_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set venv_path='/var/lib/kolla/venv' %} + +{{ macros.configure_user(name='bifrost') }} + +{% set bifrost_base_packages = [ + 'cpio' +] %} + +{% if base_package_type == 'rpm' %} + +{# NOTE(mgoddard): EPEL required for nginx #} +{{ macros.enable_extra_repos(['epel']) }} +{% endif %} + +{{ macros.install_packages(bifrost_base_packages | customizable("packages")) }} + +ENV VENV {{ venv_path }} + +{% set bifrost_base_pip_packages = [ + '/bifrost' +] %} + +ADD bifrost-base-archive /bifrost-base-source +COPY build_arg.yml /tmp/build_arg.yml + +RUN mkdir -p /requirements \ + && curl -o /requirements/upper-constraints.txt ${UPPER_CONSTRAINTS_FILE:-https://releases.openstack.org/constraints/upper/{{ openstack_release }}} \ + && python3 -m venv --system-site-packages {{ venv_path }} \ + && ln -s bifrost-base-source/* bifrost \ + && {{ macros.install_pip(['pip', 'wheel', 'setuptools']) }} \ + && {{ macros.install_pip(bifrost_base_pip_packages | customizable("pip_packages")) }} + +WORKDIR /bifrost + +{# ANSIBLE_GATHER_TIMEOUT is a workaround for https://github.com/ansible/ansible/issues/43884 #} +ENV ANSIBLE_GATHER_TIMEOUT=30 + +{% block bifrost_ansible_install %} +{%- if base_package_type == 'deb' %} +RUN apt-get --error-on=any update && \ +{%- else %} +RUN echo " " && \ +{%- endif %} + bash -c '$VENV/bin/pip install "ansible>=12,<14" && \ + $VENV/bin/ansible-galaxy collection install -r /bifrost/ansible-collections-requirements.yml && \ + $VENV/bin/ansible-playbook -vvvv -i /bifrost/playbooks/inventory/target \ + /bifrost/playbooks/install.yaml \ + -e upper_constraints_file="/requirements/upper-constraints.txt" \ + -e git_branch={{ openstack_branch_slashed }} \ + -e ipa_upstream_release={{ openstack_branch }} \ + -e @/tmp/build_arg.yml && \ +{%- if base_package_type == 'deb' %} + apt-get clean && rm -rf /var/lib/apt/lists/*' +{%- else %} + dnf clean all && rm -rf /var/dnf/cache' +{%- endif %} +{% endblock %} + +COPY bifrost_sudoers /etc/sudoers.d/kolla_bifrost_sudoers + +RUN chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_bifrost_sudoers \ + && chown -R bifrost:bifrost /bifrost + +{{ macros.kolla_patch_sources() }} + +{% block bifrost_base_footer %}{% endblock %} diff --git a/kolla/docker/bifrost/bifrost-base/bifrost_sudoers b/kolla/docker/bifrost/bifrost-base/bifrost_sudoers new file mode 100644 index 000000000..6c343a956 --- /dev/null +++ b/kolla/docker/bifrost/bifrost-base/bifrost_sudoers @@ -0,0 +1 @@ +bifrost ALL=(ALL) NOPASSWD:ALL diff --git a/kolla/docker/bifrost/bifrost-base/build_arg.yml b/kolla/docker/bifrost/bifrost-base/build_arg.yml new file mode 100644 index 000000000..8c810f133 --- /dev/null +++ b/kolla/docker/bifrost/bifrost-base/build_arg.yml @@ -0,0 +1,7 @@ +--- +skip_bootstrap: true +skip_start: true +install_dib: true +create_image_via_dib: false +ansible_python_interpreter: /var/lib/kolla/venv/bin/python +internal_ip: "127.0.0.1" diff --git a/kolla/docker/bifrost/bifrost-deploy/Dockerfile.j2 b/kolla/docker/bifrost/bifrost-deploy/Dockerfile.j2 new file mode 100644 index 000000000..04fc733fc --- /dev/null +++ b/kolla/docker/bifrost/bifrost-deploy/Dockerfile.j2 @@ -0,0 +1,35 @@ +FROM {{ namespace }}/{{ image_prefix }}bifrost-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block bifrost_deploy_header %}{% endblock %} + +ENV container docker + +{% import "macros.j2" as macros with context %} + +RUN rm -f $(find /lib/systemd/system/sysinit.target.wants/ ! -name systemd-tmpfiles-setup.service -type l); \ + rm -f /lib/systemd/system/multi-user.target.wants/*; \ + rm -f /etc/systemd/system/*.wants/*; \ + rm -f /lib/systemd/system/local-fs.target.wants/*; \ + rm -f /lib/systemd/system/sockets.target.wants/*udev*; \ + rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \ + rm -f /lib/systemd/system/basic.target.wants/*; \ + rm -f /lib/systemd/system/anaconda.target.wants/*; + +{% set bifrost_deploy_packages = [ + 'e2fsprogs', + 'systemd-sysv', +] %} + +{{ macros.install_packages(bifrost_deploy_packages | customizable("packages")) }} + +# Clear any customisation by Kolla to entrypoint & command +ENTRYPOINT [] +CMD [ "/sbin/init" ] + +{{ macros.kolla_patch_sources() }} + +{% block bifrost_deploy_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/blazar/blazar-api/Dockerfile.j2 b/kolla/docker/blazar/blazar-api/Dockerfile.j2 new file mode 100644 index 000000000..70d6ba22a --- /dev/null +++ b/kolla/docker/blazar/blazar-api/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}blazar-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block blazar_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_blazar_extend_start +RUN chmod 644 /usr/local/bin/kolla_blazar_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block blazar_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER blazar diff --git a/kolla/docker/blazar/blazar-api/extend_start.sh b/kolla/docker/blazar/blazar-api/extend_start.sh new file mode 100644 index 000000000..ff4f2b801 --- /dev/null +++ b/kolla/docker/blazar/blazar-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + blazar-db-manage --config-file /etc/blazar/blazar.conf upgrade head + exit 0 +fi diff --git a/kolla/docker/blazar/blazar-base/Dockerfile.j2 b/kolla/docker/blazar/blazar-base/Dockerfile.j2 new file mode 100644 index 000000000..433842e41 --- /dev/null +++ b/kolla/docker/blazar/blazar-base/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block blazar_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='blazar') }} + +ADD blazar-base-archive /blazar-base-source + +{% set blazar_base_pip_packages = [ + '/blazar' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s blazar-base-source/* blazar \ + && {{ macros.install_pip(blazar_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/blazar \ + && cp -r /blazar/etc/blazar/* /etc/blazar \ + && touch /usr/local/bin/kolla_blazar_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_blazar_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block blazar_base_footer %}{% endblock %} diff --git a/kolla/docker/blazar/blazar-base/extend_start.sh b/kolla/docker/blazar/blazar-base/extend_start.sh new file mode 100644 index 000000000..a96a4c113 --- /dev/null +++ b/kolla/docker/blazar/blazar-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/blazar" ]]; then + mkdir -p /var/log/kolla/blazar +fi +if [[ $(stat -c %a /var/log/kolla/blazar) != "755" ]]; then + chmod 755 /var/log/kolla/blazar +fi + +. /usr/local/bin/kolla_blazar_extend_start diff --git a/kolla/docker/blazar/blazar-manager/Dockerfile.j2 b/kolla/docker/blazar/blazar-manager/Dockerfile.j2 new file mode 100644 index 000000000..5cde3db3b --- /dev/null +++ b/kolla/docker/blazar/blazar-manager/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}blazar-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block blazar_manager_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block blazar_manager_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER blazar diff --git a/kolla/docker/ceilometer/ceilometer-base/Dockerfile.j2 b/kolla/docker/ceilometer/ceilometer-base/Dockerfile.j2 new file mode 100644 index 000000000..18bd7600a --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-base/Dockerfile.j2 @@ -0,0 +1,43 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ceilometer_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='ceilometer') }} + +{% set ceilometer_base_pip_packages = [ + '/ceilometer' +] %} + +{% set ceilometer_base_plugins_pip_packages = [ + '/plugins/*' +] %} + +ADD ceilometer-base-archive /ceilometer-base-source +ADD plugins-archive / + +COPY ceilometer_sudoers /etc/sudoers.d/kolla_ceilometer_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +# NOTE(egonzalez): Remove ceilometer from constraint or will fail. +RUN ln -s ceilometer-base-source/* ceilometer \ + && {{ macros.upper_constraints_remove("ceilometer") }} \ + && {{ macros.install_pip(ceilometer_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/ceilometer \ + && cp -r /ceilometer/etc/ceilometer/* /etc/ceilometer/ \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/ceilometer/rootwrap.conf \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(ceilometer_base_plugins_pip_packages) }}; \ + fi \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_ceilometer_sudoers \ + && touch /usr/local/bin/kolla_ceilometer_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_ceilometer_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ceilometer_base_footer %}{% endblock %} diff --git a/kolla/docker/ceilometer/ceilometer-base/ceilometer_sudoers b/kolla/docker/ceilometer/ceilometer-base/ceilometer_sudoers new file mode 100644 index 000000000..dd861bb58 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-base/ceilometer_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown -R ceilometer\: /var/lib/ceilometer/, /bin/chown -R ceilometer\: /var/lib/ceilometer/ diff --git a/kolla/docker/ceilometer/ceilometer-base/extend_start.sh b/kolla/docker/ceilometer/ceilometer-base/extend_start.sh new file mode 100644 index 000000000..4d3fe6b61 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-base/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +CEILOMETER_LOG_DIR=/var/log/kolla/ceilometer + +if [[ ! -d "${CEILOMETER_LOG_DIR}" ]]; then + mkdir -p "${CEILOMETER_LOG_DIR}" +fi +if [[ $(stat -c %U:%G "${CEILOMETER_LOG_DIR}") != "ceilometer:kolla" ]]; then + chown ceilometer:kolla "${CEILOMETER_LOG_DIR}" +fi +if [[ $(stat -c %a "${CEILOMETER_LOG_DIR}") != "755" ]]; then + chmod 755 "${CEILOMETER_LOG_DIR}" +fi + +. /usr/local/bin/kolla_ceilometer_extend_start diff --git a/kolla/docker/ceilometer/ceilometer-central/Dockerfile.j2 b/kolla/docker/ceilometer/ceilometer-central/Dockerfile.j2 new file mode 100644 index 000000000..df96d8ed3 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-central/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}ceilometer-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ceilometer_central_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block ceilometer_central_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER ceilometer diff --git a/kolla/docker/ceilometer/ceilometer-compute/Dockerfile.j2 b/kolla/docker/ceilometer/ceilometer-compute/Dockerfile.j2 new file mode 100644 index 000000000..879c4fb01 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-compute/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM {{ namespace }}/{{ image_prefix }}ceilometer-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ceilometer_compute_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ceilometer_compute_packages = [ + 'python3-libvirt' + ] %} +{% elif base_package_type == 'deb' %} + {% set ceilometer_compute_packages = [ + 'python3-libvirt' + ] %} +{% endif %} + +{{ macros.install_packages(ceilometer_compute_packages | customizable("packages")) }} + +# NOTE(jeffrey4l): just for back compatibility +{% set ceilometer_compute_pip_packages = [] %} + +RUN {{ macros.install_pip(ceilometer_compute_pip_packages | customizable("pip_packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block ceilometer_compute_footer %}{% endblock %} +{% block footer %}{% endblock %} + +# NOTE(huikang): non-root user does not work with libvirt.sock. +# Need configuration in nova-libvirt container to allow +# USER ceilometer to access libvirt.sock diff --git a/kolla/docker/ceilometer/ceilometer-ipmi/Dockerfile.j2 b/kolla/docker/ceilometer/ceilometer-ipmi/Dockerfile.j2 new file mode 100644 index 000000000..a767dc842 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-ipmi/Dockerfile.j2 @@ -0,0 +1,27 @@ +FROM {{ namespace }}/{{ image_prefix }}ceilometer-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ceilometer_ipmi_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ceilometer_ipmi_packages = [ + 'ipmitool' + ] %} +{% elif base_package_type == 'deb' %} + {% set ceilometer_ipmi_packages = [ + 'ipmitool' + ] %} +{% endif %} + +{{ macros.install_packages(ceilometer_ipmi_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block ceilometer_ipmi_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER ceilometer diff --git a/kolla/docker/ceilometer/ceilometer-notification/Dockerfile.j2 b/kolla/docker/ceilometer/ceilometer-notification/Dockerfile.j2 new file mode 100644 index 000000000..1fc03ffc4 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-notification/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}ceilometer-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ceilometer_notification_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_ceilometer_extend_start +RUN chmod 644 /usr/local/bin/kolla_ceilometer_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ceilometer_notification_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER ceilometer diff --git a/kolla/docker/ceilometer/ceilometer-notification/extend_start.sh b/kolla/docker/ceilometer/ceilometer-notification/extend_start.sh new file mode 100644 index 000000000..0abeeb1e1 --- /dev/null +++ b/kolla/docker/ceilometer/ceilometer-notification/extend_start.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + if [[ "${CEILOMETER_DATABASE_TYPE}" == "gnocchi" ]]; then + ceilometer-upgrade ${CEILOMETER_UPGRADE_PARAMS} + fi + sudo chown -R ceilometer: /var/lib/ceilometer/ + exit 0 +fi diff --git a/kolla/docker/cinder/cinder-api/Dockerfile.j2 b/kolla/docker/cinder/cinder-api/Dockerfile.j2 new file mode 100644 index 000000000..b82fba6d3 --- /dev/null +++ b/kolla/docker/cinder/cinder-api/Dockerfile.j2 @@ -0,0 +1,22 @@ +FROM {{ namespace }}/{{ image_prefix }}cinder-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cinder_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set cinder_api_packages = [ +] %} + +{{ macros.install_packages(cinder_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_cinder_extend_start + +RUN chmod 644 /usr/local/bin/kolla_cinder_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cinder_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/cinder/cinder-api/extend_start.sh b/kolla/docker/cinder/cinder-api/extend_start.sh new file mode 100644 index 000000000..94b0fe875 --- /dev/null +++ b/kolla/docker/cinder/cinder-api/extend_start.sh @@ -0,0 +1,14 @@ +#!/bin/bash +set -o errexit + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + cinder-manage db sync + exit 0 +fi + +if [[ "${!KOLLA_OSM[@]}" ]]; then + cinder-manage db online_data_migrations + exit 0 +fi diff --git a/kolla/docker/cinder/cinder-backup/Dockerfile.j2 b/kolla/docker/cinder/cinder-backup/Dockerfile.j2 new file mode 100644 index 000000000..15be355dd --- /dev/null +++ b/kolla/docker/cinder/cinder-backup/Dockerfile.j2 @@ -0,0 +1,33 @@ +FROM {{ namespace }}/{{ image_prefix }}cinder-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cinder_backup_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set cinder_backup_packages = [ + 'device-mapper-multipath', + 'lsscsi', + 'nfs-utils', + 'sysfsutils' + ] %} +{% elif base_package_type == 'deb' %} + {% set cinder_backup_packages = [ + 'lsscsi', + 'multipath-tools', + 'nfs-common', + 'sysfsutils' + ] %} +{% endif %} + +{{ macros.install_packages(cinder_backup_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block cinder_backup_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER cinder diff --git a/kolla/docker/cinder/cinder-base/Dockerfile.j2 b/kolla/docker/cinder/cinder-base/Dockerfile.j2 new file mode 100644 index 000000000..bd25d9b18 --- /dev/null +++ b/kolla/docker/cinder/cinder-base/Dockerfile.j2 @@ -0,0 +1,60 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cinder_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='cinder') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['ceph', 'epel']) }} + + {% set cinder_base_packages = [ + 'ceph-common', + 'cryptsetup', + 'lvm2', + 'nvme-cli', + 'qemu-img', + 'systemd-udev' + ] %} +{% elif base_package_type == 'deb' %} + {% set cinder_base_packages = [ + 'ceph-common', + 'cryptsetup', + 'lvm2', + 'nvme-cli', + 'python3-cephfs', + 'python3-rados', + 'python3-rbd', + 'qemu-utils' + ] %} +{% endif %} +{{ macros.install_packages(cinder_base_packages | customizable("packages")) }} + +{% set cinder_base_pip_packages = [ + '/cinder' +] %} + +ADD cinder-base-archive /cinder-base-source + +COPY cinder_sudoers /etc/sudoers.d/kolla_cinder_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s cinder-base-source/* cinder \ + && {{ macros.install_pip(cinder_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/cinder \ + && cp -r /cinder/etc/cinder/* /etc/cinder/ \ + && cp /var/lib/kolla/venv/etc/pycadf/cinder_api_audit_map.conf /etc/cinder/ \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/cinder/rootwrap.conf \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_cinder_sudoers \ + && touch /usr/local/bin/kolla_cinder_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_cinder_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cinder_base_footer %}{% endblock %} diff --git a/kolla/docker/cinder/cinder-base/cinder_sudoers b/kolla/docker/cinder/cinder-base/cinder_sudoers new file mode 100644 index 000000000..3750f31a0 --- /dev/null +++ b/kolla/docker/cinder/cinder-base/cinder_sudoers @@ -0,0 +1 @@ +cinder ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/cinder-rootwrap /etc/cinder/rootwrap.conf * diff --git a/kolla/docker/cinder/cinder-base/extend_start.sh b/kolla/docker/cinder/cinder-base/extend_start.sh new file mode 100644 index 000000000..ddf1469c9 --- /dev/null +++ b/kolla/docker/cinder/cinder-base/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/cinder" ]]; then + mkdir -p /var/log/kolla/cinder +fi +if [[ $(stat -c %U:%G /var/log/kolla/cinder) != "cinder:kolla" ]]; then + chown -R cinder:kolla /var/log/kolla/cinder +fi +if [[ $(stat -c %a /var/log/kolla/cinder) != "755" ]]; then + chmod 755 /var/log/kolla/cinder +fi + +. /usr/local/bin/kolla_cinder_extend_start diff --git a/kolla/docker/cinder/cinder-scheduler/Dockerfile.j2 b/kolla/docker/cinder/cinder-scheduler/Dockerfile.j2 new file mode 100644 index 000000000..c43792dcc --- /dev/null +++ b/kolla/docker/cinder/cinder-scheduler/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}cinder-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cinder_scheduler_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block cinder_scheduler_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER cinder diff --git a/kolla/docker/cinder/cinder-volume/Dockerfile.j2 b/kolla/docker/cinder/cinder-volume/Dockerfile.j2 new file mode 100644 index 000000000..0e4f38a6e --- /dev/null +++ b/kolla/docker/cinder/cinder-volume/Dockerfile.j2 @@ -0,0 +1,58 @@ +FROM {{ namespace }}/{{ image_prefix }}cinder-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cinder_volume_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set cinder_volume_packages = [ + 'lsscsi', + 'device-mapper-multipath', + 'nfs-utils', + 'nvmetcli', + 'sysfsutils', + 'targetcli' + ] %} +{% elif base_package_type == 'deb' %} + {% set cinder_volume_packages = [ + 'lsscsi', + 'multipath-tools', + 'nfs-common', + 'sysfsutils', + 'targetcli-fb', + 'thin-provisioning-tools', + 'tgt' + ] %} +{% endif %} + +{{ macros.install_packages(cinder_volume_packages | customizable("packages")) }} + +{% if base_package_type == 'rpm' %} + +{% block cinder_volume_redhat_setup %} +{% endblock %} + +{% elif base_package_type == 'deb' %} + +{% block cinder_volume_ubuntu_setup %} +RUN sed -i '1 i include /var/lib/cinder/volumes/*' /etc/tgt/targets.conf +{% endblock %} + +{% endif %} + +COPY cinder_sudoers /etc/sudoers.d/kolla_cinder_volume_sudoers +COPY extend_start.sh /usr/local/bin/kolla_cinder_extend_start + +RUN chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_cinder_volume_sudoers \ + && chmod 644 /usr/local/bin/kolla_cinder_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cinder_volume_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER cinder diff --git a/kolla/docker/cinder/cinder-volume/cinder_sudoers b/kolla/docker/cinder/cinder-volume/cinder_sudoers new file mode 100644 index 000000000..f3bec8b13 --- /dev/null +++ b/kolla/docker/cinder/cinder-volume/cinder_sudoers @@ -0,0 +1,5 @@ +cinder ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/cinder-rootwrap /etc/cinder/rootwrap.conf * +%kolla ALL=(root) NOPASSWD: /bin/chown -R cinder\:kolla /var/lib/cinder, /usr/bin/chown -R cinder\:kolla /var/lib/cinder +%kolla ALL=(root) NOPASSWD: /bin/chmod 2775 /var/lib/cinder, /usr/bin/chmod 2775 /var/lib/cinder +%kolla ALL=(root) NOPASSWD: /bin/chown -R cinder\:kolla /etc/iscsi, /usr/bin/chown -R cinder\:kolla /etc/iscsi +%kolla ALL=(root) NOPASSWD: /bin/chmod 2775 /etc/iscsi, /usr/bin/chmod 2775 /etc/iscsi diff --git a/kolla/docker/cinder/cinder-volume/extend_start.sh b/kolla/docker/cinder/cinder-volume/extend_start.sh new file mode 100644 index 000000000..67e866143 --- /dev/null +++ b/kolla/docker/cinder/cinder-volume/extend_start.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +if [[ $(stat -c %U:%G /var/lib/cinder) != "cinder:kolla" ]]; then + sudo chown -R cinder:kolla /var/lib/cinder +fi +if [[ $(stat -c %a /var/lib/cinder) != "2775" ]]; then + sudo chmod 2775 /var/lib/cinder +fi +if [[ $(stat -c %U:%G /etc/iscsi) != "cinder:kolla" ]]; then + sudo chown -R cinder:kolla /etc/iscsi +fi +if [[ $(stat -c %a /etc/iscsi) != "2775" ]]; then + sudo chmod 2775 /etc/iscsi +fi diff --git a/kolla/docker/cloudkitty/cloudkitty-api/Dockerfile.j2 b/kolla/docker/cloudkitty/cloudkitty-api/Dockerfile.j2 new file mode 100644 index 000000000..fd3d124f3 --- /dev/null +++ b/kolla/docker/cloudkitty/cloudkitty-api/Dockerfile.j2 @@ -0,0 +1,21 @@ +FROM {{ namespace }}/{{ image_prefix }}cloudkitty-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cloudkitty_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set cloudkitty_api_packages = [ +] %} + +{{ macros.install_packages(cloudkitty_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_cloudkitty_extend_start +RUN chmod 644 /usr/local/bin/kolla_cloudkitty_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cloudkitty_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/cloudkitty/cloudkitty-api/extend_start.sh b/kolla/docker/cloudkitty/cloudkitty-api/extend_start.sh new file mode 100644 index 000000000..26d4a8c36 --- /dev/null +++ b/kolla/docker/cloudkitty/cloudkitty-api/extend_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + cloudkitty-dbsync upgrade + cloudkitty-storage-init + exit 0 +fi diff --git a/kolla/docker/cloudkitty/cloudkitty-base/Dockerfile.j2 b/kolla/docker/cloudkitty/cloudkitty-base/Dockerfile.j2 new file mode 100644 index 000000000..b545d4adf --- /dev/null +++ b/kolla/docker/cloudkitty/cloudkitty-base/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cloudkitty_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='cloudkitty') }} + +{% set cloudkitty_base_pip_packages = [ + '/cloudkitty' +] %} + +ADD cloudkitty-base-archive /cloudkitty-base-source + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s cloudkitty-base-source/* cloudkitty \ + && {{ macros.install_pip(cloudkitty_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/cloudkitty \ + && cp -r /cloudkitty/etc/cloudkitty/* /etc/cloudkitty/ \ + && touch /usr/local/bin/kolla_cloudkitty_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_cloudkitty_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cloudkitty_base_footer %}{% endblock %} diff --git a/kolla/docker/cloudkitty/cloudkitty-base/extend_start.sh b/kolla/docker/cloudkitty/cloudkitty-base/extend_start.sh new file mode 100644 index 000000000..cf49f9caf --- /dev/null +++ b/kolla/docker/cloudkitty/cloudkitty-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/cloudkitty" ]]; then + mkdir -p /var/log/kolla/cloudkitty +fi +if [[ $(stat -c %a /var/log/kolla/cloudkitty) != "755" ]]; then + chmod 755 /var/log/kolla/cloudkitty +fi + +. /usr/local/bin/kolla_cloudkitty_extend_start diff --git a/kolla/docker/cloudkitty/cloudkitty-processor/Dockerfile.j2 b/kolla/docker/cloudkitty/cloudkitty-processor/Dockerfile.j2 new file mode 100644 index 000000000..33f30fd33 --- /dev/null +++ b/kolla/docker/cloudkitty/cloudkitty-processor/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}cloudkitty-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cloudkitty_processor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set cloudkitty_processor_packages = [ +] %} + +{{ macros.install_packages(cloudkitty_processor_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block cloudkitty_processor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER cloudkitty diff --git a/kolla/docker/collectd/Dockerfile.j2 b/kolla/docker/collectd/Dockerfile.j2 new file mode 100644 index 000000000..32ded377e --- /dev/null +++ b/kolla/docker/collectd/Dockerfile.j2 @@ -0,0 +1,81 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block collectd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='collectd') }} + +{% set collectd_packages = [ + 'collectd' +] %} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['opstools']) }} + + {% set collectd_packages = collectd_packages + [ + 'collectd-amqp', + 'collectd-amqp1', + 'collectd-apache', + 'collectd-bind', + 'collectd-ceph', + 'collectd-chrony', + 'collectd-connectivity', + 'collectd-curl', + 'collectd-curl_json', + 'collectd-curl_xml', + 'collectd-dbi', + 'collectd-disk', + 'collectd-dns', + 'collectd-ipmi', + 'collectd-logparser', + 'collectd-mcelog', + 'collectd-mysql', + 'collectd-netlink', + 'collectd-openldap', + 'collectd-ovs-events', + 'collectd-ovs-stats', + 'collectd-ping', + 'collectd-procevent', + 'collectd-python', + 'collectd-sensors', + 'collectd-smart', + 'collectd-snmp', + 'collectd-snmp-agent', + 'collectd-sysevent', + 'collectd-utils', + 'collectd-virt', + 'collectd-write_http', + 'collectd-write_kafka', + 'collectd-write_prometheus', + ] %} + + {% if base_arch =='x86_64' %} + {% set collectd_packages = collectd_packages + [ + 'collectd-hugepages', + 'collectd-pcie-errors', + 'collectd-pmu', + 'collectd-rdt', + 'collectd-turbostat' + ] %} + {% endif %} + +{% endif %} + +{{ macros.install_packages(collectd_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && chown -R collectd /var/lib/collectd \ + && chown -R collectd /var/run/ + +{{ macros.kolla_patch_sources() }} + +{% block collectd_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER collectd diff --git a/kolla/docker/collectd/extend_start.sh b/kolla/docker/collectd/extend_start.sh new file mode 100644 index 000000000..80ef63db3 --- /dev/null +++ b/kolla/docker/collectd/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/collectd" ]]; then + mkdir -p /var/log/kolla/collectd +fi +if [[ $(stat -c %a /var/log/kolla/collectd) != "755" ]]; then + chmod 755 /var/log/kolla/collectd +fi diff --git a/kolla/docker/cron/Dockerfile.j2 b/kolla/docker/cron/Dockerfile.j2 new file mode 100644 index 000000000..d3a9213ac --- /dev/null +++ b/kolla/docker/cron/Dockerfile.j2 @@ -0,0 +1,35 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cron_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set cron_packages = [ + 'cronie', + 'logrotate' + ] %} + +# NOTE(hrw): In RHEL 9 family it is done by systemd timer, we want cron to +# handle it. +COPY logrotate /etc/cron.daily/logrotate + +{% elif base_package_type == 'deb' %} + {% set cron_packages = [ + 'cron', + 'logrotate' + ] %} +{% endif %} + +{{ macros.install_packages(cron_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cron_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/cron/extend_start.sh b/kolla/docker/cron/extend_start.sh new file mode 100644 index 000000000..3476302e1 --- /dev/null +++ b/kolla/docker/cron/extend_start.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +CRON_LOGROTATE_CURRENT_PATH="$(find /etc/cron* -name logrotate)" +CRON_LOGROTATE_CURRENT_SCHEDULE=$(echo "${CRON_LOGROTATE_CURRENT_PATH}" | sed -r 's/(.*)(hourly|daily|weekly|monthly)(.*)/\2/g') + +if [ -z $CRON_LOGROTATE_CURRENT_PATH ]; then + echo "logrotate is not handled by cron" +else + # Pass only for hourly|daily|weekly|monthly + if [[ "${KOLLA_LOGROTATE_SCHEDULE:-undefined}" =~ hourly|daily|weekly|monthly ]]; then + + CRON_LOGROTATE_DESIRED_PATH="/etc/cron.${KOLLA_LOGROTATE_SCHEDULE}/logrotate" + + if [[ "${CRON_LOGROTATE_CURRENT_PATH}" != "${CRON_LOGROTATE_DESIRED_PATH}" ]]; then + mv ${CRON_LOGROTATE_CURRENT_PATH} ${CRON_LOGROTATE_DESIRED_PATH} + CRON_LOGROTATE_CURRENT_SCHEDULE="${KOLLA_LOGROTATE_SCHEDULE}" + fi + fi + + echo "[i] Cron schedule for logrotate is currently set to: ${CRON_LOGROTATE_CURRENT_SCHEDULE}." +fi diff --git a/kolla/docker/cron/logrotate b/kolla/docker/cron/logrotate new file mode 100755 index 000000000..1ac157001 --- /dev/null +++ b/kolla/docker/cron/logrotate @@ -0,0 +1,18 @@ +#!/bin/sh + +# skip in favour of systemd timer +if [ -d /run/systemd/system ]; then + exit 0 +fi + +# this cronjob persists removals (but not purges) +if [ ! -x /usr/sbin/logrotate ]; then + exit 0 +fi + +/usr/sbin/logrotate /etc/logrotate.conf +EXITVALUE=$? +if [ $EXITVALUE != 0 ]; then + /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]" +fi +exit $EXITVALUE diff --git a/kolla/docker/cyborg/cyborg-agent/Dockerfile.j2 b/kolla/docker/cyborg/cyborg-agent/Dockerfile.j2 new file mode 100644 index 000000000..dfc1adc0b --- /dev/null +++ b/kolla/docker/cyborg/cyborg-agent/Dockerfile.j2 @@ -0,0 +1,22 @@ +FROM {{ namespace }}/{{ image_prefix }}cyborg-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cyborg_agent_header %}{% endblock %} +{% import "macros.j2" as macros with context %} + +{% set cyborg_agent_packages = [ + 'pciutils', +] %} + +{{ macros.install_packages(cyborg_agent_packages | customizable("packages")) }} + +{% set cyborg_agent_pip_packages = [ ] %} + +RUN {{ macros.install_pip(cyborg_agent_pip_packages | customizable("pip_packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block cyborg_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/cyborg/cyborg-api/Dockerfile.j2 b/kolla/docker/cyborg/cyborg-api/Dockerfile.j2 new file mode 100644 index 000000000..d67cdeb28 --- /dev/null +++ b/kolla/docker/cyborg/cyborg-api/Dockerfile.j2 @@ -0,0 +1,19 @@ +FROM {{ namespace }}/{{ image_prefix }}cyborg-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cyborg_api_header %}{% endblock %} +{% import "macros.j2" as macros with context %} + +{% set cyborg_api_packages = [ +] %} +{{ macros.install_packages(cyborg_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_cyborg_extend_start +RUN chmod 644 /usr/local/bin/kolla_cyborg_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cyborg_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/cyborg/cyborg-api/extend_start.sh b/kolla/docker/cyborg/cyborg-api/extend_start.sh new file mode 100644 index 000000000..b1c7af7af --- /dev/null +++ b/kolla/docker/cyborg/cyborg-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + cyborg-dbsync upgrade + exit 0 +fi diff --git a/kolla/docker/cyborg/cyborg-base/Dockerfile.j2 b/kolla/docker/cyborg/cyborg-base/Dockerfile.j2 new file mode 100644 index 000000000..c3f3e602a --- /dev/null +++ b/kolla/docker/cyborg/cyborg-base/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cyborg_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='cyborg') }} + +ADD cyborg-base-archive /cyborg-base-source + +{% set cyborg_base_pip_packages = [ + '/cyborg' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY cyborg_sudoers /etc/sudoers.d/kolla_cyborg_sudoers + +RUN ln -s cyborg-base-source/* cyborg \ + && {{ macros.install_pip(cyborg_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/cyborg/ \ + && cp -r /cyborg/etc/cyborg/* /etc/cyborg/ \ + && chmod 750 /etc/sudoers.d \ + && touch /usr/local/bin/kolla_cyborg_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_cyborg_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block cyborg_footer %}{% endblock %} diff --git a/kolla/docker/cyborg/cyborg-base/cyborg_sudoers b/kolla/docker/cyborg/cyborg-base/cyborg_sudoers new file mode 100644 index 000000000..63440026d --- /dev/null +++ b/kolla/docker/cyborg/cyborg-base/cyborg_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown -R cyborg\: /var/lib/cyborg/, /bin/chown -R cyborg\: /var/lib/cyborg/ diff --git a/kolla/docker/cyborg/cyborg-base/extend_start.sh b/kolla/docker/cyborg/cyborg-base/extend_start.sh new file mode 100755 index 000000000..10a58c626 --- /dev/null +++ b/kolla/docker/cyborg/cyborg-base/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Create log dir for Cyborg logs +CYBORG_LOG_DIR="/var/log/kolla/cyborg" +if [[ ! -d "${CYBORG_LOG_DIR}" ]]; then + mkdir -p ${CYBORG_LOG_DIR} +fi +if [[ $(stat -c %U:%G ${CYBORG_LOG_DIR}) != "cyborg:kolla" ]]; then + chown cyborg:kolla ${CYBORG_LOG_DIR} +fi +if [[ $(stat -c %a ${CYBORG_LOG_DIR}) != "755" ]]; then + chmod 755 ${CYBORG_LOG_DIR} +fi + +. /usr/local/bin/kolla_cyborg_extend_start diff --git a/kolla/docker/cyborg/cyborg-conductor/Dockerfile.j2 b/kolla/docker/cyborg/cyborg-conductor/Dockerfile.j2 new file mode 100644 index 000000000..d17d1cacd --- /dev/null +++ b/kolla/docker/cyborg/cyborg-conductor/Dockerfile.j2 @@ -0,0 +1,13 @@ +FROM {{ namespace }}/{{ image_prefix }}cyborg-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block cyborg_conductor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block cyborg_conductor_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/designate/designate-api/Dockerfile.j2 b/kolla/docker/designate/designate-api/Dockerfile.j2 new file mode 100644 index 000000000..6ca9ac180 --- /dev/null +++ b/kolla/docker/designate/designate-api/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block designate_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER designate diff --git a/kolla/docker/designate/designate-backend-bind9/Dockerfile.j2 b/kolla/docker/designate/designate-backend-bind9/Dockerfile.j2 new file mode 100644 index 000000000..cf1277aeb --- /dev/null +++ b/kolla/docker/designate/designate-backend-bind9/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_backend_bind9_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set designate_backend_bind9_packages = ['bind'] %} + +{{ macros.install_packages(designate_backend_bind9_packages | customizable("packages")) }} + +{% elif base_package_type == 'deb' %} + {% set designate_backend_bind9_packages = ['bind9'] %} + +{{ macros.install_packages(designate_backend_bind9_packages | customizable("packages")) }} + +{% endif %} + +{% set designate_backend_bind_name = 'bind' if base_package_type == 'deb' else 'named' %} + +RUN mkdir -p /var/lib/kolla/ /var/lib/{{ designate_backend_bind_name }}/ /run/{{ designate_backend_bind_name }} \ + && chown -R root: /var/lib/{{ designate_backend_bind_name }} /run/{{ designate_backend_bind_name }} \ + && chmod 755 /run/{{ designate_backend_bind_name }} + +{{ macros.kolla_patch_sources() }} + +{% block designate_backend_bind9_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/designate/designate-base/Dockerfile.j2 b/kolla/docker/designate/designate-base/Dockerfile.j2 new file mode 100644 index 000000000..26a0beca1 --- /dev/null +++ b/kolla/docker/designate/designate-base/Dockerfile.j2 @@ -0,0 +1,33 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='designate') }} + +{% set designate_base_pip_packages = [ + '/designate' +] %} + +ADD designate-base-archive /designate-base-source + +COPY designate_sudoers /etc/sudoers.d/kolla_designate_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s designate-base-source/* designate \ + && {{ macros.install_pip(designate_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/designate \ + && cp -r /designate/etc/designate/* /etc/designate/ \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/designate/rootwrap.conf \ + && chmod 750 /etc/sudoers.d \ + && chmod 640 /etc/sudoers.d/kolla_designate_sudoers \ + && touch /usr/local/bin/kolla_designate_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_designate_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block designate_base_footer %}{% endblock %} diff --git a/kolla/docker/designate/designate-base/designate_sudoers b/kolla/docker/designate/designate-base/designate_sudoers new file mode 100644 index 000000000..d06679fe2 --- /dev/null +++ b/kolla/docker/designate/designate-base/designate_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /var/lib/kolla/venv/bin/designate-rootwrap /etc/designate/rootwrap.conf * diff --git a/kolla/docker/designate/designate-base/extend_start.sh b/kolla/docker/designate/designate-base/extend_start.sh new file mode 100644 index 000000000..66b376c30 --- /dev/null +++ b/kolla/docker/designate/designate-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/designate" ]]; then + mkdir -p /var/log/kolla/designate +fi +if [[ $(stat -c %a /var/log/kolla/designate) != "755" ]]; then + chmod 755 /var/log/kolla/designate +fi + +. /usr/local/bin/kolla_designate_extend_start diff --git a/kolla/docker/designate/designate-central/Dockerfile.j2 b/kolla/docker/designate/designate-central/Dockerfile.j2 new file mode 100644 index 000000000..81c3c901f --- /dev/null +++ b/kolla/docker/designate/designate-central/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_central_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_designate_extend_start +RUN chmod 644 /usr/local/bin/kolla_designate_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block designate_central_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER designate diff --git a/kolla/docker/designate/designate-central/extend_start.sh b/kolla/docker/designate/designate-central/extend_start.sh new file mode 100644 index 000000000..8e90f55fc --- /dev/null +++ b/kolla/docker/designate/designate-central/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [[ ! -f "/var/log/kolla/designate/designate-manage.log" ]]; then + touch /var/log/kolla/designate/designate-manage.log + chmod 644 /var/log/kolla/designate/designate-manage.log +fi + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + designate-manage database sync + exit 0 +fi diff --git a/kolla/docker/designate/designate-mdns/Dockerfile.j2 b/kolla/docker/designate/designate-mdns/Dockerfile.j2 new file mode 100644 index 000000000..dd2e6df75 --- /dev/null +++ b/kolla/docker/designate/designate-mdns/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_mdns_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block designate_mdns_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER designate diff --git a/kolla/docker/designate/designate-producer/Dockerfile.j2 b/kolla/docker/designate/designate-producer/Dockerfile.j2 new file mode 100644 index 000000000..bd1ce4e1d --- /dev/null +++ b/kolla/docker/designate/designate-producer/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_producer_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block designate_producer_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER designate diff --git a/kolla/docker/designate/designate-sink/Dockerfile.j2 b/kolla/docker/designate/designate-sink/Dockerfile.j2 new file mode 100644 index 000000000..8b8e50adf --- /dev/null +++ b/kolla/docker/designate/designate-sink/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_sink_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block designate_sink_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER designate diff --git a/kolla/docker/designate/designate-worker/Dockerfile.j2 b/kolla/docker/designate/designate-worker/Dockerfile.j2 new file mode 100644 index 000000000..b4e190df6 --- /dev/null +++ b/kolla/docker/designate/designate-worker/Dockerfile.j2 @@ -0,0 +1,27 @@ +FROM {{ namespace }}/{{ image_prefix }}designate-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block designate_worker_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +# The bind9 package here is only to provide the rndc binary. +{% if base_package_type == 'rpm' %} + {% set designate_worker_packages = [ + 'bind' + ] %} +{% elif base_package_type == 'deb' %} + {% set designate_worker_packages = [ + 'bind9' + ] %} +{% endif %} +{{ macros.install_packages(designate_worker_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block designate_worker_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER designate diff --git a/kolla/docker/dnsmasq/Dockerfile.j2 b/kolla/docker/dnsmasq/Dockerfile.j2 new file mode 100644 index 000000000..882613be7 --- /dev/null +++ b/kolla/docker/dnsmasq/Dockerfile.j2 @@ -0,0 +1,19 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block dnsmasq_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set dnsmasq_packages = ['dnsmasq'] %} +{{ macros.install_packages(dnsmasq_packages| customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{% block dnsmasq_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/dnsmasq/extend_start.sh b/kolla/docker/dnsmasq/extend_start.sh new file mode 100644 index 000000000..0c9734fa1 --- /dev/null +++ b/kolla/docker/dnsmasq/extend_start.sh @@ -0,0 +1,31 @@ +#!/bin/bash + +DNSMASQ_PIDFILE=${DNSMASQ_PIDFILE:-/run/ironic/dnsmasq.pid} +DNSMASQ_PIDFILE_DIR="$(dirname $DNSMASQ_PIDFILE)" + +if [[ ! -d "/var/log/kolla/ironic" ]]; then + mkdir -p /var/log/kolla/ironic +fi +if [[ $(stat -c %a /var/log/kolla/ironic) != "755" ]]; then + chmod 755 /var/log/kolla/ironic +fi +if [[ ! -r "/var/log/kolla/ironic/dnsmasq.log" ]]; then + touch /var/log/kolla/ironic/dnsmasq.log + chown ironic:ironic /var/log/kolla/ironic/dnsmasq.log +fi + +if [[ ! -d "$DNSMASQ_PIDFILE_DIR" ]]; then + mkdir -p "$DNSMASQ_PIDFILE_DIR" +fi + +# NOTE(wszumski): This writes the PID of dnsmasq out to a file. The PIDFILE can be used in +# another container to send a signal to dnsmasq to reload its config (providing that the two +# containers share a PID namespace). The concrete use case is for the Ironic PXE filter to +# clean up stale host entries on startup as documented in: +# +# https://docs.openstack.org/ironic/latest/admin/inspection/pxe_filter.html +# +# We cannot use the pid-file option in dnsmasq, since it will only write the PIDFILE if you +# run dnsmasq in its non-forking mode i.e you do use the --no-daemon or --keep-in-foreground +# options. +echo $$ > "$DNSMASQ_PIDFILE" diff --git a/kolla/docker/etcd/Dockerfile.j2 b/kolla/docker/etcd/Dockerfile.j2 new file mode 100644 index 000000000..aafcd8666 --- /dev/null +++ b/kolla/docker/etcd/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block etcd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='etcd') }} + +{% block etcd_install %} +ADD etcd-archive /etcd-source + +RUN ln -s etcd-source/* etcd \ + && cp /etcd/etcd /etcd/etcdctl /usr/bin +{% endblock %} + +COPY etcd_sudoers /etc/sudoers.d/kolla_etcd_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_etcd_sudoers + +{{ macros.kolla_patch_sources() }} + +{% block etcd_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER etcd diff --git a/kolla/docker/etcd/etcd_sudoers b/kolla/docker/etcd/etcd_sudoers new file mode 100644 index 000000000..d3e244be0 --- /dev/null +++ b/kolla/docker/etcd/etcd_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown etcd\: /var/lib/etcd/, /bin/chown etcd\: /var/lib/etcd/ diff --git a/kolla/docker/etcd/extend_start.sh b/kolla/docker/etcd/extend_start.sh new file mode 100644 index 000000000..c54023299 --- /dev/null +++ b/kolla/docker/etcd/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +# Create log directory, with appropriate permissions +if [[ ! -d "/var/log/kolla/etcd" ]]; then + mkdir -p /var/log/kolla/etcd +fi +if [[ $(stat -c %a /var/log/kolla/etcd) != "755" ]]; then + chmod 755 /var/log/kolla/etcd +fi + +if [[ $(stat -c %U /var/lib/etcd/) != "etcd" ]]; then + sudo chown etcd: /var/lib/etcd/ +fi diff --git a/kolla/docker/fluentd/Dockerfile.j2 b/kolla/docker/fluentd/Dockerfile.j2 new file mode 100644 index 000000000..c63e1b990 --- /dev/null +++ b/kolla/docker/fluentd/Dockerfile.j2 @@ -0,0 +1,62 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} + +{% set fluentd_user = 'fluentd' %} + +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" fluentd_binary="fluentd" fluentd_user="{{ fluentd_user }}" +{% endblock %} + +{% block fluentd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.enable_extra_repos(['fluentd']) }} + +{% if base_package_type == 'rpm' %} + + {% set fluentd_packages = [ + 'gcc-c++', + 'make', + 'fluent-package', + ] %} + +{% elif base_package_type == 'deb' %} + + {% set fluentd_packages = [ + 'g++', + 'make', + 'fluent-package', + ] %} + +{% endif %} + +{{ macros.configure_user(name=fluentd_user, groups='mysql') }} + +COPY fluentd_sudoers /etc/sudoers.d/kolla_fluentd_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +{{ macros.install_packages(fluentd_packages | customizable("packages")) }} \ + && chmod 440 /etc/sudoers.d/kolla_fluentd_sudoers \ + && mkdir -p /etc/{{ fluentd_user }} \ + && mkdir -p /var/run/{{ fluentd_user }} \ + && chown -R {{ fluentd_user }}: /var/run/{{ fluentd_user }} \ + && chmod 644 /usr/local/bin/kolla_extend_start + +{% block fluentd_plugins_install %} + +{% set fluentd_plugins = [ + 'fluent-plugin-grok-parser', + 'fluent-plugin-prometheus', + 'fluent-plugin-rewrite-tag-filter', +] %} + +{{ macros.install_fluent_plugins(fluentd_plugins | customizable("plugins")) }} + +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block fluentd_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER {{ fluentd_user }} diff --git a/kolla/docker/fluentd/extend_start.sh b/kolla/docker/fluentd/extend_start.sh new file mode 100644 index 000000000..6b304b92c --- /dev/null +++ b/kolla/docker/fluentd/extend_start.sh @@ -0,0 +1,20 @@ +#!/bin/bash + +# Give processes executed with the "kolla" group the permission to create files +# and sub-directories in the /var/log/kolla directory. +# +# Also set the setgid permission on the /var/log/kolla directory so that new +# files and sub-directories in that directory inherit its group id ("kolla"). + +if [ ! -d /var/log/kolla ]; then + mkdir -p /var/log/kolla +fi +if [[ $(stat -c %U:%G /var/log/kolla) != "fluentd:kolla" ]]; then + sudo chown fluentd:kolla /var/log/kolla +fi +if [[ $(stat -c %a /var/log/kolla) != "2775" ]]; then + sudo chmod 2775 /var/log/kolla +fi +if [[ (-d /var/lib/fluentd) && ($(stat -c %U:%G /var/lib/fluentd) != "fluentd:kolla") ]]; then + sudo chown fluentd:kolla /var/lib/fluentd +fi diff --git a/kolla/docker/fluentd/fluentd_sudoers b/kolla/docker/fluentd/fluentd_sudoers new file mode 100644 index 000000000..25ca93f5a --- /dev/null +++ b/kolla/docker/fluentd/fluentd_sudoers @@ -0,0 +1,8 @@ +%kolla ALL=(root) NOPASSWD: /bin/chown fluentd\:kolla /var/log/kolla, /usr/bin/chown fluentd\:kolla /var/log/kolla +%kolla ALL=(root) NOPASSWD: /bin/chown td-agent\:kolla /var/log/kolla, /usr/bin/chown td-agent\:kolla /var/log/kolla +%kolla ALL=(root) NOPASSWD: /bin/chown fluentd\:kolla /var/lib/fluentd, /usr/bin/chown fluentd\:kolla /var/lib/fluentd +%kolla ALL=(root) NOPASSWD: /bin/chown td-agent\:kolla /var/lib/td-agent, /usr/bin/chown td-agent\:kolla /var/lib/td-agent +%kolla ALL=(root) NOPASSWD: /bin/chown fluentd\:kolla /var/lib/td-agent, /usr/bin/chown fluentd\:kolla /var/lib/td-agent +%kolla ALL=(root) NOPASSWD: /bin/chmod 2775 /var/log/kolla, /usr/bin/chmod 2775 /var/log/kolla +%kolla ALL=(root) NOPASSWD: /bin/chmod 2775 /var/lib/fluentd, /usr/bin/chmod 2775 /var/lib/fluentd +%kolla ALL=(root) NOPASSWD: /bin/chmod 2775 /var/lib/td-agent, /usr/bin/chmod 2775 /var/lib/td-agent diff --git a/kolla/docker/glance/glance-api/Dockerfile.j2 b/kolla/docker/glance/glance-api/Dockerfile.j2 new file mode 100644 index 000000000..e3efbfef3 --- /dev/null +++ b/kolla/docker/glance/glance-api/Dockerfile.j2 @@ -0,0 +1,38 @@ +FROM {{ namespace }}/{{ image_prefix }}glance-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block glance_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set glance_api_packages = [ + 'lsscsi', + 'device-mapper-multipath', + 'nvme-cli', + 'qemu-img', + 'systemd-udev' + ] %} +{% elif base_package_type == 'deb' %} + {% set glance_api_packages = [ + 'lsscsi', + 'multipath-tools', + 'nfs-common', + 'nvme-cli', + 'qemu-utils' + ] %} +{% endif %} + +{{ macros.install_packages(glance_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_glance_extend_start +RUN chmod 644 /usr/local/bin/kolla_glance_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block glance_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER glance diff --git a/kolla/docker/glance/glance-api/extend_start.sh b/kolla/docker/glance/glance-api/extend_start.sh new file mode 100644 index 000000000..3363539a5 --- /dev/null +++ b/kolla/docker/glance/glance-api/extend_start.sh @@ -0,0 +1,27 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + glance-manage db_sync + glance-manage db_load_metadefs + exit 0 +fi + +# Migrate database and exit if KOLLA_UPGRADE variable is set. This catches all cases +# of the KOLLA_UPGRADE variable being set, including empty. +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + if [[ "${!GLANCE_DB_EXPAND[@]}" ]]; then + echo "Expanding database" + glance-manage db expand + fi + if [[ "${!GLANCE_DB_MIGRATE[@]}" ]]; then + echo "Migrating database" + glance-manage db migrate + fi + if [[ "${!GLANCE_DB_CONTRACT[@]}" ]]; then + echo "Contracting database" + glance-manage db contract + fi + exit 0 +fi diff --git a/kolla/docker/glance/glance-base/Dockerfile.j2 b/kolla/docker/glance/glance-base/Dockerfile.j2 new file mode 100644 index 000000000..885cc4353 --- /dev/null +++ b/kolla/docker/glance/glance-base/Dockerfile.j2 @@ -0,0 +1,54 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block glance_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='glance') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['ceph', 'epel']) }} + + {% set glance_base_packages = [ + 'python3-rados', + 'python3-rbd' + ] %} +{% elif base_package_type == 'deb' %} + {% set glance_base_packages = [ + 'python3-rados', + 'python3-rbd' + ] %} +{% endif %} + +{{ macros.install_packages(glance_base_packages | customizable("packages")) }} + +ADD glance-base-archive /glance-base-source + +{% set glance_base_pip_packages = [ + '/glance', + 'glance_store[cinder,vmware,swift,s3]' +] %} + +# add missing rootwrap config present in glance_store repo +COPY etc/glance /etc/glance +COPY glance_sudoers /etc/sudoers.d/kolla_glance_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s glance-base-source/* glance \ + && {{ macros.install_pip(glance_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/glance \ + && cp -r /glance/etc/* /etc/glance/ \ + && cp /var/lib/kolla/venv/etc/pycadf/glance_api_audit_map.conf /etc/glance/ \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/glance/rootwrap.conf \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_glance_sudoers \ + && touch /usr/local/bin/kolla_glance_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_glance_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block glance_base_footer %}{% endblock %} diff --git a/kolla/docker/glance/glance-base/etc/glance/rootwrap.conf b/kolla/docker/glance/glance-base/etc/glance/rootwrap.conf new file mode 100644 index 000000000..56e7529af --- /dev/null +++ b/kolla/docker/glance/glance-base/etc/glance/rootwrap.conf @@ -0,0 +1,27 @@ +# Configuration for glance-rootwrap +# This file should be owned by (and only-writable by) the root user + +[DEFAULT] +# List of directories to load filter definitions from (separated by ','). +# These directories MUST all be only writeable by root ! +filters_path=/etc/glance/rootwrap.d,/usr/share/glance/rootwrap + +# List of directories to search executables in, in case filters do not +# explicitly specify a full path (separated by ',') +# If not specified, defaults to system PATH environment variable. +# These directories MUST all be only writeable by root ! +exec_dirs=/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin + +# Enable logging to syslog +# Default value is False +use_syslog=False + +# Which syslog facility to use. +# Valid values include auth, authpriv, syslog, local0, local1... +# Default value is 'syslog' +syslog_log_facility=syslog + +# Which messages to log. +# INFO means log all usage +# ERROR means only log unsuccessful attempts +syslog_log_level=ERROR diff --git a/kolla/docker/glance/glance-base/etc/glance/rootwrap.d/glance_cinder_store.filters b/kolla/docker/glance/glance-base/etc/glance/rootwrap.d/glance_cinder_store.filters new file mode 100644 index 000000000..46c389b7e --- /dev/null +++ b/kolla/docker/glance/glance-base/etc/glance/rootwrap.d/glance_cinder_store.filters @@ -0,0 +1,12 @@ +# glance-rootwrap command filters for glance cinder store +# This file should be owned by (and only-writable by) the root user + +[Filters] +# cinder store driver +disk_chown: RegExpFilter, chown, root, chown, \d+, /dev/(?!.*/\.\.).* + +# os-brick library commands +# os_brick.privileged.run_as_root oslo.privsep context +# This line ties the superuser privs with the config files, context name, +# and (implicitly) the actual python code invoked. +privsep-rootwrap: RegExpFilter, privsep-helper, root, privsep-helper, --config-file, /etc/(?!\.\.).*, --privsep_context, os_brick.privileged.default, --privsep_sock_path, /tmp/.* diff --git a/kolla/docker/glance/glance-base/extend_start.sh b/kolla/docker/glance/glance-base/extend_start.sh new file mode 100644 index 000000000..4f5f5ecaf --- /dev/null +++ b/kolla/docker/glance/glance-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/glance" ]]; then + mkdir -p /var/log/kolla/glance +fi +if [[ $(stat -c %a /var/log/kolla/glance) != "755" ]]; then + chmod 755 /var/log/kolla/glance +fi + +. /usr/local/bin/kolla_glance_extend_start diff --git a/kolla/docker/glance/glance-base/glance_sudoers b/kolla/docker/glance/glance-base/glance_sudoers new file mode 100644 index 000000000..9af870983 --- /dev/null +++ b/kolla/docker/glance/glance-base/glance_sudoers @@ -0,0 +1 @@ +glance ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/glance-rootwrap /etc/glance/rootwrap.conf * diff --git a/kolla/docker/gnocchi/gnocchi-api/Dockerfile.j2 b/kolla/docker/gnocchi/gnocchi-api/Dockerfile.j2 new file mode 100644 index 000000000..c0cc2cc33 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-api/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}gnocchi-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block gnocchi_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_gnocchi_extend_start +RUN chmod 644 /usr/local/bin/kolla_gnocchi_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block gnocchi_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/gnocchi/gnocchi-api/extend_start.sh b/kolla/docker/gnocchi/gnocchi-api/extend_start.sh new file mode 100644 index 000000000..dda0461c6 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + sudo -H -u gnocchi gnocchi-upgrade --log-file /var/log/kolla/gnocchi/gnocchi-upgrade.log + exit 0 +fi diff --git a/kolla/docker/gnocchi/gnocchi-base/Dockerfile.j2 b/kolla/docker/gnocchi/gnocchi-base/Dockerfile.j2 new file mode 100644 index 000000000..91199ac39 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-base/Dockerfile.j2 @@ -0,0 +1,56 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block gnocchi_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='gnocchi') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['ceph', 'epel']) }} + + {% set gnocchi_base_packages = [ + 'librados2-devel', + 'python3-rados', + ] %} + +{% elif base_package_type == 'deb' %} + + {% set gnocchi_base_packages = [ + 'librados-dev', + 'python3-rados', + ] %} + + +{% endif %} + +{{ macros.install_packages(gnocchi_base_packages | customizable("packages")) }} + +ADD gnocchi-base-archive /gnocchi-base-source + +{% set gnocchi_base_pip_packages = [ + 'gnocchiclient', + '/gnocchi[keystone,mysql,file,ceph,s3]' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY gnocchi_sudoers /etc/sudoers.d/kolla_gnocchi_sudoers + +RUN {{ macros.upper_constraints_version_change("Werkzeug", "3.0.1", "2.2.3") }} + +RUN ln -s gnocchi-base-source/* gnocchi \ + && {{ macros.install_pip(gnocchi_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/gnocchi \ + && cp /var/lib/kolla/venv/etc/pycadf/gnocchi_api_audit_map.conf /etc/gnocchi/ \ + && chmod 750 /etc/sudoers.d \ + && chmod 640 /etc/sudoers.d/kolla_gnocchi_sudoers \ + && touch /usr/local/bin/kolla_gnocchi_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_gnocchi_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block gnocchi_base_footer %}{% endblock %} diff --git a/kolla/docker/gnocchi/gnocchi-base/extend_start.sh b/kolla/docker/gnocchi/gnocchi-base/extend_start.sh new file mode 100644 index 000000000..adc05b1b3 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-base/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +# Create log dir for Gnocchi logs +GNOCCHI_LOG_DIR="/var/log/kolla/gnocchi" +if [[ ! -d "${GNOCCHI_LOG_DIR}" ]]; then + mkdir -p ${GNOCCHI_LOG_DIR} +fi +if [[ $(stat -c %U:%G ${GNOCCHI_LOG_DIR}) != "gnocchi:kolla" ]]; then + chown gnocchi:kolla ${GNOCCHI_LOG_DIR} +fi +if [[ $(stat -c %a ${GNOCCHI_LOG_DIR}) != "755" ]]; then + chmod 755 ${GNOCCHI_LOG_DIR} +fi + +. /usr/local/bin/kolla_gnocchi_extend_start diff --git a/kolla/docker/gnocchi/gnocchi-base/gnocchi_sudoers b/kolla/docker/gnocchi/gnocchi-base/gnocchi_sudoers new file mode 100644 index 000000000..c2a01d709 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-base/gnocchi_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown -R gnocchi\: /var/lib/gnocchi/, /bin/chown -R gnocchi\: /var/lib/gnocchi/ diff --git a/kolla/docker/gnocchi/gnocchi-metricd/Dockerfile.j2 b/kolla/docker/gnocchi/gnocchi-metricd/Dockerfile.j2 new file mode 100644 index 000000000..fe9978fa2 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-metricd/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}gnocchi-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block gnocchi_metricd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block gnocchi_metricd_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER gnocchi diff --git a/kolla/docker/gnocchi/gnocchi-statsd/Dockerfile.j2 b/kolla/docker/gnocchi/gnocchi-statsd/Dockerfile.j2 new file mode 100644 index 000000000..8f1574946 --- /dev/null +++ b/kolla/docker/gnocchi/gnocchi-statsd/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}gnocchi-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block gnocchi_statsd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block gnocchi_statsd_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER gnocchi diff --git a/kolla/docker/grafana/Dockerfile.j2 b/kolla/docker/grafana/Dockerfile.j2 new file mode 100644 index 000000000..e401d91b6 --- /dev/null +++ b/kolla/docker/grafana/Dockerfile.j2 @@ -0,0 +1,42 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block grafana_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.enable_extra_repos(['grafana']) }} + +{% set grafana_packages = ['grafana'] %} + +{{ macros.configure_user(name='grafana', homedir='/usr/share/grafana') }} + +{{ macros.install_packages(grafana_packages | customizable("packages")) }} + +WORKDIR /usr/share/grafana + +COPY grafana_sudoers /etc/sudoers.d/kolla_grafana_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +{% block grafana_plugins_install %} + +{% set grafana_default_plugins = ['grafana-opensearch-datasource'] %} +{% set grafana_plugins = grafana_default_plugins | customizable("plugins") %} + +{% if grafana_plugins | length > 0 %} +RUN {{ (['grafana-cli plugins install %s'] * grafana_plugins | length ) | join(' && ') | format(*grafana_plugins) }} +{% endif %} +{% endblock %} + +RUN chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_grafana_sudoers \ + && chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block grafana_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER grafana diff --git a/kolla/docker/grafana/extend_start.sh b/kolla/docker/grafana/extend_start.sh new file mode 100644 index 000000000..5ed4dc56d --- /dev/null +++ b/kolla/docker/grafana/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/grafana" ]]; then + mkdir -p /var/log/kolla/grafana +fi +if [[ $(stat -c %a /var/log/kolla/grafana) != "755" ]]; then + chmod 755 /var/log/kolla/grafana +fi diff --git a/kolla/docker/grafana/grafana_sudoers b/kolla/docker/grafana/grafana_sudoers new file mode 100644 index 000000000..386829969 --- /dev/null +++ b/kolla/docker/grafana/grafana_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/bin/chown -R grafana\: /var/lib/grafana/, /bin/chown -R grafana\: /var/lib/grafana/ diff --git a/kolla/docker/hacluster/hacluster-base/Dockerfile.j2 b/kolla/docker/hacluster/hacluster-base/Dockerfile.j2 new file mode 100644 index 000000000..045f21e1e --- /dev/null +++ b/kolla/docker/hacluster/hacluster-base/Dockerfile.j2 @@ -0,0 +1,22 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block hacluster_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type =='rpm' %} + +{{ macros.enable_extra_repos(['hacluster']) }} + +{% endif %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block hacluster_base_footer %}{% endblock %} diff --git a/kolla/docker/hacluster/hacluster-base/extend_start.sh b/kolla/docker/hacluster/hacluster-base/extend_start.sh new file mode 100644 index 000000000..c0e9301d0 --- /dev/null +++ b/kolla/docker/hacluster/hacluster-base/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/hacluster" ]]; then + mkdir -p /var/log/kolla/hacluster +fi +if [[ $(stat -c %a /var/log/kolla/hacluster) != "755" ]]; then + chmod 755 /var/log/kolla/hacluster +fi diff --git a/kolla/docker/hacluster/hacluster-corosync/Dockerfile.j2 b/kolla/docker/hacluster/hacluster-corosync/Dockerfile.j2 new file mode 100644 index 000000000..74d47c380 --- /dev/null +++ b/kolla/docker/hacluster/hacluster-corosync/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}hacluster-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block hacluster_corosync_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set hacluster_corosync_packages = ['corosync'] %} +{{ macros.install_packages(hacluster_corosync_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block hacluster_corosync_footer %}{% endblock %} diff --git a/kolla/docker/hacluster/hacluster-pacemaker-remote/Dockerfile.j2 b/kolla/docker/hacluster/hacluster-pacemaker-remote/Dockerfile.j2 new file mode 100644 index 000000000..64c381e1f --- /dev/null +++ b/kolla/docker/hacluster/hacluster-pacemaker-remote/Dockerfile.j2 @@ -0,0 +1,21 @@ +FROM {{ namespace }}/{{ image_prefix }}hacluster-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block hacluster_pacemaker_remote_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set hacluster_pacemaker_remote_packages = ['pacemaker-remote'] %} +{% if base_package_type == 'deb' %} + {% set hacluster_pacemaker_remote_packages = hacluster_pacemaker_remote_packages + [ + 'pacemaker-cli-utils' + ] %} +{% endif %} + +{{ macros.install_packages(hacluster_pacemaker_remote_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block hacluster_pacemaker_remote_footer %}{% endblock %} diff --git a/kolla/docker/hacluster/hacluster-pacemaker/Dockerfile.j2 b/kolla/docker/hacluster/hacluster-pacemaker/Dockerfile.j2 new file mode 100644 index 000000000..33eeb3144 --- /dev/null +++ b/kolla/docker/hacluster/hacluster-pacemaker/Dockerfile.j2 @@ -0,0 +1,21 @@ +FROM {{ namespace }}/{{ image_prefix }}hacluster-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block hacluster_pacemaker_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set hacluster_pacemaker_packages = ['pacemaker'] %} +{% if base_package_type == 'deb' %} + {% set hacluster_pacemaker_packages = hacluster_pacemaker_packages + [ + 'pacemaker-cli-utils' + ] %} +{% endif %} + +{{ macros.install_packages(hacluster_pacemaker_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block hacluster_pacemaker_footer %}{% endblock %} diff --git a/kolla/docker/hacluster/hacluster-pcs/Dockerfile.j2 b/kolla/docker/hacluster/hacluster-pcs/Dockerfile.j2 new file mode 100644 index 000000000..a146d0d4b --- /dev/null +++ b/kolla/docker/hacluster/hacluster-pcs/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}hacluster-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block hacluster_pcs_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set hacluster_pcs_packages = ['pcs','crmsh'] %} +{{ macros.install_packages(hacluster_pcs_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block hacluster_pcs_footer %}{% endblock %} diff --git a/kolla/docker/haproxy/haproxy-ssh/Dockerfile.j2 b/kolla/docker/haproxy/haproxy-ssh/Dockerfile.j2 new file mode 100644 index 000000000..a674cc75e --- /dev/null +++ b/kolla/docker/haproxy/haproxy-ssh/Dockerfile.j2 @@ -0,0 +1,42 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block haproxy_ssh_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='haproxy', shell='/bin/bash') }} + +{% if base_package_type == 'rpm' %} + {% set haproxy_ssh_packages = [ + 'openssh-server', + 'openssh-clients', + 'rsync', + ] %} + +{% elif base_package_type == 'deb' %} + {% set haproxy_ssh_packages = [ + 'openssh-server', + 'openssh-client', + 'rsync', + ] %} + +RUN mkdir -p /var/run/sshd \ + && chmod 0755 /var/run/sshd + +{% endif %} + +{{ macros.install_packages(haproxy_ssh_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && sed -ri 's/session(\s+)required(\s+)pam_loginuid.so/session\1optional\2pam_loginuid.so/' /etc/pam.d/sshd + +COPY update-loadbalancer-cert.sh /usr/bin/update-loadbalancer-cert + +{{ macros.kolla_patch_sources() }} + +{% block haproxy_ssh_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/haproxy/haproxy-ssh/extend_start.sh b/kolla/docker/haproxy/haproxy-ssh/extend_start.sh new file mode 100644 index 000000000..4b2239100 --- /dev/null +++ b/kolla/docker/haproxy/haproxy-ssh/extend_start.sh @@ -0,0 +1,37 @@ +#!/bin/bash + +SSH_HOST_KEY_TYPES=( "rsa" "ecdsa" "ed25519" ) + +for key_type in ${SSH_HOST_KEY_TYPES[@]}; do + KEY_PATH=/etc/ssh/ssh_host_${key_type}_key + if [[ ! -f "${KEY_PATH}" ]]; then + ssh-keygen -q -t ${key_type} -f ${KEY_PATH} -N "" + fi +done + +mkdir -p /var/lib/haproxy/.ssh + +if [[ $(stat -c %U:%G /var/lib/haproxy/.ssh) != "haproxy:haproxy" ]]; then + chown haproxy: /var/lib/haproxy/.ssh +fi + +FOLDERS_LEGO="/etc/letsencrypt /etc/letsencrypt/backups" +USERGROUP="haproxy:haproxy" + +for folder in ${FOLDERS_LEGO}; do + mkdir -p ${folder} + + if [[ $(stat -c %U:%G ${folder}) != "${USERGROUP}" ]]; then + chown ${USERGROUP} ${folder} + fi + + if [[ "${folder}" == "/etc/letsencrypt" ]]; then + if [[ $(stat -c %a ${folder}) != "751" ]]; then + chmod 751 ${folder} + fi + else + if [[ $(stat -c %a ${folder}) != "755" ]]; then + chmod 755 ${folder} + fi + fi +done diff --git a/kolla/docker/haproxy/haproxy-ssh/update-loadbalancer-cert.sh b/kolla/docker/haproxy/haproxy-ssh/update-loadbalancer-cert.sh new file mode 100755 index 000000000..7e4122c65 --- /dev/null +++ b/kolla/docker/haproxy/haproxy-ssh/update-loadbalancer-cert.sh @@ -0,0 +1,125 @@ +#!/bin/bash + +function log_info { + local message="${1}" + + echo "$(date '+%Y/%m/%d %H:%M:%S') [INFO] ${message}" +} + +function log_error { + local message="${1}" + + echo "$(date '+%Y/%m/%d %H:%M:%S') [ERROR] ${message}" +} + +function haproxy_transaction_start { + local cert_input=${1} + local cert_dest=${2} + + local transaction_result="" + local transaction_grep_check="" + + transaction_grep_check="Transaction (created|updated) for certificate $(echo $cert_dest | sed -e 's|/|\\/|g')!" + transaction_result=$(echo -e "set ssl cert ${cert_dest} <<\n$(cat ${cert_input})\n" | socat unix-connect:/var/lib/kolla/haproxy/haproxy.sock -) + if echo "${transaction_result}" | grep -Pq "${transaction_grep_check}"; then + log_info "[${cert_dest} - update] Transaction ${cert_input} -> ${cert_dest} started." + else + log_error "[${cert_dest} - update] Transaction ${cert_input} -> ${cert_dest} failed, please check if haproxy admin socket is running and ${cert_input} is not corrupted." + exit 1 + fi + + local cert_input_sha1="" + local cert_dest_sha1="" + + cert_input_sha1=$(openssl x509 -noout -fingerprint -sha1 -inform pem -in ${cert_input} | awk -F '=' '{print $2}' | sed -e 's/://g') + cert_dest_sha1=$(echo "show ssl cert *${cert_dest}" | socat unix-connect:/var/lib/kolla/haproxy/haproxy.sock - | awk -F 'SHA1 FingerPrint: ' '{print $2}' | sed '/^$/d') + if [ "${cert_input_sha1}" = "${cert_dest_sha1}" ]; then + log_info "[${cert_dest} - update] Transaction ${cert_input} -> ${cert_dest} successful." + else + log_error "[${cert_dest} - update] Transaction ${cert_input} -> ${cert_dest} failed, SHA1 fingerprint of ${cert_input} is not the same as uploaded one." + exit 1 + fi +} + +function haproxy_upload_to_memory { + local cert_input=${1} + local cert_dest=${2} + + local cert_upload_output="" + + cert_upload_output=$(echo "commit ssl cert ${cert_dest}" | socat unix-connect:/var/lib/kolla/haproxy/haproxy.sock -) + if echo "${cert_upload_output}" | grep -q "Success!"; then + log_info "[${cert_dest} - update] Certificate ${cert_input} uploaded to haproxy memory." + else + log_error "[${cert_dest} - update] Certificate ${cert_input} upload to haproxy memory failed, please check if haproxy admin socket is running and ${cert_input} is not corrupted." + exit 1 + fi +} + +function haproxy_write_to_disk { + local cert_input=${1} + local cert_haproxy_path=${2} + + local cert_backup_suffix="" + local cert_backup_path="" + local cert_backup_name="" + + cert_backup_suffix="-$(date +%Y-%m-%d-%H-%M-%S).pem" + cert_backup_path=$(echo "${cert_input}" | awk -v suffix="$cert_backup_suffix" -F '.pem' '{print $1suffix}') + cert_backup_name=$(echo ${cert_backup_path} | awk -F '/' '{print $NF}') + mkdir -p /etc/letsencrypt/backups + log_info "[${cert_haproxy_path} - update] Backuping currently loaded ${cert_haproxy_path} -> /etc/letsencrypt/backups/${cert_backup_name}" + cp -a ${cert_haproxy_path} /etc/letsencrypt/backups/${cert_backup_name} + cp -a ${cert_input} ${cert_haproxy_path} + rm -f ${cert_input} +} + + +# Parser + +INTERNAL_SET="false" +EXTERNAL_SET="false" + +VALID_ARGS=$(getopt -o ie --long internal,external -- "$@") +if [[ $? -ne 0 ]]; then + exit 1; +fi + +eval set -- "$VALID_ARGS" +while [ : ]; do + case "$1" in + -i | --internal) + CERT_TYPE="internal" + INTERNAL_SET="true" + shift + ;; + -e | --external) + CERT_TYPE="external" + EXTERNAL_SET="true" + shift + ;; + --) shift; + break + ;; + esac +done + +if [ "${INTERNAL_SET}" = "true" ] || [ "${EXTERNAL_SET}" = "true" ]; then + if [ "${INTERNAL_SET}" = "${EXTERNAL_SET}" ]; then + echo "[e] Only --internal or --external parameter is allowed at a time" + exit 1 + fi + if [ "${INTERNAL_SET}" = "true" ]; then + HAPROXY_CERT_INCOMING_PATH="/var/lib/haproxy/haproxy-internal.pem" + HAPROXY_CERT_PATH="/etc/haproxy/certificates/haproxy-internal.pem" + else + HAPROXY_CERT_INCOMING_PATH="/var/lib/haproxy/haproxy.pem" + HAPROXY_CERT_PATH="/etc/haproxy/certificates/haproxy.pem" + fi +fi + +# Main + +haproxy_transaction_start ${HAPROXY_CERT_INCOMING_PATH} ${HAPROXY_CERT_PATH} +haproxy_upload_to_memory ${HAPROXY_CERT_INCOMING_PATH} ${HAPROXY_CERT_PATH} +haproxy_write_to_disk ${HAPROXY_CERT_INCOMING_PATH} ${HAPROXY_CERT_PATH} diff --git a/kolla/docker/haproxy/haproxy/Dockerfile.j2 b/kolla/docker/haproxy/haproxy/Dockerfile.j2 new file mode 100644 index 000000000..36c7ca943 --- /dev/null +++ b/kolla/docker/haproxy/haproxy/Dockerfile.j2 @@ -0,0 +1,26 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block haproxy_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='haproxy') }} + +{% set haproxy_packages = [ + 'haproxy' +] %} +{{ macros.install_packages(haproxy_packages | customizable("packages")) }} + +COPY ensure_latest_config.sh /usr/local/bin/kolla_ensure_haproxy_latest_config + +RUN mkdir -p /var/lib/kolla/haproxy \ + && chown -R haproxy: /var/lib /run \ + && chmod 755 /usr/local/bin/kolla_ensure_haproxy_latest_config + +{{ macros.kolla_patch_sources() }} + +{% block haproxy_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/haproxy/haproxy/ensure_latest_config.sh b/kolla/docker/haproxy/haproxy/ensure_latest_config.sh new file mode 100644 index 000000000..4b84f3aed --- /dev/null +++ b/kolla/docker/haproxy/haproxy/ensure_latest_config.sh @@ -0,0 +1,14 @@ +#!/bin/bash + +set -o errexit + +CURRENT_CONFIG_HASH=$(sha1sum /etc/haproxy/haproxy.cfg | cut -f1 -d' ') +NEW_CONFIG_HASH=$(sha1sum /var/lib/kolla/config_files/haproxy.cfg | cut -f1 -d' ') + +if [[ $CURRENT_CONFIG_HASH != $NEW_CONFIG_HASH ]]; then + changed=changed + python /usr/local/bin/kolla_set_configs + kill -USR2 $(pgrep -f /usr/sbin/haproxy-systemd-wrapper) +fi + +echo $changed diff --git a/kolla/docker/heat/heat-api-cfn/Dockerfile.j2 b/kolla/docker/heat/heat-api-cfn/Dockerfile.j2 new file mode 100644 index 000000000..db3030c8d --- /dev/null +++ b/kolla/docker/heat/heat-api-cfn/Dockerfile.j2 @@ -0,0 +1,13 @@ +FROM {{ namespace }}/{{ image_prefix }}heat-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block heat_api_cfn_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block heat_api_cfn_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/heat/heat-api/Dockerfile.j2 b/kolla/docker/heat/heat-api/Dockerfile.j2 new file mode 100644 index 000000000..af2471279 --- /dev/null +++ b/kolla/docker/heat/heat-api/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}heat-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block heat_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_heat_extend_start +RUN chmod 644 /usr/local/bin/kolla_heat_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block heat_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/heat/heat-api/extend_start.sh b/kolla/docker/heat/heat-api/extend_start.sh new file mode 100644 index 000000000..ddf4f81f4 --- /dev/null +++ b/kolla/docker/heat/heat-api/extend_start.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + heat-manage db_sync + + EXISTING_DOMAINS=$(openstack domain list -f value -c Name) + + if ! echo "$EXISTING_DOMAINS" | grep '^heat_user_domain$' &>/dev/null; then + openstack domain create heat_user_domain + openstack user create --domain heat_user_domain heat_domain_admin --password ${HEAT_DOMAIN_ADMIN_PASSWORD} + openstack role add --domain heat_user_domain --user-domain heat_user_domain --user heat_domain_admin admin + fi + + exit 0 +fi diff --git a/kolla/docker/heat/heat-base/Dockerfile.j2 b/kolla/docker/heat/heat-base/Dockerfile.j2 new file mode 100644 index 000000000..a06ea6f0d --- /dev/null +++ b/kolla/docker/heat/heat-base/Dockerfile.j2 @@ -0,0 +1,41 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block heat_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='heat') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + +{% endif %} + +{% set heat_base_packages = [ +] %} + +{{ macros.install_packages(heat_base_packages | customizable("packages")) }} + +ADD heat-base-archive /heat-base-source + +{% set heat_base_pip_packages = [ + '/heat' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s heat-base-source/* heat \ + && {{ macros.install_pip(heat_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/heat \ + && cp -r /heat/etc/heat/* /etc/heat/ \ + && cp /var/lib/kolla/venv/etc/pycadf/heat_api_audit_map.conf /etc/heat/ \ + && touch /usr/local/bin/kolla_heat_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_heat_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block heat_base_footer %}{% endblock %} diff --git a/kolla/docker/heat/heat-base/extend_start.sh b/kolla/docker/heat/heat-base/extend_start.sh new file mode 100644 index 000000000..1c1e86b8e --- /dev/null +++ b/kolla/docker/heat/heat-base/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/heat" ]]; then + mkdir -p /var/log/kolla/heat +fi +if [[ $(stat -c %U:%G /var/log/kolla/heat) != "heat:kolla" ]]; then + chown -R heat:kolla /var/log/kolla/heat +fi +if [[ $(stat -c %a /var/log/kolla/heat) != "755" ]]; then + chmod 755 /var/log/kolla/heat +fi + +. /usr/local/bin/kolla_heat_extend_start diff --git a/kolla/docker/heat/heat-engine/Dockerfile.j2 b/kolla/docker/heat/heat-engine/Dockerfile.j2 new file mode 100644 index 000000000..86c943582 --- /dev/null +++ b/kolla/docker/heat/heat-engine/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}heat-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block heat_engine_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block heat_engine_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER heat diff --git a/kolla/docker/horizon/Dockerfile.j2 b/kolla/docker/horizon/Dockerfile.j2 new file mode 100644 index 000000000..73dc65dd1 --- /dev/null +++ b/kolla/docker/horizon/Dockerfile.j2 @@ -0,0 +1,74 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block horizon_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='horizon') }} + +{% if base_package_type == 'rpm' %} + + {% set horizon_packages = [ + 'gettext' + ] %} + +{{ macros.install_packages(horizon_packages | customizable("packages")) }} +{% elif base_package_type == 'deb' %} + + {% set horizon_packages = [ + 'gettext', + 'locales', + 'tzdata' + ] %} + +{{ macros.install_packages(horizon_packages | customizable("packages")) }} + +{% endif %} + +ADD horizon-archive /horizon-source +ADD plugins-archive / + +{% set horizon_pip_packages = [ + '/horizon', + 'django_redis' +] %} + +{% set horizon_plugins_pip_packages = [ + '/plugins/*' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +# NOTE(hrw): to install horizon from unpacked sources we cannot have it in upper-constraints.txt +# NOTE(kevko): This dance with local settings python paths below is needed +# because we are using different distros with different python version and we need to +# know to which path symlink should point to. +RUN ln -s horizon-source/* horizon \ + && {{ macros.upper_constraints_remove("horizon") }} \ + && {{ macros.install_pip(horizon_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/openstack-dashboard \ + && cp -r /horizon/openstack_dashboard/conf/* /etc/openstack-dashboard/ \ + && cp /horizon/openstack_dashboard/local/local_settings.py.example /etc/openstack-dashboard/local_settings.py \ + && local_settings=$(python -c 'import os;import openstack_dashboard;settings=os.path.dirname(openstack_dashboard.__file__) + "/local/local_settings.py";print(settings);') \ + && rm -f $local_settings \ + && ln -s /etc/openstack-dashboard/local_settings.py $local_settings \ + && mkdir -p /etc/openstack-dashboard/local_settings.d \ + && local_settings_d=$(python -c 'import os;import openstack_dashboard;settings_d=os.path.dirname(openstack_dashboard.__file__) + "/local/local_settings.d";print(settings_d);') \ + && rm -rf $local_settings_d \ + && ln -s /etc/openstack-dashboard/local_settings.d $local_settings_d \ + && cp /horizon/manage.py /var/lib/kolla/venv/bin/manage.py \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(horizon_plugins_pip_packages) }}; \ + fi \ + && for locale in /var/lib/kolla/venv/lib/python3/site-packages/*/locale; do \ + (cd ${locale%/*} && /var/lib/kolla/venv/bin/django-admin compilemessages) \ + done \ + && chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block horizon_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/horizon/extend_start.sh b/kolla/docker/horizon/extend_start.sh new file mode 100644 index 000000000..d1198adb4 --- /dev/null +++ b/kolla/docker/horizon/extend_start.sh @@ -0,0 +1,248 @@ +#!/bin/bash + +set -o errexit + +FORCE_GENERATE="${FORCE_GENERATE:-no}" +HASH_PATH=/var/lib/kolla/.settings.md5sum.txt + +SITE_PACKAGES="/var/lib/kolla/venv/lib/python3/site-packages" + +MANAGE_PY="/var/lib/kolla/venv/bin/python /var/lib/kolla/venv/bin/manage.py" + +if [[ ! -f ${SITE_PACKAGES}/openstack_dashboard/local/local_settings.py ]]; then + ln -s /etc/openstack-dashboard/local_settings \ + ${SITE_PACKAGES}/openstack_dashboard/local/local_settings.py +fi + +if [[ -f /etc/openstack-dashboard/custom_local_settings ]]; then + CUSTOM_SETTINGS_FILE="${SITE_PACKAGES}/openstack_dashboard/local/custom_local_settings.py" + + if [[ ! -L ${CUSTOM_SETTINGS_FILE} ]]; then + ln -s /etc/openstack-dashboard/custom_local_settings ${CUSTOM_SETTINGS_FILE} + fi +fi + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + $MANAGE_PY migrate --noinput + exit 0 +fi + +function config_dashboard { + ENABLE=$1 + SRC=$2 + DEST=$3 + if [[ ! -f ${SRC} ]]; then + echo "WARNING: ${SRC} is required" + elif [[ "${ENABLE}" == "yes" ]] && [[ ! -f "${DEST}" ]]; then + cp -a "${SRC}" "${DEST}" + FORCE_GENERATE="yes" + elif [[ "${ENABLE}" != "yes" ]] && [[ -f "${DEST}" ]]; then + # remove pyc pyo files too + rm -f "${DEST}" "${DEST}c" "${DEST}o" + FORCE_GENERATE="yes" + fi +} + +function config_blazar_dashboard { + for file in ${SITE_PACKAGES}/blazar_dashboard/enabled/_*[^__].py; do + config_dashboard "${ENABLE_BLAZAR:-no}" \ + "${SITE_PACKAGES}/blazar_dashboard/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_cloudkitty_dashboard { + for file in ${SITE_PACKAGES}/cloudkittydashboard/enabled/_*[^__].py; do + config_dashboard "${ENABLE_CLOUDKITTY:-no}" \ + "${SITE_PACKAGES}/cloudkittydashboard/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_designate_dashboard { + for file in ${SITE_PACKAGES}/designatedashboard/enabled/_*[^__].py; do + config_dashboard "${ENABLE_DESIGNATE:-no}" \ + "${SITE_PACKAGES}/designatedashboard/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_fwaas_dashboard { + for file in ${SITE_PACKAGES}/neutron_fwaas_dashboard/enabled/_*[^__].py; do + config_dashboard "${ENABLE_FWAAS:-no}" \ + "${SITE_PACKAGES}/neutron_fwaas_dashboard/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_heat_dashboard { + for file in ${SITE_PACKAGES}/heat_dashboard/enabled/_*[^__].py; do + config_dashboard "${ENABLE_HEAT:-no}" \ + "${SITE_PACKAGES}/heat_dashboard/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done + + config_dashboard "${ENABLE_HEAT:-no}" \ + "${SITE_PACKAGES}/heat_dashboard/conf/heat_policy.yaml" \ + "/etc/openstack-dashboard/heat_policy.yaml" + config_dashboard "${ENABLE_HEAT:-no}" \ + "${SITE_PACKAGES}/heat_dashboard/conf/default_policies/heat.yaml" \ + "/etc/openstack-dashboard/default_policies/heat.yaml" +} + +function config_ironic_dashboard { + for file in ${SITE_PACKAGES}/ironic_ui/enabled/_*[^__].py; do + config_dashboard "${ENABLE_IRONIC:-no}" \ + "${SITE_PACKAGES}/ironic_ui/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_magnum_dashboard { + for file in ${SITE_PACKAGES}/magnum_ui/enabled/_*[^__].py; do + config_dashboard "${ENABLE_MAGNUM:-no}" \ + "${SITE_PACKAGES}/magnum_ui/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_manila_ui { + for file in ${SITE_PACKAGES}/manila_ui/local/enabled/_*[^__].py; do + config_dashboard "${ENABLE_MANILA:-no}" \ + "${SITE_PACKAGES}/manila_ui/local/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done + + config_dashboard "${ENABLE_MANILA:-no}" \ + "${SITE_PACKAGES}/manila_ui/conf/manila_policy.yaml" \ + "/etc/openstack-dashboard/manila_policy.yaml" + config_dashboard "${ENABLE_MANILA:-no}" \ + "${SITE_PACKAGES}/manila_ui/conf/default_policies/manila.yaml" \ + "/etc/openstack-dashboard/default_policies/manila.yaml" +} + +function config_masakari_dashboard { + for file in ${SITE_PACKAGES}/masakaridashboard/local/enabled/_*[^__].py; do + config_dashboard "${ENABLE_MASAKARI:-no}" \ + "${SITE_PACKAGES}/masakaridashboard/local/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done + config_dashboard "${ENABLE_MASAKARI:-no}"\ + "${SITE_PACKAGES}/masakaridashboard/conf/masakari_policy.yaml" \ + "/etc/openstack-dashboard/masakari_policy.yaml" + config_dashboard "${ENABLE_MASAKARI:-no}"\ + "${SITE_PACKAGES}/masakaridashboard/local/local_settings.d/_50_masakari.py" \ + "${SITE_PACKAGES}/openstack_dashboard/local/local_settings.d/_50_masakari.py" +} + +function config_mistral_dashboard { + config_dashboard "${ENABLE_MISTRAL:-no}" \ + "${SITE_PACKAGES}/mistraldashboard/enabled/_50_mistral.py" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/_50_mistral.py" +} + +function config_neutron_vpnaas_dashboard { + config_dashboard "${ENABLE_NEUTRON_VPNAAS:-no}" \ + "${SITE_PACKAGES}/neutron_vpnaas_dashboard/enabled/_7100_project_vpn_panel.py" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/_7100_project_vpn_panel.py" +} + +function config_octavia_dashboard { + config_dashboard "${ENABLE_OCTAVIA:-no}" \ + "${SITE_PACKAGES}/octavia_dashboard/enabled/_1482_project_load_balancer_panel.py" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/_1482_project_load_balancer_panel.py" +} + + +function config_tacker_dashboard { + for file in ${SITE_PACKAGES}/tacker_horizon/enabled/_*[^__].py; do + config_dashboard "${ENABLE_TACKER:-no}" \ + "${SITE_PACKAGES}/tacker_horizon/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_trove_dashboard { + for file in ${SITE_PACKAGES}/trove_dashboard/enabled/_*[^__].py; do + config_dashboard "${ENABLE_TROVE:-no}" \ + "${SITE_PACKAGES}/trove_dashboard/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done +} + +function config_watcher_dashboard { + for file in ${SITE_PACKAGES}/watcher_dashboard/local/enabled/_*[^__].py; do + config_dashboard "${ENABLE_WATCHER:-no}" \ + "${SITE_PACKAGES}/watcher_dashboard/local/enabled/${file##*/}" \ + "${SITE_PACKAGES}/openstack_dashboard/local/enabled/${file##*/}" + done + + config_dashboard "${ENABLE_WATCHER:-no}" \ + "${SITE_PACKAGES}/watcher_dashboard/conf/watcher_policy.json" \ + "/etc/openstack-dashboard/watcher_policy.json" +} + +# Regenerate the compressed javascript and css if any configuration files have +# changed. Use a static modification date when generating the tarball +# so that we only trigger on content changes. +function settings_bundle { + # NOTE(yoctozepto): We ignore errors here (|| true) to make it work with + # `set -o pipefail` (files might be missing - no problem). + tar -cf- --mtime=1970-01-01 \ + /etc/openstack-dashboard/local_settings \ + /etc/openstack-dashboard/custom_local_settings \ + /etc/openstack-dashboard/local_settings.d \ + /etc/openstack-dashboard/themes 2> /dev/null || true +} + +function settings_changed { + changed=1 + + if [[ ! -f $HASH_PATH ]] || ! settings_bundle | md5sum -c --status $HASH_PATH || [[ $FORCE_GENERATE == yes ]]; then + changed=0 + fi + + return ${changed} +} + +config_blazar_dashboard +config_cloudkitty_dashboard +config_designate_dashboard +config_fwaas_dashboard +config_heat_dashboard +config_ironic_dashboard +config_magnum_dashboard +config_manila_ui +config_masakari_dashboard +config_mistral_dashboard +config_neutron_vpnaas_dashboard +config_octavia_dashboard +config_tacker_dashboard +config_trove_dashboard +config_watcher_dashboard + +if settings_changed; then + ${MANAGE_PY} collectstatic --noinput --clear + ${MANAGE_PY} compress --force + settings_bundle | md5sum > $HASH_PATH +fi + +# NOTE(sbezverk) since Horizon is now storing logs in its own location, /var/log/horizon +# needs to be created if it does not exist +if [[ ! -d "/var/log/kolla/horizon" ]]; then + mkdir -p /var/log/kolla/horizon +fi + +if [[ $(stat -c %U:%G /var/log/kolla/horizon) != "horizon:kolla" ]]; then + chown -R horizon:kolla /var/log/kolla/horizon +fi + +if [[ $(stat -c %a /var/log/kolla/horizon) != "755" ]]; then + chmod 755 /var/log/kolla/horizon +fi + +if [[ -f ${SITE_PACKAGES}/openstack_dashboard/local/.secret_key_store ]] && [[ $(stat -c %U ${SITE_PACKAGES}/openstack_dashboard/local/.secret_key_store) != "horizon" ]]; then + chown horizon ${SITE_PACKAGES}/openstack_dashboard/local/.secret_key_store +fi diff --git a/kolla/docker/httpd/Dockerfile.j2 b/kolla/docker/httpd/Dockerfile.j2 new file mode 100644 index 000000000..ec5637283 --- /dev/null +++ b/kolla/docker/httpd/Dockerfile.j2 @@ -0,0 +1,42 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block apache_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} +{{ macros.enable_extra_repos(['epel']) }} + {% set apache_packages = [ + 'httpd', + 'mod_ssl', + 'mod_auth_mellon', + 'mod_auth_openidc', + 'mod_proxy_uwsgi' + ] %} +{% elif base_package_type == 'deb' %} + {% set apache_packages = [ + 'apache2', + 'ca-certificates', + 'libapache2-mod-auth-mellon', + 'libapache2-mod-auth-openidc' + ] %} +{% endif %} + +{{ macros.install_packages(apache_packages | customizable("packages")) }} + +{% if base_package_type == 'rpm' %} +RUN sed -i -r 's,^(Listen 80),#\1,' /etc/httpd/conf/httpd.conf \ + && sed -i -r 's,^(Listen 443),#\1,' /etc/httpd/conf.d/ssl.conf +{% elif base_package_type == 'deb' %} +RUN echo > /etc/apache2/ports.conf +{% endif %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY httpd_setup.sh /usr/local/bin/kolla_httpd_setup +RUN chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_httpd_setup +USER root + +{% block apache_footer %}{% endblock %} diff --git a/kolla/docker/httpd/extend_start.sh b/kolla/docker/httpd/extend_start.sh new file mode 100644 index 000000000..d47af64b9 --- /dev/null +++ b/kolla/docker/httpd/extend_start.sh @@ -0,0 +1 @@ +. /usr/local/bin/kolla_httpd_setup diff --git a/kolla/docker/httpd/httpd_setup.sh b/kolla/docker/httpd/httpd_setup.sh new file mode 100644 index 000000000..35f7b5b1e --- /dev/null +++ b/kolla/docker/httpd/httpd_setup.sh @@ -0,0 +1,51 @@ +#!/bin/bash + +# This script performs setup necessary to run the Apache httpd web server. +# It should be sourced rather than executed as environment variables are set. + +# Assume the service runs on top of Apache httpd when user is root. +if [[ "$(whoami)" == 'root' ]]; then + # NOTE(pbourke): httpd will not clean up after itself in some cases which + # results in the container not being able to restart. (bug #1489676, 1557036) + if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + # NOTE(yoctozepto): APACHE_CONFDIR has to be set to pass the next step + # under the `set -o nounset` regime + APACHE_CONFDIR= + # Loading Apache2 ENV variables + . /etc/apache2/envvars + install -d /var/run/apache2/ + rm -rf /var/run/apache2/* + else + rm -rf /var/run/httpd/* /run/httpd/* /tmp/httpd* + # NOTE(mmalchuk): This added to make Rocky/Centos similar to Ubuntu/Debian + # to provide /server-status handler for local monitoring of the Apache. + # The module already loaded in the /etc/httpd/conf.modules.d/00-base.conf. + cat << EOF >/etc/httpd/conf.modules.d/99-server-status.conf +<Location "/server-status"> + SetHandler server-status + Require local +</Location> +EOF + fi + + # CentOS/Rocky have an issue with mod_ssl which produces an invalid Apache + # configuration in /etc/httpd/conf.d/ssl.conf. This causes the following error + # on startup: + # SSLCertificateFile: file '/etc/pki/tls/certs/localhost.crt' does not exist or is empty + # Work around this by generating certificates manually. + # NOTE(mnasiadka): in EL9 upgrade jobs gencerts is failing on wrong permissions to dhparams.pem + if [[ "${KOLLA_BASE_DISTRO}" =~ centos|rocky ]] && [[ ! -e /etc/pki/tls/certs/localhost.crt ]]; then + rm -f /tmp/dhparams.pem + /usr/libexec/httpd-ssl-gencerts + fi +fi + +# The default system locale with unicode support +LANG=C.UTF-8 + +# Override the default locale if configured +if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + [ -f /etc/default/locale ] && . /etc/default/locale +else + [ -f /etc/locale.conf ] && . /etc/locale.conf +fi diff --git a/kolla/docker/ironic/ironic-api/Dockerfile.j2 b/kolla/docker/ironic/ironic-api/Dockerfile.j2 new file mode 100644 index 000000000..1c10d0372 --- /dev/null +++ b/kolla/docker/ironic/ironic-api/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}ironic-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ironic_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set ironic_api_packages = [ +] %} +{{ macros.install_packages(ironic_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_ironic_extend_start +RUN chmod 644 /usr/local/bin/kolla_ironic_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ironic_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ironic/ironic-api/extend_start.sh b/kolla/docker/ironic/ironic-api/extend_start.sh new file mode 100644 index 000000000..ce2f7fb3e --- /dev/null +++ b/kolla/docker/ironic/ironic-api/extend_start.sh @@ -0,0 +1,19 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + ironic-dbsync upgrade + ironic-dbsync online_data_migrations + exit 0 +fi + +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + ironic-dbsync upgrade + exit 0 +fi + +if [[ "${!KOLLA_OSM[@]}" ]]; then + ironic-dbsync online_data_migrations + exit 0 +fi diff --git a/kolla/docker/ironic/ironic-base/Dockerfile.j2 b/kolla/docker/ironic/ironic-base/Dockerfile.j2 new file mode 100644 index 000000000..e2f7871f6 --- /dev/null +++ b/kolla/docker/ironic/ironic-base/Dockerfile.j2 @@ -0,0 +1,32 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ironic_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='ironic', shell='/bin/bash') }} + +ADD ironic-base-archive /ironic-base-source +ADD ironic_sudoers /etc/sudoers.d/kolla_ironic_sudoers + +{% set ironic_base_pip_packages = [ + '/ironic' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s ironic-base-source/* ironic \ + && {{ macros.install_pip(ironic_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/ironic \ + && cp /var/lib/kolla/venv/etc/pycadf/ironic_api_audit_map.conf /etc/ironic/ \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_ironic_sudoers \ + && touch /usr/local/bin/kolla_ironic_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_ironic_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ironic_base_footer %}{% endblock %} diff --git a/kolla/docker/ironic/ironic-base/extend_start.sh b/kolla/docker/ironic/ironic-base/extend_start.sh new file mode 100644 index 000000000..dc6b05caa --- /dev/null +++ b/kolla/docker/ironic/ironic-base/extend_start.sh @@ -0,0 +1,22 @@ +#!/bin/bash + +LOG_PATH=/var/log/kolla/ironic +METRICS_PATH=/var/lib/ironic-metrics + +if [[ ! -d "${LOG_PATH}" ]]; then + mkdir -p "${LOG_PATH}" +fi +if [[ ! -d "${METRICS_PATH}" ]]; then + sudo mkdir -p "${METRICS_PATH}" +fi +if [[ $(stat -c %a "${LOG_PATH}") != "755" ]]; then + chmod 755 "${LOG_PATH}" +fi +if [[ $(stat -c %U:%G "${METRICS_PATH}") != "ironic:ironic" ]]; then + sudo chown ironic:ironic "${METRICS_PATH}" +fi +if [[ $(stat -c %a "${METRICS_PATH}") != "2775" ]]; then + sudo chmod 2775 "${METRICS_PATH}" +fi + +. /usr/local/bin/kolla_ironic_extend_start diff --git a/kolla/docker/ironic/ironic-base/ironic_sudoers b/kolla/docker/ironic/ironic-base/ironic_sudoers new file mode 100644 index 000000000..9b9deed4d --- /dev/null +++ b/kolla/docker/ironic/ironic-base/ironic_sudoers @@ -0,0 +1,3 @@ +ironic ALL = (root) NOPASSWD: /bin/mkdir -p /var/lib/ironic-metrics, /usr/bin/mkdir -p /var/lib/ironic-metrics +ironic ALL = (root) NOPASSWD: /bin/chown ironic\:ironic /var/lib/ironic-metrics, /usr/bin/chown ironic\:ironic /var/lib/ironic-metrics +ironic ALL = (root) NOPASSWD: /bin/chmod 2755 /var/lib/ironic-metrics, /usr/bin/chmod 2775 /var/lib/ironic-metrics diff --git a/kolla/docker/ironic/ironic-conductor/Dockerfile.j2 b/kolla/docker/ironic/ironic-conductor/Dockerfile.j2 new file mode 100644 index 000000000..bce981fb0 --- /dev/null +++ b/kolla/docker/ironic/ironic-conductor/Dockerfile.j2 @@ -0,0 +1,76 @@ +FROM {{ namespace }}/{{ image_prefix }}ironic-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ironic_conductor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ironic_conductor_packages = [ + 'dosfstools', + 'e2fsprogs', + 'fuse', + 'gdisk', + 'ipmitool', + 'mtools', + 'openssh-clients', + 'parted', + 'psmisc', + 'python3-systemd', + 'qemu-img', + 'systemd-udev', + 'util-linux', + 'xfsprogs', + 'xorriso' + ] %} + {% if base_arch in ['x86_64'] %} + {% set ironic_conductor_packages = ironic_conductor_packages + [ + 'syslinux' + ] %} + {% endif %} +{% elif base_package_type == 'deb' %} + {% set ironic_conductor_packages = [ + 'bsdmainutils', + 'dosfstools', + 'e2fsprogs', + 'gdisk', + 'genisoimage', + 'ipmitool', + 'isolinux', + 'mtools', + 'openssh-client', + 'parted', + 'psmisc', + 'python3-systemd', + 'qemu-utils', + 'shellinabox', + 'udev', + 'xfsprogs', + ] %} +{% endif %} + +{% set ironic_conductor_pip_packages = [ + '-r /ironic/driver-requirements.txt', + 'ironic-staging-drivers', +] %} + +{% set ironic_conductor_plugins_pip_packages = [ +'/plugins/*' +] %} + +ADD plugins-archive / +RUN {{ macros.install_pip(ironic_conductor_pip_packages | customizable("pip_packages")) }} \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(ironic_conductor_plugins_pip_packages) }}; \ + fi + +{{ macros.install_packages(ironic_conductor_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block ironic_conductor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER ironic diff --git a/kolla/docker/ironic/ironic-prometheus-exporter/Dockerfile.j2 b/kolla/docker/ironic/ironic-prometheus-exporter/Dockerfile.j2 new file mode 100644 index 000000000..2ac448dfd --- /dev/null +++ b/kolla/docker/ironic/ironic-prometheus-exporter/Dockerfile.j2 @@ -0,0 +1,17 @@ +FROM {{ namespace }}/{{ image_prefix }}ironic-conductor:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +USER root + +{% block ironic_prometheus_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +ENV IRONIC_CONFIG /etc/ironic/ironic.conf + +{{ macros.kolla_patch_sources() }} + +{% block ironic_prometheus_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ironic/ironic-pxe-filter/Dockerfile.j2 b/kolla/docker/ironic/ironic-pxe-filter/Dockerfile.j2 new file mode 100644 index 000000000..5b593e9f0 --- /dev/null +++ b/kolla/docker/ironic/ironic-pxe-filter/Dockerfile.j2 @@ -0,0 +1,24 @@ +FROM {{ namespace }}/{{ image_prefix }}ironic-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ironic_pxe_filter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set ironic_pxe_filter_packages = [] %} + +{% set ironic_pxe_filter_pip_packages = [] %} + +RUN {{ macros.install_pip(ironic_pxe_filter_pip_packages | customizable("pip_packages")) }} + +{{ macros.install_packages(ironic_pxe_filter_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +COPY extend_start.sh /usr/local/bin/kolla_ironic_extend_start +RUN chmod 644 /usr/local/bin/kolla_ironic_extend_start + +{% block ironic_pxe_filter_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ironic/ironic-pxe-filter/extend_start.sh b/kolla/docker/ironic/ironic-pxe-filter/extend_start.sh new file mode 100644 index 000000000..c7a807c8d --- /dev/null +++ b/kolla/docker/ironic/ironic-pxe-filter/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash +IRONIC_DHCP_HOSTS_DIR=${IRONIC_DHCP_HOSTS_DIR:-/etc/dnsmasq/dhcp-hostsdir} +DNSMASQ_PIDFILE=${DNSMASQ_PIDFILE:-/run/ironic/dnsmasq.pid} + +# NOTE(wszumski): This container must be in same process namespace as dnsmasq +rm -f $IRONIC_DHCP_HOSTS_DIR/* && kill -HUP $(cat "$DNSMASQ_PIDFILE") || true diff --git a/kolla/docker/ironic/ironic-pxe/Dockerfile.j2 b/kolla/docker/ironic/ironic-pxe/Dockerfile.j2 new file mode 100644 index 000000000..0475a5b05 --- /dev/null +++ b/kolla/docker/ironic/ironic-pxe/Dockerfile.j2 @@ -0,0 +1,55 @@ +FROM {{ namespace }}/{{ image_prefix }}ironic-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ironic_pxe_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ironic_pxe_packages = [ + 'dosfstools', + 'grub2-tools', + 'grub2-efi-*64', + 'grub2-efi-aa64-modules', + 'ipxe-bootimgs', + 'ipxe-bootimgs-aarch64', + 'mtools', + 'shim-*64', + 'syslinux-tftpboot', + 'tftp-server', + ] %} + +{{ macros.install_packages(ironic_pxe_packages | customizable("packages")) }} +{% elif base_package_type == 'deb' %} + {% set ironic_pxe_packages = [ + 'dosfstools', + 'grub-efi-*64-signed', + 'ipxe', + 'mtools', + 'pxelinux', + 'shim-signed', + 'syslinux-common', + 'tftpd-hpa' + ] %} + + {% if base_arch == 'x86_64' %} + {% set ironic_pxe_packages = ironic_pxe_packages + [ + 'syslinux' + ] %} + {% endif %} + +{{ macros.install_packages(ironic_pxe_packages | customizable("packages")) }} +{% endif %} + +ENV TFTPBOOT_PATH=/tftpboot \ + HTTPBOOT_PATH=/httpboot +COPY tftp-map-file-template /map-file-template +COPY extend_start.sh /usr/local/bin/kolla_ironic_extend_start +RUN chmod 644 /usr/local/bin/kolla_ironic_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ironic_pxe_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ironic/ironic-pxe/extend_start.sh b/kolla/docker/ironic/ironic-pxe/extend_start.sh new file mode 100644 index 000000000..06a8312b4 --- /dev/null +++ b/kolla/docker/ironic/ironic-pxe/extend_start.sh @@ -0,0 +1,103 @@ +#!/bin/bash + + +# For x86 legacy BIOS boot mode +function prepare_pxe_pxelinux { + if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + cp /usr/lib/PXELINUX/pxelinux.0 \ + /usr/lib/syslinux/modules/bios/{chain.c32,ldlinux.c32} \ + ${TFTPBOOT_PATH}/ + elif [[ "${KOLLA_BASE_DISTRO}" =~ centos|rocky ]]; then + if [[ "${TFTPBOOT_PATH}" != /tftpboot ]]; then + cp /tftpboot/{pxelinux.0,chain.c32,ldlinux.c32} \ + ${TFTPBOOT_PATH}/ + fi + fi +} + +# For UEFI boot mode +function prepare_pxe_grub { + if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + shim_src_file="/usr/lib/shim/shim*64.efi.signed" + grub_src_file="/usr/lib/grub/*-efi-signed/grubnet*64.efi.signed" + elif [[ "${KOLLA_BASE_DISTRO}" =~ centos|rocky ]]; then + shim_src_file="/boot/efi/EFI/${KOLLA_BASE_DISTRO}/shim*64.efi" + grub_src_file="/boot/efi/EFI/${KOLLA_BASE_DISTRO}/grub*64.efi" + fi + + if [[ "${KOLLA_BASE_ARCH}" == "x86_64" ]]; then + shim_dst_file="bootx64.efi" + grub_dst_file="grubx64.efi" + elif [[ "${KOLLA_BASE_ARCH}" == "aarch64" ]]; then + shim_dst_file="bootaa64.efi" + grub_dst_file="grubaa64.efi" + fi + + cp $shim_src_file ${TFTPBOOT_PATH}/$shim_dst_file + cp $grub_src_file ${TFTPBOOT_PATH}/$grub_dst_file +} + +function prepare_ipxe { + # NOTE(mgoddard): Ironic uses snponly.efi as the default for + # uefi_ipxe_bootfile_name since Xena. In Wallaby and earlier releases it + # was ipxe.efi. Ensure that both exist, using symlinks where the files are + # named differently to allow the original names to be used in ironic.conf. + if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + # NOTE(m-anson): ipxe-arm64.efi is not symlinked from /boot to + # /usr/lib/ipxe by the Ubuntu ipxe package, so fix that here. + if [[ -e /boot/ipxe-arm64.efi ]]; then + ln -s /boot/ipxe-arm64.efi /usr/lib/ipxe/ + fi + cp /usr/lib/ipxe/{undionly.kpxe,ipxe*.efi,snponly.efi} ${TFTPBOOT_PATH}/ + elif [[ "${KOLLA_BASE_DISTRO}" =~ centos|rocky ]]; then + cp /usr/share/ipxe/{undionly.kpxe,ipxe-snponly-x86_64.efi} ${TFTPBOOT_PATH}/ + cp /usr/share/ipxe/arm64-efi/snponly.efi ${TFTPBOOT_PATH}/ipxe-snponly-aarch64.efi + if [[ ! -e ${TFTPBOOT_PATH}/snponly.efi ]]; then + ln -s ${TFTPBOOT_PATH}/ipxe-snponly-${KOLLA_BASE_ARCH}.efi ${TFTPBOOT_PATH}/snponly.efi + fi + fi +} + +function prepare_esp_image { + # NOTE(bbezak): based on https://docs.openstack.org/ironic/2024.2/install/configure-esp.html + # ESP image needs to be provided for UEFI boot with virtual media: + # https://docs.openstack.org/ironic/2024.2/admin/drivers/redfish.html#virtual-media-boot + if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + shim_src_file="/usr/lib/shim/shim*64.efi.signed" + grub_src_file="/usr/lib/grub/*-efi-signed/grubnet*64.efi.signed" + elif [[ "${KOLLA_BASE_DISTRO}" =~ centos|rocky ]]; then + shim_src_file="/boot/efi/EFI/${KOLLA_BASE_DISTRO}/shim*64.efi" + grub_src_file="/boot/efi/EFI/${KOLLA_BASE_DISTRO}/grub*64.efi" + fi + + if [[ "${KOLLA_BASE_ARCH}" == "x86_64" ]]; then + shim_dst_file="bootx64.efi" + grub_dst_file="grubx64.efi" + elif [[ "${KOLLA_BASE_ARCH}" == "aarch64" ]]; then + shim_dst_file="bootaa64.efi" + grub_dst_file="grubaa64.efi" + fi + + DEST=${HTTPBOOT_PATH}/esp.img + dd if=/dev/zero of=$DEST bs=4096 count=2048 + mkfs.msdos -F 12 -n ESP_IMAGE $DEST + mmd -i $DEST EFI EFI/BOOT + mcopy -i $DEST -v $shim_src_file ::EFI/BOOT/$shim_dst_file + mcopy -i $DEST -v $grub_src_file ::EFI/BOOT/$grub_dst_file + mdir -i $DEST ::EFI/BOOT +} + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + mkdir -p ${TFTPBOOT_PATH} ${HTTPBOOT_PATH} + chown ironic: ${TFTPBOOT_PATH} ${HTTPBOOT_PATH} + prepare_pxe_pxelinux + prepare_pxe_grub + prepare_ipxe + prepare_esp_image + exit 0 +fi + +# Template out a TFTP map file, using the TFTPBOOT_PATH variable. +envsubst < /map-file-template > /map-file diff --git a/kolla/docker/ironic/ironic-pxe/tftp-map-file-template b/kolla/docker/ironic/ironic-pxe/tftp-map-file-template new file mode 100644 index 000000000..5d3243a7e --- /dev/null +++ b/kolla/docker/ironic/ironic-pxe/tftp-map-file-template @@ -0,0 +1,4 @@ +re ^(${TFTPBOOT_PATH}/) ${TFTPBOOT_PATH}/\2 +re ^${TFTPBOOT_PATH}/ ${TFTPBOOT_PATH}/ +re ^(^/) ${TFTPBOOT_PATH}/\1 +re ^([^/]) ${TFTPBOOT_PATH}/\1 diff --git a/kolla/docker/iscsid/Dockerfile.j2 b/kolla/docker/iscsid/Dockerfile.j2 new file mode 100644 index 000000000..a1e4bba61 --- /dev/null +++ b/kolla/docker/iscsid/Dockerfile.j2 @@ -0,0 +1,36 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block iscsid_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set iscsid_packages = [ + 'iscsi-initiator-utils', + 'python3-rtslib', + 'targetcli' + ] %} + +{% elif base_package_type == 'deb' %} + {% set iscsid_packages = [ + 'open-iscsi', + 'python3-rtslib-fb', + 'targetcli-fb' + ] %} + +{% endif %} + +{{ macros.install_packages(iscsid_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +# NOTE(hrw): CentOS Stream 9 lacks initiatorname.iscsi file +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && rm -f /etc/iscsi/initiatorname.iscsi + +{{ macros.kolla_patch_sources() }} + +{% block iscsid_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/iscsid/extend_start.sh b/kolla/docker/iscsid/extend_start.sh new file mode 100644 index 000000000..78f2317d2 --- /dev/null +++ b/kolla/docker/iscsid/extend_start.sh @@ -0,0 +1,7 @@ +#!/bin/bash + +# check if unique iSCSI initiator name already exists +if [[ ! -f /etc/iscsi/initiatorname.iscsi ]]; then + echo "Generating new iSCSI initiator name" + echo InitiatorName=$(/sbin/iscsi-iname) > /etc/iscsi/initiatorname.iscsi +fi diff --git a/kolla/docker/keepalived/Dockerfile.j2 b/kolla/docker/keepalived/Dockerfile.j2 new file mode 100644 index 000000000..2dcdeccd7 --- /dev/null +++ b/kolla/docker/keepalived/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block keepalived_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.enable_extra_repos(['mariadb']) }} + +{% if base_package_type == 'rpm' %} + {% set keepalived_packages = [ + 'keepalived', + 'MariaDB-client' + ] %} +{% elif base_package_type == 'deb' %} + {% set keepalived_packages = [ + 'keepalived', + 'mariadb-client' + ] %} +{% endif %} +{{ macros.install_packages(keepalived_packages | customizable("packages")) }} + +COPY check_alive.sh / + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && chmod 755 /check_alive.sh + +{{ macros.kolla_patch_sources() }} + +{% block keepalived_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/keepalived/check_alive.sh b/kolla/docker/keepalived/check_alive.sh new file mode 100644 index 000000000..857131123 --- /dev/null +++ b/kolla/docker/keepalived/check_alive.sh @@ -0,0 +1,33 @@ +#!/bin/bash + +# This will return 0 when it successfully passes all checks for all daemons +# Failures return 1 + +declare -A check_results +final_result=0 + +if [ -d "/checks" ]; then + CHECKS=$(find /checks -type f) +fi + +if [ "${CHECKS}" ]; then + # Store results + for check in ${CHECKS}; do + # Run check but do not print stderr + # as single check can be executed manually to see the result + ${check} 2>/dev/null + check_results[${check}]=$? + done + + # Print results and save the final result + for i in "${!check_results[@]}"; do + if [ "${check_results[$i]}" == "0" ]; then + echo "Keepalived check script ${i} succeeded." + else + final_result=1 + echo "Keepalived check script ${i} failed." + fi + done + + exit ${final_result} +fi diff --git a/kolla/docker/keepalived/extend_start.sh b/kolla/docker/keepalived/extend_start.sh new file mode 100644 index 000000000..889da64fd --- /dev/null +++ b/kolla/docker/keepalived/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# Workaround for bug #1485079 +if [ -f /run/keepalived.pid ]; then + rm /run/keepalived.pid +fi diff --git a/kolla/docker/kerbside/kerbside-api/Dockerfile.j2 b/kolla/docker/kerbside/kerbside-api/Dockerfile.j2 new file mode 100644 index 000000000..6ea99eb7a --- /dev/null +++ b/kolla/docker/kerbside/kerbside-api/Dockerfile.j2 @@ -0,0 +1,9 @@ +FROM {{ namespace }}/{{ image_prefix }}kerbside-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +USER kerbside diff --git a/kolla/docker/kerbside/kerbside-api/extend_start.sh b/kolla/docker/kerbside/kerbside-api/extend_start.sh new file mode 100644 index 000000000..92ef80a22 --- /dev/null +++ b/kolla/docker/kerbside/kerbside-api/extend_start.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Make the log directory +mkdir -p /var/log/kolla/kerbside diff --git a/kolla/docker/kerbside/kerbside-base/Dockerfile.j2 b/kolla/docker/kerbside/kerbside-base/Dockerfile.j2 new file mode 100644 index 000000000..77f881399 --- /dev/null +++ b/kolla/docker/kerbside/kerbside-base/Dockerfile.j2 @@ -0,0 +1,38 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block kerbside_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='kerbside', groups='kerbside') }} + +{% if base_package_type == 'rpm' %} + {% set kerbside_packages = [ + 'mariadb-devel', + 'pkgconfig' + ] %} +{% elif base_package_type == 'deb' %} + {% set kerbside_packages = [ + 'libmariadb-dev-compat', + 'pkg-config' + ] %} +{% endif %} + +{{ macros.install_packages(kerbside_packages | customizable("packages")) }} + +{% set kerbside_pip_packages = [ + '/kerbside' +] %} + +ADD kerbside-base-archive /kerbside-source +RUN ln -s kerbside-source/* kerbside \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(kerbside_plugins_pip_packages) }}; \ + fi \ + && {{ macros.install_pip(kerbside_pip_packages | customizable("pip_packages"), false) }} \ + && rm -f /etc/machine-id + +{% block kerbside_base_footer %}{% endblock %} diff --git a/kolla/docker/kerbside/kerbside-proxy/Dockerfile.j2 b/kolla/docker/kerbside/kerbside-proxy/Dockerfile.j2 new file mode 100644 index 000000000..6ea99eb7a --- /dev/null +++ b/kolla/docker/kerbside/kerbside-proxy/Dockerfile.j2 @@ -0,0 +1,9 @@ +FROM {{ namespace }}/{{ image_prefix }}kerbside-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +USER kerbside diff --git a/kolla/docker/kerbside/kerbside-proxy/extend_start.sh b/kolla/docker/kerbside/kerbside-proxy/extend_start.sh new file mode 100644 index 000000000..92ef80a22 --- /dev/null +++ b/kolla/docker/kerbside/kerbside-proxy/extend_start.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +# Make the log directory +mkdir -p /var/log/kolla/kerbside diff --git a/kolla/docker/keystone/keystone-base/Dockerfile.j2 b/kolla/docker/keystone/keystone-base/Dockerfile.j2 new file mode 100644 index 000000000..faa424fa7 --- /dev/null +++ b/kolla/docker/keystone/keystone-base/Dockerfile.j2 @@ -0,0 +1,45 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block keystone_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='keystone') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['epel']) }} + + {% set keystone_base_packages = [ + 'cyrus-sasl-devel', + 'openldap-devel', + ] %} + +{% elif base_package_type == 'deb' %} + {% set keystone_base_packages = [ + 'libldap-common', + 'libldap2-dev', + 'libsasl2-dev', + ] %} +{% endif %} +{{ macros.install_packages(keystone_base_packages | customizable("packages")) }} + +{% block keystone_source_install %} +ADD keystone-base-archive /keystone-base-source + +{% set keystone_base_pip_packages = [ + '/keystone[ldap]', +] %} + +RUN ln -s keystone-base-source/* keystone \ + && {{ macros.install_pip(keystone_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/keystone \ + && cp -r /keystone/etc/* /etc/keystone/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block keystone_base_footer %}{% endblock %} diff --git a/kolla/docker/keystone/keystone-fernet/Dockerfile.j2 b/kolla/docker/keystone/keystone-fernet/Dockerfile.j2 new file mode 100644 index 000000000..da32ddb86 --- /dev/null +++ b/kolla/docker/keystone/keystone-fernet/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM {{ namespace }}/{{ image_prefix }}keystone-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block keystone_fernet_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set keystone_fernet_packages = [ + 'cronie', + 'openssh-clients', + 'rsync' + ] %} +{% elif base_package_type == 'deb' %} + {% set keystone_fernet_packages = [ + 'cron', + 'openssh-client', + 'rsync' + ] %} +{% endif %} +{{ macros.install_packages(keystone_fernet_packages | customizable("packages")) }} + +COPY fetch_fernet_tokens.py /usr/bin/ +COPY keystone_bootstrap.sh /usr/local/bin/kolla_keystone_bootstrap +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && chmod 755 /usr/local/bin/kolla_keystone_bootstrap /usr/bin/fetch_fernet_tokens.py + +{{ macros.kolla_patch_sources() }} + +{% block keystone_fernet_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/keystone/keystone-fernet/extend_start.sh b/kolla/docker/keystone/keystone-fernet/extend_start.sh new file mode 100644 index 000000000..cf356949f --- /dev/null +++ b/kolla/docker/keystone/keystone-fernet/extend_start.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +FERNET_SYNC=/usr/bin/fernet-node-sync.sh +FERNET_TOKEN_DIR="/etc/keystone/fernet-keys" + +if [[ -f "${FERNET_SYNC}" ]]; then + ${FERNET_SYNC} +fi + +if [[ $(stat -c %U:%G ${FERNET_TOKEN_DIR}) != "keystone:keystone" ]]; then + chown keystone:keystone ${FERNET_TOKEN_DIR} +fi diff --git a/kolla/docker/keystone/keystone-fernet/fetch_fernet_tokens.py b/kolla/docker/keystone/keystone-fernet/fetch_fernet_tokens.py new file mode 100644 index 000000000..c57943630 --- /dev/null +++ b/kolla/docker/keystone/keystone-fernet/fetch_fernet_tokens.py @@ -0,0 +1,83 @@ +#!/usr/bin/python + +# 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. + +# Basically this module will fetch the fernet tokens and compare them to the +# required time constrains to determine whether the host needs to resync with +# other nodes in the cluster. +import argparse +from datetime import datetime +from datetime import timedelta +import json +import os +import sys + +# Adding nosec since this fails bandit B105, 'Possible hardcoded password'. +TOKEN_PATH = '/etc/keystone/fernet-keys' # nosec + + +def json_exit(msg=None, failed=False, changed=False): + if type(msg) is not dict: + msg = {'msg': str(msg)} + msg.update({'failed': failed, 'changed': changed}) + print(json.dumps(msg)) + sys.exit() + + +def has_file(filename_path): + if not os.path.exists(filename_path): + return False + return True + + +def num_tokens(): + _, _, files = next(os.walk(TOKEN_PATH)) + return len(files) + + +def tokens_populated(expected): + return num_tokens() >= int(expected) + + +def token_stale(seconds, filename='0'): + max_token_age = datetime.now() - timedelta(seconds=int(seconds)) + filename_path = os.path.join(TOKEN_PATH, filename) + + if not has_file(filename_path): + return True + modified_date = datetime.fromtimestamp(os.path.getmtime(filename_path)) + return modified_date < max_token_age + + +def main(): + parser = argparse.ArgumentParser(description='''Checks to see if a fernet + token no older than a desired time.''') + parser.add_argument('-t', '--time', + help='Time in seconds for a token rotation', + required=True) + parser.add_argument('-f', '--filename', + help='Filename of token to check', + default='0') + parser.add_argument('-n', '--number', + help='Minimum number of tokens that should exist', + required=True) + args = parser.parse_args() + + json_exit({ + 'populated': tokens_populated(args.number), + 'update_required': token_stale(args.time, args.filename), + }) + + +if __name__ == '__main__': + main() diff --git a/kolla/docker/keystone/keystone-fernet/keystone_bootstrap.sh b/kolla/docker/keystone/keystone-fernet/keystone_bootstrap.sh new file mode 100644 index 000000000..d361767bb --- /dev/null +++ b/kolla/docker/keystone/keystone-fernet/keystone_bootstrap.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# 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. + +set -x + +USERNAME=$1 +GROUP=$2 + +function fail_json { + echo '{"failed": true, "msg": "'$1'", "changed": true}' + exit 1 +} + +function exit_json { + echo '{"failed": false, "changed": '"${changed}"'}' +} + +changed="false" +keystone_bootstrap=$(keystone-manage --config-file /etc/keystone/keystone.conf fernet_setup --keystone-user ${USERNAME} --keystone-group ${GROUP} 2>&1) +if [[ $? != 0 ]]; then + fail_json "${keystone_bootstrap}" +fi + +changed=$(echo "${keystone_bootstrap}" | awk ' + /Key repository is already initialized/ {count++} + END { + if (count == 1) changed="true"; else changed="false" + print changed + }' +) + +exit_json diff --git a/kolla/docker/keystone/keystone-ssh/Dockerfile.j2 b/kolla/docker/keystone/keystone-ssh/Dockerfile.j2 new file mode 100644 index 000000000..af290bd5f --- /dev/null +++ b/kolla/docker/keystone/keystone-ssh/Dockerfile.j2 @@ -0,0 +1,38 @@ +FROM {{ namespace }}/{{ image_prefix }}keystone-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block keystone_ssh_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='keystone', shell='/bin/bash') }} + +{% if base_package_type == 'rpm' %} + {% set keystone_ssh_packages = [ + 'openssh-server', + 'rsync' + ] %} + +{% elif base_package_type == 'deb' %} + {% set keystone_ssh_packages = [ + 'openssh-server', + 'rsync' + ] %} + +RUN mkdir -p /var/run/sshd \ + && chmod 0755 /var/run/sshd + +{% endif %} +{{ macros.install_packages(keystone_ssh_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN sed -ri 's/session(\s+)required(\s+)pam_loginuid.so/session\1optional\2pam_loginuid.so/' /etc/pam.d/sshd \ + && chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block keystone_ssh_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/keystone/keystone-ssh/extend_start.sh b/kolla/docker/keystone/keystone-ssh/extend_start.sh new file mode 100644 index 000000000..559cd65a9 --- /dev/null +++ b/kolla/docker/keystone/keystone-ssh/extend_start.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# NOTE(mnasiadka): CentOS 10 does not support dsa +SSH_HOST_KEY_TYPES=( "rsa" "ecdsa" "ed25519" ) + +for key_type in ${SSH_HOST_KEY_TYPES[@]}; do + KEY_PATH=/etc/ssh/ssh_host_${key_type}_key + if [[ ! -f "${KEY_PATH}" ]]; then + ssh-keygen -q -t ${key_type} -f ${KEY_PATH} -N "" + fi +done + +mkdir -p /var/lib/keystone/.ssh + +if [[ $(stat -c %U:%G /var/lib/keystone/.ssh) != "keystone:keystone" ]]; then + sudo chown keystone: /var/lib/keystone/.ssh +fi diff --git a/kolla/docker/keystone/keystone/Dockerfile.j2 b/kolla/docker/keystone/keystone/Dockerfile.j2 new file mode 100644 index 000000000..742626c05 --- /dev/null +++ b/kolla/docker/keystone/keystone/Dockerfile.j2 @@ -0,0 +1,45 @@ +FROM {{ namespace }}/{{ image_prefix }}keystone-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block keystone_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set keystone_packages = [ + 'krb5-devel', + ] %} +{% elif base_package_type == 'deb' %} + {% set keystone_packages = [ + 'libkrb5-dev', + ] %} +{% endif %} +{{ macros.install_packages(keystone_packages | customizable("packages")) }} + +{% set keystone_pip_packages = [ + 'requests-kerberos', +] %} + +RUN {{ macros.install_pip(keystone_pip_packages | customizable("pip_packages")) }} + +ADD plugins-archive / + +{% set keystone_plugins_pip_packages = [ + '/plugins/*', +] %} + +COPY keystone_bootstrap.sh /usr/local/bin/kolla_keystone_bootstrap +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && chmod 755 /usr/local/bin/kolla_keystone_bootstrap \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(keystone_plugins_pip_packages) }}; \ + fi + +{{ macros.kolla_patch_sources() }} + +{% block keystone_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/keystone/keystone/extend_start.sh b/kolla/docker/keystone/keystone/extend_start.sh new file mode 100644 index 000000000..b45c94d0d --- /dev/null +++ b/kolla/docker/keystone/keystone/extend_start.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +# Create log dir for Keystone logs +KEYSTONE_LOG_DIR="/var/log/kolla/keystone" +if [[ ! -d "${KEYSTONE_LOG_DIR}" ]]; then + mkdir -p ${KEYSTONE_LOG_DIR} +fi +if [[ $(stat -c %U:%G ${KEYSTONE_LOG_DIR}) != "keystone:kolla" ]]; then + chown keystone:kolla ${KEYSTONE_LOG_DIR} +fi +if [ ! -f "${KEYSTONE_LOG_DIR}/keystone.log" ]; then + touch ${KEYSTONE_LOG_DIR}/keystone.log +fi +if [[ $(stat -c %U:%G ${KEYSTONE_LOG_DIR}/keystone.log) != "keystone:keystone" ]]; then + chown keystone:keystone ${KEYSTONE_LOG_DIR}/keystone.log +fi +if [[ $(stat -c %a ${KEYSTONE_LOG_DIR}) != "755" ]]; then + chmod 755 ${KEYSTONE_LOG_DIR} +fi + +EXTRA_KEYSTONE_MANAGE_ARGS=${EXTRA_KEYSTONE_MANAGE_ARGS-} +# Upgrade and exit if KOLLA_UPGRADE variable is set. This catches all cases +# of the KOLLA_UPGRADE variable being set, including empty. +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + # TODO(duonghq): check doctor result here + # TODO: find reason why doctor failed in gate + # sudo -H -u keystone keystone-manage doctor + sudo -H -u keystone keystone-manage ${EXTRA_KEYSTONE_MANAGE_ARGS} db_sync --expand + sudo -H -u keystone keystone-manage ${EXTRA_KEYSTONE_MANAGE_ARGS} db_sync --migrate + exit 0 +fi + +# Contract database and exit if KOLLA_FINISH_UPGRADE variable is set. +# This catches all cases of the KOLLA_FINISH_UPGRADE variable being set, +# including empty. +if [[ "${!KOLLA_FINISH_UPGRADE[@]}" ]]; then + sudo -H -u keystone keystone-manage ${EXTRA_KEYSTONE_MANAGE_ARGS} db_sync --contract + exit 0 +fi + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + sudo -H -u keystone keystone-manage ${EXTRA_KEYSTONE_MANAGE_ARGS} db_sync + exit 0 +fi diff --git a/kolla/docker/keystone/keystone/keystone_bootstrap.sh b/kolla/docker/keystone/keystone/keystone_bootstrap.sh new file mode 100644 index 000000000..1b04d99b6 --- /dev/null +++ b/kolla/docker/keystone/keystone/keystone_bootstrap.sh @@ -0,0 +1,66 @@ +#!/bin/bash + +set -o pipefail + +# NOTE(SamYaple): Kolla needs to wraps `keystone-manage bootstrap` to ensure +# any change is reported correctly for idempotency. This script will exit with +# valid json that can be parsed with information about if the task has failed +# and if anything changed. + +USERNAME=$1 +PASSWORD=$2 +if [ -z "$PASSWORD" ]; then + # Avoid having the password always come in via CLI (which makes + # it show up in things like ara) + PASSWORD="$OS_BOOTSTRAP_PASSWORD" +fi +PROJECT=$3 +ROLE=$4 +if [ $# -ge 8 ]; then + # ignored ADMIN_URL compat mode + # ADMIN_URL=$5 + INTERNAL_URL=$6 + PUBLIC_URL=$7 + REGION=$8 +else + # no ADMIN_URL modern mode + INTERNAL_URL=$5 + PUBLIC_URL=$6 + REGION=$7 +fi + +function fail_json { + echo '{"failed": true, "msg": "'$1'", "changed": true}' + exit 1 +} + +function exit_json { + echo '{"failed": false, "changed": '"${changed}"'}' +} + +changed="false" +# NOTE(mgoddard): pipe through cat -v to remove unprintable control characters +# which prevent JSON decoding. +# NOTE(yoctozepto): also apply sed to escape double quotation marks +# and backslashes +keystone_bootstrap=$(keystone-manage bootstrap --bootstrap-username "${USERNAME}" --bootstrap-password "${PASSWORD}" --bootstrap-project-name "${PROJECT}" --bootstrap-role-name "${ROLE}" --bootstrap-internal-url "${INTERNAL_URL}" --bootstrap-public-url "${PUBLIC_URL}" --bootstrap-service-name "keystone" --bootstrap-region-id "${REGION}" 2>&1 | cat -v | sed 's/\\/\\\\/g' | sed 's/"/\\"/g') +if [[ $? != 0 ]]; then + fail_json "${keystone_bootstrap}" +fi + +changed=$(echo "${keystone_bootstrap}" | awk ' + /Domain default already exists, skipping creation./ || + /Project '"${PROJECT}"' already exists, skipping creation./ || + /User '"${USERNAME}"' already exists, skipping creation./ || + /Role '"${ROLE}"' exists, skipping creation./ || + /User '"${USERNAME}"' already has '"${ROLE}"' on '"${PROJECT}"'./ || + /Region '"${REGION}"' exists, skipping creation./ || + /Skipping internal endpoint as already created/ || + /Skipping public endpoint as already created/ {count++} + END { + if (count == 9) changed="false"; else changed="true" + print changed + }' +) + +exit_json diff --git a/kolla/docker/kolla-toolbox/Dockerfile.j2 b/kolla/docker/kolla-toolbox/Dockerfile.j2 new file mode 100644 index 000000000..eac78905d --- /dev/null +++ b/kolla/docker/kolla-toolbox/Dockerfile.j2 @@ -0,0 +1,129 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block kolla_toolbox_header %}{% endblock %} + +{% set venv_path='/opt/ansible' %} +{% set os_client_config= venv_path + '/lib/python3/site-packages/os_client_config/defaults.json' %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='ansible') }} +{{ macros.configure_user(name='rabbitmq') }} + +{{ macros.enable_extra_repos(['erlang', 'rabbitmq']) }} + +{% block rabbitmq_apt_preferences %} +{% if base_package_type == 'deb' %} +COPY apt_preferences_rabbitmq.{{ base_distro }} /etc/apt/preferences.d/rabbitmq +{% endif %} +{% endblock %} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['crb', 'epel', 'openvswitch']) }} + + {% set kolla_toolbox_packages = [ + 'erlang-27.*', + 'gcc', + 'gdisk', + 'git', + 'jq', + 'libffi-devel', + 'libxml2-devel', + 'libxslt-devel', + 'make', + 'openssh-clients', + 'openssl-devel', + 'openvswitch${KOLLA_RPM_OVS_VERSION}', + 'python3', + 'python3-devel', + 'rabbitmq-server-4.2.*' + ] %} + +{% elif base_package_type == 'deb' %} + {% set kolla_toolbox_packages = [ + 'build-essential', + 'ca-certificates', + 'gdisk', + 'git', + 'jq', + 'libffi-dev', + 'libssl-dev', + 'libxslt1-dev', + 'openvswitch-switch', + 'python3-dev', + 'python3-venv', + 'rabbitmq-server', + ] %} +{% endif %} +{{ macros.install_packages(kolla_toolbox_packages | customizable("packages")) }} + +{% block kolla_toolbox_pip_conf %} +ENV UPPER_CONSTRAINTS_FILE=/requirements/upper-constraints.txt +{% endblock %} + +{% block kolla_toolbox_upper_constraints %} +ADD kolla-toolbox-archive /kolla-toolbox-source + +RUN case "$UPPER_CONSTRAINTS_FILE" in \ + http*) mkdir -p /requirements && curl -LO $UPPER_CONSTRAINTS_FILE /requirements/upper-constraints.txt ;; \ + *) ln -s kolla-toolbox-source/* /requirements ;; \ + esac \ + && {{ macros.upper_constraints_remove("openstacksdk") }} \ + && python3 -m venv --system-site-packages {{ venv_path }} \ + && KOLLA_DISTRO_PYTHON_VERSION=$(/usr/bin/python3 -c "import sys; print('{}.{}'.format(sys.version_info.major, sys.version_info.minor))") \ + && cd {{ venv_path }}/lib \ + && ln -s python${KOLLA_DISTRO_PYTHON_VERSION} {{ venv_path }}/lib/python3 +{% endblock %} + +ENV PATH {{ venv_path }}/bin:$PATH + +{% set kolla_toolbox_pip_packages = [ + 'ansible-core==2.20.*', + 'ansible-runner', + 'cmd2', + 'openstacksdk', + 'os-client-config', + 'pbr', + 'pymysql', + 'python-ironicclient', + 'python-openstackclient', + 'pytz', + 'pyudev', + ] %} + +RUN {{ macros.install_pip(['pip', 'wheel', 'setuptools']) }} \ + && {{ macros.install_pip((kolla_toolbox_pip_packages | customizable("pip_packages"))) }} \ + && mkdir -p /etc/ansible /usr/share/ansible \ + && echo 'localhost ansible_connection=local ansible_python_interpreter={{ venv_path }}/bin/python' > /etc/ansible/hosts \ + && sed -i 's| "identity_api_version": "2.0",| "identity_api_version": "3",|' {{ os_client_config }} + +{% block kolla_toolbox_collections_install %} +COPY requirements.yml /var/lib/ansible/ +RUN fail=1; for i in $(seq 1 5); do if \ +ansible-galaxy collection install --timeout 120 -p /usr/share/ansible/collections -r /var/lib/ansible/requirements.yml \ +; then fail=0; break; fi; echo "Collection download failed, retrying"; sleep 5; done; \ +if [ "$fail" -eq 1 ]; then exit 1; fi + +ENV ANSIBLE_LIBRARY /usr/share/ansible:$ANSIBLE_LIBRARY +{% endblock %} + +COPY ansible.cfg /etc/ansible/ansible.cfg +COPY ansible_sudoers /etc/sudoers.d/kolla_ansible_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY kolla_toolbox.sh /usr/local/bin/kolla_toolbox + +RUN chmod 644 /etc/ansible/ansible.cfg \ + /usr/local/bin/kolla_extend_start \ + && chmod 755 /usr/local/bin/kolla_toolbox \ + && chmod 440 /etc/sudoers.d/kolla_ansible_sudoers + +{{ macros.kolla_patch_sources() }} + +{% block kolla_toolbox_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER ansible diff --git a/kolla/docker/kolla-toolbox/ansible.cfg b/kolla/docker/kolla-toolbox/ansible.cfg new file mode 100644 index 000000000..ec505f4a4 --- /dev/null +++ b/kolla/docker/kolla-toolbox/ansible.cfg @@ -0,0 +1,4 @@ +[defaults] +inject_facts_as_vars = False +log_path = /var/log/kolla/ansible.log +remote_tmp = /tmp diff --git a/kolla/docker/kolla-toolbox/ansible_sudoers b/kolla/docker/kolla-toolbox/ansible_sudoers new file mode 100644 index 000000000..5a3f109b4 --- /dev/null +++ b/kolla/docker/kolla-toolbox/ansible_sudoers @@ -0,0 +1,3 @@ +Defaults secure_path="/opt/ansible/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" + +ansible ALL=(root) NOPASSWD: /opt/ansible/bin/ansible localhost -m find_disks -a *, /usr/local/bin/ansible localhost -m find_disks -a * diff --git a/kolla/docker/kolla-toolbox/apt_preferences_rabbitmq.debian b/kolla/docker/kolla-toolbox/apt_preferences_rabbitmq.debian new file mode 120000 index 000000000..f1cc84d9b --- /dev/null +++ b/kolla/docker/kolla-toolbox/apt_preferences_rabbitmq.debian @@ -0,0 +1 @@ +../rabbitmq/apt_preferences_rabbitmq.debian
\ No newline at end of file diff --git a/kolla/docker/kolla-toolbox/apt_preferences_rabbitmq.ubuntu b/kolla/docker/kolla-toolbox/apt_preferences_rabbitmq.ubuntu new file mode 120000 index 000000000..977ded074 --- /dev/null +++ b/kolla/docker/kolla-toolbox/apt_preferences_rabbitmq.ubuntu @@ -0,0 +1 @@ +../rabbitmq/apt_preferences_rabbitmq.ubuntu
\ No newline at end of file diff --git a/kolla/docker/kolla-toolbox/extend_start.sh b/kolla/docker/kolla-toolbox/extend_start.sh new file mode 100644 index 000000000..198587145 --- /dev/null +++ b/kolla/docker/kolla-toolbox/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [[ ! -f "/var/log/kolla/ansible.log" ]]; then + touch /var/log/kolla/ansible.log +fi + +if [[ $(stat -c %U:%G /var/log/kolla/ansible.log) != "ansible:kolla" ]]; then + chown -R ansible:kolla /var/log/kolla/ansible.log +fi + +if [[ $(stat -c %a /var/log/kolla/ansible.log) != "664" ]]; then + chmod 664 /var/log/kolla/ansible.log +fi diff --git a/kolla/docker/kolla-toolbox/kolla_toolbox.sh b/kolla/docker/kolla-toolbox/kolla_toolbox.sh new file mode 100644 index 000000000..5dfd65338 --- /dev/null +++ b/kolla/docker/kolla-toolbox/kolla_toolbox.sh @@ -0,0 +1,16 @@ +#!/usr/bin/env bash + +catch_term() { + exit 0 +} + +catch_quit() { + exit 0 +} + +trap catch_term SIGTERM +trap catch_quit SIGQUIT + +while :; do + sleep 1 +done diff --git a/kolla/docker/kolla-toolbox/requirements.yml b/kolla/docker/kolla-toolbox/requirements.yml new file mode 100644 index 000000000..83c795142 --- /dev/null +++ b/kolla/docker/kolla-toolbox/requirements.yml @@ -0,0 +1,14 @@ +--- +collections: + - name: ansible.posix + version: '<3' + - name: community.general + version: '<13' + - name: community.mysql + version: '<5' + - name: community.rabbitmq + version: '<2' + - name: openstack.cloud + version: '<3' + - name: openvswitch.openvswitch + version: '<3' diff --git a/kolla/docker/letsencrypt/letsencrypt-base/Dockerfile.j2 b/kolla/docker/letsencrypt/letsencrypt-base/Dockerfile.j2 new file mode 100644 index 000000000..8e9e60db9 --- /dev/null +++ b/kolla/docker/letsencrypt/letsencrypt-base/Dockerfile.j2 @@ -0,0 +1,14 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block letsencrypt_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block letsencrypt_base_footer %}{% endblock %} diff --git a/kolla/docker/letsencrypt/letsencrypt-base/extend_start.sh b/kolla/docker/letsencrypt/letsencrypt-base/extend_start.sh new file mode 100644 index 000000000..0300f0b44 --- /dev/null +++ b/kolla/docker/letsencrypt/letsencrypt-base/extend_start.sh @@ -0,0 +1,69 @@ +#!/bin/bash + +# Logs + +if [[ ! -d "/var/log/kolla/letsencrypt" ]]; then + mkdir -p /var/log/kolla/letsencrypt +fi +if [[ $(stat -c %a /var/log/kolla/letsencrypt) != "755" ]]; then + chmod 755 /var/log/kolla/letsencrypt +fi + +# Structure for lego and webserver + +FOLDERS_LEGO="/etc/letsencrypt /etc/letsencrypt/lego /etc/letsencrypt/lego/internal /etc/letsencrypt/lego/external" +FOLDERS_WEBSERVER="/etc/letsencrypt/http-01 /etc/letsencrypt/http-01/.well-known /etc/letsencrypt/http-01/.well-known/acme-challenge" + +if [[ "${KOLLA_BASE_DISTRO}" =~ debian|ubuntu ]]; then + USER="www-data" + GROUP="www-data" + USERGROUP_WEBSERVER="${USER}:${GROUP}" + USERGROUP="haproxy:haproxy" +else + USER="apache" + GROUP="apache" + USERGROUP_WEBSERVER="${USER}:${GROUP}" + USERGROUP="haproxy:haproxy" +fi + +for folder in ${FOLDERS_LEGO}; do + if [[ ! -d "${folder}" ]]; then + mkdir -p ${folder} + fi + + if [[ $(stat -c %U:%G ${folder}) != "${USERGROUP}" ]]; then + if getent passwd ${USER} 2 > /dev/null; then + chown ${USERGROUP} ${folder} + fi + fi + + if [[ "${folder}" == "/etc/letsencrypt" ]]; then + if [[ $(stat -c %a ${folder}) != "751" ]]; then + chmod 751 ${folder} + fi + else + if [[ $(stat -c %a ${folder}) != "755" ]]; then + chmod 755 ${folder} + fi + fi +done + +for folder in ${FOLDERS_WEBSERVER}; do + if [[ ! -d "${folder}" ]]; then + mkdir -p ${folder} + fi + + if [[ $(stat -c %U:%G ${folder}) != "${USERGROUP_WEBSERVER}" ]]; then + if getent passwd ${USER} 2 > /dev/null; then + chown ${USERGROUP_WEBSERVER} ${folder} + fi + fi + + if [[ $(stat -c %a ${folder}) != "755" ]]; then + chmod 755 ${folder} + fi +done + +if [ -e /usr/local/bin/kolla_letsencrypt_extend_start ]; then + . /usr/local/bin/kolla_letsencrypt_extend_start +fi diff --git a/kolla/docker/letsencrypt/letsencrypt-lego/Dockerfile.j2 b/kolla/docker/letsencrypt/letsencrypt-lego/Dockerfile.j2 new file mode 100755 index 000000000..b7cda214e --- /dev/null +++ b/kolla/docker/letsencrypt/letsencrypt-lego/Dockerfile.j2 @@ -0,0 +1,41 @@ +FROM {{ namespace }}/{{ image_prefix }}letsencrypt-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block letsencrypt_lego_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='letsencrypt', shell='/bin/bash') }} + +{% if base_package_type == 'rpm' %} + {% set letsencrypt_lego_packages = [ + 'openssh-clients', + 'cronie', + 'rsync' + ] %} +{% elif base_package_type == 'deb' %} + {% set letsencrypt_lego_packages = [ + 'openssh-client', + 'cron', + 'rsync' + ] %} +{% endif %} +{{ macros.install_packages(letsencrypt_lego_packages | customizable("packages")) }} + +{% block letsencrypt_lego_install %} +ADD letsencrypt-lego-archive /lego-source + +RUN cp -r /lego-source/lego /opt/ +{% endblock %} + +COPY letsencrypt-certificates.sh /usr/bin/letsencrypt-certificates +COPY sync-and-update-certificate.sh /usr/bin/sync-and-update-certificate + +RUN chmod +x /usr/bin/letsencrypt-certificates /usr/bin/sync-and-update-certificate + +{{ macros.kolla_patch_sources() }} + +{% block letsencrypt_lego_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/letsencrypt/letsencrypt-lego/letsencrypt-certificates.sh b/kolla/docker/letsencrypt/letsencrypt-lego/letsencrypt-certificates.sh new file mode 100755 index 000000000..83bdede87 --- /dev/null +++ b/kolla/docker/letsencrypt/letsencrypt-lego/letsencrypt-certificates.sh @@ -0,0 +1,226 @@ +#!/bin/bash + +function log_info { + local message="${1}" + + echo "$(date '+%Y/%m/%d %H:%M:%S') [INFO] ${message}" +} + +function log_error { + local message="${1}" + + echo "$(date '+%Y/%m/%d %H:%M:%S') [ERROR] ${message}" +} + +function obtain_or_renew_certificate { + local certificate_fqdns="${1}" + local certificate_type="${2}" + local listen_port="${3}" + local valid_days="${4}" + local acme_url="${5}" + local mail="${6}" + local letsencrypt_ssh_port="${7}" + local eab="${8}" + local hmac="${9}" + local key_id="${10}" + local letsencrypt_key_type="${11:-}" + + certificate_domain_opts=$(echo ${certificate_fqdns} | sed -r -e 's/^/,/g' -e 's/,/--domains=/g' -e 's/--/ --/g') + certificate_fqdn=$(echo ${certificate_fqdns} | awk -F ',' '{print $1}') + certificate_fqdns=$(echo ${certificate_fqdns} | sed -r 's/,/\ /g') + + if [ -d "/etc/letsencrypt/lego/${certificate_type}/certificates" ]; then + garbage_count=$(find /etc/letsencrypt/lego/${certificate_type}/certificates/ -type f | grep -v "${certificate_fqdn}" | wc -l) + if [ ${garbage_count} -ne 0 ]; then + log_info "[${certificate_fqdn} - cron] Cleaning up garbage in certificates directory." + find /etc/letsencrypt/lego/${certificate_type}/certificates/ -type f | grep -v "${certificate_fqdn}" | xargs rm -f + fi + fi + + if [ -e "/etc/letsencrypt/lego/${certificate_type}/certificates/${certificate_fqdn}.pem" ]; then + certificate_current_fqdns=$(openssl x509 -text -in /etc/letsencrypt/lego/${certificate_type}/certificates/${certificate_fqdn}.pem \ + | grep DNS: \ + | sed -r -e 's/\ *DNS://g' -e 's/^/,/g' -e 's/$/,/g') + + local domains_add="" + for i in ${certificate_fqdns}; do + if ! echo "${certificate_current_fqdns}" | grep -q ",${i},"; then + domains_add="${domains_add} ${i}" + fi + done + domains_add=$(echo "${domains_add}" | sed -r -e 's/^\ //g' -e 's/\ /, /g') + + if [ "${domains_add}" != "" ]; then + log_info "[${certificate_fqdn} - cron] Domains ${domains_add} will be added to certificate." + rm -f /etc/letsencrypt/lego/${certificate_type}/certificates/* + fi + fi + + [ ! -e "/etc/letsencrypt/lego/${certificate_type}/certificates/${certificate_fqdn}.pem" ] && local lego_action="run" || local lego_action="renew" + + if [ "${eab}" = "true" ]; then + if [ "${hmac}" != "NONE" ] && [ "${key_id}" != "NONE" ]; then + eab_opts="--eab --hmac ${hmac} --kid ${key_id}" + else + eab_opts="" + log_error "External Account Binding requires EAB key ID and EAB HMAC key." + exit 1 + fi + fi + + log_info "[${certificate_fqdn} - cron] Obtaining certificate for domains ${certificate_fqdns}." + mapfile -t cmd_output < <(/opt/lego --email="${mail}" \ + $( [ -n "${letsencrypt_key_type}" ] && echo "--key-type ${letsencrypt_key_type}" ) \ + ${certificate_domain_opts} \ + --server "${acme_url}" \ + --path "/etc/letsencrypt/lego/${certificate_type}/" \ + --http.webroot "/etc/letsencrypt/http-01" \ + --http.port ${listen_port} \ + --cert.timeout ${valid_days} \ + --accept-tos \ + --http \ + ${eab_opts} \ + --pem ${lego_action} \ + --${lego_action}-hook="/usr/bin/sync-and-update-certificate --${certificate_type} --fqdn ${certificate_fqdn} --haproxies-ssh ${letsencrypt_ssh_port}" 2>&1) + + # Fix LOG formatting as some output has no same format + # + # Example: + # + # 2023/10/31 11:52:26 No key found for account michal.arbet@ultimum.io. Generating a P256 key. + # 2023/10/31 11:52:26 Saved key to /etc/letsencrypt/lego/external/accounts/acme-v02.api.letsencrypt.org/michal.arbet@ultimum.io/keys/michal.arbet@ultimum.io.key + # 2023/10/31 11:52:27 [INFO] acme: Registering account for michal.arbet@ultimum.io + # !!!! HEADS UP !!!! + + for i in "${cmd_output[@]}"; do + if [ "${i}" == "" ]; then + continue + fi + if ! echo "${i}" | grep -q '\[INFO\]'; then + if [ "$(echo "${i}" | awk -F ' ' '{print $1}')" == "$(date +%Y/%m/%d)" ]; then + echo "${i}" | awk '{out = ""; for (i = 3; i <= NF; i++) {out = out " " $i}; print $1" "$2" [INFO]"out}' + else + dt=$(date '+%Y/%m/%d %H:%M:%S') + echo "${i}" | awk -v dt="$dt" '{print dt" [INFO] "$0}' + fi + else + echo "${i}" + fi + done +} + + +# Parser + +INTERNAL_SET="false" +EXTERNAL_SET="false" +EXTERNAL_ACCOUNT_BINDING="false" +HMAC="NONE" +KEY_ID="NONE" +LOG_FILE="/var/log/kolla/letsencrypt/lesencrypt-lego.log" + + +VALID_ARGS=$(getopt -o ief:p:d:m:a:v:h:k: --long internal,external,fqdns:,port:,days:,mail:,acme:,vips:,haproxies-ssh:,eab,kid:,hmac:,key-type: -- "$@") +if [[ $? -ne 0 ]]; then + exit 1; +fi + +eval set -- "$VALID_ARGS" +while [ : ]; do + case "$1" in + -i | --internal) + CERT_TYPE="internal" + INTERNAL_SET="true" + shift + ;; + -e | --external) + CERT_TYPE="external" + EXTERNAL_SET="true" + shift + ;; + -f | --fqdns) + FQDNS="${2}" + shift 2 + ;; + -p | --port) + PORT="${2}" + shift 2 + ;; + -d | --days) + DAYS="${2}" + shift 2 + ;; + -m | --mail) + MAIL="${2}" + shift 2 + ;; + -a | --acme) + ACME="${2}" + shift 2 + ;; + -v | --vips) + VIPS="${2}" + shift 2 + ;; + -h | --haproxies-ssh) + LETSENCRYPT_SSH_PORT="${2}" + shift 2 + ;; + --eab) + EXTERNAL_ACCOUNT_BINDING="true" + shift + ;; + --hmac) + HMAC="${2}" + shift 2 + ;; + --kid) + KEY_ID="${2}" + shift 2 + ;; + -k | --key-type) + LETSENCRYPT_KEY_TYPE="${2}" + shift 2 + ;; + --) shift; + break + ;; + esac +done + +FQDN=$(echo "${FQDNS}" | awk -F ',' '{print $1}') + +if [ "${INTERNAL_SET}" = "true" ] || [ "${EXTERNAL_SET}" = "true" ]; then + if [ "${INTERNAL_SET}" = "${EXTERNAL_SET}" ]; then + log_error "[${FQDN} - cron] Only --internal or --external parameter is allowed at a time." + exit 1 + fi + + LETSENCRYPT_VIP_ADDRESSES="$(echo ${VIPS} | sed -e 's/,/|/g')" + if [ "${INTERNAL_SET}" = "true" ]; then + LETSENCRYPT_INTERNAL_FQDNS="${FQDNS}" + fi + + if [ "${EXTERNAL_SET}" = "true" ]; then + LETSENCRYPT_EXTERNAL_FQDNS="${FQDNS}" + fi + + if /usr/sbin/ip a | egrep -q "${LETSENCRYPT_VIP_ADDRESSES}"; then + log_info "[${FQDN} - cron] This Letsencrypt-lego host is active..." + if [ "${LETSENCRYPT_INTERNAL_FQDNS}" != "" ]; then + log_info "[${FQDN} - cron] Processing domains ${LETSENCRYPT_INTERNAL_FQDNS}" + obtain_or_renew_certificate ${LETSENCRYPT_INTERNAL_FQDNS} internal ${PORT} ${DAYS} ${ACME} ${MAIL} ${LETSENCRYPT_SSH_PORT} ${EXTERNAL_ACCOUNT_BINDING} ${HMAC} ${KEY_ID} ${LETSENCRYPT_KEY_TYPE} + fi + + if [ "${LETSENCRYPT_EXTERNAL_FQDNS}" != "" ]; then + log_info "[${FQDN} - cron] Processing domains ${LETSENCRYPT_EXTERNAL_FQDNS}" + obtain_or_renew_certificate ${LETSENCRYPT_EXTERNAL_FQDNS} external ${PORT} ${DAYS} ${ACME} ${MAIL} ${LETSENCRYPT_SSH_PORT} ${EXTERNAL_ACCOUNT_BINDING} ${HMAC} ${KEY_ID} ${LETSENCRYPT_KEY_TYPE} + fi + else + log_info "[${FQDN} - cron] This Letsencrypt-lego host is passive, nothing to do..." + fi +fi + +if [ -d "/etc/letsencrypt/lego" ]; then + chown -R haproxy:haproxy /etc/letsencrypt/lego +fi diff --git a/kolla/docker/letsencrypt/letsencrypt-lego/sync-and-update-certificate.sh b/kolla/docker/letsencrypt/letsencrypt-lego/sync-and-update-certificate.sh new file mode 100644 index 000000000..e1e421c46 --- /dev/null +++ b/kolla/docker/letsencrypt/letsencrypt-lego/sync-and-update-certificate.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +function log_info { + local message="${1}" + + echo "$(date '+%Y/%m/%d %H:%M:%S') [INFO] ${message}" +} + +function log_error { + local message="${1}" + + echo "$(date '+%Y/%m/%d %H:%M:%S') [ERROR] ${message}" +} + + +# Parser + +INTERNAL_SET="false" +EXTERNAL_SET="false" +LOG_FILE="/var/log/kolla/letsencrypt/lesencrypt-lego.log" + + +VALID_ARGS=$(getopt -o ief:l: --long internal,external,fqdn:,haproxies-ssh: -- "$@") +if [[ $? -ne 0 ]]; then + exit 1; +fi + +eval set -- "$VALID_ARGS" +while [ : ]; do + case "$1" in + -i | --internal) + CERT_TYPE="internal" + INTERNAL_SET="true" + shift + ;; + -e | --external) + CERT_TYPE="external" + EXTERNAL_SET="true" + shift + ;; + -f | --fqdn) + FQDN="${2}" + shift 2 + ;; + -l | --haproxies-ssh) + HAPROXIES_SSH_HOSTS_PORT="${2}" + shift 2 + ;; + --) shift; + break + ;; + esac +done + +if [ "${INTERNAL_SET}" = "true" ] || [ "${EXTERNAL_SET}" = "true" ]; then + if [ "${INTERNAL_SET}" = "${EXTERNAL_SET}" ]; then + log_error "[${FQDN} - hook] Only --internal or --external parameter is allowed at a time" + exit 1 + fi + + HAPROXIES_SSH_HOSTS_PORT=$(echo ${HAPROXIES_SSH_HOSTS_PORT} | sed -e 's/,/ /g') + + for i in ${HAPROXIES_SSH_HOSTS_PORT}; do + + server=$(echo $i | awk -F ':' '{print $1}') + port=$(echo $i | awk -F ':' '{print $2}') + + if ! /usr/sbin/ip a | grep -q "${server}"; then + + log_info "[${FQDN} - hook] Rsync lego data /etc/letsencrypt/lego/ to server ${server} and port ${port}" + rsync -a -e "ssh -p ${port} -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o IdentityFile=/var/lib/letsencrypt/.ssh/id_rsa" /etc/letsencrypt/lego/ haproxy@${server}:/etc/letsencrypt/lego/ --delete >/dev/null 2>&1 + if [ "$?" -eq 0 ]; then + log_info "[${FQDN} - hook] Rsync Successful." + fi + + else + log_info "[${FQDN} - hook] Rsync lego data /etc/letsencrypt/lego/ to server ${server} and port ${port} not needed." + fi + + if [ "${INTERNAL_SET}" = "true" ]; then + internal_cert_path=$(find /etc/letsencrypt/lego/internal/ -name '*.pem') + sed -i '/^$/d' ${internal_cert_path} + rsync -av -e "ssh -p ${port} -o StrictHostKeyChecking=no -o IdentityFile=/var/lib/letsencrypt/.ssh/id_rsa" ${internal_cert_path} haproxy@${server}:/var/lib/haproxy/haproxy-internal.pem --delete >/dev/null 2>&1 + ssh -p ${port} -i /var/lib/letsencrypt/.ssh/id_rsa -o StrictHostKeyChecking=no haproxy@${server} "/usr/bin/update-loadbalancer-cert --internal" + else + external_cert_path=$(find /etc/letsencrypt/lego/external/ -name '*.pem') + sed -i '/^$/d' ${external_cert_path} + rsync -av -e "ssh -p ${port} -o StrictHostKeyChecking=no -o IdentityFile=/var/lib/letsencrypt/.ssh/id_rsa" ${external_cert_path} haproxy@${server}:/var/lib/haproxy/haproxy.pem --delete >/dev/null 2>&1 + ssh -p ${port} -i /var/lib/letsencrypt/.ssh/id_rsa -o StrictHostKeyChecking=no haproxy@${server} "/usr/bin/update-loadbalancer-cert --external" + fi + + done +fi diff --git a/kolla/docker/macros.j2 b/kolla/docker/macros.j2 new file mode 100644 index 000000000..34d67335c --- /dev/null +++ b/kolla/docker/macros.j2 @@ -0,0 +1,97 @@ +{% macro install_packages(packages, chain=False, clean=clean_package_cache) -%} +{% if packages is defined and packages|length > 0 -%} + {% if not chain -%} RUN {% endif -%} + {%- if base_package_type == 'rpm' -%} + {{ distro_package_manager }} -y install {{ packages | join(' ') }} + {%- if clean %} \ + && {{ distro_package_manager }} clean all && rm -rf /var/cache/{{ distro_package_manager }}{% endif -%} + {%- elif base_package_type == 'deb' -%} + {#- + debian_package_install is a utility method to build up an appropriate + set of commands to install packages in a debian-based environment that + may include URL links to a .deb package + -#} + {{ debian_package_install(packages, clean) }} + {%- endif %} +{%- endif %} +{%- endmacro %} + +{# Be Extra vigilant about introducing any extra whitespace at the + end of the macro for chaining purposes -#} +{% macro rpm_security_update(cleanup) -%} + {{ distro_package_manager }} -y distro-sync --security --sec-severity=Important --sec-severity=Critical + {%- if cleanup %} \ + && {{ distro_package_manager }} clean all && rm -rf /var/cache/{{ distro_package_manager }}{% endif -%} +{%- endmacro %} + +{% macro sed(file='', expressions=[]) -%} +{% if file != '' and expressions|length >0 %} + RUN {% for expression in expressions %} sed -i "{{ file }}" -e "{{ expression }}" {% if not loop.last %} && {% endif %} {% endfor %} +{% else %} + RUN echo "file and expressions must be set to use the sed macro"; /bin/false +{% endif %} +{%- endmacro %} + +{% macro install_pip(packages, constraints=true, python_version='3') %} +{%- if packages is sequence and packages|length > 0 -%} + python{{ python_version }} -m pip --no-cache-dir install --upgrade{{ ' ' }} + {%- if constraints %}-c /requirements/upper-constraints.txt {% endif -%} + {{ packages | join(' ') }} +{%- else -%} + true +{%- endif -%} +{% endmacro %} + +{% macro configure_user(name, groups=None, shell=None, homedir=None) %} +{%- if name not in users %} +{{ raise_error("Failed to find configuration for '" + name + "' user. Try specifying '" + name + "-user' config section.") }} +{%- endif %} +{% set user=users[name] %} +{%- if not homedir %} +{% set homedir='/var/lib/' + name %} +{%- endif %} +RUN usermod --append --home {{ homedir }} --groups kolla {{ name }} \ + {%- if groups %} + && usermod --append --groups {{ groups }} {{ name }} \ + {%- endif %} + {%- if shell %} + && chsh --shell {{ shell }} {{ name }} \ + {%- endif %} + && mkdir -p {{ homedir }} \ + && chown -R {{ user.uid }}:{{ user.gid }} {{ homedir }} +{% endmacro %} + +{% macro install_fluent_plugins(plugins, chain=False) -%} +{% if plugins is defined and plugins|length > 0 -%} + {% if not chain -%} RUN {% endif -%} + ulimit -n 1024 && fluent-gem install {{ plugins | join(' ') }} +{%- endif %} +{%- endmacro %} + +{% macro enable_extra_repos(repos) %} + +{{ handle_repos(repos, 'enable') }} + +{% endmacro %} + +{% macro disable_extra_repos(repos) %} + +{{ handle_repos(repos, 'disable') }} + +{% endmacro %} + +{% macro upper_constraints_remove(package_name) -%} +sed -e "/^{{ package_name }}===/d" -i requirements/upper-constraints.txt +{%- endmacro %} + +{# NOTE(hrw): we change to "==" to allow for "21.*" syntax #} +{% macro upper_constraints_version_change(package_name, from, to) -%} +sed -e "s/^{{package_name}}==={{ from }}/{{package_name}}=={{ to }}/g" -i requirements/upper-constraints.txt +{%- endmacro %} + +{% macro kolla_patch_sources() -%} +{% if patches_path %} + COPY patches /patches + RUN kolla_patch +{% endif %} +{%- endmacro %} diff --git a/kolla/docker/magnum/magnum-api/Dockerfile.j2 b/kolla/docker/magnum/magnum-api/Dockerfile.j2 new file mode 100644 index 000000000..304b54e20 --- /dev/null +++ b/kolla/docker/magnum/magnum-api/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}magnum-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block magnum_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_magnum_extend_start +RUN chmod 644 /usr/local/bin/kolla_magnum_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block magnum_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER magnum diff --git a/kolla/docker/magnum/magnum-api/extend_start.sh b/kolla/docker/magnum/magnum-api/extend_start.sh new file mode 100644 index 000000000..0f92f6e7b --- /dev/null +++ b/kolla/docker/magnum/magnum-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + magnum-db-manage upgrade + exit 0 +fi diff --git a/kolla/docker/magnum/magnum-base/Dockerfile.j2 b/kolla/docker/magnum/magnum-base/Dockerfile.j2 new file mode 100644 index 000000000..ac17b94b4 --- /dev/null +++ b/kolla/docker/magnum/magnum-base/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block magnum_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='magnum') }} + +ADD magnum-base-archive /magnum-base-source + +{% set magnum_base_pip_packages = [ + '/magnum[osprofiler]', + 'magnum-cluster-api' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s magnum-base-source/* magnum \ + && {{ macros.install_pip(magnum_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/magnum \ + && cp -r /magnum/etc/magnum/* /etc/magnum \ + && mv /etc/magnum/keystone_auth_default_policy.sample /etc/magnum/keystone_auth_default_policy.json \ + && touch /usr/local/bin/kolla_magnum_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_magnum_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block magnum_base_footer %}{% endblock %} diff --git a/kolla/docker/magnum/magnum-base/extend_start.sh b/kolla/docker/magnum/magnum-base/extend_start.sh new file mode 100644 index 000000000..2e58c9776 --- /dev/null +++ b/kolla/docker/magnum/magnum-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/magnum" ]]; then + mkdir -p /var/log/kolla/magnum +fi +if [[ $(stat -c %a /var/log/kolla/magnum) != "755" ]]; then + chmod 755 /var/log/kolla/magnum +fi + +. /usr/local/bin/kolla_magnum_extend_start diff --git a/kolla/docker/magnum/magnum-conductor/Dockerfile.j2 b/kolla/docker/magnum/magnum-conductor/Dockerfile.j2 new file mode 100644 index 000000000..6e2df8fed --- /dev/null +++ b/kolla/docker/magnum/magnum-conductor/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}magnum-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block magnum_conductor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +ADD plugins-archive / +RUN cp /plugins/linux-{{ debian_arch }}/helm /usr/local/bin/helm + +{{ macros.kolla_patch_sources() }} + +{% block magnum_conductor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER magnum diff --git a/kolla/docker/manila/manila-api/Dockerfile.j2 b/kolla/docker/manila/manila-api/Dockerfile.j2 new file mode 100644 index 000000000..d7b75d388 --- /dev/null +++ b/kolla/docker/manila/manila-api/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}manila-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block manila_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set manila_api_packages = [ +] %} +{{ macros.install_packages(manila_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_manila_extend_start + +RUN chmod 644 /usr/local/bin/kolla_manila_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block manila_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER manila diff --git a/kolla/docker/manila/manila-api/extend_start.sh b/kolla/docker/manila/manila-api/extend_start.sh new file mode 100644 index 000000000..bea77dbba --- /dev/null +++ b/kolla/docker/manila/manila-api/extend_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash +set -o errexit + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + manila-manage db sync + exit 0 +fi diff --git a/kolla/docker/manila/manila-base/Dockerfile.j2 b/kolla/docker/manila/manila-base/Dockerfile.j2 new file mode 100644 index 000000000..a236a20df --- /dev/null +++ b/kolla/docker/manila/manila-base/Dockerfile.j2 @@ -0,0 +1,48 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block manila_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='manila') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + + {% set manila_base_packages = ['openvswitch${KOLLA_RPM_OVS_VERSION}'] %} + +{% elif base_package_type == 'deb' %} + + {% set manila_base_packages = ['openvswitch-switch'] %} + +{% endif %} + +{{ macros.install_packages(manila_base_packages | customizable("packages")) }} + +ADD manila-base-archive /manila-base-source + +{% set manila_base_pip_packages = [ + '/manila' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY manila_sudoers /etc/sudoers.d/kolla_manila_sudoers + +RUN ln -s manila-base-source/* manila \ + && {{ macros.install_pip(manila_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/manila /var/cache/manila \ + && cp -r /manila/etc/manila/* /etc/manila/ \ + && chown -R manila: /var/cache/manila \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/manila/rootwrap.conf \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_manila_sudoers \ + && touch /usr/local/bin/kolla_manila_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_manila_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block manila_base_footer %}{% endblock %} diff --git a/kolla/docker/manila/manila-base/extend_start.sh b/kolla/docker/manila/manila-base/extend_start.sh new file mode 100644 index 000000000..c018416a3 --- /dev/null +++ b/kolla/docker/manila/manila-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/manila" ]]; then + mkdir -p /var/log/kolla/manila +fi +if [[ $(stat -c %a /var/log/kolla/manila) != "755" ]]; then + chmod 755 /var/log/kolla/manila +fi + +. /usr/local/bin/kolla_manila_extend_start diff --git a/kolla/docker/manila/manila-base/manila_sudoers b/kolla/docker/manila/manila-base/manila_sudoers new file mode 100644 index 000000000..623e6789b --- /dev/null +++ b/kolla/docker/manila/manila-base/manila_sudoers @@ -0,0 +1 @@ +manila ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/manila-rootwrap /etc/manila/rootwrap.conf * diff --git a/kolla/docker/manila/manila-data/Dockerfile.j2 b/kolla/docker/manila/manila-data/Dockerfile.j2 new file mode 100644 index 000000000..06e1d9dc9 --- /dev/null +++ b/kolla/docker/manila/manila-data/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}manila-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block manila_data_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + + {% set manila_data_packages = [ + 'nfs-utils' + ] %} + +{% elif base_package_type == 'deb' %} + + {% set manila_data_packages = [ + 'nfs-common' + ] %} + +{% endif %} + +{{ macros.install_packages(manila_data_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block manila_data_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER manila diff --git a/kolla/docker/manila/manila-scheduler/Dockerfile.j2 b/kolla/docker/manila/manila-scheduler/Dockerfile.j2 new file mode 100644 index 000000000..12f7860f4 --- /dev/null +++ b/kolla/docker/manila/manila-scheduler/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}manila-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block manila_scheduler_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block manila_scheduler_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER manila diff --git a/kolla/docker/manila/manila-share/Dockerfile.j2 b/kolla/docker/manila/manila-share/Dockerfile.j2 new file mode 100644 index 000000000..161b6865a --- /dev/null +++ b/kolla/docker/manila/manila-share/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM {{ namespace }}/{{ image_prefix }}manila-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block manila_share_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set manila_share_packages = [ + 'ceph-common', + 'sqlite', + ] %} +{% elif base_package_type == 'deb' %} + {% set manila_share_packages = [ + 'ceph-common', + 'glusterfs-client', + 'python3-cephfs', + 'python3-rados', + 'python3-rbd', + 'sqlite3' + ] %} + +{% endif %} + +{{ macros.install_packages(manila_share_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block manila_share_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER manila diff --git a/kolla/docker/mariadb-server/Dockerfile.j2 b/kolla/docker/mariadb-server/Dockerfile.j2 new file mode 100644 index 000000000..612b37330 --- /dev/null +++ b/kolla/docker/mariadb-server/Dockerfile.j2 @@ -0,0 +1,96 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mariadb_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='mysql') }} + +{% if base_package_type == 'rpm' %} + +{# NOTE(mgoddard): EPEL required for pv package #} +{{ macros.enable_extra_repos(['epel', 'mariadb']) }} + + {% set mariadb_packages = [ + 'expect', + 'mariadb', + 'mariadb-backup', + 'mariadb-server', + 'pv', + 'rsync', + 'tar' + ] %} + +{# NOTE(yoctozepto): this is to ensure Kolla Ansible can configure MariaDB to find it #} +RUN ln -s /usr/lib64/galera-4 /usr/lib64/galera + +{% elif base_package_type == 'deb' %} +{{ macros.enable_extra_repos(['mariadb']) }} + {% set mariadb_packages = [ + 'expect', + 'mariadb-backup', + 'mariadb-client', + 'mariadb-server', + 'pv', + 'rsync', + 'tar' + ] %} +{% endif %} + +{{ macros.install_packages(mariadb_packages | customizable("packages")) }} + +{% block mariadb_healthcheck %} +ENV MARIADB_VERSION=11.4 +ADD plugins-archive / +RUN install -m 755 /plugins/mariadb-server-plugin-mariadb-docker-archive*/$MARIADB_VERSION/healthcheck.sh /usr/bin/healthcheck.sh +{% endblock %} + +COPY mariadb_sudoers /etc/sudoers.d/kolla_mariadb_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY security_reset.expect /usr/local/bin/kolla_security_reset +COPY backup.sh /usr/local/bin/kolla_mariadb_backup.sh +COPY backup_replica.sh /usr/local/bin/kolla_mariadb_backup_replica.sh + +RUN chmod 644 /usr/local/bin/kolla_extend_start \ + && chmod 755 /usr/local/bin/kolla_security_reset \ + /usr/local/bin/kolla_mariadb_backup.sh \ + /usr/local/bin/kolla_mariadb_backup_replica.sh \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_mariadb_sudoers \ + && rm -rf /var/lib/mysql/* + +{% if base_package_type == 'deb' %} +RUN mkdir -p /var/run/mysqld && chown mysql /var/run/mysqld && chmod 755 /var/run/mysqld +{% endif %} + +{% if docker_healthchecks %} +{% block healthcheck_installation %} + +COPY healthcheck_mariadb /usr/local/bin/healthcheck_mariadb +RUN chmod 755 /usr/local/bin/healthcheck_mariadb + +{% endblock %} +{% endif %} + +{% if use_dumb_init %} +{% block mariadb_entrypoint %} +# NOTE(mgoddard): Override the dumb-init arguments to avoid passing +# --single-child. This does not play well with mysqld_safe, which ignores +# SIGTERM, meaning Docker needs to forcibly kill the container to stop it. +# Without --single-child, the TERM signal is sent to all subprocesses, +# including mysqld. + +ENTRYPOINT ["dumb-init", "--"] +CMD ["kolla_start"] +{% endblock %} +{% endif %} + +{{ macros.kolla_patch_sources() }} + +{% block mariadb_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER mysql diff --git a/kolla/docker/mariadb-server/backup.sh b/kolla/docker/mariadb-server/backup.sh new file mode 100644 index 000000000..be63cd938 --- /dev/null +++ b/kolla/docker/mariadb-server/backup.sh @@ -0,0 +1,73 @@ +#!/usr/bin/env bash + +set -eu +set -o pipefail + +# Execute a full backup +backup_full() { + echo "Taking a full backup" + LAST_FULL_DATE=$(date +%d-%m-%Y-%s) + BACKUP_FILE="mysqlbackup-${LAST_FULL_DATE}.qp.xbc.xbs.gz" + BACKUP_PATH="$BACKUP_DIR/full-${LAST_FULL_DATE}" + mkdir -p "$BACKUP_PATH" + + mariabackup \ + --defaults-file=/etc/mysql/my.cnf \ + --backup \ + --stream=xbstream \ + --history=$LAST_FULL_DATE | gzip > \ + "$BACKUP_PATH/$BACKUP_FILE" + + echo "$BACKUP_PATH/$BACKUP_FILE" > "$BACKUP_DIR/last_full_file" +} + +# Execute an incremental backup +backup_incremental() { + echo "Taking an incremental backup" + + if [ ! -r "$BACKUP_DIR/last_full_file" ]; then + echo "Error: No full backup file found." + exit 1 + fi + + FULL_BACKUP_FILE=$(cat "$BACKUP_DIR/last_full_file") + LAST_FULL_DATE=$(basename "$(dirname "$FULL_BACKUP_FILE")" | sed 's/^full-//') + NOW=$(date +%H-%M-%S-%d-%m-%Y) + INCR_DIR="$BACKUP_DIR/incr-${NOW}-since-${LAST_FULL_DATE}" + mkdir -p "$INCR_DIR" + + TMP_BASEDIR=$(mktemp -d) + echo "Decompressing full backup to temp dir: $TMP_BASEDIR" + gunzip -c "$FULL_BACKUP_FILE" | mbstream -x -C "$TMP_BASEDIR" + + mariabackup \ + --defaults-file=/etc/mysql/my.cnf \ + --backup \ + --stream=xbstream \ + --incremental-basedir="$TMP_BASEDIR" \ + --history="incr-${NOW}" | gzip > \ + "$INCR_DIR/incremental-${NOW}-mysqlbackup-${LAST_FULL_DATE}.qp.xbc.xbs.gz" + + rm -rf "$TMP_BASEDIR" +} + +BACKUP_DIR=/backup/ +cd "$BACKUP_DIR" + +if [ -n "${BACKUP_TYPE:-}" ]; then + case "$BACKUP_TYPE" in + "full") + backup_full + ;; + "incremental") + backup_incremental + ;; + *) + echo "Only full or incremental options are supported." + exit 1 + ;; + esac +else + echo "You need to specify either full or incremental backup options." + exit 1 +fi diff --git a/kolla/docker/mariadb-server/backup_replica.sh b/kolla/docker/mariadb-server/backup_replica.sh new file mode 100644 index 000000000..fe10bc61b --- /dev/null +++ b/kolla/docker/mariadb-server/backup_replica.sh @@ -0,0 +1,149 @@ +#!/usr/bin/env bash + +set -eu +set -o pipefail + +BACKUP_DIR=/backup/ +DEFAULT_MY_CNF="/etc/mysql/my.cnf" +REPLICA_MY_CNF="$(mktemp)" +RETRY_INTERVAL=5 # Interval between retries (in seconds) +MAX_RETRIES=12 # Max retries (12 retries * 5 seconds = 60 seconds) +VERIFY_DB_SERVER_CERT="${VERIFY_DB_SERVER_CERT:=FALSE}" + +# Cleanup function to remove the REPLICA_MY_CNF file +cleanup() { + rm -f "${REPLICA_MY_CNF}" +} + +# Set trap to ensure cleanup occurs on exit or error +trap cleanup EXIT + +cd "${BACKUP_DIR}" + +# Execute a full backup +backup_full() { + echo "Taking a full backup" + LAST_FULL_DATE=$(date +%d-%m-%Y-%s) + BACKUP_FILE="backup-full-${LAST_FULL_DATE}.mbs.gz" + BACKUP_PATH="${BACKUP_DIR}/full-${LAST_FULL_DATE}" + mkdir -p "${BACKUP_PATH}" + + mariabackup \ + --defaults-file="${REPLICA_MY_CNF}" \ + --backup \ + --stream=mbstream \ + --history="${LAST_FULL_DATE}" \ + | gzip > "${BACKUP_PATH}/${BACKUP_FILE}" + + echo "${BACKUP_PATH}/${BACKUP_FILE}" > "${BACKUP_DIR}/last_full_file" +} + +# Execute an incremental backup +backup_incremental() { + if [ ! -r "${BACKUP_DIR}/last_full_file" ]; then + echo "Error: No full backup file found." + exit 1 + fi + + FULL_BACKUP_FILE=$(cat "${BACKUP_DIR}/last_full_file") + LAST_FULL_DATE=$(basename "$(dirname "${FULL_BACKUP_FILE}")" | sed 's/^full-//') + NOW=$(date +%H-%M-%S-%d-%m-%Y) + INCR_DIR="${BACKUP_DIR}/incr-${NOW}-since-${LAST_FULL_DATE}" + mkdir -p "${INCR_DIR}" + + # Temp dir for full base restore + TMP_BASEDIR=$(mktemp -d) + + echo "Decompressing full backup to temp dir: ${TMP_BASEDIR}" + gunzip -c "${FULL_BACKUP_FILE}" | mbstream -x -C "${TMP_BASEDIR}" + + mariabackup \ + --defaults-file="${REPLICA_MY_CNF}" \ + --backup \ + --stream=mbstream \ + --incremental-basedir="${TMP_BASEDIR}" \ + --history="incr-${NOW}" \ + | gzip > "${INCR_DIR}/backup-incremental-${NOW}.mbs.gz" + + rm -rf "${TMP_BASEDIR}" +} + +# Retry logic for database queries +retry_mysql_query() { + local query="$1" + local result="" + local attempt=1 + + while [ ${attempt} -le ${MAX_RETRIES} ]; do + result=$(mariadb --ssl-verify-server-cert="${VERIFY_DB_SERVER_CERT}" -h "${HOST}" -u "${USER}" -p"${PASS}" -s -N -e "${query}" 2>/dev/null || true) + if [ -n "${result}" ]; then + echo "${result}" + return 0 + fi + echo "Attempt ${attempt}/${MAX_RETRIES} failed. Retrying in ${RETRY_INTERVAL} seconds..." + sleep "${RETRY_INTERVAL}" + attempt=$((attempt + 1)) + done + + echo "Error: Failed to execute the query after ${MAX_RETRIES} attempts." + return 1 +} + +get_and_set_replica_server() { + HOST="$(grep '^host' "${DEFAULT_MY_CNF}" | awk -F '=' '{print $2}' | xargs)" + USER="$(grep '^user' "${DEFAULT_MY_CNF}" | awk -F '=' '{print $2}' | xargs)" + PASS="$(grep '^password' "${DEFAULT_MY_CNF}" | awk -F '=' '{print $2}' | xargs)" + + ALL_HOSTS_SELECT="SELECT REGEXP_REPLACE(VARIABLE_VALUE, ':[0-9]*','') FROM information_schema.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_incoming_addresses';" + ALL_HOSTS=$(retry_mysql_query "${ALL_HOSTS_SELECT}") + if [ -z "${ALL_HOSTS}" ]; then + echo "Backup failed due to inability to fetch a list of servers." + exit 1 + fi + + ACTIVE_HOST_SELECT='SELECT @@hostname;' + ACTIVE_HOST=$(retry_mysql_query "${ACTIVE_HOST_SELECT}" | xargs getent hosts | awk '{print $1}') + if [ -z "${ACTIVE_HOST}" ]; then + echo "Backup failed due to inability to fetch active host." + exit 1 + fi + + # Multinode + if echo "${ALL_HOSTS}" | grep -q ','; then + for server in $(echo "${ALL_HOSTS}" | tr ',' '\n'); do + if [[ "${server}" != "${ACTIVE_HOST}" ]]; then + REPLICA_HOST="${server}" + break + fi + done + # Single node + else + REPLICA_HOST="${ALL_HOSTS}" + fi + if [ -z "${REPLICA_HOST}" ]; then + echo "Backup failed due to inability to determine replica host." + exit 1 + fi + + cp "${DEFAULT_MY_CNF}" "${REPLICA_MY_CNF}" + sed -i "s/${HOST}/${REPLICA_HOST}/g" "${REPLICA_MY_CNF}" +} + +if [ -n "${BACKUP_TYPE}" ]; then + get_and_set_replica_server + case "${BACKUP_TYPE}" in + "full") + backup_full + ;; + "incremental") + backup_incremental + ;; + *) + echo "Only full or incremental options are supported." + exit 1 + ;; + esac +else + echo "You need to specify either full or incremental backup options." + exit 1 +fi diff --git a/kolla/docker/mariadb-server/extend_start.sh b/kolla/docker/mariadb-server/extend_start.sh new file mode 100644 index 000000000..f14c85949 --- /dev/null +++ b/kolla/docker/mariadb-server/extend_start.sh @@ -0,0 +1,61 @@ +#!/bin/bash + +: ${MARIADB_LOG_DIR:=/var/log/kolla/mariadb} + +function bootstrap_db { + mariadbd-safe --wsrep-new-cluster --skip-networking --wsrep-on=OFF --pid-file=/var/lib/mysql/mariadb.pid & + # Wait for the mariadb server to be "Ready" before starting the security reset with a max timeout + # NOTE(huikang): the location of mysql's socket file varies depending on the OS distributions. + # Querying the cluster status has to be executed after the existence of mysql.sock and mariadb.pid. + TIMEOUT=${DB_MAX_TIMEOUT:-60} + while [[ ! -S /var/lib/mysql/mysql.sock ]] && \ + [[ ! -S /var/run/mysqld/mysqld.sock ]] || \ + [[ ! -f /var/lib/mysql/mariadb.pid ]]; do + if [[ ${TIMEOUT} -gt 0 ]]; then + let TIMEOUT-=1 + sleep 1 + else + exit 1 + fi + done + + sudo -E kolla_security_reset + + set +o xtrace + mariadb -u root --password="${DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' IDENTIFIED BY '${DB_ROOT_PASSWORD}' WITH GRANT OPTION;" + mariadb -u root --password="${DB_ROOT_PASSWORD}" -e "GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '${DB_ROOT_PASSWORD}' WITH GRANT OPTION;" + mariadb-admin -uroot -p"${DB_ROOT_PASSWORD}" shutdown + set -o xtrace +} + +# Create log directory, with appropriate permissions +if [[ ! -d "${MARIADB_LOG_DIR}" ]]; then + mkdir -p ${MARIADB_LOG_DIR} +fi +if [[ $(stat -c %a ${MARIADB_LOG_DIR}) != "755" ]]; then + chmod 755 ${MARIADB_LOG_DIR} +fi + +# This catches all cases of the BOOTSTRAP variable being set, including empty +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + mariadb-install-db 2>&1 | tee -a ${MARIADB_LOG_DIR}/mariadb-bootstrap.log + bootstrap_db 2>&1 | tee -a ${MARIADB_LOG_DIR}/mariadb-bootstrap.log + exit 0 +fi + +# This catches all cases of the KOLLA_UPGRADE variable being set, including empty +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + # The mariadb-upgrade command treats any directories under /var/lib/mysql as + # databases. Somehow we can end up with a .pki directory, which causes the + # command to fail with this error: + # Incorrect database name '#mysql50#.pki' when selecting the database + # There doesn't seem to be anything in the directory, so remove it. + rm -rf /var/lib/mysql/.pki + + mariadb-upgrade --host=${DB_HOST} --port=${DB_PORT} --user=root --password="${DB_ROOT_PASSWORD}" 2>&1 | tee -a ${MARIADB_LOG_DIR}/mariadb-upgrade.log + exit 0 +fi + +if [[ "${!BOOTSTRAP_ARGS[@]}" ]]; then + ARGS="${BOOTSTRAP_ARGS}" +fi diff --git a/kolla/docker/mariadb-server/healthcheck_mariadb b/kolla/docker/mariadb-server/healthcheck_mariadb new file mode 100755 index 000000000..0d9f59a95 --- /dev/null +++ b/kolla/docker/mariadb-server/healthcheck_mariadb @@ -0,0 +1,19 @@ +#!/bin/bash + +set -e + +MYSQL_USERNAME="${MYSQL_USERNAME:=-haproxy}" +MYSQL_TIMEOUT=10 + +MYSQL_CMDLINE="mysql -sN --connect-timeout=${MYSQL_TIMEOUT} -u ${MYSQL_USERNAME}" + +WSREP_STATUS=$($MYSQL_CMDLINE -e "SHOW STATUS LIKE 'wsrep_local_state_comment';" | awk '{print $2}') + +if [[ "${WSREP_STATUS}" == "Synced" ]] +then + echo "MariaDB Galera Cluster Node is synced." + exit 0 +else + echo "MariaDB Galera Cluster Node is NOT synced" + exit 1 +fi diff --git a/kolla/docker/mariadb-server/mariadb_sudoers b/kolla/docker/mariadb-server/mariadb_sudoers new file mode 100644 index 000000000..150534e16 --- /dev/null +++ b/kolla/docker/mariadb-server/mariadb_sudoers @@ -0,0 +1 @@ +%kolla ALL=(root) NOPASSWD: /usr/local/bin/kolla_security_reset diff --git a/kolla/docker/mariadb-server/security_reset.expect b/kolla/docker/mariadb-server/security_reset.expect new file mode 100644 index 000000000..06f1d5c8e --- /dev/null +++ b/kolla/docker/mariadb-server/security_reset.expect @@ -0,0 +1,67 @@ +#!/usr/bin/expect -f + +if [catch {set timeout $env(DB_MAX_TIMEOUT)}] {set timeout 10} +spawn mariadb-secure-installation +expect { + timeout { send_user "\nFailed to get 'Enter current password for root (enter for none):' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Enter current password for root (enter for none):' prompt\n"; exit 1 } + "Enter current password for root (enter for none):" +} +send "\r" + +expect { + timeout { send_user "\nFailed to get 'Switch to unix_socket authentication [Y/n] ' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Switch to unix_socket authentication [Y/n]' prompt\n"; exit 1 } + "Switch to unix_socket authentication \\\[Y/n\\\] " +} +send "n\r" + +expect { + timeout { send_user "\nFailed to get 'Change the root password? [Y/n]' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Change the root password? [Y/n]' prompt\n"; exit 1 } + "Change the root password? \\\[Y/n\\\] " +} +send "y\r" + +expect { + timeout { send_user "\nFailed to get 'New password:' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'New password:' prompt\n"; exit 1 } + "New password:" +} +send "$env(DB_ROOT_PASSWORD)\r" + +expect { + timeout { send_user "\nFailed to get 'Re-enter new password:' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Re-enter new password:' prompt\n"; exit 1 } + "Re-enter new password:" +} +send "$env(DB_ROOT_PASSWORD)\r" + +expect { + timeout { send_user "\nFailed to get 'Remove anonymous users?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Remove anonymous users?' prompt\n"; exit 1 } + "Remove anonymous users?" +} +send "y\r" + +expect { + timeout { send_user "\nFailed to get 'Disallow root login remotely?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Disallow root login remotely?' prompt\n"; exit 1 } + "Disallow root login remotely?" +} +send "n\r" + +expect { + timeout { send_user "\nFailed to get 'Remove test database and access to it?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Remove test database and access to it?' prompt\n"; exit 1 } + "Remove test database and access to it?" +} +send "y\r" + +expect { + timeout { send_user "\nFailed to get 'Reload privilege tables now?' prompt\n"; exit 1 } + eof { send_user "\nFailed to get 'Reload privilege tables now?' prompt\n"; exit 1 } + "Reload privilege tables now?" +} +send "y\r" +expect eof diff --git a/kolla/docker/masakari/masakari-api/Dockerfile.j2 b/kolla/docker/masakari/masakari-api/Dockerfile.j2 new file mode 100644 index 000000000..5285c6a36 --- /dev/null +++ b/kolla/docker/masakari/masakari-api/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}masakari-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block masakari_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_masakari_extend_start +RUN chmod 644 /usr/local/bin/kolla_masakari_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block masakari_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/masakari/masakari-api/extend_start.sh b/kolla/docker/masakari/masakari-api/extend_start.sh new file mode 100755 index 000000000..549759f49 --- /dev/null +++ b/kolla/docker/masakari/masakari-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + masakari-manage db sync + exit 0 +fi diff --git a/kolla/docker/masakari/masakari-base/Dockerfile.j2 b/kolla/docker/masakari/masakari-base/Dockerfile.j2 new file mode 100644 index 000000000..97e31247e --- /dev/null +++ b/kolla/docker/masakari/masakari-base/Dockerfile.j2 @@ -0,0 +1,43 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block masakari_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='masakari') }} + +{% if base_package_type == 'rpm' %} + + {% set masakari_base_packages = [ + ] %} + +{% elif base_package_type == 'deb' %} + + {% set masakari_base_packages = [ + ] %} + +{% endif %} + +{{ macros.install_packages(masakari_base_packages | customizable("packages")) }} + +ADD masakari-base-archive /masakari-base-source + +{% set masakari_base_pip_packages = [ + '/masakari' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s masakari-base-source/* masakari \ + && {{ macros.install_pip(masakari_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/masakari \ + && cp -r /masakari/etc/masakari/* /etc/masakari/ \ + && touch /usr/local/bin/kolla_masakari_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_masakari_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block masakari_base_footer %}{% endblock %} diff --git a/kolla/docker/masakari/masakari-base/extend_start.sh b/kolla/docker/masakari/masakari-base/extend_start.sh new file mode 100755 index 000000000..4f13d3e8b --- /dev/null +++ b/kolla/docker/masakari/masakari-base/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/masakari" ]]; then + mkdir -p /var/log/kolla/masakari +fi +if [[ $(stat -c %U:%G /var/log/kolla/masakari) != "masakari:kolla" ]]; then + chown -R masakari:kolla /var/log/kolla/masakari +fi +if [[ $(stat -c %a /var/log/kolla/masakari) != "755" ]]; then + chmod 755 /var/log/kolla/masakari +fi + +. /usr/local/bin/kolla_masakari_extend_start diff --git a/kolla/docker/masakari/masakari-engine/Dockerfile.j2 b/kolla/docker/masakari/masakari-engine/Dockerfile.j2 new file mode 100644 index 000000000..8dfb3175c --- /dev/null +++ b/kolla/docker/masakari/masakari-engine/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}masakari-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block masakari_engine_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block masakari_engine_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER masakari diff --git a/kolla/docker/masakari/masakari-monitors/Dockerfile.j2 b/kolla/docker/masakari/masakari-monitors/Dockerfile.j2 new file mode 100644 index 000000000..92b8c3947 --- /dev/null +++ b/kolla/docker/masakari/masakari-monitors/Dockerfile.j2 @@ -0,0 +1,55 @@ +FROM {{ namespace }}/{{ image_prefix }}masakari-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block masakari_monitors_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['hacluster']) }} + + {% set masakari_monitors_packages = [ + 'cyrus-sasl-md5', + 'cyrus-sasl-scram', + 'python3-libvirt', + 'pacemaker-cli', + 'tcpdump', + ] %} + +{% elif base_package_type == 'deb' %} + + {% set masakari_monitors_packages = [ + 'libsasl2-modules-gssapi-mit', + 'python3-libvirt', + 'pacemaker-cli-utils', + 'sasl2-bin', + 'tcpdump', + ] %} + +{% endif %} + +{{ macros.install_packages(masakari_monitors_packages | customizable("packages")) }} + +ADD masakari-monitors-archive /masakari-monitors-source + +{% set masakari_monitors_pip_packages = [ + '/masakari-monitors' +] %} + +COPY masakari_monitors_sudoers /etc/sudoers.d/kolla_masakari_monitors_sudoers + +RUN ln -s masakari-monitors-source/* masakari-monitors \ + && {{ macros.install_pip(masakari_monitors_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/masakari-monitors \ + && chmod 750 /etc/sudoers.d \ + && chmod 640 /etc/sudoers.d/kolla_masakari_monitors_sudoers + +{{ macros.kolla_patch_sources() }} + +{% block masakari_monitors_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER masakari diff --git a/kolla/docker/masakari/masakari-monitors/masakari_monitors_sudoers b/kolla/docker/masakari/masakari-monitors/masakari_monitors_sudoers new file mode 100644 index 000000000..be3867b5c --- /dev/null +++ b/kolla/docker/masakari/masakari-monitors/masakari_monitors_sudoers @@ -0,0 +1,5 @@ +masakari ALL=(root) NOPASSWD: /var/lib/kolla/venv/bin/privsep-helper +masakari ALL=(root) NOPASSWD: /usr/sbin/tcpdump * +masakari ALL=(root) NOPASSWD: /usr/sbin/crm_mon -X +masakari ALL=(root) NOPASSWD: /usr/sbin/crmadmin * +masakari ALL=(root) NOPASSWD: /usr/sbin/cibadmin --query diff --git a/kolla/docker/memcached/Dockerfile.j2 b/kolla/docker/memcached/Dockerfile.j2 new file mode 100644 index 000000000..dfe90b18e --- /dev/null +++ b/kolla/docker/memcached/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block memcached_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='memcached', homedir='/run/memcache') }} + +{% set memcached_packages = ['memcached'] %} +{{ macros.install_packages(memcached_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block memcached_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER memcached diff --git a/kolla/docker/mistral/mistral-api/Dockerfile.j2 b/kolla/docker/mistral/mistral-api/Dockerfile.j2 new file mode 100644 index 000000000..be3e431e1 --- /dev/null +++ b/kolla/docker/mistral/mistral-api/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}mistral-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mistral_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set mistral_api_packages = [ +] %} +{{ macros.install_packages(mistral_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_mistral_extend_start +RUN chmod 644 /usr/local/bin/kolla_mistral_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block mistral_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/mistral/mistral-api/extend_start.sh b/kolla/docker/mistral/mistral-api/extend_start.sh new file mode 100644 index 000000000..113adb8a2 --- /dev/null +++ b/kolla/docker/mistral/mistral-api/extend_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + mistral-db-manage --config-file /etc/mistral/mistral.conf upgrade head + mistral-db-manage --config-file /etc/mistral/mistral.conf populate + exit 0 +fi diff --git a/kolla/docker/mistral/mistral-base/Dockerfile.j2 b/kolla/docker/mistral/mistral-base/Dockerfile.j2 new file mode 100644 index 000000000..1d72c1cac --- /dev/null +++ b/kolla/docker/mistral/mistral-base/Dockerfile.j2 @@ -0,0 +1,38 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mistral_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='mistral') }} + +ADD mistral-base-archive /mistral-base-source +ADD plugins-archive / + +{% set mistral_base_pip_packages = [ + '/mistral', + 'redis' +] %} + +{% set mistral_base_plugins_pip_packages = [ + '/plugins/*' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s mistral-base-source/* mistral \ + && {{ macros.install_pip(mistral_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/mistral \ + && cp -r /mistral/etc/* /etc/mistral/ \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(mistral_base_plugins_pip_packages) }}; \ + fi \ + && touch /usr/local/bin/kolla_mistral_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_mistral_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block mistral_base_footer %}{% endblock %} diff --git a/kolla/docker/mistral/mistral-base/extend_start.sh b/kolla/docker/mistral/mistral-base/extend_start.sh new file mode 100644 index 000000000..ac2980d6c --- /dev/null +++ b/kolla/docker/mistral/mistral-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/mistral" ]]; then + mkdir -p /var/log/kolla/mistral +fi +if [[ $(stat -c %a /var/log/kolla/mistral) != "755" ]]; then + chmod 755 /var/log/kolla/mistral +fi + +. /usr/local/bin/kolla_mistral_extend_start diff --git a/kolla/docker/mistral/mistral-engine/Dockerfile.j2 b/kolla/docker/mistral/mistral-engine/Dockerfile.j2 new file mode 100644 index 000000000..c5fd5eb0d --- /dev/null +++ b/kolla/docker/mistral/mistral-engine/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}mistral-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mistral_engine_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block mistral_engine_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER mistral diff --git a/kolla/docker/mistral/mistral-event-engine/Dockerfile.j2 b/kolla/docker/mistral/mistral-event-engine/Dockerfile.j2 new file mode 100644 index 000000000..2a05ecf76 --- /dev/null +++ b/kolla/docker/mistral/mistral-event-engine/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}mistral-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mistral_event_engine_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block mistral_event_engine_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER mistral diff --git a/kolla/docker/mistral/mistral-executor/Dockerfile.j2 b/kolla/docker/mistral/mistral-executor/Dockerfile.j2 new file mode 100644 index 000000000..aeae9ed06 --- /dev/null +++ b/kolla/docker/mistral/mistral-executor/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}mistral-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mistral_executor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block mistral_executor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER mistral diff --git a/kolla/docker/multipathd/Dockerfile.j2 b/kolla/docker/multipathd/Dockerfile.j2 new file mode 100644 index 000000000..1341c62a7 --- /dev/null +++ b/kolla/docker/multipathd/Dockerfile.j2 @@ -0,0 +1,21 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block multipathd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set multipathd_packages = ['device-mapper-multipath'] %} +{% elif base_package_type == 'deb' %} + {% set multipathd_packages = ['multipath-tools'] %} +{% endif %} + +{{ macros.install_packages(multipathd_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block multipathd_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/networking-baremetal/ironic-neutron-agent/Dockerfile.j2 b/kolla/docker/networking-baremetal/ironic-neutron-agent/Dockerfile.j2 new file mode 100644 index 000000000..a7ae6ccb4 --- /dev/null +++ b/kolla/docker/networking-baremetal/ironic-neutron-agent/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ironic_neutron_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block ironic_neutron_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-base/Dockerfile.j2 b/kolla/docker/neutron/neutron-base/Dockerfile.j2 new file mode 100644 index 000000000..e91c1e6e6 --- /dev/null +++ b/kolla/docker/neutron/neutron-base/Dockerfile.j2 @@ -0,0 +1,104 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.enable_extra_repos(['docker-ce']) }} +{{ macros.configure_user(name='neutron') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + + {% set neutron_base_packages = [ + 'conntrack-tools', + 'dnsmasq', + 'dnsmasq-utils', + 'docker-ce-cli', + 'haproxy', + 'iproute-tc', + 'ipset', + 'iptables', + 'iputils', + 'keepalived', + 'net-tools', + 'openvswitch${KOLLA_RPM_OVS_VERSION}', + 'python3-openvswitch${KOLLA_RPM_OVS_VERSION}', + 'radvd', + 'uuid' + ] %} + +{% elif base_package_type == 'deb' %} + + {% set neutron_base_packages = [ + 'conntrack', + 'dnsmasq', + 'dnsmasq-utils', + 'docker-ce-cli', + 'haproxy', + 'iproute2', + 'ipset', + 'iptables', + 'iputils-arping', + 'iputils-ping', + 'keepalived', + 'net-tools', + 'openvswitch-switch', + 'python3-openvswitch', + 'radvd', + 'uuid-runtime' + ] %} + +{% endif %} + +{{ macros.install_packages(neutron_base_packages | customizable("packages")) }} + +ADD neutron-base-archive /neutron-base-source +ADD plugins-archive / + +{% set neutron_base_pip_packages = [ + '/neutron', + 'oslo-vmware', + 'tap-as-a-service' +] %} + +{% set neutron_base_plugins_pip_packages = [ + '/plugins/*' +] %} + +COPY neutron_sudoers /etc/sudoers.d/kolla_neutron_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN mkdir -p /usr/local/lib/neutron-wrappers /usr/local/etc/neutron-wrappers +COPY dnsmasq haproxy keepalived neutron-keepalived-state-change radvd copy-wrappers delete-wrappers /usr/local/lib/neutron-wrappers/ +RUN chmod +x /usr/local/lib/neutron-wrappers/copy-wrappers \ + && chmod +x /usr/local/lib/neutron-wrappers/delete-wrappers + +RUN ln -s neutron-base-source/* neutron \ + && {{ macros.upper_constraints_remove('networking-generic-switch') }} \ + && {{ macros.install_pip(neutron_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/neutron \ + && cp -r /neutron/etc/* /etc/neutron/ \ + && cp -r /neutron/etc/neutron/* /etc/neutron/ \ + && cp /var/lib/kolla/venv/etc/pycadf/neutron_api_audit_map.conf /etc/neutron/ \ + && mv /etc/neutron/neutron/ /etc/neutron/plugins/ \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/neutron/rootwrap.conf \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(neutron_base_plugins_pip_packages) }} \ + && for neutron_plugins in $(ls /plugins); do \ + if [ -d "/plugins/$neutron_plugins/etc/neutron/rootwrap.d" ]; then \ + cp /plugins/$neutron_plugins/etc/neutron/rootwrap.d/* /etc/neutron/rootwrap.d; \ + fi; \ + done; \ + fi \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_neutron_sudoers \ + && touch /usr/local/bin/kolla_neutron_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_neutron_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block neutron_base_footer %}{% endblock %} diff --git a/kolla/docker/neutron/neutron-base/copy-wrappers b/kolla/docker/neutron/neutron-base/copy-wrappers new file mode 100644 index 000000000..e03bdfdf7 --- /dev/null +++ b/kolla/docker/neutron/neutron-base/copy-wrappers @@ -0,0 +1,9 @@ +#!/bin/bash +for binary in dnsmasq haproxy keepalived neutron-keepalived-state-change radvd; do + cp /usr/local/lib/neutron-wrappers/${binary} /usr/local/bin/${binary} + chmod +x /usr/local/bin/${binary} +done + +echo "KOLLA_IMAGE=${KOLLA_IMAGE}" > /usr/local/etc/neutron-wrappers/config +echo "KOLLA_NAME=${KOLLA_NAME}" >> /usr/local/etc/neutron-wrappers/config +echo "KOLLA_SERVICE_NAME=${KOLLA_SERVICE_NAME}" >> /usr/local/etc/neutron-wrappers/config diff --git a/kolla/docker/neutron/neutron-base/delete-wrappers b/kolla/docker/neutron/neutron-base/delete-wrappers new file mode 100644 index 000000000..239d977f2 --- /dev/null +++ b/kolla/docker/neutron/neutron-base/delete-wrappers @@ -0,0 +1,6 @@ +#!/bin/bash +for binary in dnsmasq haproxy keepalived neutron-keepalived-state-change radvd; do + rm -f /usr/local/bin/${binary} +done + +rm -f /usr/local/etc/neutron-wrappers/config diff --git a/kolla/docker/neutron/neutron-base/dnsmasq b/kolla/docker/neutron/neutron-base/dnsmasq new file mode 100644 index 000000000..44b73f0b2 --- /dev/null +++ b/kolla/docker/neutron/neutron-base/dnsmasq @@ -0,0 +1,45 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_dnsmasq_${NETNS} + +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec ${NETNS} /usr/sbin/dnsmasq -k" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t1 podman" + CMD="/usr/sbin/dnsmasq -k" +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${SERVICE}_dnsmasq_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') + +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla/ \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + $CMD $ARGS diff --git a/kolla/docker/neutron/neutron-base/extend_start.sh b/kolla/docker/neutron/neutron-base/extend_start.sh new file mode 100644 index 000000000..e2a2dfca4 --- /dev/null +++ b/kolla/docker/neutron/neutron-base/extend_start.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/neutron" ]]; then + mkdir -p /var/log/kolla/neutron +fi +if [[ $(stat -c %a /var/log/kolla/neutron) != "755" ]]; then + chmod 755 /var/log/kolla/neutron +fi + +# NOTE(hrw): from RHEL 9 release notes: +# "Iptables-nft and ipset are now deprecated, which included the utilities, +# iptables, ip6tables, ebtables, and arptables. These are all replaced by the +# nftables framework." +# so no need to even use u-a on RHEL 9 family as there is one provider +# (and there is no u-a for ip6tables so script fails) + +if [[ ! ${KOLLA_BASE_DISTRO} =~ centos|rocky ]]; then + if /usr/bin/update-alternatives --display iptables; then + # NOTE(yoctozepto): Kolla-Ansible does not always set KOLLA_LEGACY_IPTABLES; + # the workaround below ensures it gets set to `false` in such cases to fix + # this code under `set -o nounset`. + KOLLA_LEGACY_IPTABLES=${KOLLA_LEGACY_IPTABLES-false} + + if [[ $KOLLA_LEGACY_IPTABLES == "true" ]]; then + sudo /usr/bin/update-alternatives --set iptables /usr/sbin/iptables-legacy + sudo /usr/bin/update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy + else + sudo /usr/bin/update-alternatives --auto iptables + sudo /usr/bin/update-alternatives --auto ip6tables + fi + fi +fi + +. /usr/local/bin/kolla_neutron_extend_start diff --git a/kolla/docker/neutron/neutron-base/haproxy b/kolla/docker/neutron/neutron-base/haproxy new file mode 100644 index 000000000..43b9ef9d2 --- /dev/null +++ b/kolla/docker/neutron/neutron-base/haproxy @@ -0,0 +1,45 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_haproxy_${NETNS} +HAPROXY_CMD='$(if [ -f /usr/sbin/haproxy-systemd-wrapper ]; then echo "/usr/sbin/haproxy -Ds"; else echo "/usr/sbin/haproxy -Ws"; fi)' +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec ${NETNS} "'$HAPROXY' +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman" + CMD='$HAPROXY' +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${KOLLA_NAME}_haproxy_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') + +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + /bin/bash -c "HAPROXY=\"$HAPROXY_CMD\"; exec $CMD $ARGS" diff --git a/kolla/docker/neutron/neutron-base/keepalived b/kolla/docker/neutron/neutron-base/keepalived new file mode 100644 index 000000000..6bb2b4d3d --- /dev/null +++ b/kolla/docker/neutron/neutron-base/keepalived @@ -0,0 +1,47 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_keepalived_${NETNS} + +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec ${NETNS} /usr/sbin/keepalived -n -l -D" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman" + CMD='/usr/sbin/keepalived -n -l -D' +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${KOLLA_SERVICE}_keepalived_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') + +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /lib/modules:/lib/modules:ro \ + -v /sbin/modprobe:/sbin/modprobe:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla/ \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + $CMD $ARGS diff --git a/kolla/docker/neutron/neutron-base/neutron-keepalived-state-change b/kolla/docker/neutron/neutron-base/neutron-keepalived-state-change new file mode 100644 index 000000000..0b30d88cf --- /dev/null +++ b/kolla/docker/neutron/neutron-base/neutron-keepalived-state-change @@ -0,0 +1,40 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" + +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETNS=$(ip netns identify) +NAME=${KOLLA_NAME}_keepalived_${NETNS} +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker exec --detach" + CMD="ip netns exec ${NETNS} /usr/bin/neutron-keepalived-state-change" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman exec" + CMD="/usr/bin/neutron-keepalived-state-change" +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +# The state change daemon only runs as a daemon for the moment so we need to +# run it within an existing container with a sensibly matching lifetime. The +# related keepalived container seems an obvious choice. +container_id=$($CLI ps --filter name=$NAME --format "{{.ID}}") + +if [[ -z $container_id ]]; +then + echo "WARNING: keepalived container is not running." + exit 0 +fi + +$CLI -u root \ + --privileged \ + $NAME \ + $CMD $ARGS diff --git a/kolla/docker/neutron/neutron-base/neutron_sudoers b/kolla/docker/neutron/neutron-base/neutron_sudoers new file mode 100644 index 000000000..d0de94f0e --- /dev/null +++ b/kolla/docker/neutron/neutron-base/neutron_sudoers @@ -0,0 +1,11 @@ +neutron ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/neutron-rootwrap /etc/neutron/rootwrap.conf * +neutron ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/neutron-rootwrap-daemon /etc/neutron/rootwrap.conf +neutron ALL = (root) NOPASSWD: /usr/bin/update-alternatives --set iptables /usr/sbin/iptables-legacy +neutron ALL = (root) NOPASSWD: /usr/bin/update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy +neutron ALL = (root) NOPASSWD: /usr/bin/update-alternatives --auto iptables +neutron ALL = (root) NOPASSWD: /usr/bin/update-alternatives --auto ip6tables +neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --set iptables /usr/sbin/iptables-legacy +neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy +neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --auto iptables +neutron ALL = (root) NOPASSWD: /usr/sbin/update-alternatives --auto ip6tables +neutron ALL = (root) NOPASSWD: /usr/local/lib/neutron-wrappers/copy-wrappers, /usr/local/lib/neutron-wrappers/delete-wrappers diff --git a/kolla/docker/neutron/neutron-base/radvd b/kolla/docker/neutron/neutron-base/radvd new file mode 100644 index 000000000..3f5dd1cfa --- /dev/null +++ b/kolla/docker/neutron/neutron-base/radvd @@ -0,0 +1,42 @@ +#!/bin/bash + +source /usr/local/etc/neutron-wrappers/config + +ARGS="$@" +# Extract the network namespace UUID from the command line args provided by +# neutron. Typically of the form (with dnsmasq as an example): +# +# dnsmasq --no-hosts --no-resolv --except-interface=lo \ +# --pid-file=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/pid \ +# --dhcp-hostsfile=/var/lib/neutron/dhcp/317716b8-919a-4a6f-8db1-78128ec3b100/host ... +NETWORK_ID=$(echo $ARGS| awk '{if (match($0, /(\w{8}-\w{4}-\w{4}-\w{4}-\w{12})/,m)) print m[0] }') +NAME=${KOLLA_NAME}_radvd_${NETWORK_ID} +if [[ -S "/var/run/docker.sock" ]]; then + CLI="docker" + CMD="ip netns exec qrouter-${NETWORK_ID} /usr/sbin/radvd -n" +elif [[ -S "/run/podman/podman.sock" ]]; then + CLI="nsenter --net=/run/netns/${NETNS} --preserve-credentials -m -t 1 podman" + CMD="/usr/sbin/radvd -n" +else + echo "Could not detect a supported container runtime, exiting." + exit 1 +fi + +LIST=$($CLI ps -a --filter name=${KOLLA_NAME}_radvd_ --format '{{.ID}}:{{.Names}}:{{.Status}}' | awk '{print $1}') +# If the NAME is already taken by a container, give it an unique name +printf "%s\n" "${LIST}" | grep -q "${NAME}$" && NAME="${NAME}_$(date +%Y-%m-%d-%H%M%S-%N)" + +echo "Starting a new child container ${NAME} using image ${KOLLA_IMAGE}" +$CLI run --rm --detach \ + -v /etc/kolla/${KOLLA_SERVICE_NAME}:/etc/neutron:ro \ + -v /run/netns:/run/netns:shared \ + -v neutron_metadata_socket:/var/lib/neutron/kolla/ \ + -v kolla_logs:/var/log/kolla \ + --net host \ + --pid host \ + --cgroupns host \ + --privileged \ + -u root \ + --name $NAME \ + ${KOLLA_IMAGE} \ + $CMD $ARGS diff --git a/kolla/docker/neutron/neutron-bgp-dragent/Dockerfile.j2 b/kolla/docker/neutron/neutron-bgp-dragent/Dockerfile.j2 new file mode 100644 index 000000000..3ad2ab596 --- /dev/null +++ b/kolla/docker/neutron/neutron-bgp-dragent/Dockerfile.j2 @@ -0,0 +1,24 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_bgp_dragent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +ADD neutron-bgp-dragent-archive /neutron-bgp-dragent-source + + {% set neutron_bgp_dragent_pip_packages = [ + '/neutron_dynamic_routing' + ] %} + +RUN ln -s neutron-bgp-dragent-source/* neutron_dynamic_routing \ + && {{ macros.install_pip(neutron_bgp_dragent_pip_packages | customizable("pip_packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_bgp_dragent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-dhcp-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-dhcp-agent/Dockerfile.j2 new file mode 100644 index 000000000..035433bf2 --- /dev/null +++ b/kolla/docker/neutron/neutron-dhcp-agent/Dockerfile.j2 @@ -0,0 +1,22 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_dhcp_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set neutron_dhcp_agent_packages = [ +] %} + +{{ macros.install_packages(neutron_dhcp_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +{% block neutron_dhcp_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-dhcp-agent/extend_start.sh b/kolla/docker/neutron/neutron-dhcp-agent/extend_start.sh new file mode 100644 index 000000000..edaad2a3a --- /dev/null +++ b/kolla/docker/neutron/neutron-dhcp-agent/extend_start.sh @@ -0,0 +1,17 @@ +if [[ ! -d "/var/log/kolla/neutron" ]]; then + mkdir -p /var/log/kolla/neutron +fi +if [[ ! -f "/var/log/kolla/neutron/dnsmasq.log" ]]; then + touch /var/log/kolla/neutron/dnsmasq.log + chown neutron:kolla /var/log/kolla/neutron/dnsmasq.log +fi + +if [[ "${KOLLA_NEUTRON_WRAPPERS:-false}" == "true" ]]; then + echo "Copying neutron agent wrappers to /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/copy-wrappers +else + echo "Removing neutron agent wrappers from /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/delete-wrappers +fi + +. /usr/local/bin/kolla_neutron_extend_start diff --git a/kolla/docker/neutron/neutron-l3-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-l3-agent/Dockerfile.j2 new file mode 100644 index 000000000..ae0457c18 --- /dev/null +++ b/kolla/docker/neutron/neutron-l3-agent/Dockerfile.j2 @@ -0,0 +1,32 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_l3_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set neutron_l3_agent_packages = [ + 'libreswan', + 'radvd' + ] %} +{% elif base_package_type == 'deb' %} + {% set neutron_l3_agent_packages = [ + 'strongswan', + 'radvd', + 'libnetfilter-log1' + ] %} +{% endif %} + +{{ macros.install_packages(neutron_l3_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +{% block neutron_l3_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-l3-agent/extend_start.sh b/kolla/docker/neutron/neutron-l3-agent/extend_start.sh new file mode 100644 index 000000000..f95c1eda2 --- /dev/null +++ b/kolla/docker/neutron/neutron-l3-agent/extend_start.sh @@ -0,0 +1,39 @@ +#!/bin/bash +if [[ ! -d "/var/log/kolla/neutron" ]]; then + mkdir -p /var/log/kolla/neutron +fi +if [[ $(stat -c %a /var/log/kolla/neutron) != "755" ]]; then + chmod 755 /var/log/kolla/neutron +fi + +# NOTE(hrw): from RHEL 9 release notes: +# "Iptables-nft and ipset are now deprecated, which included the utilities, +# iptables, ip6tables, ebtables, and arptables. These are all replaced by the +# nftables framework." +# so no need to even use u-a on RHEL 9 family as there is one provider +# (and there is no u-a for ip6tables so script fails) +if [[ ! ${KOLLA_BASE_DISTRO} =~ centos|rocky ]]; then + if /usr/bin/update-alternatives --display iptables; then + # NOTE(yoctozepto): Kolla-Ansible does not always set KOLLA_LEGACY_IPTABLES; + # the workaround below ensures it gets set to `false` in such cases to fix + # this code under `set -o nounset`. + KOLLA_LEGACY_IPTABLES=${KOLLA_LEGACY_IPTABLES-false} + if [[ $KOLLA_LEGACY_IPTABLES == "true" ]]; then + sudo /usr/bin/update-alternatives --set iptables /usr/sbin/iptables-legacy + sudo /usr/bin/update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy + else + sudo /usr/bin/update-alternatives --auto iptables + sudo /usr/bin/update-alternatives --auto ip6tables + fi + fi +fi + +if [[ "${KOLLA_NEUTRON_WRAPPERS:-false}" == "true" ]]; then + echo "Copying neutron agent wrappers to /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/copy-wrappers +else + echo "Removing neutron agent wrappers from /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/delete-wrappers +fi + +. /usr/local/bin/kolla_neutron_extend_start diff --git a/kolla/docker/neutron/neutron-metadata-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-metadata-agent/Dockerfile.j2 new file mode 100644 index 000000000..3736f70c8 --- /dev/null +++ b/kolla/docker/neutron/neutron-metadata-agent/Dockerfile.j2 @@ -0,0 +1,22 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_metadata_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set neutron_metadata_agent_packages = [ +] %} + +{{ macros.install_packages(neutron_metadata_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +{% block neutron_metadata_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-metadata-agent/extend_start.sh b/kolla/docker/neutron/neutron-metadata-agent/extend_start.sh new file mode 100644 index 000000000..001898f68 --- /dev/null +++ b/kolla/docker/neutron/neutron-metadata-agent/extend_start.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/neutron" ]]; then + mkdir -p /var/log/kolla/neutron +fi +if [[ $(stat -c %a /var/log/kolla/neutron) != "755" ]]; then + chmod 755 /var/log/kolla/neutron +fi + +if [[ "${KOLLA_NEUTRON_WRAPPERS:-false}" == "true" ]]; then + echo "Copying neutron agent wrappers to /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/copy-wrappers +else + echo "Removing neutron agent wrappers from /usr/local/bin" + sudo -E /usr/local/lib/neutron-wrappers/delete-wrappers +fi + +. /usr/local/bin/kolla_neutron_extend_start diff --git a/kolla/docker/neutron/neutron-metering-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-metering-agent/Dockerfile.j2 new file mode 100644 index 000000000..e9d7f74e0 --- /dev/null +++ b/kolla/docker/neutron/neutron-metering-agent/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_metering_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_metering_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-mlnx-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-mlnx-agent/Dockerfile.j2 new file mode 100644 index 000000000..4ee89c19a --- /dev/null +++ b/kolla/docker/neutron/neutron-mlnx-agent/Dockerfile.j2 @@ -0,0 +1,27 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_mlnx_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set neutron_mlnx_agent_packages = [ + 'python3-libvirt', +] %} + +{{ macros.install_packages(neutron_mlnx_agent_packages | customizable("packages")) }} + +{% set neutron_mlnx_agent_pip_packages = [ + 'networking-mlnx', +] %} + +RUN {{ macros.install_pip(neutron_mlnx_agent_pip_packages | customizable("pip_packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_mlnx_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-openvswitch-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-openvswitch-agent/Dockerfile.j2 new file mode 100644 index 000000000..b9499e6f7 --- /dev/null +++ b/kolla/docker/neutron/neutron-openvswitch-agent/Dockerfile.j2 @@ -0,0 +1,17 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_openvswitch_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.install_packages(neutron_openvswitch_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_openvswitch_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-ovn-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-ovn-agent/Dockerfile.j2 new file mode 100644 index 000000000..fe4e352ac --- /dev/null +++ b/kolla/docker/neutron/neutron-ovn-agent/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_ovn_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set neutron_ovn_agent_packages = [ +] %} + +{{ macros.install_packages(neutron_ovn_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_ovn_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-ovn-vpn-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-ovn-vpn-agent/Dockerfile.j2 new file mode 100644 index 000000000..4fbaaa78f --- /dev/null +++ b/kolla/docker/neutron/neutron-ovn-vpn-agent/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_ovn_vpn_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +# Note: VPN is currently not working on RHEL 10 due to a known issue: +# https://bugs.launchpad.net/neutron/+bug/2146308 +{% if base_package_type == 'rpm' %} + {% set neutron_ovn_vpn_agent_packages = [ + 'libreswan' + ] %} +{% elif base_package_type == 'deb' %} + {% set neutron_ovn_vpn_agent_packages = [ + 'strongswan', + 'strongswan-starter', + 'strongswan-charon' + ] %} +{% endif %} + +{{ macros.install_packages(neutron_ovn_vpn_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_ovn_vpn_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-server/Dockerfile.j2 b/kolla/docker/neutron/neutron-server/Dockerfile.j2 new file mode 100644 index 000000000..bda0d3dcf --- /dev/null +++ b/kolla/docker/neutron/neutron-server/Dockerfile.j2 @@ -0,0 +1,33 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set neutron_server_pip_packages = [ + 'networking-hyperv' +] %} + +{% set neutron_server_plugins_pip_packages = [ + '/plugins/*' +] %} + +ADD plugins-archive / + +COPY extend_start.sh /usr/local/bin/kolla_neutron_extend_start + +RUN {{ macros.install_pip(neutron_server_pip_packages | customizable("pip_packages")) }} \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(neutron_server_plugins_pip_packages) }}; \ + fi \ + && chmod 644 /usr/local/bin/kolla_neutron_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block neutron_server_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/neutron/neutron-server/extend_start.sh b/kolla/docker/neutron/neutron-server/extend_start.sh new file mode 100644 index 000000000..630eb6e1f --- /dev/null +++ b/kolla/docker/neutron/neutron-server/extend_start.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + neutron-db-manage --subproject neutron upgrade head + if [[ "${!NEUTRON_BOOTSTRAP_SERVICES[@]}" ]]; then + for service in ${NEUTRON_BOOTSTRAP_SERVICES}; do + neutron-db-manage --subproject $service upgrade head + done + fi + exit 0 +fi + +# Migrate database and exit if KOLLA_UPGRADE variable is set. This catches all cases +# of the KOLLA_UPGRADE variable being set, including empty. +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + if [[ "${!NEUTRON_DB_EXPAND[@]}" ]]; then + DB_ACTION="--expand" + echo "Expanding database" + fi + if [[ "${!NEUTRON_DB_CONTRACT[@]}" ]]; then + DB_ACTION="--contract" + echo "Contracting database" + fi + + neutron-db-manage --subproject neutron upgrade $DB_ACTION + if [[ "${!NEUTRON_ROLLING_UPGRADE_SERVICES[@]}" ]]; then + for service in ${NEUTRON_ROLLING_UPGRADE_SERVICES}; do + neutron-db-manage --subproject $service upgrade $DB_ACTION + done + fi + exit 0 +fi diff --git a/kolla/docker/neutron/neutron-sriov-agent/Dockerfile.j2 b/kolla/docker/neutron/neutron-sriov-agent/Dockerfile.j2 new file mode 100644 index 000000000..c5d74fbb2 --- /dev/null +++ b/kolla/docker/neutron/neutron-sriov-agent/Dockerfile.j2 @@ -0,0 +1,17 @@ +FROM {{ namespace }}/{{ image_prefix }}neutron-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block neutron_sriov_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.install_packages(neutron_sriov_agent_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block neutron_sriov_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER neutron diff --git a/kolla/docker/nova/nova-api/Dockerfile.j2 b/kolla/docker/nova/nova-api/Dockerfile.j2 new file mode 100644 index 000000000..57846af79 --- /dev/null +++ b/kolla/docker/nova/nova-api/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set nova_api_packages = [ +] %} +{{ macros.install_packages(nova_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_nova_extend_start +RUN chmod 644 /usr/local/bin/kolla_nova_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block nova_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/nova/nova-api/extend_start.sh b/kolla/docker/nova/nova-api/extend_start.sh new file mode 100644 index 000000000..ead6c252b --- /dev/null +++ b/kolla/docker/nova/nova-api/extend_start.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# TODO(dszumski): When Nova Conductor in Kolla Ansible supports triggering DB +# operations, we should review this script and remove any duplicate +# operations. This is probably anything that isn't to do with the API. + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + nova-manage api_db sync + nova-manage db sync --local_cell + nova-manage db online_data_migrations + exit 0 +fi + +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + nova-manage api_db sync + nova-manage db sync --local_cell + exit 0 +fi + +if [[ "${!KOLLA_OSM[@]}" ]]; then + nova-manage db online_data_migrations + exit 0 +fi + +if [[ "${!KOLLA_UPGRADE_CHECK[@]}" ]]; then + nova-status upgrade check + exit $? +fi diff --git a/kolla/docker/nova/nova-base/Dockerfile.j2 b/kolla/docker/nova/nova-base/Dockerfile.j2 new file mode 100644 index 000000000..423a9760a --- /dev/null +++ b/kolla/docker/nova/nova-base/Dockerfile.j2 @@ -0,0 +1,86 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='nova', groups='qemu') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + + {% set nova_base_packages = [ + 'openvswitch${KOLLA_RPM_OVS_VERSION}', + 'python3-openvswitch${KOLLA_RPM_OVS_VERSION}' + ] %} + {% if base_arch == 'x86_64' %} + {% set nova_base_packages = nova_base_packages + [ + 'edk2-ovmf' + ] %} + {% elif base_arch == 'aarch64' %} + {% set nova_base_packages = nova_base_packages + [ + 'edk2-aarch64' + ] %} + {% endif %} + +{% elif base_package_type == 'deb' %} + + {% set nova_base_packages = [ + 'dnsmasq', + 'ebtables', + 'iproute2', + 'iptables', + 'openssh-client', + 'openvswitch-switch', + 'python3-libvirt', + 'python3-openvswitch' + ] %} + {% if base_arch == 'x86_64' %} + {% set nova_base_packages = nova_base_packages + [ + 'ovmf' + ] %} + {% elif base_arch == 'aarch64' %} + {% set nova_base_packages = nova_base_packages + [ + 'qemu-efi-aarch64', + ] %} + {% endif %} + +{% endif %} + +{{ macros.install_packages(nova_base_packages | customizable("packages")) }} + +ADD nova-base-archive /nova-base-source +ADD plugins-archive / + +{% set nova_base_pip_packages = [ + '/nova' +] %} + +{% set nova_base_plugins_pip_packages = [ + '/plugins/*' +] %} + +COPY nova_sudoers /etc/sudoers.d/kolla_nova_sudoers +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s nova-base-source/* nova \ + && {{ macros.install_pip(nova_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/nova/ \ + && cp -r /nova/etc/nova/* /etc/nova/ \ + && cp /var/lib/kolla/venv/etc/pycadf/nova_api_audit_map.conf /etc/nova/ \ + && sed -i 's|^exec_dirs.*|exec_dirs=/var/lib/kolla/venv/bin,/sbin,/usr/sbin,/bin,/usr/bin,/usr/local/bin,/usr/local/sbin|g' /etc/nova/rootwrap.conf \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(nova_base_plugins_pip_packages) }}; \ + fi \ + && chmod 750 /etc/sudoers.d \ + && chmod 440 /etc/sudoers.d/kolla_nova_sudoers \ + && touch /usr/local/bin/kolla_nova_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_nova_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block nova_base_footer %}{% endblock %} diff --git a/kolla/docker/nova/nova-base/extend_start.sh b/kolla/docker/nova/nova-base/extend_start.sh new file mode 100644 index 000000000..eee0f16a1 --- /dev/null +++ b/kolla/docker/nova/nova-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/nova" ]]; then + mkdir -p /var/log/kolla/nova +fi +if [[ $(stat -c %a /var/log/kolla/nova) != "755" ]]; then + chmod 755 /var/log/kolla/nova +fi + +. /usr/local/bin/kolla_nova_extend_start diff --git a/kolla/docker/nova/nova-base/nova_sudoers b/kolla/docker/nova/nova-base/nova_sudoers new file mode 100644 index 000000000..6d73da6d3 --- /dev/null +++ b/kolla/docker/nova/nova-base/nova_sudoers @@ -0,0 +1 @@ +nova ALL = (root) NOPASSWD: /var/lib/kolla/venv/bin/nova-rootwrap /etc/nova/rootwrap.conf * diff --git a/kolla/docker/nova/nova-compute-ironic/Dockerfile.j2 b/kolla/docker/nova/nova-compute-ironic/Dockerfile.j2 new file mode 100644 index 000000000..3c455e2ec --- /dev/null +++ b/kolla/docker/nova/nova-compute-ironic/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_compute_ironic_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set nova_compute_ironic_packages = [ + 'genisoimage', + 'nvme-cli', + 'xorriso' +] %} + +{{ macros.install_packages(nova_compute_ironic_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block nova_compute_ironic_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-compute/Dockerfile.j2 b/kolla/docker/nova/nova-compute/Dockerfile.j2 new file mode 100644 index 000000000..8b3c1bcfe --- /dev/null +++ b/kolla/docker/nova/nova-compute/Dockerfile.j2 @@ -0,0 +1,112 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_compute_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['ceph', 'epel']) }} + + {% set nova_compute_packages = [ + 'ceph-common', + 'cyrus-sasl-md5', + 'cyrus-sasl-scram', + 'device-mapper-multipath', + 'dosfstools', + 'e2fsprogs', + 'genisoimage', + 'iscsi-initiator-utils', + 'libosinfo', + 'ndctl', + 'nfs-utils', + 'nvme-cli', + 'parted', + 'python3-libguestfs', + 'python3-libvirt', + 'python3-rtslib', + 'qemu-img', + 'qemu-kvm-block-rbd', + 'rsync', + 'sysfsutils', + 'targetcli', + 'xfsprogs' + ] %} + + # NOTE(hrw): daxio is part of pmdk which is x86-64 only in CentOS 8 + {% if base_arch == 'x86_64' %} + {% set nova_compute_packages = nova_compute_packages + [ + 'daxio' + ] %} + {% endif %} + +{{ macros.install_packages(nova_compute_packages | customizable("packages")) }} + +{% elif base_package_type == 'deb' %} + + {% set nova_compute_packages = [ + 'ceph-common', + 'dosfstools', + 'e2fsprogs', + 'genisoimage', + 'libosinfo-bin', + 'libsasl2-modules-gssapi-mit', + 'multipath-tools', + 'ndctl', + 'nfs-common', + 'nvme-cli', + 'open-iscsi', + 'parted', + 'pmdk-tools', + 'python3-cephfs', + 'python3-guestfs', + 'python3-libvirt', + 'python3-rados', + 'python3-rbd', + 'python3-rtslib-fb', + 'qemu-block-extra', + 'qemu-utils', + 'rsync', + 'sasl2-bin', + 'swtpm', + 'swtpm-tools', + 'sysfsutils', + 'targetcli-fb', + 'tpm2-tools', + 'xfsprogs' + ] %} + +RUN mkdir -p /etc/ceph \ + && {{ macros.install_packages(nova_compute_packages | customizable("packages"), chain=True) }} + +{% endif %} + +{% set nova_compute_pip_packages = [ + 'oslo-vmware' + ] +%} + +{% set nova_compute_plugins_pip_packages = [ + '/plugins/*' +] %} + +ADD plugins-archive / + +COPY extend_start.sh /usr/local/bin/kolla_nova_extend_start + +RUN {{ macros.install_pip(nova_compute_pip_packages | customizable("pip_packages")) }} \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(nova_compute_plugins_pip_packages) }}; \ + fi \ + && chmod 644 /usr/local/bin/kolla_nova_extend_start \ + && rm -f /etc/machine-id + +{{ macros.kolla_patch_sources() }} + +{% block nova_compute_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-compute/extend_start.sh b/kolla/docker/nova/nova-compute/extend_start.sh new file mode 100644 index 000000000..a458625ec --- /dev/null +++ b/kolla/docker/nova/nova-compute/extend_start.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +if [[ ! -d /var/lib/nova/instances ]]; then + mkdir -p /var/lib/nova/instances +fi diff --git a/kolla/docker/nova/nova-conductor/Dockerfile.j2 b/kolla/docker/nova/nova-conductor/Dockerfile.j2 new file mode 100644 index 000000000..b14000400 --- /dev/null +++ b/kolla/docker/nova/nova-conductor/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_conductor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_nova_extend_start +RUN chmod 644 /usr/local/bin/kolla_nova_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block nova_conductor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-conductor/extend_start.sh b/kolla/docker/nova/nova-conductor/extend_start.sh new file mode 100644 index 000000000..72c9493f5 --- /dev/null +++ b/kolla/docker/nova/nova-conductor/extend_start.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + nova-manage db sync --local_cell + nova-manage db online_data_migrations + exit 0 +fi + +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + nova-manage db sync --local_cell + exit 0 +fi + +if [[ "${!KOLLA_OSM[@]}" ]]; then + nova-manage db online_data_migrations + exit 0 +fi diff --git a/kolla/docker/nova/nova-libvirt-spice/Dockerfile.j2 b/kolla/docker/nova/nova-libvirt-spice/Dockerfile.j2 new file mode 100644 index 000000000..4c7ded894 --- /dev/null +++ b/kolla/docker/nova/nova-libvirt-spice/Dockerfile.j2 @@ -0,0 +1,120 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" build-date="{{ build_date }}" +{% endblock %} + +{% block nova_libvirt_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='nova', groups='qemu') }} + +{% if base_package_type == 'rpm' %} + + {% set nova_libvirt_extra_repos = ['ceph', 'crb', 'epel', 'openvswitch'] %} + {% if base_distro == 'rocky' %} + {# + The stock Rocky qemu-kvm has SPICE compiled out. To enable + Kerbside and the nova ``spice-direct`` console we therefore + layer the ligenix COPR in so that qemu-kvm and spice-server + are available with SPICE re-enabled. The repo definition + lives in kolla/template/repos.yaml so deployers can override + it like any other extra repo. + #} + {% set nova_libvirt_extra_repos = nova_libvirt_extra_repos + ['ligenix-qemu-spice'] %} + {% endif %} + +{{ macros.enable_extra_repos(nova_libvirt_extra_repos) }} + + {% set nova_libvirt_packages = [ + 'ceph-common', + 'cyrus-sasl-md5', + 'cyrus-sasl-scram', + 'libguestfs', + 'libvirt-client', + 'libvirt-daemon', + 'libvirt-daemon-log', + 'libvirt-daemon-config-nwfilter', + 'libvirt-daemon-driver-nwfilter', + 'libvirt-daemon-driver-nodedev', + 'openvswitch${KOLLA_RPM_OVS_VERSION}', + 'qemu-img', + 'qemu-kvm', + 'swtpm', + ] %} + {% if base_arch == 'x86_64' %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'edk2-ovmf' + ] %} + {% elif base_arch == 'aarch64' %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'edk2-aarch64' + ] %} + {% endif %} + + {% if use_ligenix_qemu | default(false) and base_distro == 'rocky' %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'qemu-kvm-ui-spice', + 'spice-server', + ] %} + {% endif %} + +{% elif base_package_type == 'deb' %} + + {% set nova_libvirt_packages = [ + 'ceph-common', + 'ebtables', + 'libsasl2-modules-gssapi-mit', + 'libvirt-clients', + 'libvirt-daemon-system', + 'mdevctl', + 'openvswitch-switch', + 'pm-utils', + 'python3-cephfs', + 'python3-rados', + 'python3-rbd', + 'qemu-block-extra', + 'qemu-system', + 'qemu-system-modules-spice', + 'qemu-utils', + 'sasl2-bin', + 'swtpm', + 'swtpm-tools', + 'tpm2-tools', + 'trousers' + ] %} + + {% if base_arch == "aarch64" %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'qemu-efi-aarch64' + ] %} + {% elif base_arch == "x86_64" %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'ovmf', + ] %} + {% endif %} + + {% if base_distro in ['debian'] %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'libvirt-daemon-log', + 'usermode' + ] %} + {% endif %} +{% endif %} + +{{ macros.install_packages(nova_libvirt_packages | customizable("packages")) }} + +{% if base_package_type == 'deb' %} + +RUN rm -f /etc/libvirt/qemu/networks/default.xml /etc/libvirt/qemu/networks/autostart/default.xml + +{% endif %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY kolla_nova_libvirt_start.sh /usr/local/bin/kolla_nova_libvirt_start +RUN chmod 644 /usr/local/bin/kolla_extend_start && chmod 744 /usr/local/bin/kolla_nova_libvirt_start + +{{ macros.kolla_patch_sources() }} + +{% block nova_libvirt_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/nova/nova-libvirt-spice/extend_start.sh b/kolla/docker/nova/nova-libvirt-spice/extend_start.sh new file mode 100644 index 000000000..cc41b480b --- /dev/null +++ b/kolla/docker/nova/nova-libvirt-spice/extend_start.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ ! -e "/var/log/kolla/libvirt/libvirtd.log" ]]; then + mkdir -p /var/log/kolla/libvirt + touch /var/log/kolla/libvirt/libvirtd.log + chmod 644 /var/log/kolla/libvirt/libvirtd.log +fi +if [[ $(stat -c %a /var/log/kolla/libvirt) != "755" ]]; then + chmod 755 /var/log/kolla/libvirt + chmod 644 /var/log/kolla/libvirt/libvirtd.log +fi diff --git a/kolla/docker/nova/nova-libvirt-spice/kolla_nova_libvirt_start.sh b/kolla/docker/nova/nova-libvirt-spice/kolla_nova_libvirt_start.sh new file mode 100644 index 000000000..f06a63d9e --- /dev/null +++ b/kolla/docker/nova/nova-libvirt-spice/kolla_nova_libvirt_start.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euo pipefail + +# NOTE(mikal): Start virtlogd as a sidecar. We need this for +# nova instance console logs to rotate. Otherwise they will +# consume unbounded amounts of disk. +# +# No exec here: libvirtd will be the "main" process. +/usr/sbin/virtlogd & + +# Now hand over PID 1's direct child role to libvirtd. +exec /usr/sbin/libvirtd --listen diff --git a/kolla/docker/nova/nova-libvirt/Dockerfile.j2 b/kolla/docker/nova/nova-libvirt/Dockerfile.j2 new file mode 100644 index 000000000..fb82401b3 --- /dev/null +++ b/kolla/docker/nova/nova-libvirt/Dockerfile.j2 @@ -0,0 +1,100 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_libvirt_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='nova', groups='qemu') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['ceph', 'crb', 'epel', 'openvswitch']) }} + + {% set nova_libvirt_packages = [ + 'ceph-common', + 'cyrus-sasl-md5', + 'cyrus-sasl-scram', + 'libguestfs', + 'libvirt-client', + 'libvirt-daemon', + 'libvirt-daemon-log', + 'libvirt-daemon-config-nwfilter', + 'libvirt-daemon-driver-nwfilter', + 'libvirt-daemon-driver-nodedev', + 'openvswitch${KOLLA_RPM_OVS_VERSION}', + 'qemu-img', + 'qemu-kvm', + 'swtpm', + ] %} + {% if base_arch == 'x86_64' %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'edk2-ovmf' + ] %} + {% elif base_arch == 'aarch64' %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'edk2-aarch64' + ] %} + {% endif %} + +{% elif base_package_type == 'deb' %} + + {% set nova_libvirt_packages = [ + 'ceph-common', + 'ebtables', + 'libsasl2-modules-gssapi-mit', + 'libvirt-clients', + 'libvirt-daemon-system', + 'mdevctl', + 'openvswitch-switch', + 'pm-utils', + 'python3-cephfs', + 'python3-rados', + 'python3-rbd', + 'qemu-block-extra', + 'qemu-system', + 'qemu-system-modules-spice', + 'qemu-utils', + 'sasl2-bin', + 'swtpm', + 'swtpm-tools', + 'tpm2-tools', + 'trousers' + ] %} + + {% if base_arch == "aarch64" %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'qemu-efi-aarch64' + ] %} + {% elif base_arch == "x86_64" %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'ovmf', + ] %} + {% endif %} + + {% if base_distro in ['debian'] %} + {% set nova_libvirt_packages = nova_libvirt_packages + [ + 'libvirt-daemon-log', + 'usermode' + ] %} + {% endif %} +{% endif %} + +{{ macros.install_packages(nova_libvirt_packages | customizable("packages")) }} + +{% if base_package_type == 'deb' %} + +RUN rm -f /etc/libvirt/qemu/networks/default.xml /etc/libvirt/qemu/networks/autostart/default.xml + +{% endif %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY kolla_nova_libvirt_start.sh /usr/local/bin/kolla_nova_libvirt_start +RUN chmod 644 /usr/local/bin/kolla_extend_start && chmod 744 /usr/local/bin/kolla_nova_libvirt_start + +{{ macros.kolla_patch_sources() }} + +{% block nova_libvirt_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/nova/nova-libvirt/extend_start.sh b/kolla/docker/nova/nova-libvirt/extend_start.sh new file mode 100644 index 000000000..cc41b480b --- /dev/null +++ b/kolla/docker/nova/nova-libvirt/extend_start.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +if [[ ! -e "/var/log/kolla/libvirt/libvirtd.log" ]]; then + mkdir -p /var/log/kolla/libvirt + touch /var/log/kolla/libvirt/libvirtd.log + chmod 644 /var/log/kolla/libvirt/libvirtd.log +fi +if [[ $(stat -c %a /var/log/kolla/libvirt) != "755" ]]; then + chmod 755 /var/log/kolla/libvirt + chmod 644 /var/log/kolla/libvirt/libvirtd.log +fi diff --git a/kolla/docker/nova/nova-libvirt/kolla_nova_libvirt_start.sh b/kolla/docker/nova/nova-libvirt/kolla_nova_libvirt_start.sh new file mode 100644 index 000000000..f06a63d9e --- /dev/null +++ b/kolla/docker/nova/nova-libvirt/kolla_nova_libvirt_start.sh @@ -0,0 +1,12 @@ +#!/bin/bash +set -euo pipefail + +# NOTE(mikal): Start virtlogd as a sidecar. We need this for +# nova instance console logs to rotate. Otherwise they will +# consume unbounded amounts of disk. +# +# No exec here: libvirtd will be the "main" process. +/usr/sbin/virtlogd & + +# Now hand over PID 1's direct child role to libvirtd. +exec /usr/sbin/libvirtd --listen diff --git a/kolla/docker/nova/nova-novncproxy/Dockerfile.j2 b/kolla/docker/nova/nova-novncproxy/Dockerfile.j2 new file mode 100644 index 000000000..4952ed734 --- /dev/null +++ b/kolla/docker/nova/nova-novncproxy/Dockerfile.j2 @@ -0,0 +1,21 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_novncproxy_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set nova_novncproxy_packages = [ + 'novnc' +] %} + +{{ macros.install_packages(nova_novncproxy_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block nova_novncproxy_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-scheduler/Dockerfile.j2 b/kolla/docker/nova/nova-scheduler/Dockerfile.j2 new file mode 100644 index 000000000..5b0b0b98e --- /dev/null +++ b/kolla/docker/nova/nova-scheduler/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_scheduler_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block nova_scheduler_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-serialproxy/Dockerfile.j2 b/kolla/docker/nova/nova-serialproxy/Dockerfile.j2 new file mode 100644 index 000000000..c63e925d5 --- /dev/null +++ b/kolla/docker/nova/nova-serialproxy/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_serialproxy_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block nova_serialproxy_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-spicehtml5proxy/Dockerfile.j2 b/kolla/docker/nova/nova-spicehtml5proxy/Dockerfile.j2 new file mode 100644 index 000000000..f3a90b0c5 --- /dev/null +++ b/kolla/docker/nova/nova-spicehtml5proxy/Dockerfile.j2 @@ -0,0 +1,33 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_spicehtml5proxy_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + + {% set nova_spicehtml5proxy_packages = [ + 'python3-numpy', + 'spice-html5' + ] %} + +{% elif base_package_type == 'deb' %} + + {% set nova_spicehtml5proxy_packages = [ + 'spice-html5', + 'websockify' + ] %} + +{% endif %} + +{{ macros.install_packages(nova_spicehtml5proxy_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block nova_spicehtml5proxy_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER nova diff --git a/kolla/docker/nova/nova-ssh/Dockerfile.j2 b/kolla/docker/nova/nova-ssh/Dockerfile.j2 new file mode 100644 index 000000000..0d9e36b65 --- /dev/null +++ b/kolla/docker/nova/nova-ssh/Dockerfile.j2 @@ -0,0 +1,34 @@ +FROM {{ namespace }}/{{ image_prefix }}nova-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block nova_ssh_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='nova', shell='/bin/bash') }} + +{% set nova_ssh_packages = [ + 'openssh-server', + 'rsync' +] %} + +{% if base_package_type == 'deb' %} + +RUN mkdir -p /var/run/sshd \ + && chmod 0755 /var/run/sshd + +{% endif %} + +{{ macros.install_packages(nova_ssh_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN sed -ri 's/session(\s+)required(\s+)pam_loginuid.so/session\1optional\2pam_loginuid.so/' /etc/pam.d/sshd \ + && chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block nova_ssh_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/nova/nova-ssh/extend_start.sh b/kolla/docker/nova/nova-ssh/extend_start.sh new file mode 100644 index 000000000..b80114c0a --- /dev/null +++ b/kolla/docker/nova/nova-ssh/extend_start.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +SSH_HOST_KEY_TYPES=( "rsa" "ecdsa" "ed25519" ) + +for key_type in ${SSH_HOST_KEY_TYPES[@]}; do + KEY_PATH=/etc/ssh/ssh_host_${key_type}_key + if [[ ! -f "${KEY_PATH}" ]]; then + ssh-keygen -q -t ${key_type} -f ${KEY_PATH} -N "" + fi +done + +mkdir -p /var/lib/nova/.ssh + +if [[ $(stat -c %U:%G /var/lib/nova/.ssh) != "nova:nova" ]]; then + chown nova: /var/lib/nova/.ssh +fi diff --git a/kolla/docker/octavia/octavia-api/Dockerfile.j2 b/kolla/docker/octavia/octavia-api/Dockerfile.j2 new file mode 100644 index 000000000..ccb7bad11 --- /dev/null +++ b/kolla/docker/octavia/octavia-api/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}octavia-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block octavia_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set octavia_api_packages = [ +] %} + +{% set octavia_api_plugins_pip_packages = [ + '/plugins/*' +] %} + +ADD plugins-archive / + +COPY extend_start.sh /usr/local/bin/kolla_octavia_extend_start + +RUN if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(octavia_api_plugins_pip_packages) }} ; \ + fi \ + && chmod 644 /usr/local/bin/kolla_octavia_extend_start + +{{ macros.install_packages(octavia_api_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block octavia_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/octavia/octavia-api/extend_start.sh b/kolla/docker/octavia/octavia-api/extend_start.sh new file mode 100644 index 000000000..b05d8abf1 --- /dev/null +++ b/kolla/docker/octavia/octavia-api/extend_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + octavia-db-manage upgrade head + octavia-db-manage upgrade_persistence + exit 0 +fi diff --git a/kolla/docker/octavia/octavia-base/Dockerfile.j2 b/kolla/docker/octavia/octavia-base/Dockerfile.j2 new file mode 100644 index 000000000..81a589a09 --- /dev/null +++ b/kolla/docker/octavia/octavia-base/Dockerfile.j2 @@ -0,0 +1,48 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block octavia_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='octavia') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + + {% set octavia_base_packages = [ + 'python3-openvswitch${KOLLA_RPM_OVS_VERSION}' + ] %} + +{% elif base_package_type == 'deb' %} + + {% set octavia_base_packages = [ + 'python3-openvswitch' + ] %} + +{% endif %} + +{{ macros.install_packages(octavia_base_packages | customizable("packages")) }} + +ADD octavia-base-archive /octavia-base-source + +{% set octavia_base_pip_packages = [ + '/octavia' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s /octavia-base-source/* octavia \ + && {{ macros.install_pip(octavia_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/octavia \ + && cp -r /octavia/etc/* /etc/octavia/ \ + && cp /octavia/etc/audit/octavia_api_audit_map.conf.sample /etc/octavia/octavia_api_audit_map.conf \ + && touch /usr/local/bin/kolla_octavia_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_octavia_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block octavia_base_footer %}{% endblock %} diff --git a/kolla/docker/octavia/octavia-base/extend_start.sh b/kolla/docker/octavia/octavia-base/extend_start.sh new file mode 100644 index 000000000..b27a88a31 --- /dev/null +++ b/kolla/docker/octavia/octavia-base/extend_start.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +set -o errexit + +OCTAVIA_LOG_DIR=/var/log/kolla/octavia + +if [[ ! -d "${OCTAVIA_LOG_DIR}" ]]; then + mkdir -p ${OCTAVIA_LOG_DIR} +fi +if [[ $(stat -c %U:%G ${OCTAVIA_LOG_DIR}) != "octavia:kolla" ]]; then + chown -R octavia:kolla /var/log/kolla/octavia +fi +if [[ $(stat -c %a ${OCTAVIA_LOG_DIR}) != "755" ]]; then + chmod 755 ${OCTAVIA_LOG_DIR} +fi + +. /usr/local/bin/kolla_octavia_extend_start diff --git a/kolla/docker/octavia/octavia-driver-agent/Dockerfile.j2 b/kolla/docker/octavia/octavia-driver-agent/Dockerfile.j2 new file mode 100644 index 000000000..b3519922a --- /dev/null +++ b/kolla/docker/octavia/octavia-driver-agent/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}octavia-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block octavia_driver_agent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set octavia_driver_agent_packages = [ +] %} + +{% set octavia_driver_agent_plugins_pip_packages = [ + '/plugins/*' +] %} + +{{ macros.install_packages(octavia_driver_agent_packages | customizable("packages")) }} + +ADD plugins-archive / +RUN if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(octavia_driver_agent_plugins_pip_packages) }} ; \ + fi + +{{ macros.kolla_patch_sources() }} + +{% block octavia_driver_agent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER octavia diff --git a/kolla/docker/octavia/octavia-health-manager/Dockerfile.j2 b/kolla/docker/octavia/octavia-health-manager/Dockerfile.j2 new file mode 100644 index 000000000..1ffbe2050 --- /dev/null +++ b/kolla/docker/octavia/octavia-health-manager/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}octavia-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block octavia_health_manager_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block octavia_health_manager_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER octavia diff --git a/kolla/docker/octavia/octavia-housekeeping/Dockerfile.j2 b/kolla/docker/octavia/octavia-housekeeping/Dockerfile.j2 new file mode 100644 index 000000000..775797cca --- /dev/null +++ b/kolla/docker/octavia/octavia-housekeeping/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}octavia-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block octavia_housekeeping_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block octavia_housekeeping_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER octavia diff --git a/kolla/docker/octavia/octavia-worker/Dockerfile.j2 b/kolla/docker/octavia/octavia-worker/Dockerfile.j2 new file mode 100644 index 000000000..85d4727b7 --- /dev/null +++ b/kolla/docker/octavia/octavia-worker/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}octavia-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block octavia_worker_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block octavia_worker_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER octavia diff --git a/kolla/docker/opensearch/opensearch-dashboards/Dockerfile.j2 b/kolla/docker/opensearch/opensearch-dashboards/Dockerfile.j2 new file mode 100644 index 000000000..3249b62d2 --- /dev/null +++ b/kolla/docker/opensearch/opensearch-dashboards/Dockerfile.j2 @@ -0,0 +1,26 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block opensearch_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='opensearch-dashboards', shell='/bin/bash', homedir='/usr/share/opensearch-dashboards') }} +{{ macros.enable_extra_repos(['opensearch-dashboards']) }} + +{% set opensearch_dashboards_packages = ['opensearch-dashboards'] %} + +{{ macros.install_packages(opensearch_dashboards_packages | customizable("packages")) }} \ + && chown -R opensearch-dashboards:opensearch-dashboards /usr/share/opensearch-dashboards + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 755 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block opensearch_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER opensearch-dashboards diff --git a/kolla/docker/opensearch/opensearch-dashboards/extend_start.sh b/kolla/docker/opensearch/opensearch-dashboards/extend_start.sh new file mode 100644 index 000000000..608bb34bf --- /dev/null +++ b/kolla/docker/opensearch/opensearch-dashboards/extend_start.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/opensearch-dashboards" ]]; then + mkdir -p /var/log/kolla/opensearch-dashboards +fi +if [[ $(stat -c %a /var/log/kolla/opensearch-dashboards) != "755" ]]; then + chmod 755 /var/log/kolla/opensearch-dashboards +fi + +export DASHBOARDS_HOME=/usr/share/opensearch-dashboards + +PLUGIN_LIST=$($DASHBOARDS_HOME/bin/opensearch-dashboards-plugin list) +if [[ "${OPENSEARCH_DASHBOARDS_SECURITY_PLUGIN:-True}" == "False" ]]; then + if [[ ${PLUGIN_LIST} =~ "securityDashboards" ]]; then + $DASHBOARDS_HOME/bin/opensearch-dashboards-plugin remove securityDashboards + fi +fi diff --git a/kolla/docker/opensearch/opensearch/Dockerfile.j2 b/kolla/docker/opensearch/opensearch/Dockerfile.j2 new file mode 100644 index 000000000..6ad8fb29a --- /dev/null +++ b/kolla/docker/opensearch/opensearch/Dockerfile.j2 @@ -0,0 +1,32 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block opensearch_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='opensearch', shell='/bin/bash', homedir='/usr/share/opensearch') }} +{{ macros.enable_extra_repos(['opensearch']) }} + + {% set opensearch_packages = [ + 'opensearch' + ] %} + +ENV OPENSEARCH_INITIAL_ADMIN_PASSWORD="Kolla24OpenSearch" + +{{ macros.install_packages(opensearch_packages | customizable("packages")) }} \ + && chown -R opensearch:opensearch /usr/share/opensearch \ + && rm -f /etc/opensearch/*.pem \ + && rm -f /etc/opensearch/securityadmin_demo.sh + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 755 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block opensearch_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER opensearch diff --git a/kolla/docker/opensearch/opensearch/extend_start.sh b/kolla/docker/opensearch/opensearch/extend_start.sh new file mode 100644 index 000000000..5855b1be2 --- /dev/null +++ b/kolla/docker/opensearch/opensearch/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/opensearch" ]]; then + mkdir -p /var/log/kolla/opensearch +fi +if [[ $(stat -c %a /var/log/kolla/opensearch) != "755" ]]; then + chmod 755 /var/log/kolla/opensearch +fi diff --git a/kolla/docker/openstack-base/Dockerfile.j2 b/kolla/docker/openstack-base/Dockerfile.j2 new file mode 100644 index 000000000..b8ed2e465 --- /dev/null +++ b/kolla/docker/openstack-base/Dockerfile.j2 @@ -0,0 +1,213 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block openstack_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['crb', 'epel']) }} + + {% set openstack_base_packages = [ + 'gcc', + 'gcc-c++', + 'git', + 'httpd', + 'iproute', + 'libffi-devel', + 'libxml2-devel', + 'libxslt-devel', + 'libyaml-devel', + 'make', + 'mod_ssl', + 'openssl', + 'openssl-devel', + 'pcre2-devel', + 'postgresql', + 'postgresql-devel', + 'postgresql-server-devel', + 'python3-devel', + 'sqlite-devel', + 'uwsgi-plugin-python3', + 'zip' + ] %} + +{% elif base_package_type == 'deb' %} + {% set openstack_base_packages = [ + 'build-essential', + 'ca-certificates', + 'git', + 'libffi-dev', + 'libpcre2-dev', + 'libpq-dev', + 'libssl-dev', + 'libxml2-dev', + 'libxslt1-dev', + 'libyaml-dev', + 'libz-dev', + 'pkg-config', + 'python3-dev', + 'python3-venv', + 'uwsgi-plugin-python3', + 'zip' + ] %} + +{% endif %} + +{{ macros.install_packages(openstack_base_packages | customizable("packages")) }} + +{% set openstack_base_pip_packages = [ + 'Mako', + 'MarkupSafe', + 'Paste', + 'PasteDeploy', + 'PyNaCl', + 'PyYAML', + 'Routes', + 'SQLAlchemy', + 'Tempita', + 'WSME', + 'WebOb', + 'alembic', + 'amqp', + 'aodhclient', + 'appdirs', + 'automaton', + 'bcrypt', + 'cachetools', + 'castellan', + 'click', + 'cliff', + 'cmd2', + 'contextlib2', + 'cryptography', + 'debtcollector', + 'decorator', + 'eventlet', + 'fasteners', + 'fluent-logger', + 'funcsigs', + 'futurist', + 'gnocchiclient', + 'greenlet', + 'httplib2', + 'iso8601', + 'jinja2', + 'jsonpatch', + 'jsonpointer', + 'jsonschema', + 'keystoneauth1', + 'keystonemiddleware', + 'kombu', + 'logutils', + 'monotonic', + 'netaddr', + 'netifaces', + 'os-brick', + 'os-client-config', + 'os-traits', + 'os-win', + 'oslo.concurrency', + 'oslo.config', + 'oslo.context', + 'oslo.db', + 'oslo.i18n', + 'oslo.log', + 'oslo.messaging', + 'oslo.middleware', + 'oslo.policy', + 'oslo.privsep', + 'oslo.reports', + 'oslo.rootwrap', + 'oslo.serialization', + 'oslo.service', + 'oslo.upgradecheck', + 'oslo.utils', + 'oslo.versionedobjects', + 'oslo.vmware', + 'osprofiler', + 'paramiko', + 'pbr', + 'pecan', + 'pika', + 'prettytable', + 'psutil', + 'pycadf', + 'pymysql', + 'pyngus', + 'pyparsing', + 'pyroute2', + 'python-barbicanclient', + 'python-binary-memcached', + 'python-cinderclient', + 'python-cloudkittyclient', + 'python-dateutil', + 'python-designateclient', + 'python-editor', + 'python-glanceclient', + 'python-heatclient', + 'python-ironicclient', + 'python-keystoneclient', + 'python-magnumclient', + 'python-manilaclient', + 'python-memcached', + 'python-mistralclient', + 'python-neutronclient', + 'python-novaclient', + 'python-openstackclient', + 'python-qpid-proton', + 'python-swiftclient', + 'python-troveclient', + 'pytz', + 'repoze.lru', + 'requests', + 'requestsexceptions', + 'retrying', + 'setproctitle', + 'simplegeneric', + 'simplejson', + 'six', + 'sqlparse', + 'stevedore', + 'tooz[consul,etcd,etcd3gw,redis,postgresql,mysql,zookeeper,memcached,ipc]', + 'unicodecsv', + 'uwsgi', + 'warlock', + 'wrapt' + ] +%} + +ADD openstack-base-archive /openstack-base-source +ADD plugins-archive / + +RUN ln -s openstack-base-source/* /requirements \ + +{# NOTE(mnasiadka): Remove ovs from upper-constraints.txt because python3-openvswitch + is usually newer than UC entry and older version would get installed + in venv (see https://launchpad.net/bugs/1961874). +#} + && {{ macros.upper_constraints_remove("ovs") }} \ + && mkdir -p /var/lib/kolla \ + && python3 -m venv --system-site-packages /var/lib/kolla/venv \ + && KOLLA_DISTRO_PYTHON_VERSION=$(/usr/bin/python3 -c "import sys; print('{}.{}'.format(sys.version_info.major, sys.version_info.minor))") \ + && ln -s python${KOLLA_DISTRO_PYTHON_VERSION} /var/lib/kolla/venv/lib/python3 + +{# Block used for overriding global version constraints. + + Overriding the package version using upper_constraints_remove(package_name) or + upper_constraints_version_change(package_name, from, to) at this location will + apply to all services. +#} +{% block openstack_base_override_upper_constraints %}{% endblock %} + +ENV PATH /var/lib/kolla/venv/bin:$PATH + +RUN {{ macros.install_pip(['pip', 'wheel', 'setuptools']) }} \ + && {{ macros.install_pip(openstack_base_pip_packages | customizable("pip_packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block openstack_base_footer %}{% endblock %} diff --git a/kolla/docker/openvswitch/openvswitch-base/Dockerfile.j2 b/kolla/docker/openvswitch/openvswitch-base/Dockerfile.j2 new file mode 100644 index 000000000..44d8df41c --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-base/Dockerfile.j2 @@ -0,0 +1,45 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block openvswitch_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block ovs_install %} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + + {% set openvswitch_base_packages = [ + 'libibverbs', + 'openvswitch${KOLLA_RPM_OVS_VERSION}', + 'python3-openvswitch${KOLLA_RPM_OVS_VERSION}', + 'tcpdump' + ] %} +{% elif base_package_type == 'deb' %} + {% set openvswitch_base_packages = [ + 'openvswitch-switch', + 'python3-openvswitch', + 'tcpdump' + ] %} +{% endif %} + +{{ macros.install_packages(openvswitch_base_packages | customizable("packages")) }} + +{% endblock %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +COPY ovs_wrapper.sh /usr/local/bin/ovs_wrapper + +# NOTE(hrw): Upstream moved tcpdump to /usr/bin/ in 4.99 version (used in Debian) +RUN if [ -e /usr/sbin/tcpdump ]; then mv /usr/sbin/tcpdump /usr/bin/tcpdump; fi \ + && touch /usr/local/bin/kolla_openvswitch_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_openvswitch_extend_start \ + && chmod 755 /usr/local/bin/ovs_wrapper + +{{ macros.kolla_patch_sources() }} + +{% block openvswitch_base_footer %}{% endblock %} diff --git a/kolla/docker/openvswitch/openvswitch-base/extend_start.sh b/kolla/docker/openvswitch/openvswitch-base/extend_start.sh new file mode 100644 index 000000000..1b0ed1300 --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-base/extend_start.sh @@ -0,0 +1,12 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/openvswitch" ]]; then + mkdir -p /var/log/kolla/openvswitch +fi +if [[ $(stat -c %a /var/log/kolla/openvswitch) != "755" ]]; then + chmod 755 /var/log/kolla/openvswitch +fi + +chown -R openvswitch:openvswitch /var/log/kolla/openvswitch + +. /usr/local/bin/kolla_openvswitch_extend_start diff --git a/kolla/docker/openvswitch/openvswitch-base/ovs_wrapper.sh b/kolla/docker/openvswitch/openvswitch-base/ovs_wrapper.sh new file mode 100644 index 000000000..552c496ac --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-base/ovs_wrapper.sh @@ -0,0 +1,19 @@ +#!/usr/bin/env bash + +catch_term() { + ovs-appctl -T1 -t /run/openvswitch/$1.$child.ctl exit + exit 0 +} + +catch_quit() { + ovs-appctl -T1 -t /run/openvswitch/$1.$child.ctl exit + exit 0 +} + +trap catch_term SIGTERM +trap catch_quit SIGQUIT + +"$@" & + +child=$! +wait "$child" diff --git a/kolla/docker/openvswitch/openvswitch-db-server/Dockerfile.j2 b/kolla/docker/openvswitch/openvswitch-db-server/Dockerfile.j2 new file mode 100644 index 000000000..869dbabb6 --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-db-server/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}openvswitch-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block openvswitch_db_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_openvswitch_extend_start +RUN chmod 755 /usr/local/bin/kolla_openvswitch_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block openvswitch_db_server_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/openvswitch/openvswitch-db-server/extend_start.sh b/kolla/docker/openvswitch/openvswitch-db-server/extend_start.sh new file mode 100644 index 000000000..d25038bdd --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-db-server/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +mkdir -p "/run/openvswitch" +if [[ ! -e "/var/lib/openvswitch/conf.db" ]]; then + ovsdb-tool create "/var/lib/openvswitch/conf.db" +fi + +if [[ $(ovsdb-tool needs-conversion /var/lib/openvswitch/conf.db) == yes ]]; then + ovsdb-tool convert "/var/lib/openvswitch/conf.db" +fi + +if [[ ! -r "/var/log/kolla/openvswitch/ovsdb-server.log" ]]; then + touch /var/log/kolla/openvswitch/ovsdb-server.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovsdb-server.log +fi diff --git a/kolla/docker/openvswitch/openvswitch-db-server/releasenotes/notes/drop-ovs-ensure-configured-7973d36969e157fa.yaml b/kolla/docker/openvswitch/openvswitch-db-server/releasenotes/notes/drop-ovs-ensure-configured-7973d36969e157fa.yaml new file mode 100644 index 000000000..cc8daf1f4 --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-db-server/releasenotes/notes/drop-ovs-ensure-configured-7973d36969e157fa.yaml @@ -0,0 +1,5 @@ +--- +upgrade: + - | + ``openvswitch`` script ``ovs_ensure_configured.sh`` has been dropped after + being replaced with Ansible modules in ``kolla-ansible``. diff --git a/kolla/docker/openvswitch/openvswitch-vswitchd/Dockerfile.j2 b/kolla/docker/openvswitch/openvswitch-vswitchd/Dockerfile.j2 new file mode 100644 index 000000000..fe6dd4347 --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-vswitchd/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}openvswitch-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block openvswitch_vswitchd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_openvswitch_extend_start +RUN chmod 644 /usr/local/bin/kolla_openvswitch_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block openvswitch_vswitchd_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/openvswitch/openvswitch-vswitchd/extend_start.sh b/kolla/docker/openvswitch/openvswitch-vswitchd/extend_start.sh new file mode 100644 index 000000000..fde542130 --- /dev/null +++ b/kolla/docker/openvswitch/openvswitch-vswitchd/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +if [[ ! -r "/var/log/kolla/openvswitch/ovs-vswitchd.log" ]]; then + touch /var/log/kolla/openvswitch/ovs-vswitchd.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovs-vswitchd.log +fi + +modprobe openvswitch diff --git a/kolla/docker/ovn/ovn-base/Dockerfile.j2 b/kolla/docker/ovn/ovn-base/Dockerfile.j2 new file mode 100644 index 000000000..3efd001a3 --- /dev/null +++ b/kolla/docker/ovn/ovn-base/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}openvswitch-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovn_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ovn_base_packages = [ + 'ovn${KOLLA_RPM_OVN_VERSION}', + ] %} + +{% elif base_package_type == 'deb' %} + {% set ovn_base_packages = [ + 'ovn-common', + ] %} + +{% endif %} +{{ macros.install_packages(ovn_base_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovn_base_footer %}{% endblock %} diff --git a/kolla/docker/ovn/ovn-base/extend_start.sh b/kolla/docker/ovn/ovn-base/extend_start.sh new file mode 100644 index 000000000..eae4ab9e1 --- /dev/null +++ b/kolla/docker/ovn/ovn-base/extend_start.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +if [[ ! -d "/run/ovn" ]]; then + mkdir -p /run/ovn +fi +if [[ ! -d "/var/log/kolla/openvswitch" ]]; then + mkdir -p /var/log/kolla/openvswitch +fi +if [[ $(stat -c %a /var/log/kolla/openvswitch) != "755" ]]; then + chmod 755 /var/log/kolla/openvswitch +fi + +. /usr/local/bin/kolla_ovn_extend_start diff --git a/kolla/docker/ovn/ovn-controller/Dockerfile.j2 b/kolla/docker/ovn/ovn-controller/Dockerfile.j2 new file mode 100644 index 000000000..f95e61fee --- /dev/null +++ b/kolla/docker/ovn/ovn-controller/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}ovn-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovn_controller_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ovn_controller_packages = [ + 'ovn${KOLLA_RPM_OVN_VERSION}-host' + ] %} + +{% elif base_package_type == 'deb' %} + {% set ovn_controller_packages = [ + 'ovn-host' + ] %} + +{% endif %} +{{ macros.install_packages(ovn_controller_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_ovn_extend_start +RUN chmod 644 /usr/local/bin/kolla_ovn_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovn_controller_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovn/ovn-controller/extend_start.sh b/kolla/docker/ovn/ovn-controller/extend_start.sh new file mode 100644 index 000000000..8080ea7c8 --- /dev/null +++ b/kolla/docker/ovn/ovn-controller/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [[ ! -r "/var/log/kolla/openvswitch/ovn-controller.log" ]]; then + touch /var/log/kolla/openvswitch/ovn-controller.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovn-controller.log +fi diff --git a/kolla/docker/ovn/ovn-nb-db-server/Dockerfile.j2 b/kolla/docker/ovn/ovn-nb-db-server/Dockerfile.j2 new file mode 100644 index 000000000..ea6a53249 --- /dev/null +++ b/kolla/docker/ovn/ovn-nb-db-server/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}ovn-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovn_nb_db_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ovn_nb_db_server_packages = [ + 'ovn${KOLLA_RPM_OVN_VERSION}-central', + ] %} + +{% elif base_package_type == 'deb' %} + {% set ovn_nb_db_server_packages = [ + 'ovn-central', + ] %} + +{% endif %} +{{ macros.install_packages(ovn_nb_db_server_packages | customizable("packages")) }} + +COPY start_nb_db_server.sh /usr/local/bin/start-nb-db-server +RUN chmod 755 /usr/local/bin/start-nb-db-server +COPY extend_start.sh /usr/local/bin/kolla_ovn_extend_start +RUN chmod 644 /usr/local/bin/kolla_ovn_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovn_nb_db_server_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovn/ovn-nb-db-server/extend_start.sh b/kolla/docker/ovn/ovn-nb-db-server/extend_start.sh new file mode 100644 index 000000000..4c0e742f5 --- /dev/null +++ b/kolla/docker/ovn/ovn-nb-db-server/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [[ ! -r "/var/log/kolla/openvswitch/ovn-nb-db.log" ]]; then + touch /var/log/kolla/openvswitch/ovn-nb-db.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovn-nb-db.log +fi diff --git a/kolla/docker/ovn/ovn-nb-db-server/start_nb_db_server.sh b/kolla/docker/ovn/ovn-nb-db-server/start_nb_db_server.sh new file mode 100755 index 000000000..d08dd2890 --- /dev/null +++ b/kolla/docker/ovn/ovn-nb-db-server/start_nb_db_server.sh @@ -0,0 +1,28 @@ +#!/bin/bash + +# All the option passed to this script will be +# passed to the ovn-ctl script. Please see the options +# supported by ovn-ctl script - +# https://github.com/ovn-org/ovn/blob/master/utilities/ovn-ctl +args=$@ + +# Use ovn-ctl script to start ovn NB db server as it +# takes care of creating the db file from the schema +# file if the db file is not present. It also takes care +# of updating the db file if the schema file is updated. + +# Check for the presence of ovn-ctl script in two locations. +# If latest OVN is used (post split from openvswitch), +# then the new location for the ovn-ctl script is +# is - /usr/share/ovn/scripts/ovn-ctl. Otherwise it is +# /usr/share/openvswitch/scripts/ovn-ctl. + +if [[ -f "/usr/share/openvswitch/scripts/ovn-ctl" ]]; then + set /usr/share/openvswitch/scripts/ovn-ctl --no-monitor +elif [[ -f "/usr/share/ovn/scripts/ovn-ctl" ]]; then + set /usr/share/ovn/scripts/ovn-ctl --no-monitor +else + exit 1 +fi + +$@ $args run_nb_ovsdb diff --git a/kolla/docker/ovn/ovn-northd/Dockerfile.j2 b/kolla/docker/ovn/ovn-northd/Dockerfile.j2 new file mode 100644 index 000000000..4a15e10eb --- /dev/null +++ b/kolla/docker/ovn/ovn-northd/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}ovn-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovn_northd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ovn_northd_packages = [ + 'ovn${KOLLA_RPM_OVN_VERSION}-central', + ] %} + +{% elif base_package_type == 'deb' %} + {% set ovn_northd_packages = [ + 'ovn-central', + ] %} + +{% endif %} +{{ macros.install_packages(ovn_northd_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_ovn_extend_start +RUN chmod 644 /usr/local/bin/kolla_ovn_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovn_northd_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovn/ovn-northd/extend_start.sh b/kolla/docker/ovn/ovn-northd/extend_start.sh new file mode 100644 index 000000000..c832c5383 --- /dev/null +++ b/kolla/docker/ovn/ovn-northd/extend_start.sh @@ -0,0 +1,5 @@ +#!/bin/bash +if [[ ! -r "/var/log/kolla/openvswitch/ovn-northd.log" ]]; then + touch /var/log/kolla/openvswitch/ovn-northd.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovn-northd.log +fi diff --git a/kolla/docker/ovn/ovn-sb-db-relay/Dockerfile.j2 b/kolla/docker/ovn/ovn-sb-db-relay/Dockerfile.j2 new file mode 100644 index 000000000..427b6f7f1 --- /dev/null +++ b/kolla/docker/ovn/ovn-sb-db-relay/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}ovn-sb-db-server:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovn_sb_db_server_header %}{% endblock %} + +{% block ovn_sb_db_relay_ovn_ctl %} +{# TODO(mnasiadka): Switch to 25.03 branch when available, ideally rpm/deb packages will be + available. #} +RUN curl -o /usr/share/ovn/scripts/ovn-ctl https://raw.githubusercontent.com/ovn-org/ovn/refs/heads/main/utilities/ovn-ctl +{% endblock %} + +COPY extend_start.sh /usr/local/bin/kolla_ovn_extend_start +RUN chmod 644 /usr/local/bin/kolla_ovn_extend_start + +{% block ovn_sb_db_relay_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovn/ovn-sb-db-relay/extend_start.sh b/kolla/docker/ovn/ovn-sb-db-relay/extend_start.sh new file mode 100644 index 000000000..04b6c5357 --- /dev/null +++ b/kolla/docker/ovn/ovn-sb-db-relay/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [[ ! -r "/var/log/kolla/openvswitch/ovn-sb-relay-${RELAY_ID}.log" ]]; then + touch /var/log/kolla/openvswitch/ovn-sb-relay-${RELAY_ID}.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovn-sb-relay-${RELAY_ID}.log +fi diff --git a/kolla/docker/ovn/ovn-sb-db-server/Dockerfile.j2 b/kolla/docker/ovn/ovn-sb-db-server/Dockerfile.j2 new file mode 100644 index 000000000..afceb8173 --- /dev/null +++ b/kolla/docker/ovn/ovn-sb-db-server/Dockerfile.j2 @@ -0,0 +1,31 @@ +FROM {{ namespace }}/{{ image_prefix }}ovn-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovn_sb_db_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set ovn_sb_db_server_packages = [ + 'ovn${KOLLA_RPM_OVN_VERSION}-central', + ] %} + +{% elif base_package_type == 'deb' %} + {% set ovn_sb_db_server_packages = [ + 'ovn-central', + ] %} + +{% endif %} +{{ macros.install_packages(ovn_sb_db_server_packages | customizable("packages")) }} + +COPY start_sb_db_server.sh /usr/local/bin/start-sb-db-server +RUN chmod 755 /usr/local/bin/start-sb-db-server +COPY extend_start.sh /usr/local/bin/kolla_ovn_extend_start +RUN chmod 644 /usr/local/bin/kolla_ovn_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovn_sb_db_server_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovn/ovn-sb-db-server/extend_start.sh b/kolla/docker/ovn/ovn-sb-db-server/extend_start.sh new file mode 100644 index 000000000..07bcd1b45 --- /dev/null +++ b/kolla/docker/ovn/ovn-sb-db-server/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +if [[ ! -r "/var/log/kolla/openvswitch/ovn-sb-db.log" ]]; then + touch /var/log/kolla/openvswitch/ovn-sb-db.log + chown openvswitch:openvswitch /var/log/kolla/openvswitch/ovn-sb-db.log +fi diff --git a/kolla/docker/ovn/ovn-sb-db-server/start_sb_db_server.sh b/kolla/docker/ovn/ovn-sb-db-server/start_sb_db_server.sh new file mode 100755 index 000000000..ef39b8d25 --- /dev/null +++ b/kolla/docker/ovn/ovn-sb-db-server/start_sb_db_server.sh @@ -0,0 +1,29 @@ +#!/bin/bash + +# All the option passed to this script will be +# passed to the ovn-ctl script. Please see the options +# supported by ovn-ctl script - +# https://github.com/ovn-org/ovn/blob/master/utilities/ovn-ctl +args=$@ + +# Use ovn-ctl script to start ovn SB db server as it +# takes care of creating the db file from the schema +# file if the db file is not present. It also takes care +# of updating the db file if the schema file is updated. + +# Check for the presence of ovn-ctl script in two locations. +# If latest OVN is used (post split from openvswitch), +# then the new location for the ovn-ctl script is +# is - /usr/share/ovn/scripts/ovn-ctl. Otherwise it is +# /usr/share/openvswitch/scripts/ovn-ctl. + + +if [[ -f "/usr/share/openvswitch/scripts/ovn-ctl" ]]; then + set /usr/share/openvswitch/scripts/ovn-ctl --no-monitor +elif [[ -f "/usr/share/ovn/scripts/ovn-ctl" ]]; then + set /usr/share/ovn/scripts/ovn-ctl --no-monitor +else + exit 1 +fi + +$@ $args run_sb_ovsdb diff --git a/kolla/docker/ovsdpdk/ovsdpdk-db/Dockerfile.j2 b/kolla/docker/ovsdpdk/ovsdpdk-db/Dockerfile.j2 new file mode 100644 index 000000000..2527fa0e6 --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk-db/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}ovsdpdk:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovsdpdk_db_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_ovsdpdk_extend_start +COPY start_ovsdb_server.sh /usr/local/bin/start-ovsdb-server +RUN chmod 644 /usr/local/bin/kolla_ovsdpdk_extend_start && \ + chmod 755 /usr/local/bin/start-ovsdb-server + +{{ macros.kolla_patch_sources() }} + +{% block ovsdpdk_db_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovsdpdk/ovsdpdk-db/extend_start.sh b/kolla/docker/ovsdpdk/ovsdpdk-db/extend_start.sh new file mode 100644 index 000000000..3883b50ed --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk-db/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +mkdir -p "/run/openvswitch" +if [[ ! -e "/var/lib/openvswitch/conf.db" ]]; then + ovsdb-tool create "/var/lib/openvswitch/conf.db" +fi diff --git a/kolla/docker/ovsdpdk/ovsdpdk-db/start_ovsdb_server.sh b/kolla/docker/ovsdpdk/ovsdpdk-db/start_ovsdb_server.sh new file mode 100755 index 000000000..5c92fba78 --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk-db/start_ovsdb_server.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# NOTE: (sbezverk) ovs_bridge and ovs_ext_intf variables get initialized only when +# this script is executed for kubernetes deployment. With Ansible deployment, only +# ovsdb-server gets launched and then the following workflow step will create +# an external bridge and plug an external interface. With Kubernetes we want to +# leverage its dynamic nature of automatic scaling up and down. It means all +# activities related to creating initial bridge, plugging external interface +# must be done by DaemonSet launched container. + +ovsdb_ip=$1 +ovs_bridge=$2 +ovs_ext_intf=$3 + +# NOTE: (sbezverk) The reason for introducing this script is to be able +# to launch ovsdb-server and to create the initial external bridge in one step. +# It is required in order to be able to use DaemonSet. + +if [ ! -e $ovs_bridge ] && [ ! -e $ovs_ext_intf ]; then +# NOTE: (sbezverk) This part is executed only by kubernetes deployment. +# Creating external bridge + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db --remote=punix:/var/run/openvswitch/db.sock --run="ovs-vsctl --no-wait --db=unix:/var/run/openvswitch/db.sock add-br $ovs_bridge" +# Plug the external interface into the external bridge. + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db --remote=punix:/var/run/openvswitch/db.sock --run="ovs-vsctl --no-wait --db=unix:/var/run/openvswitch/db.sock add-port $ovs_bridge $ovs_ext_intf" +# Run ovsdb server process + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/var/run/openvswitch/db.sock --remote=ptcp:6640 --log-file=/var/log/kolla/openvswitch/ovsdb-server.log +else +# NOTE: (sbezverk) This part is executed only by kolla-ansible deployment. + /usr/sbin/ovsdb-server /var/lib/openvswitch/conf.db -vconsole:emer -vsyslog:err -vfile:info --remote=punix:/run/openvswitch/db.sock --remote=ptcp:6640:$ovsdb_ip --log-file=/var/log/kolla/openvswitch/ovsdb-server.log +fi diff --git a/kolla/docker/ovsdpdk/ovsdpdk-vswitchd/Dockerfile.j2 b/kolla/docker/ovsdpdk/ovsdpdk-vswitchd/Dockerfile.j2 new file mode 100644 index 000000000..059efd46b --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk-vswitchd/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}ovsdpdk:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block ovsdpdk_vswitchd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_ovsdpdk_extend_start +RUN chmod 644 /usr/local/bin/kolla_ovsdpdk_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovsdpdk_vswitchd_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/ovsdpdk/ovsdpdk-vswitchd/extend_start.sh b/kolla/docker/ovsdpdk/ovsdpdk-vswitchd/extend_start.sh new file mode 100644 index 000000000..cf9d733e8 --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk-vswitchd/extend_start.sh @@ -0,0 +1,6 @@ +#!/bin/bash + +# using userspace netdev datapath so do not loading ovs kernel module +# chmod openvsitch run directory so libvirt can create vhost-user sockets. +chmod 777 /var/run/openvswitch + diff --git a/kolla/docker/ovsdpdk/ovsdpdk/Dockerfile.j2 b/kolla/docker/ovsdpdk/ovsdpdk/Dockerfile.j2 new file mode 100644 index 000000000..eab4f5474 --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk/Dockerfile.j2 @@ -0,0 +1,40 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% import "macros.j2" as macros with context %} +{% block ovsdpdk_header %}{% endblock %} + +{% block ovsdpdk_install %} + +{% if base_package_type == 'rpm' %} + +#TODO(sean-k-mooney) create repo via open suse build system to package +# for centos distro. + +RUN echo 'image not yet available for {{ base_distro }}' \ + && /bin/false + +{% elif base_package_type == 'deb' %} + +{% set ovs_dpdk_packages = [ + 'crudini', + 'libdpdk-dev', + 'openvswitch-switch-dpdk' +] %} + +{{ macros.install_packages(ovs_dpdk_packages | customizable("packages")) }} + +RUN update-alternatives --set ovs-vswitchd /usr/lib/openvswitch-switch-dpdk/ovs-vswitchd-dpdk + +{% endif %} + +{% endblock %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block ovsdpdk_footer %}{% endblock %} diff --git a/kolla/docker/ovsdpdk/ovsdpdk/extend_start.sh b/kolla/docker/ovsdpdk/ovsdpdk/extend_start.sh new file mode 100644 index 000000000..60ab0c088 --- /dev/null +++ b/kolla/docker/ovsdpdk/ovsdpdk/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/openvswitch" ]]; then + mkdir -p /var/log/kolla/openvswitch +fi +if [[ $(stat -c %a /var/log/kolla/openvswitch) != "755" ]]; then + chmod 755 /var/log/kolla/openvswitch +fi + +. /usr/local/bin/kolla_ovsdpdk_extend_start diff --git a/kolla/docker/placement/placement-api/Dockerfile.j2 b/kolla/docker/placement/placement-api/Dockerfile.j2 new file mode 100644 index 000000000..a13f65bdf --- /dev/null +++ b/kolla/docker/placement/placement-api/Dockerfile.j2 @@ -0,0 +1,19 @@ +FROM {{ namespace }}/{{ image_prefix }}placement-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block placement_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set placement_api_packages = [ +] %} +{{ macros.install_packages(placement_api_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_placement_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block placement_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/placement/placement-api/extend_start.sh b/kolla/docker/placement/placement-api/extend_start.sh new file mode 100644 index 000000000..e468cbcaf --- /dev/null +++ b/kolla/docker/placement/placement-api/extend_start.sh @@ -0,0 +1,21 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + placement-manage db sync + placement-manage db online_data_migrations + exit 0 +fi + +# DB synchronisation. To be executed prior to upgrading services. +if [[ "${!KOLLA_UPGRADE[@]}" ]]; then + placement-manage db sync + exit 0 +fi + +# Online data migrations. To be executed after upgrading services. +if [[ "${!KOLLA_OSM[@]}" ]]; then + placement-manage db online_data_migrations + exit 0 +fi diff --git a/kolla/docker/placement/placement-base/Dockerfile.j2 b/kolla/docker/placement/placement-base/Dockerfile.j2 new file mode 100644 index 000000000..6454da748 --- /dev/null +++ b/kolla/docker/placement/placement-base/Dockerfile.j2 @@ -0,0 +1,44 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block placement_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='placement') }} + +{% if base_package_type == 'rpm' %} + + {% set placement_base_packages = [ + ] %} + +{% elif base_package_type == 'deb' %} + + {% set placement_base_packages = [ + ] %} + +{% endif %} + +{{ macros.install_packages(placement_base_packages | customizable("packages")) }} + +ADD placement-base-archive /placement-base-source +ADD plugins-archive / + +{% set placement_base_pip_packages = [ + '/placement' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s placement-base-source/* placement \ + && {{ macros.install_pip(placement_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/placement/ \ + && cp -r /placement/etc/placement/* /etc/placement/ \ + && touch /usr/local/bin/kolla_placement_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_placement_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block placement_base_footer %}{% endblock %} diff --git a/kolla/docker/placement/placement-base/extend_start.sh b/kolla/docker/placement/placement-base/extend_start.sh new file mode 100644 index 000000000..900ea8447 --- /dev/null +++ b/kolla/docker/placement/placement-base/extend_start.sh @@ -0,0 +1,15 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/placement" ]]; then + mkdir -p /var/log/kolla/placement + touch /var/log/kolla/placement/placement-api.log +fi +if [[ $(stat -c %U:%G /var/log/kolla/placement) != "placement:kolla" ]]; then + chown -R placement:kolla /var/log/kolla/placement +fi +if [[ $(stat -c %a /var/log/kolla/placement) != "755" ]]; then + chmod 755 /var/log/kolla/placement + chmod 644 /var/log/kolla/placement/placement-api.log +fi + +. /usr/local/bin/kolla_placement_extend_start diff --git a/kolla/docker/prometheus/prometheus-alertmanager/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-alertmanager/Dockerfile.j2 new file mode 100644 index 000000000..8f2df0492 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-alertmanager/Dockerfile.j2 @@ -0,0 +1,21 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_alertmanager_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_alertmanager_install %} +ADD prometheus-alertmanager-archive /prometheus-alertmanager-source +RUN cp -r /prometheus-alertmanager-source/* /opt/ \ + && ln -s /opt/alertmanager* /opt/prometheus_alertmanager +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_alertmanager_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-base/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-base/Dockerfile.j2 new file mode 100644 index 000000000..123bd4ba3 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-base/Dockerfile.j2 @@ -0,0 +1,17 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='prometheus') }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_base_footer %}{% endblock %} diff --git a/kolla/docker/prometheus/prometheus-base/extend_start.sh b/kolla/docker/prometheus/prometheus-base/extend_start.sh new file mode 100644 index 000000000..8613330c6 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-base/extend_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +# Create log directory, with appropriate permissions +if [[ ! -d "/var/log/kolla/prometheus" ]]; then + mkdir -p /var/log/kolla/prometheus +fi +if [[ $(stat -c %a /var/log/kolla/prometheus) != "755" ]]; then + chmod 755 /var/log/kolla/prometheus +fi diff --git a/kolla/docker/prometheus/prometheus-blackbox-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-blackbox-exporter/Dockerfile.j2 new file mode 100644 index 000000000..95018facf --- /dev/null +++ b/kolla/docker/prometheus/prometheus-blackbox-exporter/Dockerfile.j2 @@ -0,0 +1,36 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_blackbox_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + {% set blackbox_packages = [ + 'libcap' + ] %} +{% elif base_package_type == 'deb' %} + {% set blackbox_packages = [ + 'libcap2-bin' + ] %} +{% endif %} + +{{ macros.install_packages(blackbox_packages | customizable("packages")) }} + +{% block prometheus_blackbox_exporter_install %} +ADD prometheus-blackbox-exporter-archive /prometheus-blackbox-exporter-source + +RUN ln -s /prometheus-blackbox-exporter-source/* prometheus-blackbox-exporter \ + && mkdir -p /opt/blackbox_exporter/ \ + && cp /prometheus-blackbox-exporter/blackbox_exporter /opt/blackbox_exporter/ \ + && setcap cap_net_raw+ep /opt/blackbox_exporter/blackbox_exporter +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_blackbox_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-cadvisor/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-cadvisor/Dockerfile.j2 new file mode 100644 index 000000000..884f4acd2 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-cadvisor/Dockerfile.j2 @@ -0,0 +1,20 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_cadvisor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_cadvisor_install %} +ADD prometheus-cadvisor-archive /prometheus-cadvisor-source + +RUN cp /prometheus-cadvisor-source /opt/cadvisor \ + && chmod 0755 /opt/cadvisor +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_cadvisor_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/prometheus/prometheus-elasticsearch-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-elasticsearch-exporter/Dockerfile.j2 new file mode 100644 index 000000000..63d09409c --- /dev/null +++ b/kolla/docker/prometheus/prometheus-elasticsearch-exporter/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_elasticsearch_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_elasticsearch_exporter_install %} +ADD prometheus-elasticsearch-exporter-archive /prometheus-elasticsearch-exporter-source + +RUN ln -s /prometheus-elasticsearch-exporter-source/* prometheus-elasticsearch-exporter \ + && mkdir -p /opt/elasticsearch_exporter \ + && cp /prometheus-elasticsearch-exporter/elasticsearch_exporter /opt/elasticsearch_exporter/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_elasticsearch_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-libvirt-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-libvirt-exporter/Dockerfile.j2 new file mode 100644 index 000000000..c32b2f8c7 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-libvirt-exporter/Dockerfile.j2 @@ -0,0 +1,25 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_libvirt_exporter_header %}{% endblock %} + +{{ macros.install_packages(prometheus_libvirt_exporter_packages | customizable("packages")) }} + +{% block prometheus_libvirt_exporter_install %} +ADD prometheus-libvirt-exporter-archive /prometheus-libvirt-exporter-source + +RUN ln -s /prometheus-libvirt-exporter-source/* prometheus-libvirt-exporter \ + && cp /prometheus-libvirt-exporter/prometheus-libvirt-exporter /opt/libvirt-exporter + +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_libvirt_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER root diff --git a/kolla/docker/prometheus/prometheus-memcached-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-memcached-exporter/Dockerfile.j2 new file mode 100644 index 000000000..cb50c2095 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-memcached-exporter/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_memcached_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_memcached_exporter_install %} +ADD prometheus-memcached-exporter-archive /prometheus-memcached-exporter-source + +RUN ln -s /prometheus-memcached-exporter-source/* prometheus-memcached-exporter \ + && mkdir -p /opt/memcached_exporter/ \ + && cp /prometheus-memcached-exporter/memcached_exporter /opt/memcached_exporter/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_memcached_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-mtail/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-mtail/Dockerfile.j2 new file mode 100644 index 000000000..a562bfd71 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-mtail/Dockerfile.j2 @@ -0,0 +1,25 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_mtail_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_mtail_install %} +ADD prometheus-mtail-archive /prometheus-mtail-source + +RUN cp /prometheus-mtail-source/* /opt/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_mtail_footer %}{% endblock %} +{% block footer %}{% endblock %} + +# NOTE(dszumski): We run as root so that mtail can scrape root owned logs +# such as /var/log/secure which are mounted into the container as read only +# for auditing purposes. Longer term we should use a more secure mechanism +# for tailing these logs. +USER root diff --git a/kolla/docker/prometheus/prometheus-mysqld-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-mysqld-exporter/Dockerfile.j2 new file mode 100644 index 000000000..f8d2abaa6 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-mysqld-exporter/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block mysqld_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block mysqld_exporter_install %} +ADD prometheus-mysqld-exporter-archive /prometheus-mysqld-exporter-source + +RUN ln -s /prometheus-mysqld-exporter-source/* prometheus-mysqld-exporter \ + && mkdir -p /opt/mysqld_exporter \ + && cp /prometheus-mysqld-exporter/mysqld_exporter /opt/mysqld_exporter/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block mysqld_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-node-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-node-exporter/Dockerfile.j2 new file mode 100644 index 000000000..3250d3d7a --- /dev/null +++ b/kolla/docker/prometheus/prometheus-node-exporter/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block node_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block node_exporter_install %} +ADD prometheus-node-exporter-archive /prometheus-node-exporter-source + +RUN ln -s /prometheus-node-exporter-source/* prometheus-node-exporter \ + && mkdir -p /opt/node_exporter/ \ + && cp /prometheus-node-exporter/node_exporter /opt/node_exporter/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block node_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-openstack-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-openstack-exporter/Dockerfile.j2 new file mode 100644 index 000000000..437f3a6cd --- /dev/null +++ b/kolla/docker/prometheus/prometheus-openstack-exporter/Dockerfile.j2 @@ -0,0 +1,22 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_openstack_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_openstack_exporter_install %} +ADD prometheus-openstack-exporter-archive /prometheus-openstack-exporter-source + +RUN mkdir /opt/openstack-exporter \ + && cp /prometheus-openstack-exporter-source/openstack-exporter /opt/openstack-exporter/ +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_openstack_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-openstack-network-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-openstack-network-exporter/Dockerfile.j2 new file mode 100644 index 000000000..3d4d9197b --- /dev/null +++ b/kolla/docker/prometheus/prometheus-openstack-network-exporter/Dockerfile.j2 @@ -0,0 +1,24 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_openstack_network_exporter_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_openstack_network_exporter_install %} +ADD prometheus-openstack-network-exporter-archive /prometheus-openstack-network-exporter-source + +RUN mkdir /opt/openstack-network-exporter \ + && cp /prometheus-openstack-network-exporter-source /opt/openstack-network-exporter/openstack-network-exporter \ + && chmod 0755 /opt/openstack-network-exporter/openstack-network-exporter +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_openstack_network_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +# NOTE: OVN/OVS are running as root. Since we need to read sockets owned by +# these services we don't switch to the Prometheus user here. diff --git a/kolla/docker/prometheus/prometheus-server/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-server/Dockerfile.j2 new file mode 100644 index 000000000..a3b227d7e --- /dev/null +++ b/kolla/docker/prometheus/prometheus-server/Dockerfile.j2 @@ -0,0 +1,24 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block prometheus_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_server_install %} +ADD prometheus-server-archive /prometheus-server-source + +RUN ln -s /prometheus-server-source/* prometheus-server \ + && mkdir -p /opt/prometheus \ + && cp -r /prometheus-server/* /opt/prometheus/ \ + && mkdir -p /etc/prometheus /data +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_server_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/prometheus/prometheus-valkey-exporter/Dockerfile.j2 b/kolla/docker/prometheus/prometheus-valkey-exporter/Dockerfile.j2 new file mode 100644 index 000000000..c6cf79ac3 --- /dev/null +++ b/kolla/docker/prometheus/prometheus-valkey-exporter/Dockerfile.j2 @@ -0,0 +1,25 @@ +FROM {{ namespace }}/{{ image_prefix }}prometheus-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% block prometheus_valkey_exporter_header %}{% endblock %} + +{{ macros.install_packages(prometheus_valkey_exporter_packages | customizable("packages")) }} + +{% block prometheus_valkey_exporter_install %} +ADD prometheus-valkey-exporter-archive /prometheus-valkey-exporter-source + +RUN ln -s /prometheus-valkey-exporter-source/* prometheus-valkey-exporter \ + && cp /prometheus-valkey-exporter/redis_exporter /opt/valkey-exporter + +{% endblock %} + +{{ macros.kolla_patch_sources() }} + +{% block prometheus_valkey_exporter_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER prometheus diff --git a/kolla/docker/proxysql/Dockerfile.j2 b/kolla/docker/proxysql/Dockerfile.j2 new file mode 100644 index 000000000..a76dbcda8 --- /dev/null +++ b/kolla/docker/proxysql/Dockerfile.j2 @@ -0,0 +1,43 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block proxysql_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.enable_extra_repos(['proxysql']) }} + +{% set proxysql_packages = [ + 'proxysql', +] %} + +{% if base_package_type == 'rpm' %} + {% set proxysql_packages = proxysql_packages + [ + 'python3-PyYAML', + ] %} +{% elif base_package_type == 'deb' %} + {% set proxysql_packages = proxysql_packages + [ + 'python3-yaml', + ] %} +{% endif %} + +{{ macros.configure_user(name='proxysql') }} +{{ macros.install_packages(proxysql_packages | customizable("packages")) }} + +COPY kolla_proxysql_config_sync kolla_extend_start /usr/local/bin/ +RUN chmod 755 /usr/local/bin/kolla_proxysql_config_sync \ + && chmod 644 /usr/local/bin/kolla_extend_start + +RUN install -g proxysql -o proxysql -m 770 -d /var/lib/kolla/proxysql \ + && touch /etc/proxysql.cnf \ + && chown proxysql:proxysql /etc/proxysql.cnf \ + && chmod 600 /etc/proxysql.cnf + +{{ macros.kolla_patch_sources() }} + +{% block proxysql_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER proxysql diff --git a/kolla/docker/proxysql/kolla_extend_start b/kolla/docker/proxysql/kolla_extend_start new file mode 100644 index 000000000..229e8ada2 --- /dev/null +++ b/kolla/docker/proxysql/kolla_extend_start @@ -0,0 +1,21 @@ +#!/bin/bash + +PROXYSQL_LIB_DIR="/var/lib/proxysql" +PROXYSQL_LOG_DIR="/var/log/kolla/proxysql" + +if [[ ! -d "${PROXYSQL_LOG_DIR}" ]]; then + mkdir -p "${PROXYSQL_LOG_DIR}" +fi +chown -R proxysql:kolla "${PROXYSQL_LOG_DIR}" + +# Remove old pid +rm -f ${PROXYSQL_LIB_DIR}/proxysql.pid + +# As proxysql supports only one +# configuration file, there is a +# script which reads global and services +# configs (similar to haproxy) and +# generate single configuration file +# from which is internal DB created +# every time. +kolla_proxysql_config_sync diff --git a/kolla/docker/proxysql/kolla_proxysql_config_sync b/kolla/docker/proxysql/kolla_proxysql_config_sync new file mode 100644 index 000000000..094642c8a --- /dev/null +++ b/kolla/docker/proxysql/kolla_proxysql_config_sync @@ -0,0 +1,162 @@ +#!/usr/bin/python3 + +# Copyright 2021 Michal Arbet +# +# 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 logging +import os +import yaml + +# Default paths +PROXYSQL_CONFIG_DIR = "/etc/proxysql" +PROXYSQL_CONFIG = "/etc/proxysql.cnf" + +# Logging +log_format = '%(asctime)s,%(msecs)d %(name)s %(levelname)s %(message)s' +logging.basicConfig(format=log_format, + datefmt='%H:%M:%S', + level=logging.DEBUG) +LOG = logging.getLogger("proxysql_config_sync") + + +class ProxySQLConfig: + + def __init__(self, conf_dir, conf_file): + self.configs = dict() + self.config = dict() + self.configs['global'] = "{}/proxysql.yaml".format(conf_dir) + self.configs['users'] = "{}/users".format(conf_dir) + self.configs['rules'] = "{}/rules".format(conf_dir) + self.conf_file = conf_file + self._load_config() + + def _load_config(self): + users = dict() + rules = dict() + + for cfg, path in self.configs.items(): + if not os.path.isdir(path): + with open(path) as config_file: + self.config.update( + yaml.safe_load(config_file)) + else: + users['mysql_users'] = list() + rules['mysql_query_rules'] = list() + user_paths = [os.path.join(self.configs['users'], f) + for f in os.listdir(self.configs['users'])] + rule_paths = [os.path.join(self.configs['rules'], f) + for f in os.listdir(self.configs['rules'])] + + for user_conf in user_paths: + with open(user_conf) as config_file: + tmp_users = yaml.safe_load(config_file) + for i in tmp_users['mysql_users']: + users['mysql_users'].append(i) + self.config.update(users) + for rule_conf in rule_paths: + with open(rule_conf) as config_file: + tmp_rules = yaml.safe_load(config_file) + for i in tmp_rules['mysql_query_rules']: + rules['mysql_query_rules'].append(i) + self.config.update(rules) + self._sanity() + + def _sanity(self): + self._users_sanity() + self._rules_sanity() + + def _users_sanity(self): + users_added = list() + users = list() + for user in self.config['mysql_users']: + if user['username'] not in users_added: + users_added.append(user['username']) + users.append(user) + else: + LOG.warning("User {} already exist, ignoring." + .format(user['username'])) + self.config['mysql_users'] = users + + def _rules_sanity(self): + rules_added = list() + rules = list() + rule_id = 1 + for rule in self.config['mysql_query_rules']: + if 'schemaname' in rule: + key = f"schema:{rule['schemaname']}" + elif 'username' in rule: + key = f"user:{rule['username']}" + else: + LOG.warning( + f"Rule without schemaname or username found, skipping: {rule}" + ) + continue + + if key not in rules_added: + rules_added.append(key) + rule['rule_id'] = rule_id + rules.append(rule) + rule_id += 1 + else: + LOG.warning("Duplicate rule for {}, ignoring.".format(key)) + + self.config['mysql_query_rules'] = rules + + def _write_dict(self, key, value): + if not isinstance(value, list): + value = [value] + with open(self.conf_file, "a+") as f: + if key: + f.write("{} =\n".format(key)) + for i in range(len(value)): + f.write(" {\n") + for k, v in value[i].items(): + if isinstance(v, str): + v = '"{}"'.format(v) + f.write(" {} = {}\n".format(k, v)) + if i == len(value)-1: + f.write(" }\n") + else: + f.write(" },\n") + + def _write_list(self, key, values): + with open(self.conf_file, "a+") as f: + f.write("{} =\n".format(key)) + f.write("(\n") + self._write_dict(key=None, value=values) + with open(self.conf_file, "a+") as f: + f.write(")\n") + + def _write(self, key, value): + with open(self.conf_file, "a+") as f: + if isinstance(value, str): + value = '"{}"'.format(value) + f.write("{} = {}\n".format(key, value)) + + def write_config(self): + LOG.info("Writing config to {}".format(self.conf_file)) + with open(self.conf_file, 'wb') as f: + pass + for k, v in self.config.items(): + if isinstance(v, dict): + self._write_dict(k, v) + elif isinstance(v, list): + self._write_list(k, v) + else: + self._write(k, v) + + +if __name__ == "__main__": + config = ProxySQLConfig(PROXYSQL_CONFIG_DIR, PROXYSQL_CONFIG) + config.write_config() diff --git a/kolla/docker/rabbitmq/Dockerfile.j2 b/kolla/docker/rabbitmq/Dockerfile.j2 new file mode 100644 index 000000000..a167356a7 --- /dev/null +++ b/kolla/docker/rabbitmq/Dockerfile.j2 @@ -0,0 +1,69 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block rabbitmq_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='rabbitmq') }} + +{{ macros.enable_extra_repos(['erlang', 'rabbitmq']) }} + +{% block rabbitmq_apt_preferences %} +{% if base_package_type == 'deb' %} +COPY apt_preferences_rabbitmq.{{ base_distro }} /etc/apt/preferences.d/rabbitmq +{% endif %} +{% endblock %} + +{% block rabbitmq_install %} +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['crb']) }} + + {% set rabbitmq_packages = [ + 'erlang-27.*', + 'rabbitmq-server-4.2.*' + ] %} + +{% elif base_package_type == 'deb' %} + {% set rabbitmq_packages = [ + 'logrotate', + 'rabbitmq-server', + ] %} + +{% endif %} + +{{ macros.install_packages(rabbitmq_packages | customizable("packages")) }} + +{% endblock %} + +{% block rabbitmq_install_plugins %} + +RUN rm -rf /var/lib/rabbitmq/* \ + && mkdir -p /usr/lib/rabbitmq/plugins \ + && /usr/lib/rabbitmq/bin/rabbitmq-plugins enable --offline \ + rabbitmq_management \ + rabbitmq_prometheus + +{% endblock %} + +{% if docker_healthchecks %} +{% block healthcheck_installation %} + +COPY healthcheck_rabbitmq /usr/local/bin/healthcheck_rabbitmq +RUN chmod 755 /usr/local/bin/healthcheck_rabbitmq + +{% endblock %} +{% endif %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block rabbitmq_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER rabbitmq diff --git a/kolla/docker/rabbitmq/apt_preferences_rabbitmq.debian b/kolla/docker/rabbitmq/apt_preferences_rabbitmq.debian new file mode 100644 index 000000000..cc6404b3e --- /dev/null +++ b/kolla/docker/rabbitmq/apt_preferences_rabbitmq.debian @@ -0,0 +1,7 @@ +Package: rabbitmq-server +Pin: version 4.2.* +Pin-Priority: 1000 + +Package: erlang* +Pin: version 1:27.* +Pin-Priority: 1000 diff --git a/kolla/docker/rabbitmq/apt_preferences_rabbitmq.ubuntu b/kolla/docker/rabbitmq/apt_preferences_rabbitmq.ubuntu new file mode 100644 index 000000000..cc6404b3e --- /dev/null +++ b/kolla/docker/rabbitmq/apt_preferences_rabbitmq.ubuntu @@ -0,0 +1,7 @@ +Package: rabbitmq-server +Pin: version 4.2.* +Pin-Priority: 1000 + +Package: erlang* +Pin: version 1:27.* +Pin-Priority: 1000 diff --git a/kolla/docker/rabbitmq/extend_start.sh b/kolla/docker/rabbitmq/extend_start.sh new file mode 100644 index 000000000..ef28d2b5f --- /dev/null +++ b/kolla/docker/rabbitmq/extend_start.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +: ${RABBITMQ_LOG_DIR:=/var/log/kolla/rabbitmq} + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + +# NOTE(sbezverk): In kubernetes environment, if this file exists from previous +# bootstrap, the system does not allow to overwrite it (it bootstrap files with +# permission denied error) but it allows to delete it and then recreate it. + if [[ -e "/var/lib/rabbitmq/.erlang.cookie" ]]; then + rm -f /var/lib/rabbitmq/.erlang.cookie + fi + echo "${RABBITMQ_CLUSTER_COOKIE}" > /var/lib/rabbitmq/.erlang.cookie + chmod 400 /var/lib/rabbitmq/.erlang.cookie + exit 0 +fi + +if [[ ! -d "${RABBITMQ_LOG_DIR}" ]]; then + mkdir -p ${RABBITMQ_LOG_DIR} +fi + +if [[ $(stat -c %a ${RABBITMQ_LOG_DIR}) != "755" ]]; then + chmod 755 ${RABBITMQ_LOG_DIR} +fi diff --git a/kolla/docker/rabbitmq/healthcheck_rabbitmq b/kolla/docker/rabbitmq/healthcheck_rabbitmq new file mode 100644 index 000000000..277ab098c --- /dev/null +++ b/kolla/docker/rabbitmq/healthcheck_rabbitmq @@ -0,0 +1,8 @@ +#!/bin/bash + +set -e + +for check in ping status check_running check_local_alarms check_port_connectivity check_virtual_hosts; do + echo "Running rabbitmq-diagnostics $check" + rabbitmq-diagnostics -t 5 -q $check || (echo "ERROR: $check failed" && exit 1) +done diff --git a/kolla/docker/skyline/skyline-apiserver/Dockerfile.j2 b/kolla/docker/skyline/skyline-apiserver/Dockerfile.j2 new file mode 100644 index 000000000..85b40d51c --- /dev/null +++ b/kolla/docker/skyline/skyline-apiserver/Dockerfile.j2 @@ -0,0 +1,27 @@ +FROM {{ namespace }}/{{ image_prefix }}skyline-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block skyline_apiserver_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +ADD skyline-apiserver-archive /skyline-apiserver-source + +{% set skyline_apiserver_pip_packages = [ + '/skyline-apiserver' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_skyline_extend_start + +RUN ln -s skyline-apiserver-source/* skyline-apiserver \ + && {{ macros.install_pip(skyline_apiserver_pip_packages | customizable("pip_packages")) }} \ + && chmod 644 /usr/local/bin/kolla_skyline_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block skyline_apiserver_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER skyline diff --git a/kolla/docker/skyline/skyline-apiserver/extend_start.sh b/kolla/docker/skyline/skyline-apiserver/extend_start.sh new file mode 100644 index 000000000..e1802937b --- /dev/null +++ b/kolla/docker/skyline/skyline-apiserver/extend_start.sh @@ -0,0 +1,11 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + SITE_PACKAGES="/var/lib/kolla/venv/lib/python3/site-packages" + pushd ${SITE_PACKAGES}/skyline_apiserver/db/alembic + alembic upgrade head + popd + exit 0 +fi diff --git a/kolla/docker/skyline/skyline-base/Dockerfile.j2 b/kolla/docker/skyline/skyline-base/Dockerfile.j2 new file mode 100644 index 000000000..815fa504f --- /dev/null +++ b/kolla/docker/skyline/skyline-base/Dockerfile.j2 @@ -0,0 +1,19 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block skyline_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='skyline') }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN touch /usr/local/bin/kolla_skyline_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_skyline_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block skyline_base_footer %}{% endblock %} diff --git a/kolla/docker/skyline/skyline-base/extend_start.sh b/kolla/docker/skyline/skyline-base/extend_start.sh new file mode 100644 index 000000000..34362ad04 --- /dev/null +++ b/kolla/docker/skyline/skyline-base/extend_start.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/skyline" ]]; then + mkdir -p /var/log/kolla/skyline +fi +if [[ $(stat -c %U:%G /var/log/kolla/skyline) != "skyline:kolla" ]]; then + chown skyline:kolla /var/log/kolla/skyline +fi +if [[ $(stat -c %a /var/log/kolla/skyline) != "755" ]]; then + chmod 755 /var/log/kolla/skyline +fi + +if [[ ! -d "/var/lib/skyline" ]]; then + mkdir -p /var/lib/skyline +fi +if [[ $(stat -c %U:%G /var/lib/skyline) != "skyline:kolla" ]]; then + chown skyline:kolla /var/lib/skyline +fi +if [[ $(stat -c %a /var/lib/skyline) != "755" ]]; then + chmod 755 /var/lib/skyline +fi + +. /usr/local/bin/kolla_skyline_extend_start diff --git a/kolla/docker/skyline/skyline-console/Dockerfile.j2 b/kolla/docker/skyline/skyline-console/Dockerfile.j2 new file mode 100644 index 000000000..ba62f5041 --- /dev/null +++ b/kolla/docker/skyline/skyline-console/Dockerfile.j2 @@ -0,0 +1,30 @@ +FROM {{ namespace }}/{{ image_prefix }}skyline-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block skyline_console_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% set skyline_console_packages = [ + 'nginx' +] %} + +{{ macros.install_packages(skyline_console_packages | customizable("packages")) }} + +ADD skyline-console-archive /skyline-console-source + +{% set skyline_console_pip_packages = [ + '/skyline-console' +] %} + +RUN ln -s skyline-console-source/* skyline-console \ + && {{ macros.install_pip(skyline_console_pip_packages | customizable("pip_packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block skyline_console_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER root diff --git a/kolla/docker/tacker/tacker-base/Dockerfile.j2 b/kolla/docker/tacker/tacker-base/Dockerfile.j2 new file mode 100644 index 000000000..c24c8d87c --- /dev/null +++ b/kolla/docker/tacker/tacker-base/Dockerfile.j2 @@ -0,0 +1,43 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block tacker_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='tacker') }} + +{% if base_package_type == 'rpm' %} + +{{ macros.enable_extra_repos(['openvswitch']) }} + +{% endif %} + +ADD tacker-base-archive /tacker-base-source +ADD plugins-archive / + +{% set tacker_base_pip_packages = [ + '/tacker' +] %} + +{% set tacker_base_plugins_pip_packages = [ + '/plugins/*' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s tacker-base-source/* tacker \ + && {{ macros.install_pip(tacker_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/tacker \ + && cp -r /tacker/etc/tacker/* /etc/tacker \ + && if [ "$(ls /plugins)" ]; then \ + {{ macros.install_pip(tacker_base_plugins_pip_packages) }}; \ + fi \ + && touch /usr/local/bin/kolla_tacker_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_tacker_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block tacker_base_footer %}{% endblock %} diff --git a/kolla/docker/tacker/tacker-base/extend_start.sh b/kolla/docker/tacker/tacker-base/extend_start.sh new file mode 100644 index 000000000..a3b7db8d3 --- /dev/null +++ b/kolla/docker/tacker/tacker-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/tacker" ]]; then + mkdir -p /var/log/kolla/tacker +fi +if [[ $(stat -c %a /var/log/kolla/tacker) != "755" ]]; then + chmod 755 /var/log/kolla/tacker +fi + +. /usr/local/bin/kolla_tacker_extend_start diff --git a/kolla/docker/tacker/tacker-conductor/Dockerfile.j2 b/kolla/docker/tacker/tacker-conductor/Dockerfile.j2 new file mode 100644 index 000000000..676c90106 --- /dev/null +++ b/kolla/docker/tacker/tacker-conductor/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}tacker-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block tacker_conductor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block tacker_conductor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER tacker diff --git a/kolla/docker/tacker/tacker-server/Dockerfile.j2 b/kolla/docker/tacker/tacker-server/Dockerfile.j2 new file mode 100644 index 000000000..659b70bea --- /dev/null +++ b/kolla/docker/tacker/tacker-server/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}tacker-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block tacker_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_tacker_extend_start +RUN chmod 644 /usr/local/bin/kolla_tacker_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block tacker_server_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER tacker diff --git a/kolla/docker/tacker/tacker-server/extend_start.sh b/kolla/docker/tacker/tacker-server/extend_start.sh new file mode 100644 index 000000000..311d21f71 --- /dev/null +++ b/kolla/docker/tacker/tacker-server/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + tacker-db-manage --config-file /etc/tacker/tacker.conf upgrade head + exit 0 +fi diff --git a/kolla/docker/tgtd/Dockerfile.j2 b/kolla/docker/tgtd/Dockerfile.j2 new file mode 100644 index 000000000..b8cbbaaf5 --- /dev/null +++ b/kolla/docker/tgtd/Dockerfile.j2 @@ -0,0 +1,26 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block tgtd_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} + +RUN echo 'Not available for {{ base_distro }}' \ + && /bin/false + +{% elif base_package_type == 'deb' %} + {% set tgtd_packages = ['tgt'] %} + +{{ macros.install_packages(tgtd_packages | customizable("packages")) }} +RUN sed -i '1 i include /var/lib/cinder/volumes/*' /etc/tgt/targets.conf + +{% endif %} + +{{ macros.kolla_patch_sources() }} + +{% block tgtd_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/trove/trove-api/Dockerfile.j2 b/kolla/docker/trove/trove-api/Dockerfile.j2 new file mode 100644 index 000000000..8d2885b86 --- /dev/null +++ b/kolla/docker/trove/trove-api/Dockerfile.j2 @@ -0,0 +1,16 @@ +FROM {{ namespace }}/{{ image_prefix }}trove-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block trove_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_trove_extend_start +RUN chmod 644 /usr/local/bin/kolla_trove_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block trove_api_footer %}{% endblock %} +{% block footer %}{% endblock %} diff --git a/kolla/docker/trove/trove-api/extend_start.sh b/kolla/docker/trove/trove-api/extend_start.sh new file mode 100644 index 000000000..76839e2d4 --- /dev/null +++ b/kolla/docker/trove/trove-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + trove-manage db_sync + exit 0 +fi diff --git a/kolla/docker/trove/trove-base/Dockerfile.j2 b/kolla/docker/trove/trove-base/Dockerfile.j2 new file mode 100644 index 000000000..a675b2b72 --- /dev/null +++ b/kolla/docker/trove/trove-base/Dockerfile.j2 @@ -0,0 +1,30 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block trove_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='trove') }} + +ADD trove-base-archive /trove-base-source + +{% set trove_base_pip_packages = [ + '/trove' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s trove-base-source/* trove \ + && {{ macros.install_pip(trove_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/trove \ + && cp -r /trove/etc/trove/* /etc/trove/ \ + && cp /var/lib/kolla/venv/etc/pycadf/trove_api_audit_map.conf /etc/trove/ \ + && touch /usr/local/bin/kolla_trove_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_trove_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block trove_base_footer %}{% endblock %} diff --git a/kolla/docker/trove/trove-base/extend_start.sh b/kolla/docker/trove/trove-base/extend_start.sh new file mode 100644 index 000000000..581a83d7b --- /dev/null +++ b/kolla/docker/trove/trove-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/trove" ]]; then + mkdir -p /var/log/kolla/trove +fi +if [[ $(stat -c %a /var/log/kolla/trove) != "755" ]]; then + chmod 755 /var/log/kolla/trove +fi + +. /usr/local/bin/kolla_trove_extend_start diff --git a/kolla/docker/trove/trove-conductor/Dockerfile.j2 b/kolla/docker/trove/trove-conductor/Dockerfile.j2 new file mode 100644 index 000000000..4a038c7f9 --- /dev/null +++ b/kolla/docker/trove/trove-conductor/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}trove-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block trove_conductor_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block trove_conductor_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER trove diff --git a/kolla/docker/trove/trove-guestagent/Dockerfile.j2 b/kolla/docker/trove/trove-guestagent/Dockerfile.j2 new file mode 100644 index 000000000..178260cae --- /dev/null +++ b/kolla/docker/trove/trove-guestagent/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}trove-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block trove_guestagent_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block trove_guestagent_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER trove diff --git a/kolla/docker/trove/trove-taskmanager/Dockerfile.j2 b/kolla/docker/trove/trove-taskmanager/Dockerfile.j2 new file mode 100644 index 000000000..cef0a0ce9 --- /dev/null +++ b/kolla/docker/trove/trove-taskmanager/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}trove-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block trove_taskmanager_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block trove_taskmanager_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER trove diff --git a/kolla/docker/valkey/valkey-base/Dockerfile.j2 b/kolla/docker/valkey/valkey-base/Dockerfile.j2 new file mode 100644 index 000000000..bc17c0cbb --- /dev/null +++ b/kolla/docker/valkey/valkey-base/Dockerfile.j2 @@ -0,0 +1,17 @@ +FROM {{ namespace }}/{{ image_prefix }}base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block valkey_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='valkey', homedir='/run/valkey') }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block valkey_base_footer %}{% endblock %} diff --git a/kolla/docker/valkey/valkey-base/extend_start.sh b/kolla/docker/valkey/valkey-base/extend_start.sh new file mode 100644 index 000000000..3a3a321d4 --- /dev/null +++ b/kolla/docker/valkey/valkey-base/extend_start.sh @@ -0,0 +1,9 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/valkey" ]]; then + mkdir -p /var/log/kolla/valkey +fi + +if [[ $(stat -c %a /var/log/kolla/valkey) != "755" ]]; then + chmod 755 /var/log/kolla/valkey +fi diff --git a/kolla/docker/valkey/valkey-sentinel/Dockerfile.j2 b/kolla/docker/valkey/valkey-sentinel/Dockerfile.j2 new file mode 100644 index 000000000..94828a38f --- /dev/null +++ b/kolla/docker/valkey/valkey-sentinel/Dockerfile.j2 @@ -0,0 +1,26 @@ +FROM {{ namespace }}/{{ image_prefix }}valkey-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block valkey_sentinel_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} +{{ macros.enable_extra_repos(['epel']) }} + {% set valkey_sentinel_packages = ['valkey'] %} +{% elif base_package_type == 'deb' %} + {% set valkey_sentinel_packages = ['valkey-sentinel'] %} +{% endif %} +{{ macros.install_packages(valkey_sentinel_packages | customizable("packages")) }} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start +RUN chmod 644 /usr/local/bin/kolla_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block valkey_sentinel_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER valkey diff --git a/kolla/docker/valkey/valkey-sentinel/extend_start.sh b/kolla/docker/valkey/valkey-sentinel/extend_start.sh new file mode 100644 index 000000000..e6af42ef6 --- /dev/null +++ b/kolla/docker/valkey/valkey-sentinel/extend_start.sh @@ -0,0 +1,32 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/valkey" ]]; then + mkdir -p /var/log/kolla/valkey +fi + +if [[ $(stat -c %a /var/log/kolla/valkey) != "755" ]]; then + chmod 755 /var/log/kolla/valkey +fi + +# The CONFIG REWRITE command rewrites the valkey.conf +# file the server was started with, applying the minimal +# changes needed to make it reflect the configuration +# currently used by the server, which may be different +# compared to the original one because of the use of +# the CONFIG SET command. +# +# https://valkey.io/commands/config-rewrite/ +# +# Because of above behaviour it's needed to +# hack kolla's CMD. +# +# Without this hack +# /usr/local/bin/kolla_set_configs --check +# is always reporting changed. +# +# Therefore valkey-sentinel is always restarted +# even if configuration is not changed from +# kolla-ansible side. +if [ ! -z "${VALKEY_CONF}" ] && [ ! -z ${VALKEY_GEN_CONF} ]; then + cp ${VALKEY_CONF} ${VALKEY_GEN_CONF} +fi diff --git a/kolla/docker/valkey/valkey-server/Dockerfile.j2 b/kolla/docker/valkey/valkey-server/Dockerfile.j2 new file mode 100644 index 000000000..be157d89e --- /dev/null +++ b/kolla/docker/valkey/valkey-server/Dockerfile.j2 @@ -0,0 +1,23 @@ +FROM {{ namespace }}/{{ image_prefix }}valkey-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block valkey_server_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{% if base_package_type == 'rpm' %} +{{ macros.enable_extra_repos(['epel']) }} +{% endif %} + +{% set valkey_server_packages = ['valkey'] %} + +{{ macros.install_packages(valkey_server_packages | customizable("packages")) }} + +{{ macros.kolla_patch_sources() }} + +{% block valkey_server_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER valkey diff --git a/kolla/docker/watcher/watcher-api/Dockerfile.j2 b/kolla/docker/watcher/watcher-api/Dockerfile.j2 new file mode 100644 index 000000000..f31b53ecf --- /dev/null +++ b/kolla/docker/watcher/watcher-api/Dockerfile.j2 @@ -0,0 +1,18 @@ +FROM {{ namespace }}/{{ image_prefix }}watcher-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block watcher_api_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +COPY extend_start.sh /usr/local/bin/kolla_watcher_extend_start +RUN chmod 644 /usr/local/bin/kolla_watcher_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block watcher_api_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER watcher diff --git a/kolla/docker/watcher/watcher-api/extend_start.sh b/kolla/docker/watcher/watcher-api/extend_start.sh new file mode 100644 index 000000000..629ea6355 --- /dev/null +++ b/kolla/docker/watcher/watcher-api/extend_start.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# Bootstrap and exit if KOLLA_BOOTSTRAP variable is set. This catches all cases +# of the KOLLA_BOOTSTRAP variable being set, including empty. +if [[ "${!KOLLA_BOOTSTRAP[@]}" ]]; then + watcher-db-manage --config-file /etc/watcher/watcher.conf upgrade + exit 0 +fi diff --git a/kolla/docker/watcher/watcher-applier/Dockerfile.j2 b/kolla/docker/watcher/watcher-applier/Dockerfile.j2 new file mode 100644 index 000000000..db28d81d9 --- /dev/null +++ b/kolla/docker/watcher/watcher-applier/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}watcher-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block watcher_applier_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block watcher_applier_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER watcher diff --git a/kolla/docker/watcher/watcher-base/Dockerfile.j2 b/kolla/docker/watcher/watcher-base/Dockerfile.j2 new file mode 100644 index 000000000..8de6ceb9d --- /dev/null +++ b/kolla/docker/watcher/watcher-base/Dockerfile.j2 @@ -0,0 +1,29 @@ +FROM {{ namespace }}/{{ image_prefix }}openstack-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block watcher_base_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.configure_user(name='watcher') }} + +ADD watcher-base-archive /watcher-base-source + +{% set watcher_base_pip_packages = [ + '/watcher' +] %} + +COPY extend_start.sh /usr/local/bin/kolla_extend_start + +RUN ln -s watcher-base-source/* watcher \ + && {{ macros.install_pip(watcher_base_pip_packages | customizable("pip_packages")) }} \ + && mkdir -p /etc/watcher \ + && cp -r /watcher/etc/watcher/* /etc/watcher/ \ + && touch /usr/local/bin/kolla_watcher_extend_start \ + && chmod 644 /usr/local/bin/kolla_extend_start /usr/local/bin/kolla_watcher_extend_start + +{{ macros.kolla_patch_sources() }} + +{% block watcher_base_footer %}{% endblock %} diff --git a/kolla/docker/watcher/watcher-base/extend_start.sh b/kolla/docker/watcher/watcher-base/extend_start.sh new file mode 100644 index 000000000..9e27a9cf0 --- /dev/null +++ b/kolla/docker/watcher/watcher-base/extend_start.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +if [[ ! -d "/var/log/kolla/watcher" ]]; then + mkdir -p /var/log/kolla/watcher +fi +if [[ $(stat -c %a /var/log/kolla/watcher) != "755" ]]; then + chmod 755 /var/log/kolla/watcher +fi + +. /usr/local/bin/kolla_watcher_extend_start diff --git a/kolla/docker/watcher/watcher-engine/Dockerfile.j2 b/kolla/docker/watcher/watcher-engine/Dockerfile.j2 new file mode 100644 index 000000000..2518a92b6 --- /dev/null +++ b/kolla/docker/watcher/watcher-engine/Dockerfile.j2 @@ -0,0 +1,15 @@ +FROM {{ namespace }}/{{ image_prefix }}watcher-base:{{ tag }} +{% block labels %} +LABEL maintainer="{{ maintainer }}" name="{{ image_name }}" +{% endblock %} + +{% block watcher_engine_header %}{% endblock %} + +{% import "macros.j2" as macros with context %} + +{{ macros.kolla_patch_sources() }} + +{% block watcher_engine_footer %}{% endblock %} +{% block footer %}{% endblock %} + +USER watcher diff --git a/kolla/image/kolla_worker.py b/kolla/image/kolla_worker.py index 1c704d1cf..1dc37e2a6 100644 --- a/kolla/image/kolla_worker.py +++ b/kolla/image/kolla_worker.py @@ -40,6 +40,8 @@ from oslo_config import cfg PROJECT_ROOT = os.path.abspath(os.path.join( os.path.dirname(os.path.realpath(__file__)), '../..')) +KOLLA_PACKAGE_DIR = os.path.abspath(os.path.join( + os.path.dirname(os.path.realpath(__file__)), '..')) class Image(object): @@ -213,6 +215,7 @@ class KollaWorker(object): def _get_images_dir(self): possible_paths = ( + KOLLA_PACKAGE_DIR, PROJECT_ROOT, os.path.join(sys.prefix, 'share/kolla'), os.path.join(sys.prefix, 'local/share/kolla'), |
