'Operation not supported by device' in getpass with parallel #510

Closed
bitprophet opened this Issue Dec 19, 2011 · 2 comments

Projects

None yet

1 participant

@bitprophet
Member

I consistently get Operation not supported by device terminal errors when running fab -P -H <host_using_ssh_key>,<host_requring_password>.) Was trying to reproduce #493 but this appears totally unrelated.

Stacktrace:

» fab -P --linewise -H localhost,localhost:2202 -- ls                                                                                                          1
[localhost] Executing task '<remainder>'
[localhost:2202] Executing task '<remainder>'
[localhost:2202] run: ls
[localhost] run: ls
Process localhost:2202:
Traceback (most recent call last):
  File "/Users/jforcier/.virtualenvs/fabric/lib/python2.5/site-packages/multiprocessing/process.py", line 237, in _bootstrap
    self.run()
  File "/Users/jforcier/.virtualenvs/fabric/lib/python2.5/site-packages/multiprocessing/process.py", line 93, in run
    self._target(*self._args, **self._kwargs)
  File "/Users/jforcier/Documents/Code/fabric/fabric/tasks.py", line 222, in inner
    task.run(*args, **kwargs)
  File "/Users/jforcier/Documents/Code/fabric/fabric/tasks.py", line 105, in run
    return self.wrapped(*args, **kwargs)
  File "/Users/jforcier/Documents/Code/fabric/fabric/main.py", line 664, in <lambda>
    state.commands[r] = lambda: api.run(remainder_command)
  File "/Users/jforcier/Documents/Code/fabric/fabric/network.py", line 343, in host_prompting_wrapper
    return func(*args, **kwargs)
  File "/Users/jforcier/Documents/Code/fabric/fabric/operations.py", line 948, in run
    return _run_command(command, shell, pty, combine_stderr)
  File "/Users/jforcier/Documents/Code/fabric/fabric/operations.py", line 866, in _run_command
    stdout, stderr, status = _execute(default_channel(), wrapped_command, pty,
  File "/Users/jforcier/Documents/Code/fabric/fabric/state.py", line 326, in default_channel
    chan = connections[env.host_string].get_transport().open_session()
  File "/Users/jforcier/Documents/Code/fabric/fabric/network.py", line 74, in __getitem__
    self[real_key] = connect(user, host, port)
  File "/Users/jforcier/Documents/Code/fabric/fabric/network.py", line 260, in connect
    password = prompt_for_password(text)
  File "/Users/jforcier/Documents/Code/fabric/fabric/network.py", line 308, in prompt_for_password
    new_password = getpass.getpass(password_prompt, stream)
  File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/getpass.py", line 32, in unix_getpass
    old = termios.tcgetattr(fd)     # a copy to save
error: (19, 'Operation not supported by device')

I seem to recall others mentioning this, probably on IRC, but I cannot find anything in the tracker about it so here this is.

@bitprophet bitprophet was assigned Dec 19, 2011
@bitprophet
Member

The problem is that sys.stdin is, at this point, set to go to /dev/null, which doesn't support the sorts of operations getpass is trying to do with that termios.tcgetattr call.

In serial operation it works fine because sys.stdin is unaltered and still points to <open file '<stdin>' / 0>.

I assume this is due to how multiprocess handles child pipes (i.e. it makes no sense for stdin to "work" in parallel mode -- where should it go?), though if we're doing something "wrong" there it feels like a big oversight, so maybe something else is afoot.

@bitprophet
Member

Think best solution is to explicitly abort with the "hey, you're in parallel mode, no prompts for you" reason. (alternate would be to auto-flip abort_on_prompts to True, but then the error message isn't specific enough.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment