Beispiel #1
0
def create(config_path):
    """
    create a container from config
    :param config_path: path to config yaml
    """
    config = Config(config_path)
    base_image = config.args['image']
    container_id = str(uuid.uuid4())

    console.log('creating a new container (%s)' % container_id)

    # setup the cgroup
    cg = cgroups.Cgroup(container_id)
    if 'limit' in config.args.keys():
        if 'cpu' in config.args['limit'].keys():
            cg.set_cpu_limit(config.args['limit']['cpu'])
        if 'mem' in config.args['limit'].keys():
            cg.set_memory_limit(config.args['limit']['mem'])

    # file system tasks
    console.log('Spinning up a filesystem...')
    fs.setup_fs(base_image, container_id)

    for item in config.args.get('copy', []):
        console.log(f'{container_id}: copying {item["src"]} to {item["dest"]}')
        fs.copy_to_container(item['src'], item['dest'], container_id)

    # run commands if applicable
    commands = config.args.get('run', [])
    environment = dict(defaults.ENVIRONMENT, **config.args.get('env', {}))

    if len(commands) > 0:
        pocket_run.run(container_id, commands, environment)
Beispiel #2
0
def rm(pid):
    """
    remove a pocket with pocket id
    :param pid: pocket id
    """
    cg = cgroups.Cgroup(pid)
    cg.delete()
    fs.clean_fs(pid)
Beispiel #3
0
 def put_in_cgroup():
     try:
         print("exec :: put_in_cgroup :: Putting process in Cgroup...")
         pid = os.getpid()
         print("exec :: put_in_cgroup :: pid={}".format(pid))
         cg = cgroups.Cgroup(container_id)
         cg.add(pid)
         print("exec :: put_in_cgroup :: Successfully put process in Cgroup.")
     except Exception as e:
         print("exec :: put_in_cgroup :: Failed to put process in Cgroup.")
         traceback.print_exc()
Beispiel #4
0
def Rm(container_id, **kwargs):
    try:
        for image_id in os.listdir('/var/myOwnDocker/ps/{0}'.format(container_id)):
            if image_id.endswith('.log'):
                shutil.rm(os.path.join('/var/myOwnDocker/ps/{0}'.format(container_id), image_id))
            else:
                subprocess.run(['btrfs', 'subvolume', 'delete', '/var/myOwnDocker/ps/{0}/{1}'.format(container_id, image_id)], check=True)
        cg = cgroups.Cgroup(container_id)
        cg.delete()
        print("rm :: Successfully deleted container with id {0}".format(container_id))
    except Exception as e:
        print("rm :: Failed to delete container with id {0}".format(container_id))
        traceback.print_exc()
    shutil.rmtree('/var/myOwnDocker/ps/{0}'.format(container_id), ignore_errors=True)
Beispiel #5
0
def Exec(container_id, command, **kwargs):
    try:
        containers = Ps()
        if container_id not in containers:
            raise Exception("No container with id {0}".format(container_id))
        
        try:
            cg = cgroups.Cgroup(container_id)
        except Exception as e:
            raise Exception("Container with id {0} is not running".format(container_id))


        def put_in_cgroup():
            try:
                print("exec :: put_in_cgroup :: Putting process in Cgroup...")
                pid = os.getpid()
                print("exec :: put_in_cgroup :: pid={}".format(pid))
                cg = cgroups.Cgroup(container_id)
                cg.add(pid)
                print("exec :: put_in_cgroup :: Successfully put process in Cgroup.")
            except Exception as e:
                print("exec :: put_in_cgroup :: Failed to put process in Cgroup.")
                traceback.print_exc()

        print("exec :: Running command {1} in container with id {0}...".format(container_id, command))

        process = subprocess.run([command], 
            preexec_fn=put_in_cgroup, 
            universal_newlines=True, 
            check=True,
            executable='/bin/bash')
        out, err = process.stdout, process.stderr
        if out is None:
            out = ""
        if err is None:
            err = ""

        with open(os.path.join('/var/myOwnDocker/ps/{0}'.format(container_id), 'out.log'), 'a') as f:
            f.write(out + '\n')
        with open(os.path.join('/var/myOwnDocker/ps/{0}'.format(container_id), 'err.log'), 'a') as f:
            f.write(err + '\n')

        print("exec :: Command {1} ran successfully in container with id {0}.".format(container_id, command))
    
    except Exception as e:
        print("exec :: Failed to run command {1} in container with id {0}.".format(container_id, command))
        traceback.print_exc()
Beispiel #6
0
def run(container_id, commands, environment=None):
    """
    run commands in a container that has already been created
    :param container_id: container id
    :param commands: list of commands to execute
    :param environment: dictionary of key-value pairs
    """
    if environment is None:
        environment = {}

    if not os.path.exists(fs.get_path_to_container(container_id)):
        console.error("Container does not exist")
        return

    pid = os.fork()
    if pid == 0:
        # container process
        console.log('Pocket starting with process-id: %d' % os.getpid())

        cgroups.Cgroup(container_id).add(os.getpid())
        os.chroot(fs.get_path_to_container(container_id))
        os.chdir('/')

        unshare.unshare(unshare.CLONE_NEWUTS | unshare.CLONE_NEWNS
                        | unshare.CLONE_NEWPID)

        pid2 = os.fork()
        if pid2 == 0:
            fs.mount("/proc", "/proc", "proc")
            os.system(f'/bin/hostname {container_id}')
            # execute the commands
            for command in commands:
                console.log(f'{container_id}: executing - {command}')
                os.execve(
                    command.split(" ")[0], command.split(" "), environment)
        else:
            os.waitpid(pid2, 0)
    else:
        _, status = os.waitpid(pid, 0)
        fs.unmount(os.path.join(fs.get_path_to_container(container_id),
                                "proc"))
        console.log(f'Pocket pid: {pid} exited with status {status}')
Beispiel #7
0
 def put_in_cgroup():
     try:
         print(
             "run :: put_in_cgroup :: Putting process in Cgroup..."
         )
         pid = os.getpid()
         print("run :: put_in_cgroup :: pid={}".format(pid))
         cg = cgroups.Cgroup(uuid)
         cg.add(pid)
         print("run :: put_in_cgroup :: Added pid in Cgroup.")
         pyroute2.netns.setns(netns_name)
         print("run :: put_in_cgroup :: Isolated NetNS.")
         os.chdir(new_root_path)
         os.chroot(new_root_path)
         print(
             "run :: put_in_cgroup :: Successfully put process in Cgroup."
         )
     except Exception as e:
         print(
             "run :: put_in_cgroup :: Failed to put process in Cgroup."
         )
         traceback.print_exc()
Beispiel #8
0
def Run(image_id, command, **kwargs):
    try:
        images = Images()
        if image_id not in images:
            raise Exception("No image with id {0}".format(image_id))

        while True:
            uuid = ''.join(random.choices('0123456789', k=6))
            containers = Ps()
            if uuid not in containers:
                break

        uuid_path = os.path.join('/var/myOwnDocker/ps', uuid)
        if not os.path.exists(uuid_path):
            os.makedirs(uuid_path)

        print("run :: Creating container with id {0}...".format(uuid))

        ip = str(random.randint(100, 255))
        mac = str(int(uuid[-2:]))

        with pyroute2.IPDB() as ipdb:
            veth0_name = 'veth0_{0}'.format(uuid)
            veth1_name = 'veth1_{0}'.format(uuid)
            netns_name = 'netns_{0}'.format(uuid)
            bridge_interface_name = 'bridge0'

            with ipdb.create(kind='veth', ifname=veth0_name,
                             peer=veth1_name) as interface:
                interface.up()
                if bridge_interface_name not in ipdb.interfaces.keys():
                    ipdb.create(kind='bridge',
                                ifname=bridge_interface_name).commit()
                interface.set_target('master', bridge_interface_name)

            pyroute2.netns.create(netns_name)

            with ipdb.interfaces[veth1_name] as veth1:
                veth1.net_ns_fd = netns_name

            ns = pyroute2.IPDB(nl=pyroute2.NetNS(netns_name))
            with ns.interfaces.lo as lo:
                lo.up()
            with ns.interfaces[veth1_name] as veth1:
                veth1.address = "02:42:ac:11:00:{0}".format(mac)
                veth1.add_ip('10.0.0.{0}/24'.format(ip))
                veth1.up()
            ns.routes.add({'dst': 'default', 'gateway': '10.0.0.1'}).commit()

            print("run :: Creating snapshot...")

            subprocess.run([
                'btrfs', 'subvolume', 'snapshot',
                '/var/myOwnDocker/images/{0}'.format(image_id),
                '/var/myOwnDocker/ps/{0}'.format(uuid)
            ],
                           check=True)
            with open(
                    '/var/myOwnDocker/ps/{0}/{1}/etc/resolv.conf'.format(
                        uuid, image_id), 'w') as f:
                f.write('nameserver 8.8.8.8\n')
            with open(
                    '/var/myOwnDocker/ps/{0}/{1}/{2}.cmd'.format(
                        uuid, image_id, uuid), 'w') as f:
                f.write(command + '\n')

            try:
                print("run :: Creating Cgroup...")
                user = os.getlogin()
                cgroups.user.create_user_cgroups(user)
                cg = cgroups.Cgroup(uuid)
                cg.set_cpu_limit(50)
                cg.set_memory_limit(512)

                new_root_path = '/var/myOwnDocker/ps/{0}/{1}'.format(
                    uuid, image_id)

                def put_in_cgroup():
                    try:
                        print(
                            "run :: put_in_cgroup :: Putting process in Cgroup..."
                        )
                        pid = os.getpid()
                        print("run :: put_in_cgroup :: pid={}".format(pid))
                        cg = cgroups.Cgroup(uuid)
                        cg.add(pid)
                        print("run :: put_in_cgroup :: Added pid in Cgroup.")
                        pyroute2.netns.setns(netns_name)
                        print("run :: put_in_cgroup :: Isolated NetNS.")
                        os.chdir(new_root_path)
                        os.chroot(new_root_path)
                        print(
                            "run :: put_in_cgroup :: Successfully put process in Cgroup."
                        )
                    except Exception as e:
                        print(
                            "run :: put_in_cgroup :: Failed to put process in Cgroup."
                        )
                        traceback.print_exc()

                print(
                    "run :: Running container with id {0} and command {1}...".
                    format(uuid, command))

                process = subprocess.run([
                    'unshare -fmuip --mount-proc && /bin/mount -t proc proc /proc && sleep 2 && '
                    + command
                ],
                                         preexec_fn=put_in_cgroup,
                                         universal_newlines=True,
                                         check=True,
                                         executable='/bin/bash')
                out, err = process.stdout, process.stderr
                if out is None:
                    out = ""
                if err is None:
                    err = ""

                with open(
                        os.path.join('/var/myOwnDocker/ps/{0}'.format(uuid),
                                     'out.log'), 'a') as f:
                    f.write(out + '\n')
                with open(
                        os.path.join('/var/myOwnDocker/ps/{0}'.format(uuid),
                                     'err.log'), 'a') as f:
                    f.write(err + '\n')

                print(
                    "run :: Container with id {0} and command {1} ran successfully."
                    .format(uuid, command))
            except:
                print(
                    "run :: Failed to run container with id {0} and command {1}."
                    .format(uuid, command))
                traceback.print_exc()
            finally:
                pyroute2.NetNS(netns_name).close()
                pyroute2.netns.remove(netns_name)
                ipdb.interfaces[veth0_name].remove()

    except Exception as e:
        print("run :: Failed to create container.")
        traceback.print_exc()
Beispiel #9
0
def get_cgroup(container_id):
    cgroup_id = get_cgroup_id(container_id)
    with contextlib.redirect_stderr(open(os.devnull, 'w')):
        return cgroups.Cgroup(cgroup_id)