Beispiel #1
0
def contain(command, image_name, image_dir, container_id, container_dir,
            cpu_shares, memory, memory_swap, user):
    _setup_cpu_cgroup(container_id, cpu_shares)
    _setup_memory_cgroup(container_id, memory, memory_swap)

    linux.sethostname(container_id)  # change hostname to 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

    # TODO: if user is set, drop privileges using os.setuid()
    #       (and optionally os.setgid()).

    os.execvp(command[0], command)
Beispiel #2
0
def contain(command, image_name, image_dir, container_id, container_dir,
            cpu_shares, memory, memory_swap):
    _setup_cpu_cgroup(container_id, cpu_shares)
    _setup_memory_cgroup(container_id, memory, memory_swap)

    # TODO: similarly to the CPU cgorup, add Memory cgroup support here
    #       setup memory -> memory.limit_in_bytes,
    #       memory_swap -> memory.memsw.limit_in_bytes if they are not None

    linux.sethostname(container_id)  # Change hostname to 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)
Beispiel #3
0
def contain(command, image_name, image_dir, container_id, container_dir,
            cpu_shares, memory, memory_swap, user):
    _setup_cpu_cgroup(container_id, cpu_shares)
    _setup_memory_cgroup(container_id, memory, memory_swap)

    linux.sethostname(container_id)  # change hostname to 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

    # TODO: if user is set, drop privileges using os.setuid()
    #       (and optionally os.setgid()).

    os.execvp(command[0], command)
Beispiel #4
0
def contain(command, image_name, image_dir, container_id, container_dir,
            cpu_shares):
    # TODO: insert the container to a new cpu cgroup named:
    #       'rubber_docker/container_id'

    # TODO: if (cpu_shares != 0)  => set the 'cpu.shares' in our cpu cgroup

    linux.sethostname(container_id)  # change hostname to 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)
Beispiel #5
0
def contain(command, image_name, image_dir, container_id, container_dir,
            cpu_shares):
    # TODO: insert the container to a new cpu cgroup named:
    #       'rubber_docker/container_id'
    _setup_cpu_cgroup(container_id, cpu_shares)

    # TODO: if (cpu_shares != 0)  => set the 'cpu.shares' in our cpu cgroup

    linux.sethostname(container_id)  # change hostname to 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)
Beispiel #6
0
def create_container_root(image_name, image_dir, container_id, container_dir):
    image_path = _get_image_path(image_name, image_dir)
    image_root = os.path.join(image_dir, image_name, 'rootfs')

    assert os.path.exists(image_path), "unable to locate image %s" % image_name

    if not os.path.exists(image_root):
        os.makedirs(image_root)
        with tarfile.open(image_path) as t:
            # Fun fact: tar files may contain *nix devices! *facepalm*
            t.extractall(image_root,
                         members=[m for m in t.getmembers() if m.type not in (tarfile.CHRTYPE, tarfile.BLKTYPE)])

    # create directories for copy-on-write (uppperdir), overlay workdir, and a mount point
    container_cow_rw = _get_container_path(container_id, container_dir, 'cow_rw')
    container_cow_workdir = _get_container_path(container_id, container_dir, 'cow_workdir')
    container_rootfs = _get_container_path(container_id, container_dir, 'rootfs')
    for d in (container_cow_rw, container_cow_workdir, container_rootfs):
        if not os.path.exists(d):
            os.makedirs(d)

            # mount the overlay (HINT: use the MS_NODEV flag to mount)
    linux.mount('overlay', container_rootfs, 'overlay',
                linux.MS_NODEV,
                "lowerdir={image_root},upperdir={cow_rw},workdir={cow_workdir}".format(
                    image_root=image_root,
                    cow_rw=container_cow_rw,
                    cow_workdir=container_cow_workdir))

    return container_rootfs  # return the mountpoint for the overlayfs
Beispiel #7
0
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)
Beispiel #8
0
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)
Beispiel #9
0
def contain(command, image_name, image_dir, container_id, container_dir,
            cpu_shares, memory, memory_swap):
    _setup_cpu_cgroup(container_id, cpu_shares)

    # TODO: similarly to the CPU cgorup, add Memory cgroup support here
    #       setup memory -> memory.limit_in_bytes,
    #       memory_swap -> memory.memsw.limit_in_bytes if they are not None

    linux.sethostname(container_id)  # Change hostname to 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 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)
Beispiel #11
0
def create_container_root(image_name, image_dir, container_id, container_dir):
    image_path = _get_image_path(image_name, image_dir)
    image_root = os.path.join(image_dir, image_name, 'rootfs')

    assert os.path.exists(image_path), "unable to locate image %s" % image_name

    if not os.path.exists(image_root):
        os.makedirs(image_root)
        with tarfile.open(image_path) as t:
            # Fun fact: tar files may contain *nix devices! *facepalm*
            t.extractall(image_root,
                         members=[m for m in t.getmembers() if m.type not in (tarfile.CHRTYPE, tarfile.BLKTYPE)])

    # create directories for copy-on-write (uppperdir), overlay workdir, and a mount point
    container_cow_rw = _get_container_path(container_id, container_dir, 'cow_rw')
    container_cow_workdir = _get_container_path(container_id, container_dir, 'cow_workdir')
    container_rootfs = _get_container_path(container_id, container_dir, 'rootfs')
    for d in (container_cow_rw, container_cow_workdir, container_rootfs):
        if not os.path.exists(d):
            os.makedirs(d)

            # mount the overlay (HINT: use the MS_NODEV flag to mount)
    linux.mount('overlay', container_rootfs, 'overlay',
                linux.MS_NODEV,
                "lowerdir={image_root},upperdir={cow_rw},workdir={cow_workdir}".format(
                    image_root=image_root,
                    cow_rw=container_cow_rw,
                    cow_workdir=container_cow_workdir))

    return container_rootfs  # return the mountpoint for the overlayfs
Beispiel #12
0
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))

    # Mount proc
    linux.mount(None, os.path.join(new_root, 'proc'), 'proc', 0, None)

    os.chroot(new_root)
    os.chdir('/')

    os.execvp(command[0], command)
Beispiel #13
0
def contain(command, image_name, image_dir, container_id, container_dir):
    # TODO: would you like to do something before chrooting?
    # print('Created a new root fs for our container: {}'.format(new_root))
    new_root = create_container_root(image_name, image_dir, container_id, container_dir)
    linux.mount( 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'))
    # TODO: chroot into new_root
    # TODO: something after chrooting? (HINT: try running: sudo python rd.py run -i ubuntu -- /bin/sh)

    os.execvp(command[0], command)
Beispiel #14
0
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 include both functions and constants! e.g. 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

    # 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 device (e.g. null, zero, random, urandom) using os.mknode

    os.chroot(new_root)

    os.chdir('/')

    os.execvp(command[0], command)
Beispiel #15
0
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 include both functions and constants! e.g. linux.CLONE_NEWNS

    # TODO: remember shared subtrees? (https://www.kernel.org/doc/Documentation/filesystems/sharedsubtree.txt)
    #       remount / as 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',
                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 device (e.g. null, zero, random, urandom) using os.mknode

    os.chroot(new_root)

    os.chdir('/')

    os.execvp(command[0], command)
Beispiel #16
0
    def _init_system_dir(self, container_root_dir: str):
        """
        システム用のディレクトリを初期化する
        :param container_root_dir:
        :return:
        """
        proc_dir = os.path.join(container_root_dir, 'proc')
        sysfs_dir = os.path.join(container_root_dir, 'sys')
        dev_dir = os.path.join(container_root_dir, 'dev')
        for d in (proc_dir, sysfs_dir, dev_dir):
            if not os.path.exists(d):
                os.makedirs(d)

        # コンテナのルートディレクトリ配下に /proc, /sys, /dev をマウントする
        linux.mount('proc', proc_dir, 'proc', 0, '')
        linux.mount('sysfs', sysfs_dir, 'sysfs', 0, '')
        linux.mount('tmpfs', dev_dir, 'tmpfs',
                    linux.MS_NOSUID | linux.MS_STRICTATIME, 'mode=755')

        # デバイスをマウントする
        devpts_path = os.path.join(container_root_dir, 'dev', 'pts')
        if not os.path.exists(devpts_path):
            os.makedirs(devpts_path)
            linux.mount('devpts', devpts_path, 'devpts', 0, '')

        self._init_devices(os.path.join(container_root_dir, 'dev'))
Beispiel #17
0
    def _mount_image_dir(self, image: Image, container_dir: ContainerDir):
        """
        Docker イメージをマウントする
        :param image:
        :param container_dir:
        :return:
        """
        image_path = self._get_image_base_path(image, self.IMAGE_DATA_DIR)
        image_root = os.path.join(image_path, 'layers/contents')

        # オーバーレイ FS としてマウントする
        linux.mount(
            'overlay', container_dir.root_dir, 'overlay', linux.MS_NODEV,
            f"lowerdir={image_root},upperdir={container_dir.rw_dir},workdir={container_dir.work_dir}"
        )
Beispiel #18
0
def create_container_root(image_name, image_dir, container_id, container_dir):
    image_path = _get_image_path(image_name, image_dir)
    container_root = _get_container_path(container_id, container_dir, 'rootfs')

    assert os.path.exists(image_path), "unable to locate image %s" % image_name

    if not os.path.exists(container_root):
        os.makedirs(container_root)
        linux.mount('tmpfs', container_root, 'tmpfs', 0, None)

    with tarfile.open(image_path) as t:
        # Fun fact: tar files may contain *nix devices! *facepalm*
        members = [m for m in t.getmembers()
                   if m.type not in (tarfile.CHRTYPE, tarfile.BLKTYPE)]
        t.extractall(container_root, members=members)

    return container_root
Beispiel #19
0
def test_mount(tmpdir):
    import linux
    import os

    proc = str(tmpdir.mkdir('proc'))
    tmp = str(tmpdir.mkdir('tmp'))
    syspath = str(tmpdir.mkdir('sys'))

    assert linux.mount('proc', proc, 'proc') == 0
    assert linux.mount('tmpfs', tmp, 'tmpfs') == 0
    assert linux.mount('sysfs', syspath, 'sysfs') == 0

    # assert proc == ''

    assert os.listdir(proc) == os.listdir('/proc')
    assert os.listdir(syspath) == os.listdir('/sys')
    return
Beispiel #20
0
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)
Beispiel #21
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.sethostname(container_id)  # change hostname to 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.execvp(command[0], command)
Beispiel #22
0
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.rmdir('/old_root') # rmdir the old_root dir
    os.execvp(command[0], command)
Beispiel #23
0
def contain(command, image_name, image_dir, container_id, container_dir):
    linux.sethostname(container_id)  # change hostname to 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)
Beispiel #24
0
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"))
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)
Beispiel #26
0
def create_container_root(image_name, image_dir, container_id, container_dir):
    image_path = _get_image_path(image_name, image_dir)
    container_root = _get_container_path(container_id, container_dir, 'rootfs')

    assert os.path.exists(image_path), "unable to locate image %s" % image_name

    if not os.path.exists(container_root):
        os.makedirs(container_root)

    # TODO: uncomment (why?)
    linux.mount('tmpfs', container_root, 'tmpfs', 0, None)

    with tarfile.open(image_path) as t:
        # Fun fact: tar files may contain *nix devices! *facepalm*
        members = [
            m for m in t.getmembers()
            if m.type not in (tarfile.CHRTYPE, tarfile.BLKTYPE)
        ]
        t.extractall(container_root, members=members)

    return container_root
Beispiel #27
0
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'))
Beispiel #28
0
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'))
Beispiel #29
0
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)
Beispiel #30
0
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
Beispiel #31
0
    def execute(self, init_params: ContainerInitParams):
        """
        指定されたパラメータでコンテナを起動する
        :param init_params:
        :return:
        """
        # ホスト名をコンテナ ID にする
        linux.sethostname(init_params.container_id)

        # ホストのマウントテーブルを汚さないように / をプライベートマウントする
        linux.mount(None, '/', None, linux.MS_PRIVATE | linux.MS_REC, None)

        # コンテナのディレクトリを初期化し、ルートディレクトリを変更する
        container_dir = self._create_container_root_dir(
            init_params.container_id)
        print(f'Created a new root fs for our container: {container_dir}')
        self._mount_image_dir(init_params.image, container_dir)
        self._init_system_dir(container_dir.root_dir)
        self._change_root_dir(container_dir.root_dir)

        # コンテナでコマンドを実行する
        os.execvp(init_params.command[0], init_params.command)
Beispiel #32
0
 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')
def _create_mounts(new_root):
    # Create mounts (/proc, /sys, /dev) under new_root
    linux.mount('proc', os.path.join(new_root, 'proc'), 'proc', 0, '')
    # 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',
                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']):