mirror of
https://github.com/Stone-Red-Code/dvc.git
synced 2026-11-09 07:18:27 +01:00
When running from binary, we need to fixup environment variables before launching new processes. We also need to detach from the parent tty, because otherwise it causes problems for PyInstaller. Plus, when binary is built as --onefile it still creates pop-up terminal on windows, so we need to switch to --onedir. Fixes #1446 Fixes #1444 Signed-off-by: Ruslan Kuprieiev <[email protected]>
81 lines
2.1 KiB
Python
81 lines
2.1 KiB
Python
import os
|
|
import sys
|
|
from subprocess import Popen
|
|
|
|
from dvc.logger import logger
|
|
from dvc.utils import is_binary, fix_env
|
|
|
|
|
|
class Daemon(object): # pragma: no cover
|
|
def _spawn_windows(self, cmd):
|
|
from subprocess import STARTUPINFO, STARTF_USESHOWWINDOW
|
|
|
|
CREATE_NEW_PROCESS_GROUP = 0x00000200
|
|
DETACHED_PROCESS = 0x00000008
|
|
creationflags = CREATE_NEW_PROCESS_GROUP | DETACHED_PROCESS
|
|
|
|
startupinfo = STARTUPINFO()
|
|
startupinfo.dwFlags |= STARTF_USESHOWWINDOW
|
|
|
|
p = Popen(cmd,
|
|
env=fix_env(),
|
|
close_fds=True,
|
|
shell=False,
|
|
creationflags=creationflags,
|
|
startupinfo=startupinfo)
|
|
|
|
p.communicate()
|
|
|
|
def _spawn_posix(self, cmd):
|
|
# NOTE: using os._exit instead of sys.exit, because dvc built
|
|
# with PyInstaller has trouble with SystemExit exeption and throws
|
|
# errors such as "[26338] Failed to execute script __main__"
|
|
try:
|
|
pid = os.fork()
|
|
if pid > 0:
|
|
return
|
|
except OSError as exc:
|
|
logger.error("Failed at first fork", exc)
|
|
os._exit(1)
|
|
|
|
os.setsid()
|
|
os.umask(0)
|
|
|
|
try:
|
|
pid = os.fork()
|
|
if pid > 0:
|
|
os._exit(0)
|
|
except OSError as exc:
|
|
logger.error("Failed at second fork", exc)
|
|
os._exit(1)
|
|
|
|
sys.stdin.close()
|
|
sys.stdout.close()
|
|
sys.stderr.close()
|
|
|
|
p = Popen(cmd,
|
|
env=fix_env(),
|
|
close_fds=True,
|
|
shell=False)
|
|
|
|
p.communicate()
|
|
|
|
os._exit(0)
|
|
|
|
def __call__(self, args):
|
|
cmd = [sys.executable]
|
|
if not is_binary():
|
|
cmd += ['-m', 'dvc']
|
|
cmd += ['daemon', '-q'] + args
|
|
|
|
logger.debug("Trying to spawn '{}'".format(cmd))
|
|
|
|
if os.name == 'nt':
|
|
self._spawn_windows(cmd)
|
|
elif os.name == 'posix':
|
|
self._spawn_posix(cmd)
|
|
else:
|
|
raise NotImplementedError
|
|
|
|
logger.debug("Spawned '{}'".format(cmd))
|