Пример #1
0
 def __init__(self, name, hierarchies='all', user='******'):
     self.name = name
     # Get user
     self.user = user
     if self.user == 'current':
         self.user = getpass.getuser()
     # Get hierarchies
     if hierarchies == 'all':
         hierachies = HIERARCHIES
     self.hierarchies = [h for h in hierachies if h in HIERARCHIES]
     # Get user cgroups
     self.user_cgroups = {}
     system_hierarchies = os.listdir(BASE_CGROUPS)
     for hierarchy in self.hierarchies:
         if hierarchy not in system_hierarchies:
             raise CgroupsException(
                 "Hierarchy %s is not mounted" % hierarchy)
         user_cgroup = os.path.join(BASE_CGROUPS, hierarchy, self.user)
         self.user_cgroups[hierarchy] = user_cgroup
     create_user_cgroups(self.user, script=False)
     # Create name cgroups
     self.cgroups = {}
     for hierarchy, user_cgroup in self.user_cgroups.items():
         cgroup = os.path.join(user_cgroup, self.name)
         if not os.path.exists(cgroup):
             os.mkdir(cgroup)
         self.cgroups[hierarchy] = cgroup
Пример #2
0
 def __init__(self, name, hierarchies='all', user='******'):
     self.name = name
     # Get user
     self.user = user
     if self.user == 'current':
         self.user = getpass.getuser()
     # Get hierarchies
     if hierarchies == 'all':
         hierarchies = HIERARCHIES
     self.hierarchies = [h for h in hierarchies if h in HIERARCHIES]
     # Get user cgroups
     self.user_cgroups = {}
     system_hierarchies = os.listdir(BASE_CGROUPS)
     for hierarchy in self.hierarchies:
         if hierarchy not in system_hierarchies:
             raise CgroupsException("Hierarchy %s is not mounted" %
                                    hierarchy)
         user_cgroup = os.path.join(BASE_CGROUPS, hierarchy, self.user)
         self.user_cgroups[hierarchy] = user_cgroup
     create_user_cgroups(self.user, script=False)
     # Create name cgroups
     self.cgroups = {}
     for hierarchy, user_cgroup in self.user_cgroups.items():
         cgroup = os.path.join(user_cgroup, self.name)
         if not os.path.exists(cgroup):
             os.mkdir(cgroup)
         self.cgroups[hierarchy] = cgroup
Пример #3
0
def setup_cgroup(name):
    user = pwd.getpwuid(os.getuid())[0]
    print(user)
    create_user_cgroups(user)
    cg = Cgroup(name)
    print('cgroup', cg)
    cg.set_cpu_limit(100)
    print('memory limit', cg.memory_limit)
    cg.set_memory_limit(600)
    print('memory limit', cg.memory_limit)
Пример #4
0
    def run(self, *args, **kwargs):
        images = ImagesCommand().list_images()
        image_name = kwargs['<name>']
        ip_last_octet = 103 # TODO : configurable

        match = [i[3] for i in images if i[0] == image_name][0]

        target_file = os.path.join(_base_dir_, match)
        with open(target_file) as tf:
            image_details = json.loads(tf.read())
        # setup environment details
        state = json.loads(image_details['history'][0]['v1Compatibility'])

        # Extract information about this container
        env_vars = state['config']['Env']
        start_cmd = subprocess.list2cmdline(state['config']['Cmd'])
        working_dir = state['config']['WorkingDir']

        id = uuid.uuid1()

        # unique-ish name
        name = 'c_' + str(id.fields[5])[:4]

        # unique-ish mac
        mac = str(id.fields[5])[:2]

        layer_dir = os.path.join(_base_dir_, match.replace('.json', ''), 'layers', 'contents')

        with IPDB() as ipdb:
            veth0_name = 'veth0_'+name
            veth1_name = 'veth1_'+name
            netns_name = 'netns_'+name
            bridge_if_name = 'bridge0'

            existing_interfaces = ipdb.interfaces.keys()

            # Create a new virtual interface
            with ipdb.create(kind='veth', ifname=veth0_name, peer=veth1_name) as i1:
                i1.up()
                if bridge_if_name not in existing_interfaces:
                    ipdb.create(kind='bridge', ifname=bridge_if_name).commit()
                i1.set_target('master', bridge_if_name)

            # Create a network namespace
            netns.create(netns_name)

            # move the bridge interface into the new namespace
            with ipdb.interfaces[veth1_name] as veth1:
                veth1.net_ns_fd = netns_name

            # Use this network namespace as the database
            ns = IPDB(nl=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_last_octet))
                veth1.up()
            ns.routes.add({
                'dst': 'default',
                'gateway': '10.0.0.1'}).commit()

            try:
                # setup cgroup directory for this user
                user = os.getlogin()
                create_user_cgroups(user)

                # First we create the cgroup and we set it's cpu and memory limits
                cg = Cgroup(name)
                cg.set_cpu_limit(50)  # TODO : get these as command line options
                cg.set_memory_limit(500)

                # Then we a create a function to add a process in the cgroup
                def in_cgroup():
                    try:
                        pid = os.getpid()
                        cg = Cgroup(name)
                        for env in env_vars:
                            log.info('Setting ENV %s' % env)
                            os.putenv(*env.split('=', 1))

                        # Set network namespace
                        netns.setns(netns_name)

                        # add process to cgroup
                        cg.add(pid)

                        os.chroot(layer_dir)
                        if working_dir != '':
                            log.info("Setting working directory to %s" % working_dir)
                            os.chdir(working_dir)
                    except Exception as e:
                        traceback.print_exc()
                        log.error("Failed to preexecute function")
                        log.error(e)
                cmd = start_cmd
                log.info('Running "%s"' % cmd)
                process = subprocess.Popen(cmd, preexec_fn=in_cgroup, shell=True)
                process.wait()
                print(process.stdout)
                log.error(process.stderr)
            except Exception as e:
                traceback.print_exc()
                log.error(e)
            finally:
                log.info('Finalizing')
                NetNS(netns_name).close()
                netns.remove(netns_name)
                ipdb.interfaces[veth0_name].remove()
                log.info('done')
Пример #5
0
    def run(self, *args, **kwargs):
        images = ImagesCommand().list_images()
        image_name = kwargs['<name>']
        ip_last_octet = 103  # TODO : configurable

        match = [i[3] for i in images if i[0] == image_name][0]

        target_file = os.path.join(_base_dir_, match)
        with open(target_file) as tf:
            image_details = json.loads(tf.read())
        # setup environment details
        state = json.loads(image_details['history'][0]['v1Compatibility'])

        # Extract information about this container
        env_vars = state['config']['Env']
        start_cmd = subprocess.list2cmdline(state['config']['Cmd'])
        working_dir = state['config']['WorkingDir']

        id = uuid.uuid1()

        # unique-ish name
        name = 'c_' + str(id.fields[5])[:4]

        # unique-ish mac
        mac = str(id.fields[5])[:2]

        layer_dir = os.path.join(_base_dir_, match.replace('.json', ''),
                                 'layers', 'contents')

        with IPDB() as ipdb:
            veth0_name = 'veth0_' + name
            veth1_name = 'veth1_' + name
            netns_name = 'netns_' + name
            bridge_if_name = 'bridge0'

            existing_interfaces = ipdb.interfaces.keys()

            # Create a new virtual interface
            with ipdb.create(kind='veth', ifname=veth0_name,
                             peer=veth1_name) as i1:
                i1.up()
                if bridge_if_name not in existing_interfaces:
                    ipdb.create(kind='bridge', ifname=bridge_if_name).commit()
                i1.set_target('master', bridge_if_name)

            # Create a network namespace
            netns.create(netns_name)

            # move the bridge interface into the new namespace
            with ipdb.interfaces[veth1_name] as veth1:
                veth1.net_ns_fd = netns_name

            # Use this network namespace as the database
            ns = IPDB(nl=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_last_octet))
                veth1.up()
            ns.routes.add({'dst': 'default', 'gateway': '10.0.0.1'}).commit()

            try:
                # setup cgroup directory for this user
                user = os.getlogin()
                create_user_cgroups(user)

                # First we create the cgroup and we set it's cpu and memory limits
                cg = Cgroup(name)
                cg.set_cpu_limit(
                    50)  # TODO : get these as command line options
                cg.set_memory_limit(500)

                # Then we a create a function to add a process in the cgroup
                def in_cgroup():
                    try:
                        pid = os.getpid()
                        cg = Cgroup(name)
                        for env in env_vars:
                            log.info('Setting ENV %s' % env)
                            os.putenv(*env.split('=', 1))

                        # Set network namespace
                        netns.setns(netns_name)

                        # add process to cgroup
                        cg.add(pid)

                        os.chroot(layer_dir)
                        if working_dir != '':
                            log.info("Setting working directory to %s" %
                                     working_dir)
                            os.chdir(working_dir)
                    except Exception as e:
                        traceback.print_exc()
                        log.error("Failed to preexecute function")
                        log.error(e)

                cmd = start_cmd
                log.info('Running "%s"' % cmd)
                process = subprocess.Popen(cmd,
                                           preexec_fn=in_cgroup,
                                           shell=True)
                process.wait()
                print(process.stdout)
                log.error(process.stderr)
            except Exception as e:
                traceback.print_exc()
                log.error(e)
            finally:
                log.info('Finalizing')
                NetNS(netns_name).close()
                netns.remove(netns_name)
                ipdb.interfaces[veth0_name].remove()
                log.info('done')
Пример #6
0
def main():
    parser = argparse.ArgumentParser(
            prog="cgc",
            description="cli tool for managing processes using Control Groups Linux mechanism"
        )

    parser.add_argument(
            '-v',
            '--verbose',
            dest='verbose',
            action='store',
            help='verbose actions level (DEBUG,INFO,WARN), default=INFO',
            default="INFO",
        )

    parser.add_argument(
            'action',
            choices=('useradd','run','cgadd','addpid','rmpid','cgls','frz','ufrz'),
            help="action to do",
        )

    parser.add_argument(
            '--command',
            dest='command',
            action='store',
            type=str,
            help='command to run with some cgroup configuration',
            default=None,
        )
    parser.add_argument(
            '--no-swap',
            dest='no_swap',
            action='store_true',
            help='run command with swap memmory limit set to 0 bytes'
        )
    parser.add_argument(
            '--cpu',
            dest='cpu',
            action='store',
            type=int,
            help='run command with some percent of cpu-resource',
            default=None,
        )
    parser.add_argument(
            '--mem',
            dest='mem',
            action='store',
            type=int,
            help='run command with memory limit',
            default=None
        )
    parser.add_argument(
            '--cgroup',
            dest='cgroup',
            action='store',
            type=str,
            help='cgroup name',
            default=None,
        )

    parser.add_argument(
            '--user',
            dest='user',
            action='store',
            help='username to grant privileges to use cgroups',
            default=None,
        )

    args = parser.parse_args()

    print (args)

    # Logging
    formatter = logging.Formatter(
        '%(asctime)s - %(name)s - %(levelname)s - %(message)s')
    logstream = logging.StreamHandler()
    logstream.setFormatter(formatter)
    logger.addHandler(logstream)
    if args.verbose == 'DEBUG':
        logger.setLevel(logging.DEBUG)
    elif args.verbose == 'INFO':
        logger.setLevel(logging.INFO)
    elif args.verbose == 'WARN':
        logger.setLevel(logging.WARN)
    else:
        logger.setLevel(logging.ERROR)
    logger.debug('Logging level: %s' % args.verbose)

    print (args)

    if args.action == "run":
        print ("runing command {}".format(args.command))
        run_command_with_cgroups_options(args.command,cpu=args.cpu,mem=args.mem,swapless=args.no_swap if args.no_swap else False,cgroup=args.cgroup)

    elif args.action == "useradd":
        print ("adding user {}".format(args.user))
        create_user_cgroups(args.user)