diff --git a/build-tests/arm/ubuntu/test-image-rpi/appliance.kiwi b/build-tests/arm/ubuntu/test-image-rpi/appliance.kiwi
index 1c7a0e5072..9ddf8cbcf0 100644
--- a/build-tests/arm/ubuntu/test-image-rpi/appliance.kiwi
+++ b/build-tests/arm/ubuntu/test-image-rpi/appliance.kiwi
@@ -30,7 +30,7 @@
-
+
diff --git a/build-tests/x86/debian/test-image-live-disk/appliance.kiwi b/build-tests/x86/debian/test-image-live-disk/appliance.kiwi
index da1162d59b..a99a3b7ed2 100644
--- a/build-tests/x86/debian/test-image-live-disk/appliance.kiwi
+++ b/build-tests/x86/debian/test-image-live-disk/appliance.kiwi
@@ -51,7 +51,7 @@
-
+
diff --git a/build-tests/x86/ubuntu/test-image-docker/appliance.kiwi b/build-tests/x86/ubuntu/test-image-docker/appliance.kiwi
index fbd1f14c6f..726c12a075 100644
--- a/build-tests/x86/ubuntu/test-image-docker/appliance.kiwi
+++ b/build-tests/x86/ubuntu/test-image-docker/appliance.kiwi
@@ -23,7 +23,7 @@
-
+
diff --git a/build-tests/x86/ubuntu/test-image-live-disk/appliance.kiwi b/build-tests/x86/ubuntu/test-image-live-disk/appliance.kiwi
index 48f9e63563..f897875403 100644
--- a/build-tests/x86/ubuntu/test-image-live-disk/appliance.kiwi
+++ b/build-tests/x86/ubuntu/test-image-live-disk/appliance.kiwi
@@ -51,7 +51,7 @@
-
+
diff --git a/kiwi/repository/apt.py b/kiwi/repository/apt.py
index f981d53ffa..529f9d00a4 100644
--- a/kiwi/repository/apt.py
+++ b/kiwi/repository/apt.py
@@ -138,7 +138,8 @@ def add_repo(
prio: int = None, dist: str = None, components: str = None,
user: str = None, secret: str = None, credentials_file: str = None,
repo_gpgcheck: bool = None, pkg_gpgcheck: bool = None,
- sourcetype: str = None, customization_script: str = None
+ sourcetype: str = None, customization_script: str = None,
+ architectures: str = None
) -> None:
"""
Add apt_get repository
@@ -157,6 +158,8 @@ def add_repo(
:param str sourcetype: unused
:param str customization_script:
custom script called after the repo file was created
+ :param str architectures:
+ identifies which architectures are supported by this repository
"""
sources_file = '/'.join(
[self.shared_apt_get_dir['sources-dir'], name + '.sources']
@@ -175,6 +178,10 @@ def add_repo(
with open(sources_file, 'w') as repo:
repo_details = 'Types: deb' + os.linesep
repo_details += 'URIs: ' + uri + os.linesep
+ if architectures:
+ repo_details += 'Architectures: {}{}'.format(
+ architectures.replace(',', ' '), os.linesep
+ )
if not dist:
# create a debian flat repository setup. We consider the
# repository metadata to exist on the toplevel of the
diff --git a/kiwi/repository/base.py b/kiwi/repository/base.py
index 3af266aee1..22f03ed1b6 100644
--- a/kiwi/repository/base.py
+++ b/kiwi/repository/base.py
@@ -77,7 +77,7 @@ def add_repo(
self, name: str, uri: str, repo_type: str, prio: int, dist: str,
components: str, user: str, secret: str, credentials_file: str,
repo_gpgcheck: bool, pkg_gpgcheck: bool, sourcetype: str,
- customization_script: str = None
+ customization_script: str = None, architectures: str = None
) -> None:
"""
Add repository
@@ -97,6 +97,7 @@ def add_repo(
:param bool pkg_gpgcheck: unused
:param str sourcetype: unused
:param str customization_script: unused
+ :param str architectures: unused
"""
raise NotImplementedError
diff --git a/kiwi/repository/dnf4.py b/kiwi/repository/dnf4.py
index 542d8e1092..5136ccaff4 100644
--- a/kiwi/repository/dnf4.py
+++ b/kiwi/repository/dnf4.py
@@ -192,7 +192,8 @@ def add_repo(
prio: int = None, dist: str = None, components: str = None,
user: str = None, secret: str = None, credentials_file: str = None,
repo_gpgcheck: bool = False, pkg_gpgcheck: bool = False,
- sourcetype: str = None, customization_script: str = None
+ sourcetype: str = None, customization_script: str = None,
+ architectures: str = None
) -> None:
"""
Add dnf repository
@@ -212,6 +213,7 @@ def add_repo(
source type, one of 'baseurl', 'metalink' or 'mirrorlist'
:param str customization_script:
custom script called after the repo file was created
+ :param str architectures: unused
"""
repo_file = self.shared_dnf_dir['reposd-dir'] + '/' + name + '.repo'
self.repo_names.append(name + '.repo')
diff --git a/kiwi/repository/dnf5.py b/kiwi/repository/dnf5.py
index a02b6f5554..45b8cef3db 100644
--- a/kiwi/repository/dnf5.py
+++ b/kiwi/repository/dnf5.py
@@ -192,7 +192,8 @@ def add_repo(
prio: int = None, dist: str = None, components: str = None,
user: str = None, secret: str = None, credentials_file: str = None,
repo_gpgcheck: bool = False, pkg_gpgcheck: bool = False,
- sourcetype: str = None, customization_script: str = None
+ sourcetype: str = None, customization_script: str = None,
+ architectures: str = None
) -> None:
"""
Add dnf repository
@@ -212,6 +213,7 @@ def add_repo(
source type, one of 'baseurl', 'metalink' or 'mirrorlist'
:param str customization_script:
custom script called after the repo file was created
+ :param str architectures: unused
"""
repo_file = self.shared_dnf_dir['reposd-dir'] + '/' + name + '.repo'
self.repo_names.append(name + '.repo')
diff --git a/kiwi/repository/pacman.py b/kiwi/repository/pacman.py
index 85eb4bed3b..60946ab757 100644
--- a/kiwi/repository/pacman.py
+++ b/kiwi/repository/pacman.py
@@ -115,7 +115,8 @@ def add_repo(
prio: int = None, dist: str = None, components: str = None,
user: str = None, secret: str = None, credentials_file: str = None,
repo_gpgcheck: bool = False, pkg_gpgcheck: bool = False,
- sourcetype: str = None, customization_script: str = None
+ sourcetype: str = None, customization_script: str = None,
+ architectures: str = None
) -> None:
"""
Add pacman repository
@@ -134,6 +135,7 @@ def add_repo(
:param str sourcetype: unused
:param str customization_script:
custom script called after the repo file was created
+ :param str architectures: unused
"""
repo_file = '{0}/{1}.repo'.format(
self.shared_pacman_dir['repos-dir'], name
diff --git a/kiwi/repository/zypper.py b/kiwi/repository/zypper.py
index 93a80b86c5..4fc4a117f5 100644
--- a/kiwi/repository/zypper.py
+++ b/kiwi/repository/zypper.py
@@ -252,7 +252,8 @@ def add_repo(
prio: int = None, dist: str = None, components: str = None,
user: str = None, secret: str = None, credentials_file: str = None,
repo_gpgcheck: bool = False, pkg_gpgcheck: bool = False,
- sourcetype: str = None, customization_script: str = None
+ sourcetype: str = None, customization_script: str = None,
+ architectures: str = None
) -> None:
"""
Add zypper repository
@@ -271,6 +272,7 @@ def add_repo(
:param str sourcetype: unused
:param str customization_script:
custom script called after the repo file was created
+ :param str architectures: unused
"""
if credentials_file:
repo_secret = os.sep.join(
diff --git a/kiwi/schema/kiwi.rnc b/kiwi/schema/kiwi.rnc
index a6ddae0285..baec677ee9 100644
--- a/kiwi/schema/kiwi.rnc
+++ b/kiwi/schema/kiwi.rnc
@@ -36,7 +36,7 @@ volume-size-type = xsd:token {pattern = "(\d+|\d+M|\d+G|all)"}
partition-size-type = xsd:token {pattern = "(\d+|\d+M|\d+G)"}
vhd-tag-type = xsd:token {pattern = "[0-9a-f]{8}-([0-9a-f]{4}-){3}[0-9a-f]{12}"}
groups-list = xsd:token {pattern = "[a-zA-Z0-9_\-\.:]+(,[a-zA-Z0-9_\-\.:]+)*"}
-arch-name = xsd:token {pattern = "(x86_64|i586|i686|ix86|aarch64|arm64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64)(,(x86_64|i586|i686|ix86|aarch64|arm64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64))*"}
+arch-name = xsd:token {pattern = "(x86_64|i586|i686|ix86|aarch64|arm64|amd64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64)(,(x86_64|i586|i686|ix86|aarch64|arm64|amd64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64))*"}
portnum-type = xsd:token {pattern = "(\d+|\d+/(udp|tcp))"}
grub_console = xsd:token {pattern = "(none|console|gfxterm|serial|vga_text|mda_text|morse|spkmodem)( (none|console|serial|at_keyboard|usb_keyboard))*"}
fs_attributes = xsd:token {pattern = "(no-copy-on-write|synchronous-updates)(,(no-copy-on-write|synchronous-updates))*"}
@@ -1135,6 +1135,15 @@ div {
attribute sourcetype {
"baseurl" | "metalink" | "mirrorlist"
}
+ k.repository.architectures.attribute =
+ ## Specifies for which architecture(s) this repository is
+ ## supposed to provide packages. Multiple architecture names
+ ## needs to be separated by a comma
+ attribute architectures { arch-name }
+ >> sch:pattern [ id = "architectures" is-a = "repo_type"
+ sch:param [ name = "attr" value = "architectures" ]
+ sch:param [ name = "types" value = "apt-deb" ]
+ ]
k.repository.attlist =
k.repository.type.attribute? &
k.repository.profiles.attribute? &
@@ -1152,7 +1161,8 @@ div {
k.repository.package_gpgcheck.attribute? &
k.repository.priority.attribute? &
k.repository.password.attribute? &
- k.repository.username.attribute?
+ k.repository.username.attribute? &
+ k.repository.architectures.attribute?
k.repository =
## The Name of the Repository
element repository {
diff --git a/kiwi/schema/kiwi.rng b/kiwi/schema/kiwi.rng
index b50bf6f790..ee4918e74b 100644
--- a/kiwi/schema/kiwi.rng
+++ b/kiwi/schema/kiwi.rng
@@ -83,7 +83,7 @@
- (x86_64|i586|i686|ix86|aarch64|arm64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64)(,(x86_64|i586|i686|ix86|aarch64|arm64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64))*
+ (x86_64|i586|i686|ix86|aarch64|arm64|amd64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64)(,(x86_64|i586|i686|ix86|aarch64|arm64|amd64|armv5el|armv5tel|armv6hl|armv6l|armv7hl|armv7l|ppc|ppc64|ppc64le|s390|s390x|riscv64))*
@@ -1728,6 +1728,18 @@ be a simple repository url
+
+
+ Specifies for which architecture(s) this repository is
+supposed to provide packages. Multiple architecture names
+needs to be separated by a comma
+
+
+
+
+
+
+
@@ -1775,6 +1787,9 @@ be a simple repository url
+
+
+
diff --git a/kiwi/system/prepare.py b/kiwi/system/prepare.py
index 50f7aa635b..7695adf601 100644
--- a/kiwi/system/prepare.py
+++ b/kiwi/system/prepare.py
@@ -158,6 +158,7 @@ def setup_repositories(
for xml_repo in repository_sections:
repo_type = xml_repo.get_type()
repo_source = xml_repo.get_source().get_path()
+ repo_architectures = xml_repo.get_architectures()
repo_user = xml_repo.get_username()
repo_secret = xml_repo.get_password()
repo_alias = xml_repo.get_alias()
@@ -209,7 +210,8 @@ def setup_repositories(
repo_type, repo_priority, repo_dist, repo_components,
repo_user, repo_secret, uri.credentials_file_name(),
repo_repository_gpgcheck, repo_package_gpgcheck,
- repo_sourcetype, repo_customization_script
+ repo_sourcetype, repo_customization_script,
+ repo_architectures
)
if clear_cache:
repo.delete_repo_cache(repo_alias)
diff --git a/kiwi/system/setup.py b/kiwi/system/setup.py
index 6098fd3bb4..c43a9f75fc 100644
--- a/kiwi/system/setup.py
+++ b/kiwi/system/setup.py
@@ -149,6 +149,7 @@ def import_repositories_marked_as_imageinclude(self) -> None:
for xml_repo in repository_sections:
repo_type = xml_repo.get_type()
repo_source = xml_repo.get_source().get_path()
+ repo_architectures = xml_repo.get_architectures()
repo_user = xml_repo.get_username()
repo_secret = xml_repo.get_password()
repo_alias = xml_repo.get_alias()
@@ -184,7 +185,8 @@ def import_repositories_marked_as_imageinclude(self) -> None:
repo_type, repo_priority, repo_dist, repo_components,
repo_user, repo_secret, uri.credentials_file_name(),
repo_repository_gpgcheck, repo_package_gpgcheck,
- repo_sourcetype, repo_customization_script
+ repo_sourcetype, repo_customization_script,
+ repo_architectures
)
def import_cdroot_files(self, target_dir: str) -> None:
diff --git a/kiwi/xml_parse.py b/kiwi/xml_parse.py
index d6168ed838..61e9baac3e 100644
--- a/kiwi/xml_parse.py
+++ b/kiwi/xml_parse.py
@@ -2442,7 +2442,7 @@ class repository(k_source):
"""The Name of the Repository"""
subclass = None
superclass = k_source
- def __init__(self, source=None, type_=None, profiles=None, arch=None, alias=None, sourcetype=None, components=None, distribution=None, imageinclude=None, imageonly=None, repository_gpgcheck=None, customize=None, package_gpgcheck=None, priority=None, password=None, username=None):
+ def __init__(self, source=None, type_=None, profiles=None, arch=None, alias=None, sourcetype=None, components=None, distribution=None, imageinclude=None, imageonly=None, repository_gpgcheck=None, customize=None, package_gpgcheck=None, priority=None, password=None, username=None, architectures=None):
self.original_tagname_ = None
super(repository, self).__init__(source, )
self.type_ = _cast(None, type_)
@@ -2460,6 +2460,7 @@ def __init__(self, source=None, type_=None, profiles=None, arch=None, alias=None
self.priority = _cast(int, priority)
self.password = _cast(None, password)
self.username = _cast(None, username)
+ self.architectures = _cast(None, architectures)
def factory(*args_, **kwargs_):
if CurrentSubclassModule_ is not None:
subclass = getSubclassFromModule_(
@@ -2501,6 +2502,8 @@ def get_password(self): return self.password
def set_password(self, password): self.password = password
def get_username(self): return self.username
def set_username(self, username): self.username = username
+ def get_architectures(self): return self.architectures
+ def set_architectures(self, architectures): self.architectures = architectures
def validate_arch_name(self, value):
# Validate type arch-name, a restriction on xs:token.
if value is not None and Validate_simpletypes_:
@@ -2590,6 +2593,9 @@ def exportAttributes(self, outfile, level, already_processed, namespaceprefix_='
if self.username is not None and 'username' not in already_processed:
already_processed.add('username')
outfile.write(' username=%s' % (self.gds_encode(self.gds_format_string(quote_attrib(self.username), input_name='username')), ))
+ if self.architectures is not None and 'architectures' not in already_processed:
+ already_processed.add('architectures')
+ outfile.write(' architectures=%s' % (quote_attrib(self.architectures), ))
def exportChildren(self, outfile, level, namespaceprefix_='', name_='repository', fromsubclass_=False, pretty_print=True):
super(repository, self).exportChildren(outfile, level, namespaceprefix_, name_, True, pretty_print=pretty_print)
def build(self, node):
@@ -2689,6 +2695,12 @@ def buildAttributes(self, node, attrs, already_processed):
if value is not None and 'username' not in already_processed:
already_processed.add('username')
self.username = value
+ value = find_attr_value_('architectures', node)
+ if value is not None and 'architectures' not in already_processed:
+ already_processed.add('architectures')
+ self.architectures = value
+ self.architectures = ' '.join(self.architectures.split())
+ self.validate_arch_name(self.architectures) # validate type arch-name
super(repository, self).buildAttributes(node, attrs, already_processed)
def buildChildren(self, child_, node, nodeName_, fromsubclass_=False):
super(repository, self).buildChildren(child_, node, nodeName_, True)
diff --git a/test/unit/repository/apt_test.py b/test/unit/repository/apt_test.py
index 7f9bc49103..5928c4549e 100644
--- a/test/unit/repository/apt_test.py
+++ b/test/unit/repository/apt_test.py
@@ -151,11 +151,13 @@ def test_add_repo_distribution(self, mock_exists):
mock_open.return_value = MagicMock(spec=io.IOBase)
file_handle = mock_open.return_value.__enter__.return_value
self.repo.add_repo(
- 'foo', 'kiwi_iso_mount/uri', 'deb', None, 'xenial', 'a b'
+ 'foo', 'kiwi_iso_mount/uri', 'deb', None, 'xenial', 'a b',
+ architectures='amd64,arm64'
)
file_handle.write.assert_called_once_with(
'Types: deb\n'
'URIs: file:/kiwi_iso_mount/uri\n'
+ 'Architectures: amd64 arm64\n'
'Suites: xenial\n'
'Components: a b\n'
)
diff --git a/test/unit/system/prepare_test.py b/test/unit/system/prepare_test.py
index d1aa572c19..48dc717038 100644
--- a/test/unit/system/prepare_test.py
+++ b/test/unit/system/prepare_test.py
@@ -287,12 +287,12 @@ def test_setup_repositories(
call(
'uri-alias', 'uri', None, 42,
None, None, None, None, 'credentials-file', None, None,
- 'baseurl', None
+ 'baseurl', None, None
),
call(
'uri-alias', 'uri', 'rpm-md', None,
None, None, None, None, 'credentials-file', None, None,
- None, '../data/script'
+ None, '../data/script', None
)
]
assert repo.delete_repo_cache.call_args_list == [
diff --git a/test/unit/system/setup_test.py b/test/unit/system/setup_test.py
index 4fe2d43e07..ab247f69a6 100644
--- a/test/unit/system/setup_test.py
+++ b/test/unit/system/setup_test.py
@@ -1678,7 +1678,7 @@ def test_import_repositories_marked_as_imageinclude(
self.setup_with_real_xml.import_repositories_marked_as_imageinclude()
assert repo.add_repo.call_args_list[0] == call(
'uri-alias', 'uri', 'rpm-md', None, None, None, None, None,
- 'kiwiRepoCredentials', None, None, None, '../data/script'
+ 'kiwiRepoCredentials', None, None, None, '../data/script', None
)
@patch('os.path.exists')