Skip to content

Commit b57dac6

Browse files
committed
allow execution without tty
1 parent b2de18e commit b57dac6

1 file changed

Lines changed: 37 additions & 9 deletions

File tree

docker_util.py

Lines changed: 37 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import os.path
22
import pty
33
import select
4+
import subprocess
45
import sys
56
import termios
67
import tty
@@ -179,16 +180,21 @@ def remove_volume(self, volume_name: str):
179180
if volume.name == volume_name:
180181
volume.remove(True)
181182

182-
def exec_docker_subprocess(self, container: Container, command: Command = None, attributes: List = None) -> int:
183-
old_tty = termios.tcgetattr(sys.stdin)
184-
tty.setraw(sys.stdin.fileno())
183+
def exec_docker_subprocess(self, container, command: Command = None, attributes: List = None) -> int:
184+
try:
185+
old_tty = termios.tcgetattr(sys.stdin)
186+
tty.setraw(sys.stdin.fileno())
187+
return self.exec_docker_subprocess_tty(old_tty, container, command, attributes)
188+
except termios.error:
189+
return self.exec_docker_subprocess_stdout_pipe(container, command, attributes)
185190

186-
# open pseudo-terminal to interact with subprocess
187-
master_fd, slave_fd = pty.openpty()
191+
def exec_docker_subprocess_tty(self, old_tty, container, command: Command = None, attributes: List = None):
188192
try:
193+
# open pseudo-terminal to interact with subprocess
194+
master_fd, slave_fd = pty.openpty()
189195
# use os.setsid() make it run in a new process group, or bash job control will not be enabled
190196
p = Popen(
191-
self.build_command(container, command, attributes),
197+
self.build_command(container, command, attributes, _tty=True),
192198
preexec_fn=os.setsid,
193199
stdin=slave_fd,
194200
stdout=slave_fd,
@@ -197,7 +203,7 @@ def exec_docker_subprocess(self, container: Container, command: Command = None,
197203
)
198204

199205
while p.poll() is None:
200-
r, w, e = select.select([sys.stdin, master_fd], [], [], 0.5)
206+
r, w, e = select.select([sys.stdin, master_fd], [], [], 0.2)
201207
if sys.stdin in r:
202208
d = os.read(sys.stdin.fileno(), 10240)
203209
os.write(master_fd, d)
@@ -210,7 +216,28 @@ def exec_docker_subprocess(self, container: Container, command: Command = None,
210216
termios.tcsetattr(sys.stdin, termios.TCSADRAIN, old_tty)
211217
return p.poll()
212218

213-
def build_command(self, container: Container, command: Command = None, attributes: List = None) -> List[str]:
219+
def exec_docker_subprocess_stdout_pipe(self, container, command: Command = None, attributes: List = None):
220+
process = subprocess.Popen(
221+
self.build_command(container, command, attributes, _tty=False),
222+
preexec_fn=os.setsid,
223+
stdout=subprocess.PIPE,
224+
universal_newlines=True
225+
)
226+
while True:
227+
output = process.stdout.readline()
228+
if output == '' and process.poll() is not None:
229+
break
230+
if output:
231+
print(output.strip())
232+
return process.poll()
233+
234+
def build_command(
235+
self,
236+
container: Container,
237+
command: Command = None,
238+
attributes: List = None,
239+
_tty: bool = True
240+
) -> List[str]:
214241
if attributes is None:
215242
attributes = []
216243

@@ -223,11 +250,12 @@ def build_command(self, container: Container, command: Command = None, attribute
223250
cmd_base = [
224251
'docker',
225252
'run',
226-
'-it',
227253
'--pid=host',
228254
'--rm',
229255
'--name=' + self.get_container_name(container),
230256
]
257+
if _tty:
258+
cmd_base = cmd_base + ['-it']
231259
cmd_base = cmd_base + self.build_docker_run_arguments(container)
232260
return cmd_base + [
233261
container.image,

0 commit comments

Comments
 (0)