summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Maw <richard.maw@gmail.com>2014-10-15 17:47:46 +0000
committerRichard Maw <richard.maw@gmail.com>2014-10-15 18:14:49 +0000
commit048f117a45a37237894aa7e20ddf92ee14a47fc9 (patch)
treede9807db8dfd1340e3f8a180e5fae8d0398bbf6e
parent61291bd59fcefdbfcbaf0a50e46e071ccee52fcf (diff)
downloadmorph-048f117a45a37237894aa7e20ddf92ee14a47fc9.tar.gz
deploy extensions: Don't crash if someone builds at the same time
If a build happens, it creates a new network namespace, and if this happens while you have a disk image mounted, then you can't remove the mount-point, because the other namespace is using it. We can avoid the other namespace keeping this mount-point open by creating the disk image in a private mount namespace, so it never sees it. The nicest way to do this is to have every extension run in a private mount namespace, since you'd have to have extensions re-exec themselves, since the appropriate system calls aren't exposed very well.
-rw-r--r--morphlib/extensions.py4
1 files changed, 3 insertions, 1 deletions
diff --git a/morphlib/extensions.py b/morphlib/extensions.py
index af6ba279..ef233b6f 100644
--- a/morphlib/extensions.py
+++ b/morphlib/extensions.py
@@ -223,7 +223,9 @@ class ExtensionSubprocess(object):
def close_read_end():
os.close(log_read_fd)
p = subprocess.Popen(
- [filename] + args, cwd=cwd, env=new_env,
+ ['unshare', '-m', '--', '/bin/sh', '-c',
+ 'mount --make-rprivate / && exec "$@"', '-', filename] + args,
+ cwd=cwd, env=new_env,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
preexec_fn=close_read_end)
os.close(log_write_fd)