Put a hole in the sandbox once. Not once per worker.

This commit is contained in:
Andrew Hamilton 2016-03-12 23:16:52 +00:00
parent ccdd89fa28
commit 6455271aa0
3 changed files with 21 additions and 17 deletions

23
vigil
View file

@ -878,6 +878,15 @@ def _update_screen(main_widget, appearance_changed_event):
fill3.patch_screen(main_widget) fill3.patch_screen(main_widget)
def make_sandbox(mount_point):
sandbox = sandbox_fs.SandboxFs(mount_point)
sandbox.mount()
cache_path = os.path.join(os.getcwd(), tools.CACHE_PATH)
subprocess.check_call(["sudo", "mount", "--bind", cache_path,
mount_point + cache_path])
return sandbox
def main(root_path, loop, worker_count=None, is_sandboxed=True, def main(root_path, loop, worker_count=None, is_sandboxed=True,
editor_command=None, is_being_tested=False): editor_command=None, is_being_tested=False):
if worker_count is None: if worker_count is None:
@ -917,18 +926,15 @@ def main(root_path, loop, worker_count=None, is_sandboxed=True,
watch_manager_fd = _add_watch_manager_to_mainloop( watch_manager_fd = _add_watch_manager_to_mainloop(
root_path, loop, on_filesystem_change, _is_path_excluded) root_path, loop, on_filesystem_change, _is_path_excluded)
screen.workers = workers = [] screen.workers = workers = []
if is_sandboxed:
sandbox_temp_dir = tempfile.mkdtemp()
sandbox = sandbox_fs.SandboxFs(sandbox_temp_dir)
else:
sandbox = None
try:
if is_sandboxed: if is_sandboxed:
log.log_message("Making filesystem sandbox...") log.log_message("Making filesystem sandbox...")
sandbox.mount() sandbox_temp_dir = tempfile.mkdtemp()
sandbox = make_sandbox(sandbox_temp_dir)
log.log_message("Sandbox made.") log.log_message("Sandbox made.")
else: else:
log.log_message("Running without the filesystem sandbox...") log.log_message("Running without the filesystem sandbox...")
sandbox = None
try:
log.log_message("Starting workers (%s) ..." % worker_count) log.log_message("Starting workers (%s) ..." % worker_count)
for index in range(worker_count): for index in range(worker_count):
worker_ = worker.Worker(sandbox, screen._is_paused, is_being_tested) worker_ = worker.Worker(sandbox, screen._is_paused, is_being_tested)
@ -980,6 +986,9 @@ def main(root_path, loop, worker_count=None, is_sandboxed=True,
tools.dump_pickle_safe(screen, pickle_path, open=open_compressed) tools.dump_pickle_safe(screen, pickle_path, open=open_compressed)
finally: finally:
if is_sandboxed: if is_sandboxed:
cache_path = os.path.join(os.getcwd(), tools.CACHE_PATH)
subprocess.check_call(["sudo", "umount",
sandbox.mount_point + cache_path])
sandbox.umount() sandbox.umount()
os.rmdir(sandbox_temp_dir) os.rmdir(sandbox_temp_dir)
loop.remove_reader(watch_manager_fd) loop.remove_reader(watch_manager_fd)

View file

@ -31,14 +31,9 @@ class Worker:
@asyncio.coroutine @asyncio.coroutine
def create_process(self): def create_process(self):
if self.sandbox is None:
command = [__file__] command = [__file__]
else: if self.sandbox is not None:
cache_path = os.path.join(os.getcwd(), tools.CACHE_PATH) command = self.sandbox.command(command)
cache_mount = self.sandbox.mount_point + cache_path
subprocess.check_call(["sudo", "mount", "--bind", cache_path,
cache_mount])
command = self.sandbox.command([__file__])
create = asyncio.create_subprocess_exec( create = asyncio.create_subprocess_exec(
*command, stdin=asyncio.subprocess.PIPE, *command, stdin=asyncio.subprocess.PIPE,
stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE) stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)

View file

@ -12,6 +12,7 @@ import unittest
import sandbox_fs import sandbox_fs
import tools import tools
import vigil
import worker import worker
@ -43,8 +44,7 @@ class WorkerTestCase(unittest.TestCase):
def test_run_job_with_sandbox(self): def test_run_job_with_sandbox(self):
temp_dir = tempfile.mkdtemp() temp_dir = tempfile.mkdtemp()
sandbox = sandbox_fs.SandboxFs(temp_dir) sandbox = vigil.make_sandbox(temp_dir)
sandbox.mount()
try: try:
self._test_worker(sandbox) self._test_worker(sandbox)
finally: finally: