diff --git a/.gitmodules b/.gitmodules
index 83d6fce..982d68e 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -13,3 +13,27 @@
[submodule "autoconf"]
path = autoconf
url = https://src.opensuse.org/SLFO-pool/autoconf.git
+[submodule "python-pydantic"]
+ path = python-pydantic
+ url = https://src.opensuse.org/SLFO-pool/python-pydantic
+[submodule "python-pydantic-core"]
+ path = python-pydantic-core
+ url = https://src.opensuse.org/SLFO-pool/python-pydantic-core
+[submodule "python-inline-snapshot"]
+ path = python-inline-snapshot
+ url = https://src.opensuse.org/SLFO-pool/python-inline-snapshot
+[submodule "python-executing"]
+ path = python-executing
+ url = https://src.opensuse.org/SLFO-pool/python-executing
+[submodule "python-typing-inspection"]
+ path = python-typing-inspection
+ url = https://src.opensuse.org/SLFO-pool/python-typing-inspection
+[submodule "python-annotated-types"]
+ path = python-annotated-types
+ url = https://src.opensuse.org/SLFO-pool/python-annotated-types
+[submodule "python-typing_extensions"]
+ path = python-typing_extensions
+ url = https://src.opensuse.org/SLFO-pool/python-typing_extensions
+[submodule "python-flit-core"]
+ path = python-flit-core
+ url = https://src.opensuse.org/SLFO-pool/python-flit-core
diff --git a/_config b/_config
index 711b336..963942c 100644
--- a/_config
+++ b/_config
@@ -50,6 +50,15 @@ Macros:
BuildFlags: excludebuild:autoconf:el
BuildFlags: excludebuild:autoconf:testsuite
+# Missing deps for python packages related to suse-edge-components-versions
+BuildFlags: excludebuild:python-pydantic:test
+BuildFlags: excludebuild:python-pydantic-core:test
+BuildFlags: excludebuild:python-inline-snapshot:test
+BuildFlags: excludebuild:python-executing:test
+BuildFlags: excludebuild:python-annotated-types:test
+BuildFlags: excludebuild:python-typing-inspection:test
+BuildFlags: excludebuild:python-typing_extensions:test
+
# Only build manifest embedding images here
%if "%_repository" == "test_manifest_images"
BuildFlags: onlybuild:edge-image-builder-image
diff --git a/python-annotated-types b/python-annotated-types
new file mode 160000
index 0000000..ffc9e3f
--- /dev/null
+++ b/python-annotated-types
@@ -0,0 +1 @@
+Subproject commit ffc9e3fb44e2fcc3fb2c22a521f9df0c6a6417c4ae9b2a8a9a02bd3e5d555e3c
diff --git a/python-executing b/python-executing
new file mode 160000
index 0000000..ac466db
--- /dev/null
+++ b/python-executing
@@ -0,0 +1 @@
+Subproject commit ac466db0b5734fd479794b9fdc61da736b008b2ae4c73d533b785f9b67d7f541
diff --git a/python-flit-core b/python-flit-core
new file mode 160000
index 0000000..4362b05
--- /dev/null
+++ b/python-flit-core
@@ -0,0 +1 @@
+Subproject commit 4362b05ea3d7513b64a6e64a7b923fbb0bc6b676ba8cd3c528d141456ba08635
diff --git a/python-inline-snapshot b/python-inline-snapshot
new file mode 160000
index 0000000..1e91744
--- /dev/null
+++ b/python-inline-snapshot
@@ -0,0 +1 @@
+Subproject commit 1e917444d7edcfcc9862db03abfac4007783b2e29ac33bbe84e2dc1dd9f9c167
diff --git a/python-pydantic b/python-pydantic
new file mode 160000
index 0000000..f19a5a7
--- /dev/null
+++ b/python-pydantic
@@ -0,0 +1 @@
+Subproject commit f19a5a780ff647ce0cd317ddbe6d60fb216b50ade0e294b24be5798d5bb7c55c
diff --git a/python-pydantic-core b/python-pydantic-core
new file mode 160000
index 0000000..00355d0
--- /dev/null
+++ b/python-pydantic-core
@@ -0,0 +1 @@
+Subproject commit 00355d08255833b897253c1cee7752bb9a3dd0dce01359f71e040a5270c60904
diff --git a/python-rich/_service b/python-rich/_service
new file mode 100644
index 0000000..58c8622
--- /dev/null
+++ b/python-rich/_service
@@ -0,0 +1,3 @@
+
+
+
diff --git a/python-rich/pygments.patch b/python-rich/pygments.patch
new file mode 100644
index 0000000..5547d65
--- /dev/null
+++ b/python-rich/pygments.patch
@@ -0,0 +1,45 @@
+From 08be21dadfd2ce9e96e41e366ab38bd8d7cd0e39 Mon Sep 17 00:00:00 2001
+From: Dan Lazin
+Date: Tue, 7 Jan 2025 16:04:56 -0500
+Subject: [PATCH] Fix test that changed with Pygments 2.19.
+
+---
+ tests/test_markdown.py | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: rich-13.9.4/tests/test_markdown.py
+===================================================================
+--- rich-13.9.4.orig/tests/test_markdown.py
++++ rich-13.9.4/tests/test_markdown.py
+@@ -110,7 +110,7 @@ def test_inline_code():
+ inline_code_theme="emacs",
+ )
+ result = render(markdown)
+- expected = "inline \x1b[1;38;2;170;34;255;48;2;248;248;248mimport\x1b[0m\x1b[38;2;0;0;0;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m code \n"
++ expected = "inline \x1b[1;38;2;170;34;255;48;2;248;248;248mimport\x1b[0m\x1b[38;2;187;187;187;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m code \n"
+ print(result)
+ print(repr(result))
+ assert result == expected
+Index: rich-13.9.4/tests/test_syntax.py
+===================================================================
+--- rich-13.9.4.orig/tests/test_syntax.py
++++ rich-13.9.4/tests/test_syntax.py
+@@ -53,7 +53,7 @@ def test_blank_lines():
+ print(repr(result))
+ assert (
+ result
+- == "\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m1 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m2 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m3 \x1b[0m\x1b[1;38;2;0;128;0;48;2;248;248;248mimport\x1b[0m\x1b[38;2;0;0;0;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m4 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m5 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n"
++ == "\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m1 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m2 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m3 \x1b[0m\x1b[1;38;2;0;128;0;48;2;248;248;248mimport\x1b[0m\x1b[38;2;187;187;187;48;2;248;248;248m \x1b[0m\x1b[1;38;2;0;0;255;48;2;248;248;248mthis\x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m4 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n\x1b[1;38;2;24;24;24;48;2;248;248;248m \x1b[0m\x1b[38;2;173;173;173;48;2;248;248;248m5 \x1b[0m\x1b[48;2;248;248;248m \x1b[0m\n"
+ )
+
+
+@@ -119,7 +119,7 @@ def test_python_render_simple_indent_gui
+ )
+ rendered_syntax = render(syntax)
+ print(repr(rendered_syntax))
+- expected = '\x1b[34mdef\x1b[0m \x1b[32mloop_first_last\x1b[0m(values: Iterable[T]) -> Iterable[Tuple[\x1b[36mb\x1b[0m\n\x1b[2;37m│ \x1b[0m\x1b[33m"""Iterate and generate a tuple with a flag for first an\x1b[0m\n\x1b[2m│ \x1b[0miter_values = \x1b[36miter\x1b[0m(values)\n\x1b[2m│ \x1b[0m\x1b[34mtry\x1b[0m:\n\x1b[2m│ │ \x1b[0mprevious_value = \x1b[36mnext\x1b[0m(iter_values)\n\x1b[2m│ \x1b[0m\x1b[34mexcept\x1b[0m \x1b[36mStopIteration\x1b[0m:\n\x1b[2m│ │ \x1b[0m\x1b[34mreturn\x1b[0m\n\x1b[2m│ \x1b[0mfirst = \x1b[34mTrue\x1b[0m\n\x1b[2m│ \x1b[0m\x1b[34mfor\x1b[0m value \x1b[35min\x1b[0m iter_values:\n\x1b[2m│ │ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mFalse\x1b[0m, previous_value\n\x1b[2m│ │ \x1b[0mfirst = \x1b[34mFalse\x1b[0m\n\x1b[2m│ │ \x1b[0mprevious_value = value\n\x1b[2m│ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mTrue\x1b[0m, previous_value\n'
++ expected = '\x1b[34mdef\x1b[0m\x1b[37m \x1b[0m\x1b[32mloop_first_last\x1b[0m(values: Iterable[T]) -> Iterable[Tuple[\x1b[36mb\x1b[0m\n\x1b[2;37m│ \x1b[0m\x1b[33m"""Iterate and generate a tuple with a flag for first an\x1b[0m\n\x1b[2m│ \x1b[0miter_values = \x1b[36miter\x1b[0m(values)\n\x1b[2m│ \x1b[0m\x1b[34mtry\x1b[0m:\n\x1b[2m│ │ \x1b[0mprevious_value = \x1b[36mnext\x1b[0m(iter_values)\n\x1b[2m│ \x1b[0m\x1b[34mexcept\x1b[0m \x1b[36mStopIteration\x1b[0m:\n\x1b[2m│ │ \x1b[0m\x1b[34mreturn\x1b[0m\n\x1b[2m│ \x1b[0mfirst = \x1b[34mTrue\x1b[0m\n\x1b[2m│ \x1b[0m\x1b[34mfor\x1b[0m value \x1b[35min\x1b[0m iter_values:\n\x1b[2m│ │ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mFalse\x1b[0m, previous_value\n\x1b[2m│ │ \x1b[0mfirst = \x1b[34mFalse\x1b[0m\n\x1b[2m│ │ \x1b[0mprevious_value = value\n\x1b[2m│ \x1b[0m\x1b[34myield\x1b[0m first, \x1b[34mTrue\x1b[0m, previous_value\n'
+ assert rendered_syntax == expected
+
+
+
diff --git a/python-rich/python-rich.spec b/python-rich/python-rich.spec
new file mode 100644
index 0000000..f9b2489
--- /dev/null
+++ b/python-rich/python-rich.spec
@@ -0,0 +1,66 @@
+#
+# spec file for package python-rich
+#
+# Copyright (c) 2025 SUSE LLC
+# Copyright (c) 2020-2021, Martin Hauke
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+#
+
+
+%{?sle15_python_module_pythons}
+Name: python-rich
+Version: 14.0.0
+Release: 0
+Summary: A Python library for rich text and beautiful formatting in the terminal
+License: MIT
+URL: https://github.com/Textualize/rich
+#!RemoteAsset: https://github.com/Textualize/rich/archive/refs/tags/v%{version}.tar.gz rich-%{version}.tar.gz
+Source: rich-%{version}.tar.gz
+# PATCH-FIX-UPSTREAM https://github.com/Textualize/rich/pull/3604 Fix test that changed with Pygments 2.19.
+# and https://github.com/Textualize/rich/pull/3608 fix remaining tests with Pygments 2.19 #3604 did not fix
+Patch: pygments.patch
+BuildRequires: %{python_module base >= 3.8}
+BuildRequires: %{python_module markdown-it-py >= 2.2.0}
+BuildRequires: %{python_module pip}
+BuildRequires: %{python_module poetry-core}
+BuildRequires: %{python_module pygments >= 2.13.0}
+BuildRequires: fdupes
+BuildRequires: python-rpm-macros
+Requires: python-markdown-it-py >= 2.2.0
+Requires: python-pygments >= 2.13.0
+Suggests: python-ipywidgets >= 7.5.1
+BuildArch: noarch
+# TODO(edu): Disabled all tests
+%python_subpackages
+
+%description
+Render rich text, tables, progress bars, syntax highlighting,
+markdown and more to the terminal.
+
+%prep
+%autosetup -p1 -n rich-%{version}
+
+%build
+%pyproject_wheel
+
+%install
+%pyproject_install
+%python_expand %fdupes %{buildroot}%{$python_sitelib}
+
+%files %{python_files}
+%license LICENSE
+%doc README.md
+%{python_sitelib}/rich
+%{python_sitelib}/rich-%{version}.dist-info
+
+%changelog
diff --git a/python-suse-edge-components-versions/_service b/python-suse-edge-components-versions/_service
new file mode 100644
index 0000000..90bb42d
--- /dev/null
+++ b/python-suse-edge-components-versions/_service
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/python-suse-edge-components-versions/python-suse-edge-components-versions.spec b/python-suse-edge-components-versions/python-suse-edge-components-versions.spec
new file mode 100644
index 0000000..c98f0d7
--- /dev/null
+++ b/python-suse-edge-components-versions/python-suse-edge-components-versions.spec
@@ -0,0 +1,98 @@
+#
+# spec file for package python-suse-edge-components-versions
+#
+# Copyright (c) 2025 SUSE LLC
+#
+# All modifications and additions to the file contributed by third parties
+# remain the property of their copyright owners, unless otherwise agreed
+# upon. The license for this file, and modifications and additions to the
+# file, is the same license as for the pristine package itself (unless the
+# license for the pristine package is not an Open Source License, in which
+# case the license is the MIT License). An "Open Source License" is a
+# license that conforms to the Open Source Definition (Version 1.9)
+# published by the Open Source Initiative.
+# Please submit bugfixes or comments via https://bugs.opensuse.org/
+
+%global mod_name suse-edge-components-versions
+%global pythons %{primary_python}
+%if 0%{?suse_version} == 1500
+%sle15_python_module_pythons
+%endif
+
+Name: python-suse-edge-components-versions
+Version: 0.1.0
+Release: 0%{?dist}
+Summary: A tool to gather and display component versions for SUSE Edge products.
+License: Apache-2.0
+URL: https://github.com/suse-edge/support-tools/tree/main/components-versions
+#!RemoteAsset: https://github.com/suse-edge/support-tools/archive/refs/tags/components-versions-v%{version}.tar.gz
+Source: components-versions-v0.1.0.tar.gz
+BuildArch: noarch
+
+BuildRequires: python-rpm-macros
+BuildRequires: %{python_module pip}
+BuildRequires: %{python_module setuptools}
+BuildRequires: %{python_module setuptools_scm}
+BuildRequires: %{python_module wheel}
+
+# Requires:
+Requires: %{python_module kubernetes}
+Requires: %{python_module pyhelm3}
+Requires: %{python_module tabulate}
+Requires: %{python_module pydantic >= 2.0}
+Requires: helm
+
+# This macro automatically creates subpackages for each Python version
+# (e.g., python311-suse-edge-components-versions, python312-suse-edge-components-versions).
+%python_subpackages
+
+%description
+This tool provides functionality to gather and display component versions
+for various SUSE Edge products. It helps in understanding the exact versions
+of software components used in different product releases and ensures
+consistency across deployments.
+
+%prep
+# Unpack the source tarball.
+# The tarball extracts into 'support-tools-components-versions-v%{version}'.
+%setup -q -n support-tools-components-versions-v%{version}
+
+%build
+
+# The actual Python project (containing pyproject.toml and the source code)
+# is nested inside the 'components-versions' directory within the extracted tarball.
+# We need to change into this directory before building.
+cd components-versions
+%pyproject_wheel .
+cd ..
+
+%install
+cd components-versions
+%pyproject_install
+# Rename the main executable from 'components-versions' to 'suse-edge-components-versions'
+mv %{buildroot}%{_bindir}/components-versions %{buildroot}%{_bindir}/suse-edge-components-versions
+%python_clone -a %{buildroot}%{_bindir}/suse-edge-components-versions
+cd ..
+# Move the json files to /usr/share/suse-edge-components-versions instead
+mkdir -p %{buildroot}/usr/share/suse-edge-components-versions/
+mv %{buildroot}%{python_sitelib}/components_versions/data/*.json %{buildroot}/usr/share/suse-edge-components-versions/
+rmdir %{buildroot}%{python_sitelib}/components_versions/data/
+
+%post
+%python_install_alternative suse-edge-components-versions
+
+%postun
+%python_uninstall_alternative suse-edge-components-versions
+
+%files %{python_files}
+%license LICENSE
+%{python_sitelib}/components_versions
+# Include the Python package metadata (e.g., .dist-info or .egg-info).
+# The .dist-info name is based on the 'name' field in pyproject.toml.
+%{python_sitelib}/suse_edge_components_versions-%{version}*.dist-info
+# Include the main executable with its new name.
+%python_alternative %{_bindir}/suse-edge-components-versions
+# Include the json files
+/usr/share/suse-edge-components-versions/
+
+%changelog
\ No newline at end of file
diff --git a/python-typing-inspection b/python-typing-inspection
new file mode 160000
index 0000000..9400618
--- /dev/null
+++ b/python-typing-inspection
@@ -0,0 +1 @@
+Subproject commit 9400618faed93df5c23f0e6f02097b2c605b9e50898bbc414775f8e185b86b44
diff --git a/python-typing_extensions b/python-typing_extensions
new file mode 160000
index 0000000..598c5a8
--- /dev/null
+++ b/python-typing_extensions
@@ -0,0 +1 @@
+Subproject commit 598c5a8313fca8f7f46421f9e8c8203b12dcd33b60544fe1d6fbe6fc0868d8f2
diff --git a/suse-edge-components-versions-image/Dockerfile b/suse-edge-components-versions-image/Dockerfile
new file mode 100644
index 0000000..fadabb0
--- /dev/null
+++ b/suse-edge-components-versions-image/Dockerfile
@@ -0,0 +1,52 @@
+# SPDX-License-Identifier: Apache-2.0
+#!BuildTag: %%IMG_PREFIX%%suse-edge-components-versions:0.1.0
+#!BuildTag: %%IMG_PREFIX%%suse-edge-components-versions:0.1.0-%RELEASE%
+
+ARG SLE_VERSION
+FROM registry.suse.com/bci/bci-micro:$SLE_VERSION AS micro
+
+FROM registry.suse.com/bci/bci-base:$SLE_VERSION AS base
+COPY --from=micro / /installroot/
+RUN sed -i -e 's%^# rpm.install.excludedocs = no.*%rpm.install.excludedocs = yes%g' /etc/zypp/zypp.conf
+RUN zypper --installroot /installroot --non-interactive install --no-recommends python311-suse-edge-components-versions
+
+# https://opensource.suse.com/bci-docs/guides/adding-users/
+ARG USERNAME=suse
+ARG USER_UID=1000
+ARG USER_GID=$USER_UID
+
+# Create the user
+RUN groupadd --gid $USER_GID $USERNAME \
+ && useradd --uid $USER_UID --gid $USER_GID -m $USERNAME
+
+# build actual image
+FROM micro AS final
+
+MAINTAINER SUSE LLC (https://www.suse.com/)
+# Define labels according to https://en.opensuse.org/Building_derived_containers
+LABEL org.opencontainers.image.title="SUSE Edge components-versions Container Image"
+LABEL org.opencontainers.image.description="Gather and display component versions for various SUSE Edge products"
+LABEL org.opencontainers.image.url="https://github.com/suse-edge/support-tools/tree/main/components-versions"
+LABEL org.opencontainers.image.created="%BUILDTIME%"
+LABEL org.opencontainers.image.vendor="SUSE LLC"
+LABEL org.opencontainers.image.version="0.1.0"
+LABEL org.opensuse.reference="%%IMG_REPO%%/%%IMG_PREFIX%%suse-edge-components-versions:0.1.0-%RELEASE%"
+LABEL org.openbuildservice.disturl="%DISTURL%"
+LABEL com.suse.supportlevel="%%SUPPORT_LEVEL%%"
+LABEL com.suse.eula="SUSE Combined EULA February 2024"
+LABEL com.suse.lifecycle-url="https://www.suse.com/lifecycle"
+LABEL com.suse.image-type="application"
+LABEL com.suse.release-stage="released"
+# endlabelprefix
+
+COPY --from=base /installroot /
+
+# https://opensource.suse.com/bci-docs/guides/adding-users/
+COPY --from=base /etc/passwd /etc/passwd
+COPY --from=base /etc/group /etc/group
+COPY --from=base /etc/shadow /etc/shadow
+COPY --from=base /home/$USERNAME /home/$USERNAME
+
+USER ${USERNAME}
+
+ENTRYPOINT ["/usr/bin/suse-edge-components-versions"]
diff --git a/suse-edge-components-versions-image/_service b/suse-edge-components-versions-image/_service
new file mode 100644
index 0000000..2d99fa4
--- /dev/null
+++ b/suse-edge-components-versions-image/_service
@@ -0,0 +1,12 @@
+
+
+
+ Dockerfile
+ IMG_PREFIX=$(rpm --macros=/root/.rpmmacros -E %{?img_prefix})
+ IMG_PREFIX
+ IMG_REPO=$(rpm --macros=/root/.rpmmacros -E %img_repo)
+ IMG_REPO
+ SUPPORT_LEVEL=$(rpm --macros=/root/.rpmmacros -E %support_level)
+ SUPPORT_LEVEL
+
+