Beispiel #1
0
def get_active_allocations():
    auth_session = get_auth_session()
    aclient = allocation_client.Client('1', session=auth_session)

    active_allocations = {}

    # All approved allocations
    allocations = aclient.allocations.list(parent_request__isnull=True)

    for allocation in allocations:
        if (allocation.status == states.DELETED
                or allocation.status == states.SUBMITTED):
            continue
        elif allocation.status != states.APPROVED:
            try:
                allocation = aclient.allocations.get_last_approved(
                    parent_request=allocation.id)
            except exceptions.AllocationDoesNotExist:
                continue

        if not allocation.project_id:
            continue

        active_allocations[allocation.project_id] = allocation

    return active_allocations
Beispiel #2
0
def stat(host=None,
         last_changed=None,
         availability_zone=None,
         aggregate=None,
         status=None,
         project=None,
         allocation_home=None,
         exclude_availability_zone=None,
         exclude_host=None,
         exclude_aggregate=None,
         detail=None):
    """Gather statistic of all nova instances with given parameters."""
    session = get_session()
    nova = nova_client.Client(2, session=session)
    glance = glance_client.Client(2, session=session)
    keystone = keystone_client.Client(session=session)
    allocation = allocation_client.Client(1, session=session)
    instances = _list_instances(nova, glance, keystone, allocation, aggregate,
                                availability_zone, host, status, project,
                                allocation_home, exclude_availability_zone,
                                exclude_host, exclude_aggregate)
    # Summary table
    table = PrettyTable(['Name', 'Value'])
    data = {'instances': 0, 'vcpus': 0, 'ram': 0}
    table.align = 'l'
    projects_counter = Counter()
    # Detail table
    dt = PrettyTable(['Project', 'Instances', 'vCPUs', 'RAM'])
    projects = defaultdict(lambda: defaultdict(int))
    dt.align = 'l'
    for ins in instances:
        project_name = ins._info['project'].name
        projects[project_name]['instances'] += 1
        data['instances'] += 1
        projects_counter[ins._info['project'].name] += 1
        if not ins._info['flavor']['vcpus']:
            continue
        data['vcpus'] += int(ins._info['flavor']['vcpus'])
        data['ram'] += int(ins._info['flavor']['ram'])
        projects[project_name]['vcpus'] += int(ins._info['flavor']['vcpus'])
        projects[project_name]['ram'] += int(ins._info['flavor']['ram'])

    data['common'] = ',\n'.join('%s: %d' % (k, v)
                                for k, v in projects_counter.most_common(3))
    # Convert the data to bytes for humanization
    data['ram'] = data['ram'] * 1024 * 1024
    table.add_row(['Total instances', data['instances']])
    table.add_row(['vCPUs used', data['vcpus']])
    table.add_row(['RAM used', humanize.naturalsize(data['ram'], binary=True)])
    table.add_row(['Total projects affected', len(projects_counter.keys())])
    table.add_row(['Top projects affected', data['common']])
    click.echo(table)

    if detail:
        for name, p in projects.items():
            dt.add_row([
                name, p['instances'], p['vcpus'],
                humanize.naturalsize(p['ram'] * 1024 * 1024, binary=True)
            ])
        click.echo(dt)
Beispiel #3
0
def list(host=None,
         last_changed=None,
         availability_zone=None,
         column=None,
         aggregate=None,
         status=None,
         sort_by=None,
         project=None,
         allocation_home=None,
         exclude_availability_zone=None,
         exclude_host=None,
         exclude_aggregate=None):
    """List all nova instances with given parameters."""
    session = get_session()
    nova = nova_client.Client(2, session=session)
    glance = glance_client.Client(2, session=session)
    keystone = keystone_client.Client(session=session)
    allocation = allocation_client.Client(1, session=session)
    instances = _list_instances(nova, glance, keystone, allocation, aggregate,
                                availability_zone, host, status, project,
                                allocation_home, exclude_availability_zone,
                                exclude_host, exclude_aggregate)
    # INSTAN = instances
    # embed()
    if not column:
        sort_by = 'OS-EXT-SRV-ATTR:host'
    _render_table_instances(instances, column, sort_by)
Beispiel #4
0
 def __init__(self, conf):
     super(AllocationPollsterBase, self).__init__(conf)
     creds = conf.service_credentials
     self.client = client.Client(
         version='1',
         session=keystone_client.get_session(conf),
         region_name=creds.region_name,
         interface=creds.interface,
     )
Beispiel #5
0
 def setup_allocations(self):
     if not self.allocations:
         loader = loading.get_plugin_loader('password')
         username = os.environ.get('OS_USERNAME')
         password = os.environ.get('OS_PASSWORD')
         auth_url = os.environ.get('OS_AUTH_URL')
         project_name = os.environ.get('OS_TENANT_NAME')
         auth = loader.load_from_options(auth_url=auth_url,
                                         username=username,
                                         password=password,
                                         project_name=project_name,
                                         user_domain_id='default',
                                         project_domain_id='default')
         sess = session.Session(auth=auth)
         self.allocations = client.Client(1, session=sess)
Beispiel #6
0
def list_user_projects(email, conn):
    """
    user id --> all projects (including closed ones) --> flavor

    :param email: email as user ID
    :param conn: openstack connection
    :return: 
    """
    allocation_client = allocationclient.Client(1, session=conn.session)

    # step 1: get the user ID from email
    user = conn.get_user(email)
    if user is None:
        print('can not find user')
        return

    # step 2: get all the projects of a user
    roles = conn.list_role_assignments({'user': user.id})
    all_projects = [r.project for r in roles]
    # print(all_projects)
    # step 3: get all auckland GPU flavors
    akl_gpu_flavors = conn.search_flavors('akl.gpu*', get_extra=False)
    user_allocations = []
    for f in akl_gpu_flavors:
        for access in conn.list_flavor_access(f.id):
            # print(access)
            if access.project_id in all_projects:
                alloc = fetch_project_info(access.project_id,
                                           allocation_client)
                if alloc:
                    user_allocations.append(alloc)
                    # print(f'{alloc.project_name}({alloc.project_id}): {alloc.start_date} -- {alloc.end_date}')
    # output
    x = PrettyTable()
    x.field_names = [
        'project_name', 'project_id', 'status', 'start_date', 'end_date'
    ]
    for a in user_allocations:
        x.add_row([
            a.project_name, a.project_id, a.status_display, a.start_date,
            a.end_date
        ])
    print(x)
Beispiel #7
0
def update_gpu_db(osc_conn, db_conn, gpudb_conn):
    """
  save current metadata on current instances that are using a GPU

  :param osc_conn:
  :param gpudb_conn:
  :return:
  """
    allocation_client = allocationclient.Client(1, session=osc_conn.session)

    devices = fetch_pci_device_from_db(db_conn)
    all_project_ids = [
        d['project_id'] for d in devices if d['project_id'] is not None
    ]

    # process assigned projects but not VM running
    # assumption, 1 project can only have 1 GPU instance
    akl_gpu_flavor = osc_conn.search_flavors('akl.gpu*', get_extra=False)
    for f in akl_gpu_flavor:
        all_access = osc_conn.list_flavor_access(f.id)
        for a in all_access:
            # test if it already has an instance
            if a.project_id not in all_project_ids:
                # check if the project is still active
                project = fetch_project_info(a.project_id, allocation_client)
                if project is None:  # or project.end_date < str(date.today()):
                    continue
                # we need to fix the project
                #for project in fetch_project_info:

                # get extra properties and project access info
                detail = osc_conn.get_flavor_by_id(f.id, get_extra=True)
                gpu_model = detail.extra_specs['pci_passthrough:alias'].split(
                    ':')[0]
                # print(f"{a.project_id} no instance, but has flavor {f.name}, GPU={gpu_model}")
                # find an available model and change the status
                for d in devices:
                    if d['label'] == gpu_model and d['status'] == 'available':
                        d['status'] = 'reserved'
                        d['project_id'] = a.project_id
                        break

    current_gpu_node_list = fetch_gpu_nodes(gpudb_conn)

    #First we set tmp_active to 0 for all entries,
    #then for every host,device pair, we set it to 1
    #At the end, we set active to tmp_active for all entries
    cursor = gpudb_conn.cursor()
    try:
        cursor.execute('UPDATE gpu_nodes SET tmp_active = 0')
        gpudb_conn.commit()
    except pymysql.Error as e:
        print "DB clear gpu_nodes.tmp_active: ", e

    # update project_end date and contact
    for d in devices:
        # get project allocation info
        alloc = None
        if d['project_id'] is not None and len(d['project_id']) > 0:
            alloc = fetch_project_info(d['project_id'], allocation_client)
        #if alloc is not None:
        #    print alloc.__dict__
        if d['display_name'] is None and alloc is not None:
            d['display_name'] = alloc.project_name
        d['project_name'] = 'Auckland-CeR' if alloc is None else alloc.project_name
        d['start_date'] = '2017-07-04' if alloc is None else alloc.start_date
        d['end_date'] = '9999-12-31' if alloc is None else alloc.end_date
        if d['launched_at'] is None:
            d['launched_at'] = d['start_date']
        if d['terminated_at'] is None:
            d['terminated_at'] = d['end_date']
        d['contact'] = None if alloc is None else alloc.contact_email
        d['ip'] = find_ip(osc_conn, d['instance_uuid'])
        d['host'] = d['host'].replace("ntr-", "")
        d['host'] = d['host'].replace("akld2", "")

        statement1 = '''
    INSERT INTO ip2project (ip, project_name, project_uuid, start_date, end_date,  email, instance_uuid, instance_name, instance_launched_at, instance_terminated_at )
    VALUES(%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)
    ON DUPLICATE KEY UPDATE instance_terminated_at = %s, end_date = %s, final = 0
    '''

        statement2 = '''
    INSERT INTO gpu_nodes ( hypervisor, gpu_type, pci_id, tmp_active ) VALUES ( %s, %s, %s, %s )  ON DUPLICATE KEY UPDATE tmp_active = %s
    '''

        statement3 = '''
    INSERT into ip2project_gpu_nodes (ip2project_id, gpu_node_id) values 
    ((select ip2project.id from ip2project where ip = %s and project_uuid = %s and instance_uuid = %s), (select gpu_nodes.id from gpu_nodes where hypervisor = %s and pci_id = %s)) ON DUPLICATE KEY UPDATE ip2project_id = ip2project_id
    '''

        if current_gpu_node_list is not None:
            key = d['host'] + ' ' + d['dev_id']
            if key in current_gpu_node_list:
                current_gpu_node_list[key]['present'] = True

        cursor = gpudb_conn.cursor()
        try:
            cursor.execute(statement2,
                           (d['host'], d['label'], d['dev_id'], '1', '1'))
            gpudb_conn.commit()
        except pymysql.Error as e:
            print "DB Update gpu_nodes: ", e

        if d['instance_uuid'] is not None and d[
                'ip'] is not None and d['ip'] != '':
            cursor = gpudb_conn.cursor()
            try:
                cursor.execute(
                    statement1,
                    (d['ip'], d['project_name'], d['project_id'],
                     d['start_date'], d['end_date'], d['contact'],
                     d['instance_uuid'], d['display_name'], d['launched_at'],
                     d['terminated_at'], d['terminated_at'], d['end_date']))
                cursor.execute(statement3,
                               (d['ip'], d['project_id'], d['instance_uuid'],
                                d['host'], d['dev_id']))
                gpudb_conn.commit()
            except pymysql.Error as e:
                print "DB Update gpu_nodes: ", e
                gpudb_conn.rollback()
        elif d['project_id'] is not None:
            statement4 = '''
      INSERT INTO gpu_booking (project_name, project_uuid, booking_start_date, booking_end_date,  email, gpu_type, count )
      VALUES(%s,%s,%s,%s,%s,%s,%s)
      ON DUPLICATE KEY UPDATE booking_end_date = %s
      '''
            cursor = gpudb_conn.cursor()
            try:
                cursor.execute(statement4,
                               (d['project_name'], d['project_id'],
                                d['start_date'], d['end_date'], d['contact'],
                                d['label'], '1', d['end_date']))
                gpudb_conn.commit()
            except pymysql.Error as e:
                print "DB Update gpu_booking: ", e
                gpudb_conn.rollback()

    #At the end, we set active to tmp_active for all entries
    cursor = gpudb_conn.cursor()
    try:
        cursor.execute('UPDATE gpu_nodes SET active = tmp_active')
        gpudb_conn.commit()
    except pymysql.Error as e:
        print "DB set gpu_nodes.active: ", e
Beispiel #8
0
def list_gpus(osc_conn, db_conn):
    """
    list all GPUs and their utilisation

    :param osc_conn:
    :param db_conn:
    :return:
    """
    allocation_client = allocationclient.Client(1, session=osc_conn.session)

    devices = fetch_pci_device_from_db(db_conn)
    all_project_ids = [
        d['project_id'] for d in devices if d['project_id'] is not None
    ]

    # process assigned projects but not VM running
    # assumption, 1 project can only have 1 GPU instance
    akl_gpu_flavor = osc_conn.search_flavors('akl.gpu*', get_extra=False)
    for f in akl_gpu_flavor:
        all_access = osc_conn.list_flavor_access(f.id)
        for a in all_access:
            # test if it already has an instance
            if a.project_id not in all_project_ids:
                # check if the project is still active
                project = fetch_project_info(a.project_id, allocation_client)
                if project is None:  # or project.end_date < str(date.today()):
                    continue
                # we need to fix the project
                #for project in fetch_project_info:

                # get extra properties and project access info
                detail = osc_conn.get_flavor_by_id(f.id, get_extra=True)
                gpu_model = detail.extra_specs['pci_passthrough:alias'].split(
                    ':')[0]
                # print(f"{a.project_id} no instance, but has flavor {f.name}, GPU={gpu_model}")
                # find an available model and change the status
                for d in devices:
                    if d['label'] == gpu_model and d['status'] == 'available':
                        d['status'] = 'reserved'
                        d['project_id'] = a.project_id
                        break

    # update project_end date and contact
    for d in devices:
        # get project allocation info
        alloc = None
        if d['project_id'] is not None and len(d['project_id']) > 0:
            alloc = fetch_project_info(d['project_id'], allocation_client)
        #if alloc is not None:
        #    print alloc.__dict__
        if d['display_name'] is None and alloc is not None:
            d['display_name'] = alloc.project_name
        d['project_name'] = 'Auckland-CeR' if alloc is None else alloc.project_name
        d['start_date'] = 'NA' if alloc is None else alloc.start_date
        d['end_date'] = 'NA' if alloc is None else alloc.end_date
        d['contact'] = 'NA' if alloc is None else alloc.contact_email
        d['ip'] = find_ip(osc_conn, d['instance_uuid'])
        d['host'] = d['host'].replace("ntr-", "")
        d['host'] = d['host'].replace("akld2", "")

    # output
    x = PrettyTable()
    x.field_names = [
        'host', 'label', 'status', 'instance_uuid', 'display_name',
        'project_name', 'project_id', 'start_date', 'end_date', 'contact',
        'dev_id', 'ip', 'launched_at', 'terminated_at'
    ]
    for d in devices:
        row_data = []
        for f in x.field_names:
            row_data.append(d[f])
        x.add_row(row_data)
    print(x)