Commit 1bd118f7 by Bach Dániel

Merge branch 'issue-102-rebased' into 'master'

Fix node scalability #102
parents 6b0da54a 24cf80ad
{% load i18n %}
<div id="node-list-column-vm">
<a class="real-link" href="{% url "dashboard.views.node-detail" pk=record.pk %}#virtualmachines">{{ record.instance_set.count }}</a>
<a class="real-link" href="{% url "dashboard.views.node-detail" pk=record.pk %}#virtualmachines">{{ value }}</a>
</div>
......@@ -14,6 +14,7 @@ from django.core.exceptions import (
)
from django.core import signing
from django.core.urlresolvers import reverse, reverse_lazy
from django.db.models import Count
from django.http import HttpResponse, HttpResponseRedirect, Http404
from django.shortcuts import redirect, render, get_object_or_404
from django.views.decorators.http import require_GET
......@@ -921,10 +922,13 @@ class VmList(LoginRequiredMixin, SingleTableView):
class NodeList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
template_name = "dashboard/node-list.html"
model = Node
table_class = NodeListTable
table_pagination = False
def get_queryset(self):
return Node.objects.annotate(
number_of_VMs=Count('instance_set')).select_related('host')
class GroupList(LoginRequiredMixin, SuperuserRequiredMixin, SingleTableView):
template_name = "dashboard/group-list.html"
......
......@@ -25,6 +25,17 @@ from django.utils import timezone
logger = getLogger(__name__)
def node_available(function):
"""Decorate methods to ignore disabled Nodes.
"""
def decorate(self, *args, **kwargs):
if self.enabled and self.online:
return function(self, *args, **kwargs)
else:
return None
return decorate
class Node(TimeStampedModel):
"""A VM host machine, a hypervisor.
......@@ -55,19 +66,22 @@ class Node(TimeStampedModel):
def __unicode__(self):
return self.name
@method_cache(10, 5)
@method_cache(10)
def get_online(self):
"""Check if the node is online.
Runs a remote ping task if the worker is running.
Check if node is online by queue is available.
"""
try:
return self.remote_query(vm_tasks.ping, timeout=1, default=False)
except WorkerNotFound:
self.get_remote_queue_name("vm")
except:
return False
else:
return True
online = property(get_online)
@node_available
@method_cache(300)
def get_num_cores(self):
"""Number of CPU threads available to the virtual machines.
......@@ -106,6 +120,7 @@ class Node(TimeStampedModel):
self.get_num_cores(invalidate_cache=True)
self.get_ram_size(invalidate_cache=True)
@node_available
@method_cache(300)
def get_ram_size(self):
"""Bytes of total memory in the node.
......@@ -115,6 +130,7 @@ class Node(TimeStampedModel):
ram_size = property(get_ram_size)
@property
@node_available
def ram_size_with_overcommit(self):
"""Bytes of total memory including overcommit margin.
"""
......@@ -198,6 +214,7 @@ class Node(TimeStampedModel):
else:
return default
@node_available
def get_monitor_info(self):
try:
handler = GraphiteHandler()
......@@ -229,17 +246,21 @@ class Node(TimeStampedModel):
return collected
@property
@node_available
def cpu_usage(self):
return float(self.get_monitor_info()["cpu.usage"]) / 100
@property
@node_available
def ram_usage(self):
return float(self.get_monitor_info()["memory.usage"]) / 100
@property
@node_available
def byte_ram_usage(self):
return self.ram_usage * self.ram_size
@node_available
def update_vm_states(self):
"""Update state of Instances running on this Node.
......@@ -284,7 +305,8 @@ class Node(TimeStampedModel):
@classmethod
def get_state_count(cls, online, enabled):
return len([1 for i in cls.objects.filter(enabled=enabled).all()
return len([1 for i in
cls.objects.filter(enabled=enabled).select_related('host')
if i.online == online])
@permalink
......
from django.core.cache import cache
from logging import getLogger
from manager.mancelery import celery
logger = getLogger(__name__)
def check_queue(node_hostname, queue_id):
drivers = ['vmdriver', 'netdriver', 'agentdriver']
worker_list = [node_hostname + "." + d for d in drivers]
"""True if the queue is alive.
Example: check_queue('node01', 'vm'):
:param node_hostname: Short hostname of the node.
:param queue_id: Queue identifier (eg. vm).
"""
# drivers = ['vmdriver', 'netdriver', 'agentdriver']
# worker_list = [node_hostname + "." + d for d in drivers]
queue_name = node_hostname + "." + queue_id
inspect = celery.control.inspect(worker_list)
active_queues = inspect.active_queues()
active_queues = get_queues()
if active_queues is None:
return False
# v is List of List of queues dict
......@@ -18,6 +28,22 @@ def check_queue(node_hostname, queue_id):
return False
def get_queues():
"""Get active celery queues.
Result is cached for 10 seconds!
"""
key = __name__ + u'queues'
result = cache.get(key)
if result is None:
inspect = celery.control.inspect()
inspect.timeout = 0.1
result = inspect.active_queues()
logger.debug('Queue list of length %d cached.', len(result))
cache.set(key, result, 10)
return result
@celery.task(name='vmdriver.create')
def deploy(params):
pass
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment