def contain(command, image_name, image_dir, container_id, container_dir): linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None) # TODO: we added MS_REC here. wanna guess why? new_root = create_container_root(image_name, image_dir, container_id, container_dir) print('Created a new root fs for our container: {}'.format(new_root)) # Create mounts (/proc, /sys, /dev) under new_root linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '') linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '') linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs', linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755') # Add some basic devices devpts_path = os.path.join(new_root, 'dev', 'pts') if not os.path.exists(devpts_path): os.makedirs(devpts_path) linux.mount('devpts', devpts_path, 'devpts', 0, '') makedev(os.path.join(new_root, 'dev')) os.chroot(new_root) # TODO: replace with pivot_root os.chdir('/') # TODO: umount2 old root (HINT: see MNT_DETACH in man mount) os.execvp(command[0], command)
def contain(command, image_name, image_dir, container_id, container_dir): linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace # TODO: switch to a new UTS namespace, change hostname to container_id # HINT: use linux.sethostname() linux.unshare(linux.CLONE_NEWUTS) linux.sethostname(container_id) linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None) new_root = create_container_root(image_name, image_dir, container_id, container_dir) print('Created a new root fs for our container: {}'.format(new_root)) _create_mounts(new_root) old_root = os.path.join(new_root, 'old_root') os.makedirs(old_root) linux.pivot_root(new_root, old_root) os.chdir('/') linux.umount2('/old_root', linux.MNT_DETACH) # umount old root os.rmdir('/old_root') # rmdir the old_root dir os.execvp(command[0], command)
def test_unshare_net(): import os from pyLinux import linux pid = os.fork() if pid == 0: linux.unshare(linux.CLONE_NEWNET)
def contain(command, image_name, image_dir, container_id, container_dir): try: linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace except RuntimeError as e: if getattr(e, 'args', '') == (1, 'Operation not permitted'): print('Error: Use of CLONE_NEWNS with unshare(2) requires the ' 'CAP_SYS_ADMIN capability (i.e. you probably want to retry ' 'this with sudo)') raise e # TODO: we added MS_REC here. wanna guess why? linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None) new_root = create_container_root(image_name, image_dir, container_id, container_dir) print('Created a new root fs for our container: {}'.format(new_root)) def _create_mounts( new_root): # Create mounts (/proc, /sys, /dev) under new_root linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '') linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '') linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs', linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755') # Add some basic devices devpts_path = os.path.join(new_root, 'dev', 'pts') if not os.path.exists(devpts_path): os.makedirs(devpts_path) linux.mount('devpts', devpts_path, 'devpts', 0, '') makedev(os.path.join(new_root, 'dev')) _create_mounts(new_root) old_root = os.path.join(new_root, 'old_root') os.mkdirs(new_root) os.pivot_root(new_root, 'old_root') # TODO: replace with pivot_root os.chdir('/') linux.umount2("/old_root", linux.MNT_DETACH) linux.rm("/old_root") # TODO: umount2 old root (HINT: see MNT_DETACH in man 2 umount) os.execvp(command[0], command)
def contain(command, image_name, image_dir, container_id, container_dir): linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None) new_root = create_container_root(image_name, image_dir, container_id, container_dir) print('Created a new root fs for our container: {}'.format(new_root)) _create_mounts(new_root) old_root = os.path.join(new_root, 'old_root') os.makedirs(old_root) linux.pivot_root(new_root, old_root) os.chdir('/') linux.umount2('/old_root', linux.MNT_DETACH) # umount old root os.execvp(command[0], command)
def contain(command, image_name, image_dir, container_id, container_dir): linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace # TODO: switch to a new UTS namespace, change hostname to container_id # HINT: use linux.sethostname() linux.mount(None, "/", None, linux.MS_PRIVATE | linux.MS_REC, None) new_root = create_container_root(image_name, image_dir, container_id, container_dir) print("Created a new root fs for our container: {}".format(new_root)) _create_mounts(new_root) old_root = os.path.join(new_root, "old_root") os.makedirs(old_root) linux.pivot_root(new_root, old_root) os.chdir("/") linux.umount2("/old_root", linux.MNT_DETACH) # umount old root os.rmdir("/old_root") # rmdir the old_root dir os.execvp(command[0], command)
def test_unshare_mount(tmpdir): import os from pyLinux import linux def path_in_mounts(path): with open('/proc/mounts', 'r') as f: for line in f: line = line.strip() if path in line: return True return False path = os.path.join(str(tmpdir), 'meshde') os.makedirs(path) r, w = os.pipe() pid = os.fork() if pid == 0: os.close(r) w = os.fdopen(w, 'w') linux.unshare(linux.CLONE_NEWNS) linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None) linux.mount('tmpfs', path, 'tmpfs') assert path_in_mounts(path) w.write('I\'m done') w.close() else: os.close(w) r = os.fdopen(r) msg = r.read() print('Child sent:', msg) assert not path_in_mounts(path) return
def run(image_name, image_dir, container_dir, command): container_id = str(uuid.uuid4()) # TODO: Switching to a new PID namespace (using unshare) would only affect # the children of a process (because we can't change the PID of a # running process), so we'll have to unshare here OR replace # os.fork() with linux.clone() linux.unshare(linux.CLONE_NEWPID) pid = os.fork() if pid == 0: # This is the child, we'll try to do some containment here try: contain(command, image_name, image_dir, container_id, container_dir) except Exception: traceback.print_exc() os._exit(1) # something went wrong in contain() # This is the parent, pid contains the PID of the forked process # wait for the forked child, fetch the exit status _, status = os.waitpid(pid, 0) print('{} exited with status {}'.format(pid, status))
def contain(command, image_name, image_dir, container_id, container_dir): new_root = create_container_root(image_name, image_dir, container_id, container_dir) print('Created a new root fs for our container: {}'.format(new_root)) # TODO: time to say goodbye to the old mount namespace, # see "man 2 unshare" to get some help # HINT 1: there is no os.unshare(), time to use the linux module we made # just for you! # HINT 2: the linux module includes both functions and constants! # e.g. linux.CLONE_NEWNS linux.unshare(linux.CLONE_NEWNS) # TODO: remember shared subtrees? # (https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) # Make / a private mount to avoid littering our host mount table. linux.mount('/', os.path.join(new_root, '/'), 'proc', linux.MS_PRIVATE, '') # Create mounts (/proc, /sys, /dev) under new_root linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '') linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '') linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs', linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755') # Add some basic devices devpts_path = os.path.join(new_root, 'dev', 'pts') if not os.path.exists(devpts_path): os.makedirs(devpts_path) linux.mount('devpts', devpts_path, 'devpts', 0, '') for i, dev in enumerate(['stdin', 'stdout', 'stderr']): os.symlink('/proc/self/fd/%d' % i, os.path.join(new_root, 'dev', dev)) # TODO: add more devices (e.g. null, zero, random, urandom) using os.mknod. os.chroot(new_root) os.chdir('/') os.execvp(command[0], command)
def contain(cmd, cid): _set_cgroup_cpu(cid) _set_cgroup_memory(cid) linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace linux.unshare(linux.CLONE_NEWUTS) # create a new uts namespace linux.unshare(linux.CLONE_NEWNET) # create a new n/w namespace linux.sethostname(cid) # Use linux.clone in run() before fork and uncomment the above lines linux.mount(None, '/', None, linux.MS_REC | linux.MS_PRIVATE, None) new_root = create_container_root() print("New Root created.") # When using an already extracted image # linux.umount(os.path.join(new_root, 'proc')) # linux.umount(os.path.join(new_root, 'sys')) linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '') linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '') linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs', linux.MS_STRICTATIME | linux.MS_NOSUID, 'mode=755') # Add Basic Devices devs = os.path.join(new_root, 'dev', 'pts') if os.path.exists: pass else: os.makedirs(devs) linux.mount('devpts', devs, 'devpts', 0, '') _makedev(os.path.join(new_root, 'dev')) os.chroot(new_root) os.chdir("/") os.execvp(cmd[0], cmd)
def contain(command, image_name, image_dir, container_id, container_dir): linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace
pass def contain(command, image_name, image_dir, container_id, container_dir): new_root = create_container_root( image_name, image_dir, container_id, container_dir) print('Created a new root fs for our container: {}'.format(new_root)) # TODO: time to say goodbye to the old mount namespace, # see "man 2 unshare" to get some help # HINT 1: there is no os.unshare(), time to use the linux module we made # just for you! # HINT 2: the linux module includes both functions and constants! # e.g. linux.CLONE_NEWNS try: linux.unshare(linux.CLONE_NEWNS) # create a new mount namespace except RuntimeError as e: if getattr(e, 'args', '') == (1, 'Operation not permitted'): print('Error: Use of CLONE_NEWNS with unshare(2) requires the ' 'CAP_SYS_ADMIN capability (i.e. you probably want to retry ' 'this with sudo)') raise e linux.mount(None, "/", None, linux.MS_REC | linux.MS_PRIVATE) # TODO: remember shared subtrees? # (https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt) # Make / a private mount to avoid littering our host mount table. # Create mounts (/proc, /sys, /dev) under new_root linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '') linux.mount('sysfs', os.path.join(new_root, 'sys'), 'sysfs', 0, '') linux.mount('tmpfs', os.path.join(new_root, 'dev'), 'tmpfs',