-
Notifications
You must be signed in to change notification settings - Fork 203
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
implement new run_shell_cmd
function with cleaner API to replace run_cmd
+ run_cmd_qa
#4252
Comments
I had a quick brainstorm on this with @lexming, here's the plan we came up with... Goals
Current
|
So, initial condition for this to even be considered is that we are about the abort:
But additionally:
if sys.stdout.isatty() and shell_on_fail and cfg.shell_on_fail:
print("Dropping into debug shell, exit to return")
pty.spawn('bash') edit: maybe the global config option should be the name of the shell used? to allow for bash/sh/zsh or whatever? if sys.stdout.isatty() and !no_shell_on_fail and cfg.shell_on_fail is not None:
print("Dropping into debug shell, exit to return")
pty.spawn(cfg.shell_on_fail) edit: or maybe if sys.stdout.isatty() and shell_on_fail and cfg.shell_on_fail:
print("Dropping into debug shell, exit to return")
pty.spawn(os.environ.get('SHELL'))
) and maybe we should avoid sourcing the environment for the user. Might be hard to support arbitrary shells though. if sys.stdout.isatty() and shell_on_fail and cfg.shell_on_fail:
print("Dropping into debug shell, exit to return")
os.environ['PS1'] = 'EB debug shell@\h# '
pty.spawn(['bash', '--noprofile', '--norc']) |
Dropping into a totally new shell might not be very useful. We can manually replicate the initial build environment but we will never know what was the environment at the time of the crash. Imagine, for instance, something in the build scripts of the software altering We should instead first create a new shell, run the commands in it and if anything fails drop the user into that same shell. Not tested, but something as follows might work: # create pseudo-terminal
master_fd, slave_fd = pty.openpty()
# run command in it
_log.info(f"Running command '{cmd_msg}' in {work_dir}")
proc = subprocess.run(cmd, stdin=slave_fd, stdout=slave_fd, stderr=slave_fd)
# drop user into it if fail
if sys.stdout.isatty() and shell_on_fail and cfg.shell_on_fail:
print("Dropping into debug shell, exit to return")
pty.spawn(os.environ.get('SHELL'), master_fd, slave_fd) |
is it? It would drop you into the exact same environment from which the command ran, as if you had done all the steps of the easyblock manually so far. All environment variables that EB sets by default + whatever the easyblock has done up til now, and you'd see something like the last command that failed:
one could then easily try a few different configure flags, or whatever i might need to find a solution to whatever failed.
But running a script, or any program, won't affect the parent shell it was executed from. The only difference i see you could ever make is to include the extra exports (which you would see from the command which just ran) that we often put into the command string. I tried to investigate how it behaves with a small script, but pty.spawn doesn't handle actually take those arguments as such so that spawn just breaks the terminal. Couldn't figure out how it would work. |
Well, part of it was to add some flag for this run interface. I suggest |
run
function with cleaner API to replace run_cmd
+ run_cmd_qa
run_shell_cmd
function with cleaner API to replace run_cmd
+ run_cmd_qa
Note: |
The current
run_cmd
andrun_cmd_qa
functions have a very confusing API, and their implementation is ancient (dates back from a time when we still supported Python 2.4).We should implement a new
run
function, which supports running both interactive and non-interactive commands, as well as more advanced features like running a command asynchronously, and providing support to drop into an interactive shell when a command failed.The text was updated successfully, but these errors were encountered: