Given: `pex_binary(name="st2.pex", execution_mode=...
# general
p
Given:
pex_binary(name="st2.pex", execution_mode="venv", include_tools=True, venv_hermetic_scripts=False)
Is there a way to configure the pex to run a shell script when executed? It looks like
entry_point
,
executable
, and
script
all require python. My goal: I want to turn the pex into some kind of "self-extracting installer". So, running
./st2.pex
will actually run the pex-tools command required to build a venv from the pex:
PEX_TOOLs=1 ./st2.pex venv --system-site-packages --non-hermetic-scripts --prompt st2 /opt/stackstorm/st2
1
s
Not quite an answer to your question, but check out
makeself
backend: https://www.pantsbuild.org/stable/docs/shell/self-extractable-archives
p
Nice! I suppose I could embed a pex in a
makeself
archive.
s
Yep, there is an example in the docs for exactly that case
p
I found a way to make running the pex generate a venv like I wanted:
pex_binary(..., dependencies=["./pex_preamble.py", ...], extra_build_args=("--preamble-file", f"source_files/{build_file_dir()}/pex_preamble.py"))
Where this is (basically) the contents of
pex_preamble.py
Copy code
import os
import sys

# This check makes re-exec safe by ensuring we modify env+argv once.
if os.environ.pop("ST2_PEX_EXTRACT", "0") not in ("1", "skip"):
    os.environ["ST2_PEX_EXTRACT"] = "1"

    st2_base_path = "/opt/stackstorm"
    st2_venv = os.path.join(st2_base_path, "st2")
    if os.path.exists(st2_venv):
        print(f"WARNING: This will overwrite {st2_venv}.", file=sys.stderr)

    # This env var and sys.argv will create a venv in the st2_venv dir.
    os.environ["PEX_TOOLS"] = "1"
    sys.argv[1:1] = (
        "venv",
        "--force",  # remove and replace the venv if it exists
        "--non-hermetic-scripts",  # do not add -sE to python shebang
        "--system-site-packages",
        "--prompt=st2",
        st2_venv,
    )
👍 1