Skip to content

Commit

Permalink
Merge pull request #2706 from OSInside/allow_to_specify_zypp_env_vari…
Browse files Browse the repository at this point in the history
…ables

Add support for reading optional package manager env file
  • Loading branch information
Conan-Kudo authored Jan 13, 2025
2 parents 12c4c8f + 5c217af commit 9a526ed
Show file tree
Hide file tree
Showing 11 changed files with 104 additions and 0 deletions.
3 changes: 3 additions & 0 deletions kiwi/defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@
PLATFORM_MACHINE = platform.machine()
EFI_FAT_IMAGE_SIZE = 20

# optional package manager environment variables
PACKAGE_MANAGER_ENV_VARS = '/.kiwi.package_manager.env'

log = logging.getLogger('kiwi')


Expand Down
7 changes: 7 additions & 0 deletions kiwi/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -444,6 +444,13 @@ class KiwiOSReleaseImportError(KiwiError):
"""


class KiwiEnvImportError(KiwiError):
"""
Exception raised if extending os.environ with another
env file caused an issue
"""


class KiwiPackageManagerSetupError(KiwiError):
"""
Exception raised if an attempt was made to create a package
Expand Down
3 changes: 3 additions & 0 deletions kiwi/repository/apt.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,15 @@
from typing import List, Dict

# project
import kiwi.defaults as defaults
from kiwi.utils.temporary import (
Temporary, TmpT
)
from kiwi.repository.template.apt import PackageManagerTemplateAptGet
from kiwi.repository.base import RepositoryBase
from kiwi.path import Path
from kiwi.command import Command
from kiwi.utils.toenv import ToEnv

log = logging.getLogger('kiwi')

Expand Down Expand Up @@ -306,6 +308,7 @@ def _add_components(self, components: str) -> None:
def _create_apt_get_runtime_environment(self) -> Dict:
for apt_get_dir in list(self.shared_apt_get_dir.values()):
Path.create(apt_get_dir)
ToEnv(self.root_dir, defaults.PACKAGE_MANAGER_ENV_VARS)
return dict(
os.environ, LANG='C', DEBIAN_FRONTEND='noninteractive'
)
Expand Down
3 changes: 3 additions & 0 deletions kiwi/repository/dnf4.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from typing import List, Dict

# project
import kiwi.defaults as defaults
from kiwi.utils.temporary import (
Temporary, TmpT
)
Expand All @@ -29,6 +30,7 @@
from kiwi.repository.base import RepositoryBase
from kiwi.path import Path
from kiwi.utils.rpm_database import RpmDataBase
from kiwi.utils.toenv import ToEnv


class RepositoryDnf4(RepositoryBase):
Expand Down Expand Up @@ -315,6 +317,7 @@ def cleanup_unused_repos(self) -> None:
def _create_dnf_runtime_environment(self) -> Dict:
for dnf_dir in list(self.shared_dnf_dir.values()):
Path.create(dnf_dir)
ToEnv(self.root_dir, defaults.PACKAGE_MANAGER_ENV_VARS)
return dict(
os.environ, LANG='C'
)
Expand Down
3 changes: 3 additions & 0 deletions kiwi/repository/dnf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from typing import List, Dict

# project
import kiwi.defaults as defaults
from kiwi.utils.temporary import (
Temporary, TmpT
)
Expand All @@ -29,6 +30,7 @@
from kiwi.repository.base import RepositoryBase
from kiwi.path import Path
from kiwi.utils.rpm_database import RpmDataBase
from kiwi.utils.toenv import ToEnv


class RepositoryDnf5(RepositoryBase):
Expand Down Expand Up @@ -315,6 +317,7 @@ def cleanup_unused_repos(self) -> None:
def _create_dnf_runtime_environment(self) -> Dict:
for dnf_dir in list(self.shared_dnf_dir.values()):
Path.create(dnf_dir)
ToEnv(self.root_dir, defaults.PACKAGE_MANAGER_ENV_VARS)
return dict(
os.environ, LANG='C'
)
Expand Down
3 changes: 3 additions & 0 deletions kiwi/repository/pacman.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,14 @@
)

# project
import kiwi.defaults as defaults
from kiwi.utils.temporary import (
Temporary, TmpT
)
from kiwi.repository.base import RepositoryBase
from kiwi.path import Path
from kiwi.command import Command
from kiwi.utils.toenv import ToEnv


class RepositoryPacman(RepositoryBase):
Expand Down Expand Up @@ -90,6 +92,7 @@ def runtime_config(self) -> Dict:
"""
pacman runtime configuration and environment
"""
ToEnv(self.root_dir, defaults.PACKAGE_MANAGER_ENV_VARS)
return {
'pacman_args': self.pacman_args,
'command_env': os.environ
Expand Down
3 changes: 3 additions & 0 deletions kiwi/repository/zypper.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from typing import List, Dict

# project
import kiwi.defaults as defaults
from kiwi.utils.temporary import (
Temporary, TmpT
)
Expand All @@ -30,6 +31,7 @@
from kiwi.system.uri import Uri
from kiwi.path import Path
from kiwi.utils.rpm_database import RpmDataBase
from kiwi.utils.toenv import ToEnv


class RepositoryZypper(RepositoryBase):
Expand Down Expand Up @@ -427,6 +429,7 @@ def cleanup_unused_repos(self) -> None:
def _create_zypper_runtime_environment(self) -> Dict:
for zypper_dir in list(self.shared_zypper_dir.values()):
Path.create(zypper_dir)
ToEnv(self.root_dir, defaults.PACKAGE_MANAGER_ENV_VARS)
return dict(
os.environ,
LANG='C',
Expand Down
59 changes: 59 additions & 0 deletions kiwi/utils/toenv.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
# Copyright (c) 2024 SUSE Software Solutions Germany GmbH. All rights reserved.
#
# This file is part of kiwi.
#
# kiwi is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# kiwi is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with kiwi. If not, see <http://www.gnu.org/licenses/>
#
import csv
import os
from io import TextIOWrapper
from typing import Iterable

# project
from kiwi.exceptions import KiwiEnvImportError


class ToEnv:
"""
**Read env file and merge with os.environ**
"""
def __init__(self, root_dir: str, envfile: str):
self.data = {}
env_file = f'{root_dir}/{envfile}'
if os.path.isfile(env_file):
try:
with open(env_file) as osdata:
reader = csv.reader(ToEnv._rip(osdata), delimiter='=')
self.data = dict(reader)
except Exception as issue:
raise KiwiEnvImportError(
f'Import of {envfile} failed with {issue}'
)
if self.data:
os.environ.update(self.data)

@staticmethod
def _is_comment(line: str) -> bool:
return line.startswith('#')

@staticmethod
def _is_whitespace(line: str) -> bool:
return line.isspace()

@staticmethod
def _rip(csvfile: TextIOWrapper) -> Iterable[str]:
for row in csvfile:
if not ToEnv._is_comment(row) \
and not ToEnv._is_whitespace(row):
yield row
1 change: 1 addition & 0 deletions test/data/some.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ZYPP_MODALIAS_SYSFS=""
1 change: 1 addition & 0 deletions test/data/some_broken.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
xxxx
18 changes: 18 additions & 0 deletions test/unit/utils/toenv_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from pytest import raises
import os

from kiwi.utils.toenv import ToEnv
from kiwi.exceptions import KiwiEnvImportError


class TestToEnv(object):
def setup(self):
ToEnv('../data', 'some.env')
assert os.environ['ZYPP_MODALIAS_SYSFS'] == ''

def setup_method(self, cls):
self.setup()

def test_setup_raises(self):
with raises(KiwiEnvImportError):
ToEnv('../data', 'some_broken.env')

0 comments on commit 9a526ed

Please sign in to comment.