diff --git a/doc/source/ovn_versions.csv b/doc/source/ovn_versions.csv index 2c2ff50cd7..f0a8c52102 100644 --- a/doc/source/ovn_versions.csv +++ b/doc/source/ovn_versions.csv @@ -1,5 +1,5 @@ Distro,OVN, ,Source,Release -Rocky Linux,CentOS NFV SIG,25.03 +Rocky Linux,CentOS NFV SIG,25.09 Ubuntu,UCA,25.09 Debian,DEB,25.03 diff --git a/docker/base/Dockerfile.j2 b/docker/base/Dockerfile.j2 index 6c758207af..0503098dff 100644 --- a/docker/base/Dockerfile.j2 +++ b/docker/base/Dockerfile.j2 @@ -40,7 +40,7 @@ ENV PS1="$(tput bold)($(printenv KOLLA_SERVICE_NAME))$(tput sgr0)[$(id -un)@$(ho # desire such functionality. I think we will :) ENV KOLLA_RPM_OVS_VERSION=3.5 \ - KOLLA_RPM_OVN_VERSION=25.03 + KOLLA_RPM_OVN_VERSION=25.09 RUN cat /tmp/kolla_bashrc >> /etc/bashrc \ && sed -i 's|^\(override_install_langs=.*\)|# \1|' /etc/dnf/dnf.conf diff --git a/docker/base/install_projects.sh b/docker/base/install_projects.sh index a9a7948d04..c3f7182b55 100644 --- a/docker/base/install_projects.sh +++ b/docker/base/install_projects.sh @@ -5,7 +5,9 @@ # The projects are mounted there when dev mode is enabled for them # in kolla-ansible -if [ -d "/dev-mode" ]; then +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 diff --git a/docker/haproxy/haproxy-ssh/extend_start.sh b/docker/haproxy/haproxy-ssh/extend_start.sh index 421e4bd6ff..4b2239100c 100644 --- a/docker/haproxy/haproxy-ssh/extend_start.sh +++ b/docker/haproxy/haproxy-ssh/extend_start.sh @@ -1,6 +1,6 @@ #!/bin/bash -SSH_HOST_KEY_TYPES=( "rsa" "dsa" "ecdsa" "ed25519" ) +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 diff --git a/docker/neutron/neutron-ovn-vpn-agent/Dockerfile.j2 b/docker/neutron/neutron-ovn-vpn-agent/Dockerfile.j2 new file mode 100644 index 0000000000..e4166c58db --- /dev/null +++ b/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 }}" build-date="{{ build_date }}" +{% 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/docker/prometheus/prometheus-valkey-exporter/Dockerfile.j2 b/docker/prometheus/prometheus-valkey-exporter/Dockerfile.j2 new file mode 100644 index 0000000000..7f38bae193 --- /dev/null +++ b/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 }}" build-date="{{ build_date }}" +{% 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/common/sources.py b/kolla/common/sources.py index 82a90a77eb..24a0d7851a 100644 --- a/kolla/common/sources.py +++ b/kolla/common/sources.py @@ -395,6 +395,17 @@ 'releases/download/v${version}/' 'prometheus' '-${version}.linux-${debian_arch}.tar.gz')}, + 'prometheus-valkey-exporter': { + 'version': '1.82.0', + 'type': 'url', + 'sha256': { + 'amd64': '2d98dd0888f46e206bf3ad1b7c1784934a3a39cd8774cf47615f4c15594547cd', # noqa: E501 + 'arm64': '13aaa6acbb145848cb97ed3bab22747e094b3f0ed22df83c8ace593e3c527c95'}, # noqa: E501 + 'location': ('https://github.com/' + 'oliver006/redis_exporter/' + 'releases/download/v${version}/' + 'redis_exporter' + '-v${version}.linux-${debian_arch}.tar.gz')}, 'skyline-apiserver': { 'type': 'url', 'location': ('$tarballs_base/openstack/skyline-apiserver/' diff --git a/kolla/image/kolla_worker.py b/kolla/image/kolla_worker.py index 723914f5a5..680595f866 100644 --- a/kolla/image/kolla_worker.py +++ b/kolla/image/kolla_worker.py @@ -11,6 +11,8 @@ # limitations under the License. import datetime +import git +import importlib.metadata import json import os import queue @@ -42,7 +44,7 @@ class Image(object): def __init__(self, name, canonical_name, path, parent_name='', status=Status.UNPROCESSED, parent=None, - source=None, logger=None, engine_client=None): + source=None, logger=None, engine_client=None, labels=None): self.name = name self.canonical_name = canonical_name self.path = path @@ -57,11 +59,12 @@ def __init__(self, name, canonical_name, path, parent_name='', self.plugins = [] self.additions = [] self.engine_client = engine_client + self.labels = labels or {} def copy(self): c = Image(self.name, self.canonical_name, self.path, logger=self.logger, parent_name=self.parent_name, - status=self.status, parent=self.parent) + status=self.status, parent=self.parent, labels=self.labels) if self.source: c.source = self.source.copy() if self.children: @@ -143,6 +146,9 @@ def __init__(self, conf): self.image_statuses_allowed_to_fail = dict() self.maintainer = conf.maintainer self.patches_path = conf.patches_path + self.scm_labels = self._get_scm_labels() + self.build_created = (datetime.datetime.now(datetime.timezone.utc) + .strftime('%Y-%m-%dT%H:%M:%SZ')) try: self.engine_client = engine.getEngineClient(self.conf) @@ -157,6 +163,53 @@ def __init__(self, conf): LOG.info("Exception caught: {0}".format(e)) sys.exit(1) + def _get_scm_labels(self): + labels = {} + + # Method 1: Install via PIP (direct_url.json) + try: + dist = importlib.metadata.distribution('kolla') + direct_url_file = [ + p for p in dist.files if p.name == 'direct_url.json' + ] + + if direct_url_file: + content = dist.read_text('direct_url.json') + if content: + data = json.loads(content) + if 'url' in data: + labels['org.opencontainers.image.source'] = data['url'] + if 'vcs_info' in data and 'commit_id' in data['vcs_info']: + labels['org.opencontainers.image.revision'] = ( + data['vcs_info']['commit_id']) + except Exception as e: + LOG.debug(f"Could not retrieve PIP direct_url info: {e}") + + # Method 2: Fallback to Git (if PIP info is local or missing) + source = labels.get('org.opencontainers.image.source', '') + if not labels.get('org.opencontainers.image.revision') or \ + source.startswith('file:'): + try: + repo = git.Repo(PROJECT_ROOT, search_parent_directories=True) + + labels['org.opencontainers.image.revision'] = ( + repo.head.object.hexsha) + + if source.startswith('file:') or not source: + labels['org.opencontainers.image.source'] = ( + 'https://opendev.org/openstack/kolla') + + LOG.debug("Detected SCM info via Git fallback: %s", labels) + except Exception as e: + LOG.debug("Git fallback failed: %s", e) + + source_url = labels.get('org.opencontainers.image.source', '') + if source_url.startswith('file:'): + labels['org.opencontainers.image.source'] = ( + 'https://opendev.org/openstack/kolla') + + return labels + def _get_images_dir(self): possible_paths = ( PROJECT_ROOT, @@ -694,10 +747,25 @@ def process_source_installation(image, section): else: parent_name = '' del match + + oci_labels = self.scm_labels.copy() + oci_labels.update({ + "org.opencontainers.image.title": image_name, + "org.opencontainers.image.description": ( + "OpenStack Kolla {} image".format(image_name)), + "org.opencontainers.image.version": self.tag, + "org.opencontainers.image.created": self.build_created, + "org.opencontainers.image.authors": self.maintainer, + "org.opencontainers.image.url": ( + "https://opendev.org/openstack/kolla"), + "org.opencontainers.image.licenses": "Apache-2.0" + }) + image = Image(image_name, canonical_name, path, parent_name=parent_name, logger=utils.make_a_logger(self.conf, image_name), - engine_client=self.engine_client) + engine_client=self.engine_client, + labels=oci_labels) # NOTE(jeffrey4l): register the opts if the section didn't # register in the kolla/common/config.py file diff --git a/kolla/image/tasks.py b/kolla/image/tasks.py index 39d7593907..6bee905f7c 100644 --- a/kolla/image/tasks.py +++ b/kolla/image/tasks.py @@ -407,6 +407,9 @@ def reset_userinfo(tarinfo): buildargs = self.update_buildargs() kwargs = {} + if hasattr(image, 'labels') and image.labels: + kwargs['labels'] = image.labels + if self.conf.engine == engine.Engine.PODMAN.value: # TODO(kevko): dockerfile path is a workaround, # should be removed as soon as it will be fixed in podman-py diff --git a/kolla/template/repos.yaml b/kolla/template/repos.yaml index 2a40375e0e..d559f6f092 100644 --- a/kolla/template/repos.yaml +++ b/kolla/template/repos.yaml @@ -112,7 +112,7 @@ ubuntu-aarch64: rpm: ceph: gpgkey: "https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage" - metalink: "https://mirrors.centos.org/metalink?repo=centos-storage-sig-ceph-squid-9-stream&arch=$basearch" + metalink: "https://mirrors.centos.org/metalink?repo=centos-storage-sig-ceph-squid-10-stream&arch=$basearch" name: "centos-ceph-squid" crb: distro: True diff --git a/kolla/tests/test_methods.py b/kolla/tests/test_methods.py index f304623625..e1dc810d1d 100644 --- a/kolla/tests/test_methods.py +++ b/kolla/tests/test_methods.py @@ -58,7 +58,7 @@ def test_enable_repos_centos_metalink(self): expectCmd += ">>/etc/yum.repos.d/ceph.repo && " expectCmd += "echo 'gpgkey=https://www.centos.org/keys/RPM-GPG-KEY-CentOS-SIG-Storage' " # noqa: E501 expectCmd += ">>/etc/yum.repos.d/ceph.repo && " - expectCmd += "echo 'metalink=https://mirrors.centos.org/metalink?repo=centos-storage-sig-ceph-squid-9-stream&arch=$basearch' " # noqa: E501 + expectCmd += "echo 'metalink=https://mirrors.centos.org/metalink?repo=centos-storage-sig-ceph-squid-10-stream&arch=$basearch' " # noqa: E501 expectCmd += ">>/etc/yum.repos.d/ceph.repo" self.assertEqual(expectCmd, result) diff --git a/releasenotes/notes/add-oci-standard-labels-f68cc6eb3a4db7c7.yaml b/releasenotes/notes/add-oci-standard-labels-f68cc6eb3a4db7c7.yaml new file mode 100644 index 0000000000..e9ba30dfbe --- /dev/null +++ b/releasenotes/notes/add-oci-standard-labels-f68cc6eb3a4db7c7.yaml @@ -0,0 +1,10 @@ +--- +features: + - | + Implemented support for Open Container Initiative (OCI) standard labels + in generated container images. + + Kolla images are now tagged with standard metadata to improve traceability + and observability. The build process automatically detects source + information and populates labels such as build creation time, version, + source URL, and commit revision. diff --git a/releasenotes/notes/add-valkey-exporter-e21762a106307538.yaml b/releasenotes/notes/add-valkey-exporter-e21762a106307538.yaml new file mode 100644 index 0000000000..78cf5d4f8b --- /dev/null +++ b/releasenotes/notes/add-valkey-exporter-e21762a106307538.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Adds support for Valkey monitoring by introducing a new + ``prometheus-valkey-exporter`` container image. diff --git a/releasenotes/notes/releasenotes/notes/neutron-ovn-vpn-agent-kolla-image-979df04014ed9440.yaml b/releasenotes/notes/releasenotes/notes/neutron-ovn-vpn-agent-kolla-image-979df04014ed9440.yaml new file mode 100644 index 0000000000..fa67df9754 --- /dev/null +++ b/releasenotes/notes/releasenotes/notes/neutron-ovn-vpn-agent-kolla-image-979df04014ed9440.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Added the neutron ovn vpn agent container image (``neutron-ovn-vpn-agent``) diff --git a/releasenotes/notes/rocky-ovn-25.09-345468aec8cc8073.yaml b/releasenotes/notes/rocky-ovn-25.09-345468aec8cc8073.yaml new file mode 100644 index 0000000000..5af6125309 --- /dev/null +++ b/releasenotes/notes/rocky-ovn-25.09-345468aec8cc8073.yaml @@ -0,0 +1,4 @@ +--- +features: + - | + Updates OVN to version 25.09 on Rocky Linux 10. diff --git a/zuul.d/ubuntu.yaml b/zuul.d/ubuntu.yaml index c40e0b936f..8247892877 100644 --- a/zuul.d/ubuntu.yaml +++ b/zuul.d/ubuntu.yaml @@ -29,6 +29,20 @@ - name: kolla_quay_io_api secret: kolla_quay_io_api_jan_2026 +- job: + name: kolla-publish-ubuntu-noble-arm64-quay + parent: kolla-build-ubuntu-noble-arm64 + post-run: tests/playbooks/publish.yml + vars: + publisher: true + kolla_registry: quay.io + kolla_namespace: openstack.kolla + secrets: + - name: kolla_quay_io_creds + secret: kolla_quay_io_creds_jan_2026 + - name: kolla_quay_io_api + secret: kolla_quay_io_api_jan_2026 + - job: name: kolla-build-ubuntu-noble-no-infra-wheels parent: kolla-build-no-infra-wheels-base @@ -55,3 +69,4 @@ periodic: jobs: - kolla-publish-ubuntu-noble-quay + - kolla-publish-ubuntu-noble-arm64-quay