Skip to content

Commit

Permalink
Merge pull request #2674 from OSInside/containers_sections_obs_integr…
Browse files Browse the repository at this point in the history
…ation

Added containers integration with OBS
  • Loading branch information
schaefi authored Nov 13, 2024
2 parents 463f044 + 24f32d1 commit cade4b4
Show file tree
Hide file tree
Showing 5 changed files with 274 additions and 64 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>

<image schemaversion="7.5" name="kiwi-test-image-disk-containers">
<description type="system">
<author>Marcus Schäfer</author>
<contact>[email protected]</contact>
<specification>Disk test build with container import</specification>
</description>
<preferences>
<version>1.42.1</version>
<packagemanager>zypper</packagemanager>
<locale>en_US</locale>
<keytable>us</keytable>
<timezone>Europe/Berlin</timezone>
<rpm-excludedocs>true</rpm-excludedocs>
<rpm-check-signatures>false</rpm-check-signatures>
<bootsplash-theme>breeze</bootsplash-theme>
<bootloader-theme>openSUSE</bootloader-theme>
<type image="oem" filesystem="btrfs" kernelcmdline="console=ttyS0" firmware="efi" installiso="true" bootpartition="false" btrfs_root_is_snapshot="true" installboot="install">
<bootloader name="grub2" console="serial" timeout="10"/>
<oemconfig>
<oem-unattended>true</oem-unattended>
<oem-swapsize>1024</oem-swapsize>
<oem-multipath-scan>false</oem-multipath-scan>
</oemconfig>
<systemdisk>
<volume name="home" quota="5G"/>
</systemdisk>
</type>
</preferences>
<containers source="registry.opensuse.org" backend="podman">
<container name="tumbleweed" tag="latest" path="opensuse"/>
</containers>
<users>
<user password="$1$wYJUgpM5$RXMMeASDc035eX.NbYWFl0" home="/root" name="root" groups="root"/>
</users>
<repository type="rpm-md">
<source path="obsrepositories:/"/>
</repository>
<packages type="image">
<package name="patterns-openSUSE-base"/>
<package name="skopeo"/>
<package name="podman"/>
<package name="procps"/>
<package name="systemd"/>
<package name="plymouth-theme-breeze"/>
<package name="plymouth-plugin-script"/>
<package name="grub2-branding-openSUSE"/>
<package name="iputils"/>
<package name="vim"/>
<package name="grub2"/>
<package name="grub2-x86_64-efi" arch="x86_64"/>
<package name="grub2-i386-pc"/>
<package name="lvm2"/>
<package name="plymouth"/>
<package name="fontconfig"/>
<package name="fonts-config"/>
<package name="tar"/>
<package name="parted"/>
<package name="openssh"/>
<package name="iproute2"/>
<package name="less"/>
<package name="bash-completion"/>
<package name="bind-utils"/>
<package name="dhcp-client"/>
<package name="which"/>
<package name="kernel-default"/>
<package name="timezone"/>
<package name="dracut-kiwi-oem-repart"/>
<package name="dracut-kiwi-oem-dump"/>
</packages>
<packages type="bootstrap">
<package name="gawk"/>
<package name="grep"/>
<package name="gzip"/>
<package name="udev"/>
<package name="xz"/>
<package name="shadow"/>
<package name="filesystem"/>
<package name="glibc-locale"/>
<package name="cracklib-dict-full"/>
<package name="ca-certificates"/>
<package name="ca-certificates-mozilla"/>
<package name="openSUSE-release"/>
</packages>
</image>
4 changes: 1 addition & 3 deletions kiwi/system/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,7 @@ def setup_registry_import(self) -> None:
pathlib.Path(f'{self.root_dir}/{defaults.LOCAL_CONTAINERS}').mkdir(
parents=True, exist_ok=True
)
Command.run(
['chroot', self.root_dir] + container.fetch_command
)
container.fetch_command(self.root_dir)
if container.load_command:
container_files_to_load.append(container.container_file)
container_execs_to_load.append(container.load_command)
Expand Down
74 changes: 64 additions & 10 deletions kiwi/xml_state.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
#
import os
from typing import (
List, Optional, Any, Dict, NamedTuple
List, Optional, Any, Dict, NamedTuple, Callable
)
import re
import logging
Expand All @@ -32,6 +32,7 @@
from kiwi.system.uri import Uri
from kiwi.defaults import Defaults
from kiwi.utils.size import StringToSize
from kiwi.command import Command

from kiwi.exceptions import (
KiwiProfileNotFound,
Expand Down Expand Up @@ -90,7 +91,7 @@ class ContainerT(NamedTuple):
backend: str
container_file: str
fetch_only: bool
fetch_command: List[str]
fetch_command: Callable
load_command: List[str]


Expand Down Expand Up @@ -1750,10 +1751,18 @@ def get_partitions(self) -> Dict[str, ptable_entry_type]:

def get_containers(self) -> List[ContainerT]:
containers = []

def build_fetch_command(
root_dir: str,
container_uri: str = '',
container_file_name: str = '',
container_endpoint: str = ''
):
pass # pragma: nocover
for containers_section in self.get_containers_sections():
for container in containers_section.get_container():
if self.container_matches_host_architecture(container):
fetch_command = []
fetch_command = build_fetch_command
load_command = []
container_tag = container.get_tag() or 'latest'
container_path = container.get_path() or ''
Expand All @@ -1768,13 +1777,58 @@ def get_containers(self) -> List[ContainerT]:
)
container_backend = containers_section.get_backend() or ''
if container_backend in ['podman', 'docker']:
fetch_command = [
'/usr/bin/skopeo', 'copy',
'docker://{0}'.format(container_endpoint),
'oci-archive:{0}:{1}'.format(
container_file_name, container_endpoint
)
]
if Defaults.is_buildservice_worker():
container_uri = Uri(
'obsrepositories:/{0}'.format(
container_endpoint
), 'container'
).translate()

def build_fetch_command(
root_dir: str,
container_uri: str = container_uri,
container_file_name: str = container_file_name,
container_endpoint: str = container_endpoint
):
def perform():
Command.run(
[
'cp', '{0}.ociarchive'.format(
container_uri
), os.path.normpath(
'{0}/{1}'.format(
root_dir,
container_file_name
)
)
]
)
perform()
fetch_command = build_fetch_command
else:

def build_fetch_command(
root_dir: str,
container_uri: str = '',
container_file_name: str = container_file_name,
container_endpoint: str = container_endpoint
):
def perform():
Command.run(
[
'chroot', root_dir,
'/usr/bin/skopeo', 'copy',
'docker://{0}'.format(
container_endpoint
),
'oci-archive:{0}:{1}'.format(
container_file_name,
container_endpoint
)
]
)
perform()
fetch_command = build_fetch_command
if not container.get_fetch_only():
load_command = [
f'/usr/bin/{container_backend}',
Expand Down
25 changes: 25 additions & 0 deletions test/data/example_containers_config.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>

<image schemaversion="8.2" name="test-containers">
<description type="system">
<author>Some</author>
<contact>[email protected]</contact>
<specification>
Test containers section used in the buildservice
</specification>
</description>
<containers source="registry.opensuse.org" backend="podman">
<container name="tumbleweed" tag="latest" path="opensuse"/>
</containers>
<preferences>
<version>1.1.1</version>
<packagemanager>zypper</packagemanager>
<type image="xfs"/>
</preferences>
<repository>
<source path="obs://some/repo/oss"/>
</repository>
<packages type="bootstrap">
<package name="filesystem"/>
</packages>
</image>
149 changes: 98 additions & 51 deletions test/unit/xml_state_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@
)

from kiwi.defaults import Defaults
from kiwi.xml_state import (
XMLState, ContainerT
)
from kiwi.xml_state import XMLState
from kiwi.storage.disk import ptable_entry_type
from kiwi.xml_description import XMLDescription

Expand Down Expand Up @@ -412,55 +410,104 @@ def test_get_partitions(self):
)
}

def test_get_containers(self):
assert self.state.get_containers() == [
ContainerT(
name='rmtserver_latest',
backend='podman',
container_file='/var/tmp/kiwi_containers/rmtserver_latest',
fetch_only=False,
fetch_command=[
'/usr/bin/skopeo', 'copy',
'docker://registry.suse.com/home/mschaefer/'
'images_pubcloud/pct/rmtserver:latest',
'oci-archive:/var/tmp/kiwi_containers/'
'rmtserver_latest:registry.suse.com/home/mschaefer/'
'images_pubcloud/pct/rmtserver:latest'
],
load_command=[
'/usr/bin/podman', 'load', '-i',
'/var/tmp/kiwi_containers/rmtserver_latest'
]
),
ContainerT(
name='some_latest',
backend='docker',
container_file='/var/tmp/kiwi_containers/some_latest',
fetch_only=False,
fetch_command=[
'/usr/bin/skopeo', 'copy',
'docker://registry.suse.com/some:latest',
'oci-archive:/var/tmp/kiwi_containers/'
'some_latest:registry.suse.com/some:latest'
],
load_command=[
'/usr/bin/docker', 'load', '-i',
'/var/tmp/kiwi_containers/some_latest'
]
),
ContainerT(
name='foo_latest',
backend='podman',
container_file='/var/tmp/kiwi_containers/foo_latest',
fetch_only=True,
fetch_command=[
'/usr/bin/skopeo', 'copy', 'docker://docker.io/foo:latest',
'oci-archive:/var/tmp/kiwi_containers/'
'foo_latest:docker.io/foo:latest'
],
load_command=[]
)
@patch('kiwi.xml_state.Defaults.is_buildservice_worker')
@patch('kiwi.xml_state.Command.run')
def test_get_containers_in_buildservice(
self, mock_Command_run, mock_Defaults_is_buildservice_worker
):
mock_Defaults_is_buildservice_worker.return_value = True
description = XMLDescription(
'../data/example_containers_config.xml'
)
xml_data = description.load()
state = XMLState(xml_data)
containers = state.get_containers()[0]
containers.fetch_command('root_dir')
assert containers.name == 'tumbleweed_latest'
assert containers.backend == 'podman'
assert containers.container_file == \
'/var/tmp/kiwi_containers/tumbleweed_latest'
assert containers.fetch_only is False
assert containers.load_command == [
'/usr/bin/podman', 'load', '-i',
'/var/tmp/kiwi_containers/tumbleweed_latest'
]
mock_Command_run.assert_called_once_with(
[
'cp',
'/usr/src/packages/SOURCES/containers/'
'_obsrepositories/registry.opensuse.org/opensuse/'
'tumbleweed:latest.ociarchive',
'root_dir/var/tmp/kiwi_containers/tumbleweed_latest'
]
)

@patch('kiwi.xml_state.Command.run')
def test_get_containers(self, mock_Command_run):
containers = self.state.get_containers()
c1 = containers[0]
c2 = containers[1]
c3 = containers[2]

c1.fetch_command('root_dir')
assert c1.name == 'rmtserver_latest'
assert c1.backend == 'podman'
assert c1.container_file == \
'/var/tmp/kiwi_containers/rmtserver_latest'
assert c1.fetch_only is False
assert c1.load_command == [
'/usr/bin/podman', 'load', '-i',
'/var/tmp/kiwi_containers/rmtserver_latest'
]
mock_Command_run.assert_called_once_with(
[
'chroot', 'root_dir',
'/usr/bin/skopeo', 'copy',
'docker://registry.suse.com/home/mschaefer/'
'images_pubcloud/pct/rmtserver:latest',
'oci-archive:/var/tmp/kiwi_containers/'
'rmtserver_latest:registry.suse.com/home/mschaefer/'
'images_pubcloud/pct/rmtserver:latest'
]
)
mock_Command_run.reset_mock()

c2.fetch_command('root_dir')
assert c2.name == 'some_latest'
assert c2.backend == 'docker'
assert c2.container_file == \
'/var/tmp/kiwi_containers/some_latest'
assert c2.fetch_only is False
assert c2.load_command == [
'/usr/bin/docker', 'load', '-i',
'/var/tmp/kiwi_containers/some_latest'
]
mock_Command_run.assert_called_once_with(
[
'chroot', 'root_dir',
'/usr/bin/skopeo', 'copy',
'docker://registry.suse.com/some:latest',
'oci-archive:/var/tmp/kiwi_containers/'
'some_latest:registry.suse.com/some:latest'
]
)
mock_Command_run.reset_mock()

c3.fetch_command('root_dir')
assert c3.name == 'foo_latest'
assert c3.backend == 'podman'
assert c3.container_file == \
'/var/tmp/kiwi_containers/foo_latest'
assert c3.fetch_only is True
assert c3.load_command == []
mock_Command_run.assert_called_once_with(
[
'chroot', 'root_dir',
'/usr/bin/skopeo', 'copy', 'docker://docker.io/foo:latest',
'oci-archive:/var/tmp/kiwi_containers/'
'foo_latest:docker.io/foo:latest'
]
)

def test_get_volumes_custom_root_volume_name(self):
description = XMLDescription(
Expand Down

0 comments on commit cade4b4

Please sign in to comment.