diff mbox series

[layerindex-web,6/6] rrs_distros: keep the environment when fetching distro package lists

Message ID 20261115003506.53654-7-tim.orling@konsulko.com
State Under Review
Delegated to: Tim Orling
Headers show
Series Get the RRS update scripts working again | expand

Commit Message

Tim Orling Nov. 15, 2026, 12:35 a.m. UTC
OE-Core's distro_check calls bb.utils.export_proxies(), which also
exports the datastore's PATH and HOME. OE-Core's PATH puts its
scripts/git wrapper first with no python3 beside it, so once the
package lists were fetched for the first layer branch, every git command
for the next one failed with "/usr/bin/env: 'python3': No such file or
directory". Restore the environment after fetching the lists.

[YOCTO #16506]

AI-Generated: Claude Opus 5.5
Signed-off-by: Tim Orling <tim.orling@konsulko.com>
---
 rrs/tools/common.py               | 18 +++++++++++++
 rrs/tools/rrs_distros.py          |  5 ++--
 tests/test_rrs_distros_environ.py | 45 +++++++++++++++++++++++++++++++
 3 files changed, 66 insertions(+), 2 deletions(-)
 create mode 100644 tests/test_rrs_distros_environ.py
diff mbox series

Patch

diff --git a/rrs/tools/common.py b/rrs/tools/common.py
index f97d4e1..ef213af 100644
--- a/rrs/tools/common.py
+++ b/rrs/tools/common.py
@@ -24,6 +24,24 @@  def common_setup():
     os.environ['GIT_ASKPASS'] = ''
     os.environ['GIT_TERMINAL_PROMPT'] = '0'
 
+def create_distro_packages_list(distro_check, fetchdir, d):
+    """
+    Download the distros' package lists with OE-Core's oe.distro_check,
+    keeping this process's environment as it was.
+
+    distro_check's create_socket() calls bb.utils.export_proxies(), which
+    exports PATH and HOME from the datastore along with the proxy
+    variables. OE-Core's PATH puts its scripts/git wrapper first, with no
+    python3 beside it, so left in place it breaks every later git command
+    in this process.
+    """
+    saved_environ = os.environ.copy()
+    try:
+        distro_check.create_distro_packages_list(fetchdir, d)
+    finally:
+        os.environ.clear()
+        os.environ.update(saved_environ)
+
 def get_logger(name, settings):
     from logging.handlers import RotatingFileHandler
 
diff --git a/rrs/tools/rrs_distros.py b/rrs/tools/rrs_distros.py
index e6717c1..3dc745d 100755
--- a/rrs/tools/rrs_distros.py
+++ b/rrs/tools/rrs_distros.py
@@ -17,7 +17,8 @@  from datetime import datetime
 
 sys.path.insert(0, os.path.realpath(os.path.join(os.path.dirname(__file__))))
 from common import common_setup, load_recipes, \
-        get_pv_type, get_logger, DryRunRollbackException
+        get_pv_type, get_logger, DryRunRollbackException, \
+        create_distro_packages_list
 common_setup()
 from layerindex import utils
 
@@ -138,7 +139,7 @@  if __name__=="__main__":
                             # Only need to do this once
                             from oe import distro_check
                             logger.debug("Downloading distro's package information ...")
-                            distro_check.create_distro_packages_list(fetchdir, d)
+                            create_distro_packages_list(distro_check, fetchdir, d)
                             pkglst_dir = os.path.join(fetchdir, "package_lists")
 
                         RecipeDistro.objects.filter(recipe__layerbranch = layerbranch).delete()
diff --git a/tests/test_rrs_distros_environ.py b/tests/test_rrs_distros_environ.py
new file mode 100644
index 0000000..e07fa74
--- /dev/null
+++ b/tests/test_rrs_distros_environ.py
@@ -0,0 +1,45 @@ 
+# layerindex-web - tests for create_distro_packages_list() in rrs/tools/common.py
+#
+# Licensed under the MIT license, see COPYING.MIT for details
+#
+# SPDX-License-Identifier: MIT
+
+import os
+import sys
+import types
+
+import pytest
+
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'rrs', 'tools'))
+
+import common
+
+
+def fake_distro_check(fail=False):
+    # Like OE-Core's create_socket(): bb.utils.export_proxies() writes the
+    # datastore's PATH and HOME into os.environ
+    def create_distro_packages_list(fetchdir, d):
+        os.environ['PATH'] = '/oe-core/scripts:/build/tmp/hosttools'
+        os.environ['HOME'] = '/build'
+        os.environ['http_proxy'] = 'http://proxy.example.com:3128'
+        if fail:
+            raise OSError('HTTP Error 404: Not Found')
+    return types.SimpleNamespace(create_distro_packages_list=create_distro_packages_list)
+
+
+@pytest.mark.parametrize('fail', [False, True])
+def test_create_distro_packages_list_keeps_the_environment(monkeypatch, fail):
+    # [YOCTO #16506] OE-Core's PATH left in the environment made the next
+    # layer branch's git commands run OE-Core's scripts/git without python3
+    monkeypatch.setenv('PATH', '/usr/local/bin:/usr/bin:/bin')
+    monkeypatch.setenv('HOME', '/home/layers')
+    monkeypatch.delenv('http_proxy', raising=False)
+    before = dict(os.environ)
+
+    if fail:
+        with pytest.raises(OSError):
+            common.create_distro_packages_list(fake_distro_check(fail=True), '/fetch', None)
+    else:
+        common.create_distro_packages_list(fake_distro_check(), '/fetch', None)
+
+    assert dict(os.environ) == before