|
@@ -35,6 +35,7 @@ import select
|
|
|
import shutil
|
|
|
import subprocess
|
|
|
import sys
|
|
|
+import threading
|
|
|
|
|
|
# default locale
|
|
|
# will be used for all non-explicitly set LC_* variables
|
|
@@ -76,6 +77,36 @@ $TERMCMD = os.path.join(os.path.dirname(__file__), 'ranger-termite-termcmd')
|
|
|
# https://docs.docker.com/engine/security/trust/content_trust/
|
|
|
$DOCKER_CONTENT_TRUST = 1
|
|
|
|
|
|
+class StdoutTee:
|
|
|
+
|
|
|
+ def __init__(self, sink):
|
|
|
+ self._sink = sink
|
|
|
+
|
|
|
+ def __enter__(self):
|
|
|
+ self._read_fd, self._write_fd = os.pipe()
|
|
|
+ self._thread = threading.Thread(target=self._loop)
|
|
|
+ self._thread.start()
|
|
|
+ return self
|
|
|
+
|
|
|
+ def _loop(self):
|
|
|
+ while True:
|
|
|
+ try:
|
|
|
+ data = os_read_non_blocking(self._read_fd)
|
|
|
+ except OSError: # fd closed
|
|
|
+ return
|
|
|
+ if data:
|
|
|
+ self._sink.write(data)
|
|
|
+ sys.stdout.buffer.write(data)
|
|
|
+ sys.stdout.flush()
|
|
|
+
|
|
|
+ def fileno(self):
|
|
|
+ return self._write_fd
|
|
|
+
|
|
|
+ def __exit__(self, exc_type, exc_value, traceback):
|
|
|
+ os.close(self._read_fd)
|
|
|
+ os.close(self._write_fd)
|
|
|
+ self._thread.join()
|
|
|
+
|
|
|
def dpkg_listfiles(pkg_name):
|
|
|
assert isinstance(pkg_name, str)
|
|
|
paths = $(dpkg --listfiles @(pkg_name)).split('\n')[:-1]
|