From: Ryan Wilson Date: Mon, 21 Apr 2025 17:00:53 +0000 (-0700) Subject: mkosi: Override misconfigured gitconfig HTTP/HTTPS proxy with ProxyUrl X-Git-Tag: v26~234 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=63d91cc2854ff3346057bc6458f2f85b10c5d18e;p=thirdparty%2Fmkosi.git mkosi: Override misconfigured gitconfig HTTP/HTTPS proxy with ProxyUrl When running mkosi on a server with an outgoing HTTP/HTTPS proxy, Build.ProxyUrl must be set. However, some repositories (e.g. systemd) call git in their mkosi scripts (e.g. cloning package repositories for distros) and .gitconfig can also contain different http.proxy and https.proxy settings. Thus, if .gitconfig is misconfigured with the wrong proxy, the user will get confusing errors related to git fetching repositories. To ensure we use a consistent proxy across git and mkosi, we override git http proxy configuration via GIT_CONFIG_COUNT, GIT_CONFIG_KEY_{n}, GIT_CONFIG_VALUE{n} environment variables. Most of the code complexity is dealing with the case when these variables are set by the user via Environment / EnvironmentFiles. --- diff --git a/mkosi/config.py b/mkosi/config.py index be72f9b10..433f10208 100644 --- a/mkosi/config.py +++ b/mkosi/config.py @@ -2131,6 +2131,7 @@ class Config: for line in f.read_text().strip().splitlines() ) env |= self.environment + env |= finalize_git_config(self.proxy_url, env) return env @@ -5244,6 +5245,27 @@ def finalize_term() -> str: return term if sys.stderr.isatty() else "dumb" +def finalize_git_config(proxy_url: Optional[str], env: dict[str, str]) -> dict[str, str]: + if proxy_url is None: + return {} + + try: + cnt = int(env.get("GIT_CONFIG_COUNT", "0")) + except ValueError: + raise ValueError("GIT_CONFIG_COUNT environment variable must be set to a valid integer") + + # Override HTTP/HTTPS proxy in case its set in .gitconfig to a different value than proxy_url. + # No need to override http.proxy / https.proxy if set in a previous GIT_CONFIG_* variable since + # the last setting always wins. + return { + "GIT_CONFIG_COUNT": str(cnt + 2), + f"GIT_CONFIG_KEY_{cnt}": "http.proxy", + f"GIT_CONFIG_VALUE_{cnt}": proxy_url, + f"GIT_CONFIG_KEY_{cnt + 1}": "https.proxy", + f"GIT_CONFIG_VALUE_{cnt + 1}": proxy_url, + } + + def yes_no(b: bool) -> str: return "yes" if b else "no" diff --git a/tests/test_config.py b/tests/test_config.py index ce4a31392..bc52cd1c7 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1321,6 +1321,58 @@ def test_environment(tmp_path: Path) -> None: assert "TestValue2" not in sub.environment +def test_proxy(tmp_path: Path) -> None: + d = tmp_path + + # Verify environment variables are set correctly when GIT_CONFIG_COUNT is not set + (d / "mkosi.conf").write_text( + """\ + [Build] + ProxyUrl=http://proxy:8080 + """ + ) + + with chdir(d): + _, _, [config] = parse_config() + + expected = { + "GIT_CONFIG_COUNT": "2", + "GIT_CONFIG_KEY_0": "http.proxy", + "GIT_CONFIG_VALUE_0": "http://proxy:8080", + "GIT_CONFIG_KEY_1": "https.proxy", + "GIT_CONFIG_VALUE_1": "http://proxy:8080", + } + + # Only check values for keys from expected, as config.environment contains other items as well + assert {k: config.finalize_environment()[k] for k in expected.keys()} == expected + + (d / "mkosi.conf").write_text( + """\ + [Build] + ProxyUrl=http://proxy:8080 + Environment=GIT_CONFIG_COUNT=1 + GIT_CONFIG_KEY_0=user.name + GIT_CONFIG_VALUE_0=bob + """ + ) + + with chdir(d): + _, _, [config] = parse_config() + + expected = { + "GIT_CONFIG_COUNT": "3", + "GIT_CONFIG_KEY_0": "user.name", + "GIT_CONFIG_VALUE_0": "bob", + "GIT_CONFIG_KEY_1": "http.proxy", + "GIT_CONFIG_VALUE_1": "http://proxy:8080", + "GIT_CONFIG_KEY_2": "https.proxy", + "GIT_CONFIG_VALUE_2": "http://proxy:8080", + } + + # Only check values for keys from expected, as config.environment contains other items as well + assert {k: config.finalize_environment()[k] for k in expected.keys()} == expected + + def test_mkosi_version_executable(tmp_path: Path) -> None: d = tmp_path