From a0b6f143779f1e5aedeb681b51ff60faaf462bc0 Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Tue, 23 Jan 2024 18:28:31 -0500 Subject: [PATCH 1/7] enable interactive and exit for run() --- scif/main/commands.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scif/main/commands.py b/scif/main/commands.py index 9932bdd..683cb05 100644 --- a/scif/main/commands.py +++ b/scif/main/commands.py @@ -163,7 +163,6 @@ def run(self, app=None, args=None): args: a list of one or more additional arguments to pass to runscript """ - interactive = False config = self.app(app) if "apprun" not in config: bot.debug("%s does not have a runscript." % app) @@ -175,7 +174,7 @@ def run(self, app=None, args=None): # sets entrypoint # sets entryfolder - return self._exec(app, interactive=interactive) + return self._exec(app, interactive=True, exit=True) def test(self, app=None, args=None): From 91e502c4eade9555861a03eadc6025a5dceacf21 Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Tue, 23 Jan 2024 19:23:57 -0500 Subject: [PATCH 2/7] test/example, changelog, version for exit code from run --- CHANGELOG.md | 1 + docs/examples/exit-from-run/Dockerfile | 22 ++++++++++++++++++++++ docs/examples/exit-from-run/README.md | 11 +++++++++++ docs/examples/exit-from-run/apptainer.def | 16 ++++++++++++++++ docs/examples/exit-from-run/recipe.scif | 2 ++ scif/version.py | 2 +- 6 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 docs/examples/exit-from-run/Dockerfile create mode 100644 docs/examples/exit-from-run/README.md create mode 100644 docs/examples/exit-from-run/apptainer.def create mode 100644 docs/examples/exit-from-run/recipe.scif diff --git a/CHANGELOG.md b/CHANGELOG.md index ac847c9..f6db124 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ represented by the pull requests that fixed them. Versions in parentheses coincide with what is available on [pypi](https://pypi.org/project/scif/). ## [xxx](https://github.com/vsoch/scif/tree/master) (master) + - return exit code of app in run command (0.0.82) - install return value non zero should stop build (0.0.81) - removing Python less than 3.6 support (0.0.80) - code formatting with black, shell entrypoint bug (0.0.79) diff --git a/docs/examples/exit-from-run/Dockerfile b/docs/examples/exit-from-run/Dockerfile new file mode 100644 index 0000000..3907d3d --- /dev/null +++ b/docs/examples/exit-from-run/Dockerfile @@ -0,0 +1,22 @@ +# SciF Example +# +# docker build -f docs/examples/exit-from-run/Dockerfile -t scif-exit . + +FROM continuumio/miniconda3 + +####################################### +# SciF Install +####################################### + +# Can be replaced with pip install scif +RUN mkdir /code +ADD . /code +RUN python /code/setup.py install +ENV PATH=/opt/conda/bin:$PATH + +####################################### +# SciF Entrypoint +####################################### + +RUN scif install /code/docs/examples/exit-from-run/recipe.scif +ENTRYPOINT ["scif"] diff --git a/docs/examples/exit-from-run/README.md b/docs/examples/exit-from-run/README.md new file mode 100644 index 0000000..01ab87e --- /dev/null +++ b/docs/examples/exit-from-run/README.md @@ -0,0 +1,11 @@ +# Exit Code from run + +This should be built from the root of the repository as follows: + +```bash +apptainer build docs/examples/exit-from-run/apptainer.def scif.sif +apptainer run scif.sif run force_failure || echo "Got non-zero exit code: $? Success!" + +``` + + diff --git a/docs/examples/exit-from-run/apptainer.def b/docs/examples/exit-from-run/apptainer.def new file mode 100644 index 0000000..b0953c0 --- /dev/null +++ b/docs/examples/exit-from-run/apptainer.def @@ -0,0 +1,16 @@ +Bootstrap: docker +From: continuumio/miniconda3 + +# sudo singularity build scif.simg Singularity + +%runscript + exec /opt/conda/bin/scif "$@" + +%post + apt-get update && apt-get install -y git build-essential + + # Install SCIF + cd /opt && git clone https://www.github.com/vsoch/scif.git + cd scif + /opt/conda/bin/pip install setuptools + /opt/conda/bin/pip install -e . diff --git a/docs/examples/exit-from-run/recipe.scif b/docs/examples/exit-from-run/recipe.scif new file mode 100644 index 0000000..e654e0a --- /dev/null +++ b/docs/examples/exit-from-run/recipe.scif @@ -0,0 +1,2 @@ +%apprun force_fail + exit 155 diff --git a/scif/version.py b/scif/version.py index 4da0ced..1e3aa21 100644 --- a/scif/version.py +++ b/scif/version.py @@ -10,7 +10,7 @@ """ -__version__ = "0.0.81" +__version__ = "0.0.82" AUTHOR = "Vanessa Sochat" AUTHOR_EMAIL = "vsochat@stanford.edu" NAME = "scif" From 7f8c35706d6d1a86059bd66048dc183f4d5edff2 Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Tue, 23 Jan 2024 19:45:33 -0500 Subject: [PATCH 3/7] test/examples for exit-from-run --- docs/examples/exit-from-run/Dockerfile | 22 ---------------------- docs/examples/exit-from-run/README.md | 18 +++++++++++++++--- docs/examples/exit-from-run/apptainer.def | 9 ++++++--- docs/examples/exit-from-run/recipe.scif | 7 ++++++- 4 files changed, 27 insertions(+), 29 deletions(-) delete mode 100644 docs/examples/exit-from-run/Dockerfile diff --git a/docs/examples/exit-from-run/Dockerfile b/docs/examples/exit-from-run/Dockerfile deleted file mode 100644 index 3907d3d..0000000 --- a/docs/examples/exit-from-run/Dockerfile +++ /dev/null @@ -1,22 +0,0 @@ -# SciF Example -# -# docker build -f docs/examples/exit-from-run/Dockerfile -t scif-exit . - -FROM continuumio/miniconda3 - -####################################### -# SciF Install -####################################### - -# Can be replaced with pip install scif -RUN mkdir /code -ADD . /code -RUN python /code/setup.py install -ENV PATH=/opt/conda/bin:$PATH - -####################################### -# SciF Entrypoint -####################################### - -RUN scif install /code/docs/examples/exit-from-run/recipe.scif -ENTRYPOINT ["scif"] diff --git a/docs/examples/exit-from-run/README.md b/docs/examples/exit-from-run/README.md index 01ab87e..4434640 100644 --- a/docs/examples/exit-from-run/README.md +++ b/docs/examples/exit-from-run/README.md @@ -2,10 +2,22 @@ This should be built from the root of the repository as follows: -```bash -apptainer build docs/examples/exit-from-run/apptainer.def scif.sif -apptainer run scif.sif run force_failure || echo "Got non-zero exit code: $? Success!" +``` +# apptainer build scif.sif docs/examples/exit-from-run/apptainer.def +``` +The force_fail app returns exit code 155 +``` +# apptainer run scif.sif run force_fail ; echo "Out: $?" +[force_fail] executing /bin/bash /scif/apps/force_fail/scif/runscript +ERROR Return code 155 +Out: 155 ``` +The 'success' app returns exit code 0 +``` +$ apptainer run scif.sif run success ; echo "Out: $?" +[success] executing /bin/bash /scif/apps/success/scif/runscript +Out: 0 +``` diff --git a/docs/examples/exit-from-run/apptainer.def b/docs/examples/exit-from-run/apptainer.def index b0953c0..c91a714 100644 --- a/docs/examples/exit-from-run/apptainer.def +++ b/docs/examples/exit-from-run/apptainer.def @@ -1,16 +1,19 @@ Bootstrap: docker From: continuumio/miniconda3 -# sudo singularity build scif.simg Singularity +# apptainer build scif.simg docs/examples/exit-from-run/apptainer.def %runscript exec /opt/conda/bin/scif "$@" +%files + docs/examples/exit-from-run/recipe.scif /recipe.scif + . /opt/scif %post apt-get update && apt-get install -y git build-essential # Install SCIF - cd /opt && git clone https://www.github.com/vsoch/scif.git - cd scif + cd /opt/scif /opt/conda/bin/pip install setuptools /opt/conda/bin/pip install -e . + scif install /recipe.scif diff --git a/docs/examples/exit-from-run/recipe.scif b/docs/examples/exit-from-run/recipe.scif index e654e0a..db1eccb 100644 --- a/docs/examples/exit-from-run/recipe.scif +++ b/docs/examples/exit-from-run/recipe.scif @@ -1,2 +1,7 @@ %apprun force_fail - exit 155 +echo "Calling exit 155" +exit 155 + +%apprun success +echo "Running succes" +exit 0 From f7d04984fdc5fd09216f3d971aa0b2448d963a51 Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Wed, 24 Jan 2024 08:24:20 -0500 Subject: [PATCH 4/7] output even in non-interactive mode --- scif/main/commands.py | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/scif/main/commands.py b/scif/main/commands.py index 683cb05..600d4d2 100644 --- a/scif/main/commands.py +++ b/scif/main/commands.py @@ -16,7 +16,7 @@ import locale import sys import os - +import subprocess def _exec(self, app=None, interactive=False, exit=False): """exec is the underlying driver of both run and exec, taking a final @@ -90,11 +90,16 @@ def _exec(self, app=None, interactive=False, exit=False): os.system("".join(cmd)) else: - for line in os.popen(cmd): + child = subprocess.Popen(cmd, stdout=subprocess.PIPE) + streamdata = child.communicate()[0] + rc = child.returncode + for line in streamdata: try: print(line.rstrip()) except: print(line.rstrip().encode(loc)) + sys.exit(rc) + def execute(self, app, cmd=None, args=None): @@ -163,6 +168,7 @@ def run(self, app=None, args=None): args: a list of one or more additional arguments to pass to runscript """ + interactive = False config = self.app(app) if "apprun" not in config: bot.debug("%s does not have a runscript." % app) @@ -174,7 +180,8 @@ def run(self, app=None, args=None): # sets entrypoint # sets entryfolder - return self._exec(app, interactive=True, exit=True) + print(f"Run app: {app}") + return self._exec(app, interactive=interactive) def test(self, app=None, args=None): From 67ea1051bd326acb577c49a6095479b8bd37b75d Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Wed, 24 Jan 2024 09:26:05 -0500 Subject: [PATCH 5/7] output results for run() along with exit code --- docs/examples/exit-from-run/README.md | 10 ++++++---- docs/examples/exit-from-run/apptainer.def | 2 +- docs/examples/exit-from-run/recipe.scif | 2 +- scif/main/commands.py | 18 ++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/docs/examples/exit-from-run/README.md b/docs/examples/exit-from-run/README.md index 4434640..678f66b 100644 --- a/docs/examples/exit-from-run/README.md +++ b/docs/examples/exit-from-run/README.md @@ -8,16 +8,18 @@ This should be built from the root of the repository as follows: The force_fail app returns exit code 155 ``` -# apptainer run scif.sif run force_fail ; echo "Out: $?" +$ apptainer run scif.sif run force_fail ; echo "Exit Code: $?"; [force_fail] executing /bin/bash /scif/apps/force_fail/scif/runscript +Calling exit 155 ERROR Return code 155 -Out: 155 +Exit Code: 155 ``` The 'success' app returns exit code 0 ``` -$ apptainer run scif.sif run success ; echo "Out: $?" +$ apptainer run scif.sif run success ; echo "Exit Code: $?"; [success] executing /bin/bash /scif/apps/success/scif/runscript -Out: 0 +Running successfully +Exit Code: 0 ``` diff --git a/docs/examples/exit-from-run/apptainer.def b/docs/examples/exit-from-run/apptainer.def index c91a714..5e2db1b 100644 --- a/docs/examples/exit-from-run/apptainer.def +++ b/docs/examples/exit-from-run/apptainer.def @@ -15,5 +15,5 @@ From: continuumio/miniconda3 # Install SCIF cd /opt/scif /opt/conda/bin/pip install setuptools - /opt/conda/bin/pip install -e . + /opt/conda/bin/pip install . scif install /recipe.scif diff --git a/docs/examples/exit-from-run/recipe.scif b/docs/examples/exit-from-run/recipe.scif index db1eccb..7b703b4 100644 --- a/docs/examples/exit-from-run/recipe.scif +++ b/docs/examples/exit-from-run/recipe.scif @@ -3,5 +3,5 @@ echo "Calling exit 155" exit 155 %apprun success -echo "Running succes" +echo "Running successfully" exit 0 diff --git a/scif/main/commands.py b/scif/main/commands.py index 683cb05..4ae31ae 100644 --- a/scif/main/commands.py +++ b/scif/main/commands.py @@ -16,7 +16,7 @@ import locale import sys import os - +import subprocess def _exec(self, app=None, interactive=False, exit=False): """exec is the underlying driver of both run and exec, taking a final @@ -88,14 +88,12 @@ def _exec(self, app=None, interactive=False, exit=False): sys.exit(result["return_code"]) else: os.system("".join(cmd)) - else: - for line in os.popen(cmd): - try: - print(line.rstrip()) - except: - print(line.rstrip().encode(loc)) - + cmd = cmd.split(" ") + result = self._run_command( + cmd=cmd, spinner=False, quiet=False + ) + sys.exit(result["return_code"]) def execute(self, app, cmd=None, args=None): """execute a command in the context of an app. This means the following: @@ -163,6 +161,7 @@ def run(self, app=None, args=None): args: a list of one or more additional arguments to pass to runscript """ + interactive=False config = self.app(app) if "apprun" not in config: bot.debug("%s does not have a runscript." % app) @@ -173,8 +172,7 @@ def run(self, app=None, args=None): # updates environment # sets entrypoint # sets entryfolder - - return self._exec(app, interactive=True, exit=True) + return self._exec(app, interactive=interactive) def test(self, app=None, args=None): From 38aada5dd56d3c092565b665053d907cbec6427e Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Wed, 24 Jan 2024 09:33:39 -0500 Subject: [PATCH 6/7] remove unused import --- scif/main/commands.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scif/main/commands.py b/scif/main/commands.py index 04d3b5a..edbe9af 100644 --- a/scif/main/commands.py +++ b/scif/main/commands.py @@ -16,7 +16,6 @@ import locale import sys import os -import subprocess def _exec(self, app=None, interactive=False, exit=False): """exec is the underlying driver of both run and exec, taking a final From f31910d13f7e53ab8a88aeb7e3bc482902626dee Mon Sep 17 00:00:00 2001 From: Dustin Machi Date: Wed, 24 Jan 2024 14:35:44 -0500 Subject: [PATCH 7/7] fix formatting to match linter --- scif/main/commands.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scif/main/commands.py b/scif/main/commands.py index d5bc061..5dd1801 100644 --- a/scif/main/commands.py +++ b/scif/main/commands.py @@ -17,6 +17,7 @@ import sys import os + def _exec(self, app=None, interactive=False, exit=False): """exec is the underlying driver of both run and exec, taking a final SCIF and executing the command for the user. @@ -88,11 +89,10 @@ def _exec(self, app=None, interactive=False, exit=False): os.system("".join(cmd)) else: cmd = cmd.split(" ") - result = self._run_command( - cmd=cmd, spinner=False, quiet=False - ) + result = self._run_command(cmd=cmd, spinner=False, quiet=False) sys.exit(result["return_code"]) + def execute(self, app, cmd=None, args=None): """execute a command in the context of an app. This means the following: