Пример #1
0
    def add_host(self, host, data=None):
        """Add a host in the graph

        :param host: a string corresponding to the node name

        :param data: a dict containing the Grid'5000 host attributes"""
        if isinstance(host, Host):
            _host = get_host_shortname(host.address)
        else:
            _host = host
        if data:
            power = data['performance']['core_flops']
            cores = data['architecture']['nb_cores']
        else:
            power = 0
            cores = 0

        if len(self.get_host_adapters(_host)) > 0:
            logger.debug('Adding %s', style.host(_host))
            self.add_node(_host, {'kind': 'node',
                                  'power': power,
                                  'cores': cores})
            for eq in self.get_host_adapters(_host):
                if eq['mounted']:
                    self.add_equip(eq['switch'], get_host_site(_host))
        else:
            logger.warning('Node %s has no valid network connection',
                           _host)
Пример #2
0
    def add_host(self, host, data=None):
        """Add a host in the graph

        :param host: a string corresponding to the node name

        :param data: a dict containing the Grid'5000 host attributes"""
        if isinstance(host, Host):
            _host = get_host_shortname(host.address)
        else:
            _host = host
        if data:
            power = data['performance']['core_flops']
            cores = data['architecture']['nb_cores']
        else:
            power = 0
            cores = 0

        if len(self.get_host_adapters(_host)) == 0:
            logger.warning('Node %s has no valid network connection', _host)
        logger.debug('Adding %s', style.host(_host))
        self.add_node(_host, {'kind': 'node', 'power': power, 'cores': cores})
        for eq in self.get_host_adapters(_host):
            if eq['mounted']:
                self.add_equip(eq['switch'], get_host_site(_host))
                self._filter_equip_leaves()
Пример #3
0
 def get_host_adapters(self, host):
     """Return the mountable network interfaces from a host"""
     try:
         if host in self.data['hosts']:
             return [
                 m for m in self.data['hosts'][host]['network_adapters']
                 if 'switch' in m and not m['management'] and m['mountable']
                 and m['switch'] and m['interface'] == 'Ethernet'
             ]
     except:
         logger.warning("Wrong description for host %s" % style.host(host))
         logger.debug("host's network_adapters = %s" %
                      (self.data['hosts'][host]['network_adapters'], ))
         return []
Пример #4
0
 def get_host_adapters(self, host):
     """Return the mountable network interfaces from a host"""
     try:
         if host in self.data['hosts']:
             return [m for m in self.data['hosts'][host]['network_adapters']
                     if 'switch' in m
                     and not m['management']
                     and m['mountable']
                     and m['switch']
                     and m['interface'] == 'Ethernet']
     except:
         logger.warning("Wrong description for host %s" % style.host(host))
         logger.debug("host's network_adapters = %s" % (self.data['hosts'][host]['network_adapters'],))
         return []
Пример #5
0
def _is_cache_old_and_reachable(cache_dir):
    """Try to read the api_commit stored in the cache_dir and compare
    it with latest commit, return True if remote commit is different
    from cache commit"""
    try:
        with open(cache_dir + 'api_commit') as f:
            local_commit = f.readline()
    except:
        logger.detail('No commit version found')
        return True
    try:
        api_commit = get_resource_attributes('')['version']
    except:
        logger.warning('Unable to check API, reverting to cache')
        return False
    if local_commit != get_resource_attributes('')['version']:
        logger.info('Cache is outdated, will retrieve the latest commit')
        return True
    else:
        logger.detail('Already at the latest commit')
        return False
Пример #6
0
def _is_cache_old_and_reachable(cache_dir):
    """Try to read the api_commit stored in the cache_dir and compare
    it with latest commit, return True if remote commit is different
    from cache commit"""
    try:
        with open(cache_dir + 'api_commit') as f:
            local_commit = f.readline()
    except:
        logger.detail('No commit version found')
        return True
    try:
        api_commit = get_resource_attributes('')['version']
    except:
        logger.warning('Unable to check API, reverting to cache')
        return False
    if local_commit != get_resource_attributes('')['version']:
        logger.info('Cache is outdated, will retrieve the latest commit')
        return True
    else:
        logger.detail('Already at the latest commit')
        return False
Пример #7
0
def distribute_vms(vms, hosts, distribution='round-robin'):
    """Distribute the virtual machines on the hosts.

    :param vms: a list of VMs dicts which host key will be updated

    :param hosts: a list of hosts

    :param distribution: a string defining the distribution type:
     'round-robin', 'concentrated', 'n_by_hosts', 'random

    """
    logger.debug('Initial virtual machines distribution \n%s',
                 "\n".join([vm['id'] + ": " + str(vm['host']) for vm in vms]))

    if distribution in ['round-robin', 'concentrated', 'random']:
        attr = get_CPU_RAM_FLOPS(hosts)
        dist_hosts = hosts[:]
        iter_hosts = cycle(dist_hosts)
        host = iter_hosts.next()
        for vm in vms:
            remaining = attr[host].copy()
            while remaining['RAM'] - vm['mem'] <= 0 \
                    or remaining['CPU'] - vm['n_cpu'] / 3 <= 0:
                dist_hosts.remove(host)
                if len(dist_hosts) == 0:
                    req_mem = sum([vm['mem'] for vm in vms])
                    req_cpu = sum([vm['n_cpu'] for vm in vms]) / 3
                    logger.error('Not enough ressources ! \n' + 'RAM'.rjust(20)
                                 + 'CPU'.rjust(10) + '\n' + 'Needed'.ljust(15)
                                 + '%s Mb'.ljust(15) + '%s \n' +
                                 'Available'.ljust(15) + '%s Mb'.ljust(15)
                                 + '%s \n' + 'Maximum number of VM is %s',
                                 req_mem, req_cpu, attr['TOTAL']['RAM'],
                                 attr['TOTAL']['CPU'],
                                 style.emph(str(get_max_vms(hosts, vm['mem']))))
                    exit()

                iter_hosts = cycle(dist_hosts)
                host = iter_hosts.next()
                remaining = attr[host].copy()

            vm['host'] = host
            remaining['RAM'] -= vm['mem']
            remaining['CPU'] -= vm['n_cpu'] / 3
            attr[host] = remaining.copy()
            if distribution == 'round-robin':
                host = iter_hosts.next()
                remaining = attr[host].copy()
            if distribution == 'random':
                for i in range(randint(0, len(dist_hosts))):
                    host = iter_hosts.next()
                    remaining = attr[host].copy()

    elif distribution == 'n_by_hosts':
        n_by_host = int(len(vms) / len(hosts))
        i_vm = 0
        for host in hosts:
            for i in range(n_by_host):
                vms[i_vm]['host'] = host
                i_vm += 1
        if len(vms) % len(hosts) != 0:
            logger.warning('Reducing number of VMs to have %s by host',
                           style.emph(n_by_host))
            vms[:] = vms[0:n_by_host * len(hosts)]
    else:
        logger.debug('No valid distribution given')
    logger.debug('Final virtual machines distribution \n%s',
                 "\n".join([vm['id'] + ": " + str(vm['host']) for vm in vms]))
Пример #8
0
def treemap(gr,
            nodes_legend=None,
            edges_legend=None,
            nodes_labels=None,
            layout='neato',
            compact=False):
    """Create a treemap of the topology and return a matplotlib figure

    :param nodes_legend: a dict of dicts containing the parameter used to draw
     the nodes, such as 'myelement': {'color': '#9CF7BC', 'shape': 'p',
     'size': 200}

    :param edges_legend: a dict of dicts containing the parameter used to draw
     the edges, such as bandwidth: {'width': 0.2, 'color': '#666666'}

    :param nodes_labels: a dict of dicts containing the font parameters for
     the labels, such as 'myelement ': {'nodes': {}, 'font_size': 8,
     'font_weight': 'bold', 'str_func': lambda n: n.split('.')[1].title()}

    :param layout: the graphviz tool to be used to compute node position

    :param compact: represent only on node for a cluster/cabinet

    WARNING: This function use matplotlib.figure that by default requires a
    DISPLAY. If you want use this on a headless host, you need to change the
    matplotlib backend before to import execo_g5k.topology module.
    """

    base_size = 2

    _default_color = '#000000'
    _default_shape = 'o'
    _default_size = 100
    _default_width = 0.8
    _default_font_size = 10
    _default_font_weight = 'normal'

    def _default_str_func(n):
        return n.split('.')[0]

    def _default_nodes_legend():
        """Create a default legend for the nodes"""
        return {
            'renater': {
                'color': '#9CF7BC',
                'shape': 'p',
                'size': 200
            },
            'router': {
                'color': '#BFDFF2',
                'shape': '8',
                'size': 300,
                'width': 0.5
            },
            'switch': {
                'color': '#F5C9CD',
                'shape': 's',
                'size': 100,
                'width': 0.2
            },
            'host': {
                'color': '#F0F7BE',
                'shape': 'o',
                'size': 30,
                'width': 0.2
            },
            'cluster': {
                'color': '#F0F7BE',
                'shape': 'd',
                'size': 200,
                'width': _default_width
            },
            'default': {
                'color': _default_color,
                'shape': _default_shape,
                'size': _default_size
            },
            'linecard': {
                'size': 10,
                'shape': '^',
                'color': 'w',
                'width': 0.1
            },
        }

    def _default_edges_legend():
        """Defines the width and color of the edges based on bandwidth"""
        return {
            100000000: {
                'width': 0.2,
                'color': '#666666'
            },
            1000000000: {
                'width': 0.4,
                'color': '#666666'
            },
            3000000000: {
                'width': 0.6,
                'color': '#333333'
            },
            10000000000: {
                'width': 1.0,
                'color': '#111111'
            },
            20000000000: {
                'width': 2.0,
                'color': '#111111'
            },
            30000000000: {
                'width': 3.0,
                'color': '#111111'
            },
            40000000000: {
                'width': 4.0,
                'color': '#111111'
            },
            'default': {
                'width': _default_width,
                'color': _default_color
            }
        }

    def _default_nodes_labels(compact=False):
        """Defines the font labels"""
        def _default_str_func(n):
            return n.split('.')[0]

        return {
            'renater': {
                'nodes': {},
                'font_size': base_size * 4,
                'font_weight': 'normal',
                'str_func': _default_str_func
            },
            'router': {
                'nodes': {},
                'font_size': base_size * 4,
                'font_weight': 'bold'
            },
            'switch': {
                'nodes': {},
                'font_size': base_size * 4,
                'font_weight': 'normal'
            },
            'cluster': {
                'nodes': {},
                'font_size': base_size * 4,
                'font_weight': 'normal'
            },
            'host': {
                'nodes': {},
                'font_size': base_size * 3,
                'font_weight': 'normal'
            },
            'default': {
                'nodes': {},
                'font_size': _default_font_size,
                'font_weight': _default_font_weight,
                'str_func': _default_str_func
            },
            'linecard': {
                'nodes': {},
                'font_size': base_size * 3,
                'str_func': _default_str_func
            }
        }

    grdot = gr.copy()

    # Setting legend and labels
    _nodes_legend = _default_nodes_legend()
    _edges_legend = _default_edges_legend()
    _nodes_labels = _default_nodes_labels(compact)
    if nodes_legend:
        _nodes_legend.update(nodes_legend)
    if edges_legend:
        _edges_legend.update(edges_legend)
    if nodes_labels:
        _nodes_labels.update(nodes_labels)

    if not compact:
        elements = ['renater', 'router', 'switch', 'node', 'linecard']
    else:
        for site in grdot.get_sites():
            for cluster, data in grdot.get_clusters().items():
                for equip, radicals in data['equips'].items():
                    grdot.add_node(cluster + '\n' + radicals,
                                   {'kind': 'cluster'})
                    grdot.add_edge(cluster + '\n' + radicals, equip,
                                   {'bandwidth': data['bandwidth']})

        grdot.remove_nodes_from(
            [n[0] for n in grdot.nodes(True) if n[1]['kind'] == 'node'])

        elements = ['renater', 'router', 'switch', 'cluster']

    logger.debug('Legend and labels initialized')

    # substitute kind host to kind node in all the graph, as node is a reserved dot word
    for n in grdot.nodes_iter(True):
        if n[1].get('kind') == 'node':
            n[1]['kind'] = 'host'

    # Initializing plot
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111)

    logger.debug('Defining positions')
    try:
        pos = graphviz_layout(grdot, prog=layout)
    except:
        logger.warning('Error in generating graphviz layout, will use ' +
                       'spring layout that does not scale well ...')
        raise
        pos = nx.spring_layout(grdot, iterations=100)
    # Adding the nodes
    for k in elements:
        nodes = [
            node[0] for node in grdot.nodes_iter(data=True)
            if 'kind' in node[1] and node[1]['kind'] == k
        ]
        if k not in _nodes_legend:
            _nodes_legend[k] = _nodes_legend['default']
        nodes = nx.draw_networkx_nodes(
            grdot,
            pos,
            nodelist=nodes,
            node_shape=_nodes_legend[k]['shape']
            if 'shape' in _nodes_legend[k] else _default_shape,
            node_color=_nodes_legend[k]['color']
            if 'color' in _nodes_legend[k] else _default_color,
            node_size=_nodes_legend[k]['size']
            if 'size' in _nodes_legend[k] else _default_size,
            linewidths=_nodes_legend[k]['width']
            if 'width' in _nodes_legend[k] else _default_width)

    # Adding the edges
    for bandwidth, params in _edges_legend.items():
        if bandwidth != 'other':
            edges = [
                (edge[0], edge[1]) for edge in grdot.edges_iter(data=True)
                if 'bandwidth' in edge[2] and edge[2]['bandwidth'] == bandwidth
            ]
            nx.draw_networkx_edges(
                grdot,
                pos,
                edgelist=edges,
                width=params['width'] if 'width' in params else _default_width,
                edge_color=params['color']
                if 'color' in params else _default_color)
    edges = [(edge[0], edge[1]) for edge in grdot.edges_iter(data=True)
             if edge[2]['bandwidth'] not in _edges_legend]

    nx.draw_networkx_edges(grdot,
                           pos,
                           edgelist=edges,
                           width=_edges_legend['default']['width'],
                           edge_color=_edges_legend['default']['color'])
    # Adding the labels
    for node, data in grdot.nodes_iter(data=True):
        if 'nodes' not in _nodes_labels[data['kind']]:
            _nodes_labels[data['kind']]['nodes'] = {}
        if data['kind'] in _nodes_labels:
            _nodes_labels[data['kind']]['nodes'][node] = _nodes_labels[data['kind']]['str_func'](node) \
                if 'str_func' in _nodes_labels[data['kind']] else _default_str_func(node)
        else:
            _nodes_labels['default']['nodes'][node] = _nodes_labels['default'][
                'str_func'](node)

    for data in _nodes_labels.values():
        nx.draw_networkx_labels(
            grdot,
            pos,
            labels=data['nodes'],
            font_size=data['font_size']
            if 'font_size' in data else _default_font_size,
            font_weight=data['font_weight']
            if 'font_weight' in data else _default_font_weight)

    plt.axis('off')
    plt.tight_layout()

    title = 'Created by execo_g5k.topology \n%s\nAPI commit %s' % \
        (grdot.graph['date'], grdot.graph['api_commit'])
    plt.text(0.1, 0, title, transform=ax.transAxes)

    return fig
Пример #9
0
def treemap(gr, nodes_legend=None, edges_legend=None, nodes_labels=None,
            layout='neato', compact=False):
    """Create a treemap of the topology and return a matplotlib figure

    :param nodes_legend: a dict of dicts containing the parameter used to draw
     the nodes, such as 'myelement': {'color': '#9CF7BC', 'shape': 'p',
     'size': 200}

    :param edges_legend: a dict of dicts containing the parameter used to draw
     the edges, such as bandwidth: {'width': 0.2, 'color': '#666666'}

    :param nodes_labels: a dict of dicts containing the font parameters for
     the labels, such as 'myelement ': {'nodes': {}, 'font_size': 8,
     'font_weight': 'bold', 'str_func': lambda n: n.split('.')[1].title()}

    :param layout: the graphviz tool to be used to compute node position

    :param compact: represent only on node for a cluster/cabinet

    WARNING: This function use matplotlib.figure that by default requires a
    DISPLAY. If you want use this on a headless host, you need to change the
    matplotlib backend before to import execo_g5k.topology module.
    """

    base_size = 2

    _default_color = '#000000'
    _default_shape = 'o'
    _default_size = 100
    _default_width = 0.8
    _default_font_size = 10
    _default_font_weight = 'normal'

    def _default_str_func(n):
        return n.split('.')[0]

    def _default_nodes_legend():
        """Create a default legend for the nodes"""
        return {'renater':
                {'color': '#9CF7BC', 'shape': 'p', 'size': 200},
                'router':
                {'color': '#BFDFF2', 'shape': '8', 'size': 300,
                 'width': 0.5},
                'switch':
                {'color': '#F5C9CD', 'shape': 's', 'size': 100,
                 'width': 0.2},
                'node':
                {'color': '#F0F7BE', 'shape': 'o', 'size': 30,
                 'width': 0.2},
                'cluster':
                {'color': '#F0F7BE', 'shape': 'd', 'size': 200,
                 'width': _default_width},
                'default':
                {'color': _default_color, 'shape': _default_shape,
                 'size': _default_size},
                'linecard':
                {'size': 10, 'shape': '^', 'color': 'w', 'width': 0.1},
                }

    def _default_edges_legend():
        """Defines the width and color of the edges based on bandwidth"""
        return {100000000: {'width': 0.2, 'color': '#666666'},
                1000000000: {'width': 0.4, 'color': '#666666'},
                3000000000: {'width': 0.6, 'color': '#333333'},
                10000000000: {'width': 1.0, 'color': '#111111'},
                20000000000: {'width': 2.0, 'color': '#111111'},
                30000000000: {'width': 3.0, 'color': '#111111'},
                40000000000: {'width': 4.0, 'color': '#111111'},
                'default': {'width': _default_width, 'color': _default_color}}

    def _default_nodes_labels(compact=False):
        """Defines the font labels"""

        def _default_str_func(n):
            return n.split('.')[0]

        return {'renater':
                {'nodes': {},
                 'font_size': base_size * 4,
                 'font_weight': 'normal',
                 'str_func': lambda n: n.split('-')[1].title()},
                'router':
                {'nodes': {},
                 'font_size': base_size * 4,
                 'font_weight': 'bold'},
                'switch':
                {'nodes': {},
                 'font_size': base_size * 4,
                 'font_weight': 'normal'},
                'cluster':
                {'nodes': {},
                 'font_size': base_size * 4,
                 'font_weight': 'normal'},
                'node':
                {'nodes': {},
                 'font_size': base_size * 3,
                 'font_weight': 'normal'},
                'default':
                {'nodes': {},
                 'font_size': _default_font_size,
                 'font_weight': _default_font_weight,
                 'str_func': _default_str_func},
                'linecard':
                {'nodes': {},
                 'font_size': base_size * 3,
                 'str_func': lambda n: n.split('_')[1]}
                }

    # Setting legend and labels
    _nodes_legend = _default_nodes_legend()
    _edges_legend = _default_edges_legend()
    _nodes_labels = _default_nodes_labels(compact)
    if nodes_legend:
        _nodes_legend.update(nodes_legend)
    if edges_legend:
        _edges_legend.update(edges_legend)
    if nodes_labels:
        _nodes_labels.update(nodes_labels)

    if not compact:
        elements = ['renater', 'router', 'switch', 'node', 'linecard']
    else:
        for site in gr.get_sites():
            for cluster, data in gr.get_clusters().items():
                for equip, radicals in data['equips'].items():
                    gr.add_node(cluster + '\n' + radicals,
                                {'kind': 'cluster'})
                    gr.add_edge(cluster + '\n' + radicals, equip,
                                {'bandwidth': data['bandwidth']})

        gr.remove_nodes_from([n[0] for n in gr.nodes(True) if n[1]['kind'] == 'node'])

        elements = ['renater', 'router', 'switch', 'cluster']

    logger.debug('Legend and labels initialized')
    # Initializing plot
    fig = plt.figure(figsize=(10, 10))
    ax = fig.add_subplot(111)

    logger.debug('Defining positions')
    try:
        pos = nx.graphviz_layout(gr, prog=layout)
    except:
        logger.warning('Error in generating graphviz layout, will use ' +
                       'spring layout that does not scale well ...')
        raise
        pos = nx.spring_layout(gr, iterations=100)
    # Adding the nodes
    for k in elements:
        nodes = [node[0] for node in gr.nodes_iter(data=True)
                 if 'kind' in node[1] and node[1]['kind'] == k]
        if k not in _nodes_legend:
            _nodes_legend[k] = _nodes_legend['default']
        nodes = nx.draw_networkx_nodes(gr, pos, nodelist=nodes,
                                       node_shape=_nodes_legend[k]['shape']
                                       if 'shape' in _nodes_legend[k] else
                                       _default_shape,
                                       node_color=_nodes_legend[k]['color']
                                       if 'color' in _nodes_legend[k] else
                                       _default_color,
                                       node_size=_nodes_legend[k]['size']
                                       if 'size' in _nodes_legend[k] else
                                       _default_size,
                                       linewidths=_nodes_legend[k]['width']
                                       if 'width' in _nodes_legend[k] else
                                       _default_width)

    # Adding the edges
    for bandwidth, params in _edges_legend.items():
        if bandwidth != 'other':
            edges = [(edge[0], edge[1]) for edge in gr.edges_iter(data=True)
                     if 'bandwidth' in edge[2] and edge[2]['bandwidth'] == bandwidth]
            nx.draw_networkx_edges(gr, pos, edgelist=edges,
                                   width=params['width'] if 'width' in params
                                   else _default_width,
                                   edge_color=params['color'] if 'color' in params
                                   else _default_color)
    edges = [(edge[0], edge[1]) for edge in gr.edges_iter(data=True)
             if edge[2]['bandwidth'] not in _edges_legend]

    nx.draw_networkx_edges(gr, pos, edgelist=edges,
                           width=_edges_legend['default']['width'],
                           edge_color=_edges_legend['default']['color'])
    # Adding the labels
    for node, data in gr.nodes_iter(data=True):
        if 'nodes' not in _nodes_labels[data['kind']]:
            _nodes_labels[data['kind']]['nodes'] = {}
        if data['kind'] in _nodes_labels:
            _nodes_labels[data['kind']]['nodes'][node] = _nodes_labels[data['kind']]['str_func'](node) \
                if 'str_func' in _nodes_labels[data['kind']] else _default_str_func(node)
        else:
            _nodes_labels['default']['nodes'][node] = _nodes_labels['default']['str_func'](node)

    for data in _nodes_labels.values():
        nx.draw_networkx_labels(gr, pos, labels=data['nodes'],
                                font_size=data['font_size']
                                if 'font_size' in data else _default_font_size,
                                font_weight=data['font_weight']
                                if 'font_weight' in data else _default_font_weight)

    plt.axis('off')
    plt.tight_layout()

    title = 'Created by execo_g5k.topology \n%s\nAPI commit %s' % \
        (gr.graph['date'], gr.graph['api_commit'])
    plt.text(0.1, 0, title, transform=ax.transAxes)
    
    return fig
Пример #10
0
    def add_equip(self, equip, site):
        """Add a network equipment """
        if equip not in self.data['network'][site]:
            logger.warning('Equipment %s not described in API' % (equip,))
            return
        data = self.data['network'][site][equip]
        logger.debug('Adding equipment %s', equip)
        self.add_node(equip, kind=data['kind'],
                      backplane=data['backplane_bps'])
        lc_data = data['linecards']
        if data['kind'] == 'router':
            router_bw = data['backplane_bps']
            for i_lc, lc in enumerate([n for n in lc_data if 'ports' in n]):
                lc_node = equip + '_lc' + str(i_lc)
                lc_has_element = False
                for port in sorted([p for p in lc['ports'] if 'uid' in p]):
                    kind = port['kind'] if 'kind' in port else lc['kind']
                    bandwidth = lc['rate'] if 'rate' not in port else port['rate']
                    if self.has_node(port['uid']):
                        if kind == 'node':
                            for e in self.get_host_adapters(port['uid']):
                                if e['switch'] == equip:
                                    if ('port' in port and port['port'] == e['device']) or ('port' not in port and e['device'] == 'eth0'):
                                        lc_has_element = True
                                        key1 = lc_node + '_' + port['uid'] + '_' + e['device']
                                        logger.debug('Adding link between %s and %s %s' % (
                                                     lc_node, port['uid'], e['device']))
                                        self.add_edge(lc_node, port['uid'], key1,
                                                      bandwidth=bandwidth,
                                                      active=e['mounted'])

                                        key2 = equip + '_' + lc_node
                                        logger.debug('Adding link between %s and %s',
                                                     equip, lc_node)
                                        self.add_edge(equip, lc_node, key2,
                                                      bandwidth=router_bw, active=True)
                        if kind == 'switch':
                            lc_has_element = True
                            key1 = lc_node + '_' + port['uid']
                            self.add_edge(lc_node, port['uid'], key1,
                                          bandwidth=bandwidth, active=True)
                            key2 = equip + '_' + lc_node
                            self.add_edge(equip, lc_node, key2,
                                          bandwidth=router_bw, active=True)
                    if 'renater' in port['uid']:
                        lc_has_element = True
                        self.add_node(port['uid'], kind='renater')
                        key1 = lc_node + ' ' + port['uid']
                        self.add_edge(lc_node, port['uid'], key1,
                                      bandwidth=bandwidth, active=True)
                        key2 = equip + '_' + lc_node
                        self.add_edge(equip, lc_node, key2,
                                      bandwidth=router_bw, active=True)
                if lc_has_element:
                    logger.debug('Adding linecard %s', lc_node)
                    backplane = lc['backplane_bps'] if 'backplane_bps' \
                        in lc else data['backplane_bps']
                    self.add_node(lc_node, kind='linecard',
                                  backplane=backplane)
        else:
            # some switch have two linecards ?? pat, sgraphene1 => REPORT BUG
            for lc in [n for n in lc_data if 'ports' in n]:
                for port in sorted([p for p in lc['ports'] if 'uid' in p]):
                    kind = port['kind'] if 'kind' in port else lc['kind']
                    bandwidth = lc['rate'] if 'rate' not in port else port['rate']
                    if self.has_node(port['uid']):
                        if kind == 'node':
                            for e in self.get_host_adapters(port['uid']):
                                if e['switch'] == equip:
                                    key = equip + '_' + port['uid'] + '_' + e['device']
                                    self.add_edge(equip, port['uid'], key,
                                              bandwidth=bandwidth,
                                                  active=e['mounted'])
                        if kind == 'switch':
                            key = equip + '_' + port['uid']
                            self.add_edge(equip, port['uid'], key,
                                              bandwidth=bandwidth, active=True)
                    if kind == 'router':
                        self.add_equip(port['uid'], site)
Пример #11
0
def distribute_vms(vms, hosts, distribution='round-robin'):
    """Distribute the virtual machines on the hosts.

    :param vms: a list of VMs dicts which host key will be updated

    :param hosts: a list of hosts

    :param distribution: a string defining the distribution type:
     'round-robin', 'concentrated', 'n_by_hosts', 'random

    """
    logger.debug('Initial virtual machines distribution \n%s',
                 "\n".join([vm['id'] + ": " + str(vm['host']) for vm in vms]))

    if distribution in ['round-robin', 'concentrated', 'random']:
        attr = get_CPU_RAM_FLOPS(hosts)
        dist_hosts = hosts[:]
        iter_hosts = cycle(dist_hosts)
        host = iter_hosts.next()
        for vm in vms:
            remaining = attr[host].copy()
            while remaining['RAM'] - vm['mem'] <= 0 \
                    or remaining['CPU'] - vm['n_cpu'] / 3 <= 0:
                dist_hosts.remove(host)
                if len(dist_hosts) == 0:
                    req_mem = sum([vm['mem'] for vm in vms])
                    req_cpu = sum([vm['n_cpu'] for vm in vms]) / 3
                    logger.error(
                        'Not enough ressources ! \n' + 'RAM'.rjust(20) +
                        'CPU'.rjust(10) + '\n' + 'Needed'.ljust(15) +
                        '%s Mb'.ljust(15) + '%s \n' + 'Available'.ljust(15) +
                        '%s Mb'.ljust(15) + '%s \n' +
                        'Maximum number of VM is %s', req_mem, req_cpu,
                        attr['TOTAL']['RAM'], attr['TOTAL']['CPU'],
                        style.emph(str(get_max_vms(hosts, vm['mem']))))
                    exit()

                iter_hosts = cycle(dist_hosts)
                host = iter_hosts.next()
                remaining = attr[host].copy()

            vm['host'] = host
            remaining['RAM'] -= vm['mem']
            remaining['CPU'] -= vm['n_cpu'] / 3
            attr[host] = remaining.copy()
            if distribution == 'round-robin':
                host = iter_hosts.next()
                remaining = attr[host].copy()
            if distribution == 'random':
                for i in range(randint(0, len(dist_hosts))):
                    host = iter_hosts.next()
                    remaining = attr[host].copy()

    elif distribution == 'n_by_hosts':
        n_by_host = int(len(vms) / len(hosts))
        i_vm = 0
        for host in hosts:
            for i in range(n_by_host):
                vms[i_vm]['host'] = host
                i_vm += 1
        if len(vms) % len(hosts) != 0:
            logger.warning('Reducing number of VMs to have %s by host',
                           style.emph(n_by_host))
            vms[:] = vms[0:n_by_host * len(hosts)]
    else:
        logger.debug('No valid distribution given')
    logger.debug('Final virtual machines distribution \n%s',
                 "\n".join([vm['id'] + ": " + str(vm['host']) for vm in vms]))
Пример #12
0
    logger.setLevel(logging.INFO)

logger.debug('Options\n'+'\n'.join( [ set_style(option.ljust(20),'emph')+\
                    '= '+str(value).ljust(10) for option, value in vars(options).iteritems() if value is not None ]))





logger.info('%s', set_style('-- Find yoUr Nodes on g5K --', 'log_header'))
logger.info('From %s to %s', set_style(options.startdate, 'emph'), 
            set_style(options.enddate, 'emph'))

if options.resources is None:
    options.resources = 'suno:2,sol:2,griffon:10,rennes:20'
    logger.warning('No resources given, will use demo values ')

logger.info('Resources: %s', set_style(options.resources, 'emph'))
logger.info('Walltime: %s', set_style(options.walltime, 'emph'))
logger.info('Mode: %s', set_style(options.mode, 'emph'))
if prog is not None:
    logger.info('Program: %s', set_style(prog, 'emph'))
    
if options.plots:
    if 'grid5000.fr' in getfqdn():
        options.plots = False
        logger.warning('Plots are disabled on Grid5000 frontend until the migration to Wheezy')
    

resources = {}
for element in options.resources.split(','):
Пример #13
0
    def add_equip(self, equip, site):
        """Add a network equipment """
        if equip not in self.data['network'][site]:
            logger.warning('Equipment %s not described in API' % (equip, ))
            return
        data = self.data['network'][site][equip]
        logger.debug('Adding equipment %s', equip)
        self.add_node(equip,
                      kind=data['kind'],
                      backplane=data['backplane_bps'])
        lc_data = data['linecards']
        if data['kind'] == 'router':
            router_bw = data['backplane_bps']
            for i_lc, lc in enumerate([n for n in lc_data if 'ports' in n]):
                lc_node = equip + '_lc' + str(i_lc)
                lc_has_element = False
                for port in sorted([p for p in lc['ports'] if 'uid' in p]):
                    kind = port['kind'] if 'kind' in port else lc['kind']
                    bandwidth = lc['rate'] if 'rate' not in port else port[
                        'rate']
                    if self.has_node(port['uid']):
                        if kind == 'node':
                            for e in self.get_host_adapters(port['uid']):
                                if e['switch'] == equip:
                                    if ('port' in port
                                            and port['port'] == e['device']
                                        ) or ('port' not in port
                                              and e['device'] == 'eth0'):
                                        lc_has_element = True
                                        key1 = lc_node + '_' + port[
                                            'uid'] + '_' + e['device']
                                        logger.debug(
                                            'Adding link between %s and %s %s'
                                            % (lc_node, port['uid'],
                                               e['device']))
                                        self.add_edge(lc_node,
                                                      port['uid'],
                                                      key1,
                                                      bandwidth=bandwidth,
                                                      active=e['mounted'])

                                        key2 = equip + '_' + lc_node
                                        logger.debug(
                                            'Adding link between %s and %s',
                                            equip, lc_node)
                                        self.add_edge(equip,
                                                      lc_node,
                                                      key2,
                                                      bandwidth=router_bw,
                                                      active=True)
                        if kind == 'switch':
                            lc_has_element = True
                            key1 = lc_node + '_' + port['uid']
                            self.add_edge(lc_node,
                                          port['uid'],
                                          key1,
                                          bandwidth=bandwidth,
                                          active=True)
                            key2 = equip + '_' + lc_node
                            self.add_edge(equip,
                                          lc_node,
                                          key2,
                                          bandwidth=router_bw,
                                          active=True)
                    if 'renater' in port['uid']:
                        lc_has_element = True
                        self.add_node(port['uid'], kind='renater')
                        key1 = lc_node + ' ' + port['uid']
                        self.add_edge(lc_node,
                                      port['uid'],
                                      key1,
                                      bandwidth=bandwidth,
                                      active=True)
                        key2 = equip + '_' + lc_node
                        self.add_edge(equip,
                                      lc_node,
                                      key2,
                                      bandwidth=router_bw,
                                      active=True)
                if lc_has_element:
                    logger.debug('Adding linecard %s', lc_node)
                    backplane = lc['backplane_bps'] if 'backplane_bps' \
                        in lc else data['backplane_bps']
                    self.add_node(lc_node,
                                  kind='linecard',
                                  backplane=backplane)
        else:
            # some switch have two linecards ?? pat, sgraphene1 => REPORT BUG
            for lc in [n for n in lc_data if 'ports' in n]:
                for port in sorted([p for p in lc['ports'] if 'uid' in p]):
                    kind = port['kind'] if 'kind' in port else lc['kind']
                    bandwidth = lc['rate'] if 'rate' not in port else port[
                        'rate']
                    if self.has_node(port['uid']):
                        if kind == 'node':
                            for e in self.get_host_adapters(port['uid']):
                                if e['switch'] == equip:
                                    key = equip + '_' + port['uid'] + '_' + e[
                                        'device']
                                    self.add_edge(equip,
                                                  port['uid'],
                                                  key,
                                                  bandwidth=bandwidth,
                                                  active=e['mounted'])
                        if kind == 'switch':
                            key = equip + '_' + port['uid']
                            self.add_edge(equip,
                                          port['uid'],
                                          key,
                                          bandwidth=bandwidth,
                                          active=True)
                    if kind == 'router':
                        self.add_equip(port['uid'], site)