Skip to content

Isolate hsi calls#440

Open
xylar wants to merge 2 commits intoE3SM-Project:mainfrom
xylar:isolate-hsi-calls
Open

Isolate hsi calls#440
xylar wants to merge 2 commits intoE3SM-Project:mainfrom
xylar:isolate-hsi-calls

Conversation

@xylar
Copy link
Copy Markdown
Contributor

@xylar xylar commented Apr 10, 2026

Summary

Objectives:

Issue resolution:

Select one: This pull request is...

  • a bug fix: increment the patch version

Please fill out either the "Small Change" or "Big Change" section (the latter includes the numbered subsections), and delete the other.

Small Change

  • To merge, I will use "Squash and merge". That is, this change should be a single commit.
  • Logic: I have visually inspected the entire pull request myself.
  • Pre-commit checks: All the pre-commits checks have passed.

xylar added 2 commits April 10, 2026 12:28
This merge removes `LD_LIBRARY_PATH` and `LD_PRELOAD` from the
environment before making `hsi` calls so conda or pixi environments
don't cause conflicts (e.g. with `libncurses`).
@xylar
Copy link
Copy Markdown
Contributor Author

xylar commented Apr 10, 2026

I'm not in a great position to test zstash itself. I did test this script that I used to reproduce the problem:

#!/usr/bin/env python3
import os
import shlex
import subprocess
import sys


def build_env(mode: str) -> dict[str, str]:
    env = os.environ.copy()

    if mode == "inherit":
        return env

    if mode == "drop-loader":
        env.pop("LD_LIBRARY_PATH", None)
        env.pop("LD_PRELOAD", None)
        return env

    if mode == "drop-pixi":
        env.pop("LD_LIBRARY_PATH", None)
        env.pop("LD_PRELOAD", None)
        for key in list(env):
            if key.startswith("PIXI_") or key.startswith("CONDA_"):
                env.pop(key, None)
        return env

    if mode == "minimal":
        return {
            "HOME": env["HOME"],
            "USER": env.get("USER", ""),
            "LOGNAME": env.get("LOGNAME", ""),
            "PATH": "/usr/bin:/bin",
            "TERM": env.get("TERM", "xterm"),
        }

    raise ValueError(f"Unknown mode: {mode}")


def main() -> int:
    mode = sys.argv[1] if len(sys.argv) > 1 else "inherit"
    command = " ".join(sys.argv[2:]) if len(sys.argv) > 2 else "hsi --help"

    env = build_env(mode)
    args = shlex.split(command)

    print(f"mode={mode}")
    print(f"command={args}")
    for key in ["LD_LIBRARY_PATH", "LD_PRELOAD", "PATH", "HOME", "USER", "LOGNAME"]:
        print(f"{key}={env.get(key)!r}")
    print("-" * 60)

    proc = subprocess.Popen(
        args,
        stdout=subprocess.PIPE,
        stderr=subprocess.PIPE,
        env=env,
        text=True,
    )
    stdout, stderr = proc.communicate()

    print(f"returncode={proc.returncode}")
    print("stdout:")
    print(stdout if stdout else "<empty>")
    print("stderr:")
    print(stderr if stderr else "<empty>")

    return proc.returncode


if __name__ == "__main__":
    raise SystemExit(main())

When this script is run from the e3sm-unified 1.13.0rc4 environment, I see:

./test_hsi_env.py inherit

reproduces the error:

stderr:
/usr/bin/.hsi-9.3_u1.exe: /global/common/software/e3sm/anaconda_envs/e3smu_1_13_0rc4/pm-cpu/pixi_login/.pixi/envs/default/lib/libncurses.so.6: version `NCURSEST6_5.7.20081102' not found (required by /usr/bin/.hsi-9.3_u1.exe)

The implementation here is equivalent to:

/test_hsi_env.py minimal

which produces a clean help message from hsi.

@forsyth2
Copy link
Copy Markdown
Collaborator

I'm not in a great position to test zstash itself.

@xylar I've run the test suite using the commits from this branch, but in a dev environment since they aren't included in Unified rc4. Unfortunately, that doesn't actually let us know if the new code works in the Unified environment.

Testing details
cd ~/ez/zstash
git status
# On branch main
# nothing to commit, working tree clean
git fetch xylar isolate-hsi-calls
git checkout -b isolate-hsi-calls xylar/isolate-hsi-calls

nersc_conda # Bash function to activate conda
rm -rf build
conda clean --all --y
conda env create -f conda/dev.yml -n zstash_pr440_20260410
conda activate zstash_pr440_20260410
pre-commit run --all-files
python -m pip install .

git log --oneline | head -n 3
# 2aca27b Add unit tests for sanitized commands
# f916017 Sanitize environment before `hsi` subprocess calls
# ed6a77e Bump to 1.6.0rc1 (#438)
# Good, matches https://github.com/E3SM-Project/zstash/pull/440/commits
# AND is based off 1.6.0rc1

pytest tests/unit/test_*.py
# 27 passed, 46 warnings in 0.56s
python -m unittest tests/integration/python_tests/group_by_command/test_*.py
# Ran 69 tests in 412.734s
# OK
python -m unittest tests/integration/python_tests/group_by_workflow/test_*.py
# Ran 4 tests in 5.055s
# OK

cd tests/integration/bash_tests/run_from_perlmutter/
time ./follow_symlinks.sh 
# real	0m40.858s
# Good, no errors
time ./test_update_non_empty_hpss.bash
# real	0m11.592s
# Good, no errors

# Log into globus.org
# Log into endpoints (NERSC Perlmutter, Globus Tutorial Collection 1) at globus.org: File Manager > Add the endpoints in the "Collection" fields
time ./test_ls_globus.bash # NOTE: Paste auth code
# real	0m41.169s
# No errors

This was referenced Apr 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants