1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-24 15:15:22 +00:00

Merge pull request #156 from catborise/master

Django version requirement, Libxml2->lxml change, account detail validation add, some bugs
This commit is contained in:
Anatoliy Guskov 2018-07-06 12:07:47 +03:00 committed by GitHub
commit 85aac6fa0a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
23 changed files with 353 additions and 136 deletions

1
.gitignore vendored
View file

@ -9,3 +9,4 @@ console/cert.pem*
tags
dhcpd.*
webvirtcloud/settings.py
*migrations/*

View file

@ -32,7 +32,7 @@ print(''.join([random.SystemRandom().choice(haystack) for _ in range(50)]))
### Install WebVirtCloud panel (Ubuntu)
```bash
sudo apt-get -y install git python-virtualenv python-dev libxml2-dev libvirt-dev zlib1g-dev nginx supervisor libsasl2-modules gcc pkg-config
sudo apt-get -y install git python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev nginx supervisor libsasl2-modules gcc pkg-config
git clone https://github.com/retspen/webvirtcloud
cd webvirtcloud
cp webvirtcloud/settings.py.template webvirtcloud/settings.py

View file

@ -0,0 +1,35 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 12:36
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0009_auto_20171026_0805'),
]
operations = [
migrations.AlterField(
model_name='userattributes',
name='max_cpus',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value'),
),
migrations.AlterField(
model_name='userattributes',
name='max_disk_size',
field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value'),
),
migrations.AlterField(
model_name='userattributes',
name='max_instances',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value'),
),
migrations.AlterField(
model_name='userattributes',
name='max_memory',
field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value'),
),
]

View file

@ -0,0 +1,36 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 13:13
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('accounts', '0010_auto_20180625_1236'),
]
operations = [
migrations.AlterField(
model_name='userattributes',
name='max_cpus',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
),
migrations.AlterField(
model_name='userattributes',
name='max_disk_size',
field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
),
migrations.AlterField(
model_name='userattributes',
name='max_instances',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
),
migrations.AlterField(
model_name='userattributes',
name='max_memory',
field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.MinValueValidator(-1)]),
),
]

View file

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 13:31
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import re
class Migration(migrations.Migration):
dependencies = [
('accounts', '0011_auto_20180625_1313'),
]
operations = [
migrations.AlterField(
model_name='userattributes',
name='max_cpus',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
),
migrations.AlterField(
model_name='userattributes',
name='max_disk_size',
field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
),
migrations.AlterField(
model_name='userattributes',
name='max_instances',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
),
migrations.AlterField(
model_name='userattributes',
name='max_memory',
field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.')]),
),
]

View file

@ -0,0 +1,37 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 13:58
from __future__ import unicode_literals
import django.core.validators
from django.db import migrations, models
import re
class Migration(migrations.Migration):
dependencies = [
('accounts', '0012_auto_20180625_1331'),
]
operations = [
migrations.AlterField(
model_name='userattributes',
name='max_cpus',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
),
migrations.AlterField(
model_name='userattributes',
name='max_disk_size',
field=models.IntegerField(default=20, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
),
migrations.AlterField(
model_name='userattributes',
name='max_instances',
field=models.IntegerField(default=1, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
),
migrations.AlterField(
model_name='userattributes',
name='max_memory',
field=models.IntegerField(default=2048, help_text=b'-1 for unlimited. Any integer value', validators=[django.core.validators.RegexValidator(re.compile('^-?\\d+\\Z'), code='invalid', message='Enter a valid integer.'), django.core.validators.MinValueValidator(-1)]),
),
]

View file

@ -2,6 +2,7 @@ from django.db import models
from django.contrib.auth.models import User
from django.conf import settings
from instances.models import Instance
from django.core.validators import integer_validator, MinValueValidator
class UserInstance(models.Model):
@ -26,10 +27,10 @@ class UserSSHKey(models.Model):
class UserAttributes(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
can_clone_instances = models.BooleanField(default=True)
max_instances = models.IntegerField(default=1)
max_cpus = models.IntegerField(default=1)
max_memory = models.IntegerField(default=2048)
max_disk_size = models.IntegerField(default=20)
max_instances = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[integer_validator,MinValueValidator(-1),])
max_cpus = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[integer_validator,MinValueValidator(-1)])
max_memory = models.IntegerField(default=2048, help_text="-1 for unlimited. Any integer value", validators=[integer_validator,MinValueValidator(-1)])
max_disk_size = models.IntegerField(default=20, help_text="-1 for unlimited. Any integer value", validators=[integer_validator,MinValueValidator(-1)])
@staticmethod
def create_missing_userattributes(user):

View file

@ -92,25 +92,25 @@
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Max instances" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_instances" class="form-control" value="{{ user.userattributes.max_instances }}">
<input type="text" name="userattributes_max_instances" class="form-control" value="{{ user.userattributes.max_instances}}" required="True" >
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Max cpus" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_cpus" class="form-control" value="{{ user.userattributes.max_cpus }}">
<input type="text" name="userattributes_max_cpus" class="form-control" value="{{ user.userattributes.max_cpus }}" required="True">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Max memory (MB)" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_memory" class="form-control" value="{{ user.userattributes.max_memory }}">
<input type="text" name="userattributes_max_memory" class="form-control" value="{{ user.userattributes.max_memory}}" required="True">
</div>
</div>
<div class="form-group">
<label class="col-sm-4 control-label">{% trans "Max disk size (GB)" %}</label>
<div class="col-sm-6">
<input type="text" name="userattributes_max_disk_size" class="form-control" value="{{ user.userattributes.max_disk_size }}">
<input type="text" name="userattributes_max_disk_size" class="form-control" value="{{ user.userattributes.max_disk_size }}" required="True">
</div>
</div>
</div>

View file

@ -1,12 +1,11 @@
from django.conf.urls import url
from django.contrib import auth
from django.contrib.auth import views as auth_views
from . import views
urlpatterns = [
url(r'^login/$', 'django.contrib.auth.views.login',
{'template_name': 'login.html'}, name='login'),
url(r'^logout/$', 'django.contrib.auth.views.logout',
{'template_name': 'logout.html'}, name='logout'),
url(r'^profile/$', views.profile, name='profile'),
url(r'^$', views.accounts, name='accounts'),
url(r'^login/$', auth_views.LoginView.as_view(template_name='login.html'), name='login'),
url(r'^logout/$', auth_views.LogoutView.as_view(template_name='logout.html'), name='logout'),
url(r'^profile/$', views.profile, name='profile'), url(r'^$', views.accounts, name='accounts'),
url(r'^profile/(?P<user_id>[0-9]+)/$', views.account, name='account'),
]

View file

@ -8,6 +8,8 @@ from accounts.models import *
from instances.models import Instance
from accounts.forms import UserAddForm
from django.conf import settings
from django.core.validators import ValidationError
@login_required
@ -92,21 +94,30 @@ def accounts(request):
UserAttributes.configure_user(new_user)
return HttpResponseRedirect(request.get_full_path())
if 'edit' in request.POST:
CHECKBOX_MAPPING = {'on': True, 'off': False, }
user_id = request.POST.get('user_id', '')
user_pass = request.POST.get('user_pass', '')
user_edit = User.objects.get(id=user_id)
user_edit.set_password(user_pass)
user_edit.is_staff = request.POST.get('user_is_staff', False)
user_edit.is_superuser = request.POST.get('user_is_superuser', False)
if user_pass != '': user_edit.set_password(user_pass)
user_edit.is_staff = CHECKBOX_MAPPING.get(request.POST.get('user_is_staff', 'off'))
user_edit.is_superuser = CHECKBOX_MAPPING.get(request.POST.get('user_is_superuser', 'off'))
user_edit.save()
userattributes = user_edit.userattributes
userattributes.can_clone_instances = request.POST.get('userattributes_can_clone_instances', False)
userattributes.max_instances = request.POST.get('userattributes_max_instances', 0)
userattributes.max_cpus = request.POST.get('userattributes_max_cpus', 0)
userattributes.max_memory = request.POST.get('userattributes_max_memory', 0)
userattributes.max_disk_size = request.POST.get('userattributes_max_disk_size', 0)
userattributes.save()
UserAttributes.create_missing_userattributes(user_edit)
user_edit.userattributes.can_clone_instances = CHECKBOX_MAPPING.get(request.POST.get('userattributes_can_clone_instances', 'off'))
user_edit.userattributes.max_instances = request.POST.get('userattributes_max_instances', 0)
user_edit.userattributes.max_cpus = request.POST.get('userattributes_max_cpus', 0)
user_edit.userattributes.max_memory = request.POST.get('userattributes_max_memory', 0)
user_edit.userattributes.max_disk_size = request.POST.get('userattributes_max_disk_size', 0)
try:
user_edit.userattributes.clean_fields()
except ValidationError as exc:
error_messages.append(exc)
else:
user_edit.userattributes.save()
return HttpResponseRedirect(request.get_full_path())
if 'block' in request.POST:
user_id = request.POST.get('user_id', '')

View file

@ -123,7 +123,7 @@ def computes(request):
compute_edit.hostname = data['hostname']
compute_edit.login = data['login']
compute_edit.password = data['password']
compute.edit_details = data['details']
#compute_edit.details = data['details']
compute_edit.save()
return HttpResponseRedirect(request.get_full_path())
else:

View file

@ -39,19 +39,38 @@
<table class="table table-hover table-striped sortable-theme-bootstrap" data-sortable>
<thead >
<tr>
<th>#</th>
<th>Name<br>Description</th>
<th>Host<br>User</th>
<th>Status</th>
<th>VCPU</th>
<th>Memory<br>({% trans "MB" %})</th>
<th data-sortable="false" style="width:205px;">Actions</th>
<th data-sortable="false" style="width:205px;">Actions & Usage</th>
</tr>
</thead>
<tbody class="searchable">
{% for host, inst in all_host_vms.items %}
<!-- copied /-->
<tr class="success" style="font-size:16px">
<td>{{ forloop.counter }}</td>
<td><a href="{% url 'overview' host.0 %}">{{ host.1 }}</a></td>
<td></td>
<td>{% ifequal host.2 1 %}<span class="label label-success">{% trans "Active" %}
</span>{% endifequal %}
{% ifequal host.2 2 %}<span class="label label-danger">{% trans "Not Active" %}
</span>{% endifequal %}
{% ifequal host.2 3 %}<span class="label label-danger">{% trans "Connection Failed" %}
</span>{% endifequal %}
</td>
<td style="text-align:center;">{{ host.3 }}</td>
<td style="text-align:right;">{{ host.4|filesizeformat }}</td>
<td style="text-align:left;">Mem Usage: {{ host.5 }}%</td>
</tr>
<!-- copied /-->
{% for vm, info in inst.items %}
<tr>
<td><a href="{% url 'instance' host.0 vm %}">{{ vm }}</a><br><small><em>{{ info.title }}</em></small></td>
<td></td>
<td>{{ forloop.counter }} &emsp; <a href="{% url 'instance' host.0 vm %}">{{ vm }}</a><br><small><em>{{ info.title }}</em></small></td>
<td><a href="{% url 'overview' host.0 %}">{{ host.1 }}</a><br><small><em>{% if info.userinstances.count > 0 %}{{ info.userinstances.first_user.user.username }}{% if info.userinstances.count > 1 %} (+{{ info.userinstances.count|add:"-1" }}){% endif %}{% endif %}</em></small></td>
<td>{% ifequal info.status 1 %}
<span class="text-success">{% trans "Active" %}</span>
@ -63,8 +82,8 @@
<span class="text-warning">{% trans "Suspend" %}</span>
{% endifequal %}
</td>
<td>{{ info.vcpu }}</td>
<td>{{ info.memory }}</td>
<td style="text-align:center;">{{ info.vcpu }}</td>
<td style="text-align:right;">{{ info.memory |filesizeformat }}</td>
<td><form action="" method="post" role="form">{% csrf_token %}
<input type="hidden" name="name" value="{{ vm }}"/>
<input type="hidden" name="compute_id" value="{{ host.0 }}"/>

View file

@ -68,11 +68,22 @@ def instances(request):
i.delete()
try:
check_uuid = Instance.objects.get(compute_id=comp.id, name=vm)
check_uuid = Instance.objects.get(compute_id=comp["id"], name=vm)
if check_uuid.uuid != info['uuid']:
check_uuid.save()
all_host_vms[comp.id, comp.name][vm]['is_template'] = check_uuid.is_template
all_host_vms[comp.id, comp.name][vm]['userinstances'] = get_userinstances_info(check_uuid)
all_host_vms[comp_info["id"],
comp_info["name"],
comp_info["status"],
comp_info["cpu"],
comp_info["mem_size"],
comp_info["mem_perc"]][vm]['is_template'] = check_uuid.is_template
all_host_vms[comp_info["id"],
comp_info["name"],
comp_info["status"],
comp_info["cpu"],
comp_info["mem_size"],
comp_info["mem_perc"]][vm]['userinstances'] = get_userinstances_info(check_uuid)
except Instance.DoesNotExist:
check_uuid = Instance(compute_id=comp.id, name=vm, uuid=info['uuid'])
check_uuid.save()
@ -90,14 +101,27 @@ def instances(request):
all_user_vms[usr_inst].update({'compute_id': usr_inst.instance.compute.id})
else:
for comp in computes:
if connection_manager.host_is_up(comp.type, comp.hostname):
status = connection_manager.host_is_up(comp.type, comp.hostname)
if status:
try:
conn = wvmHostDetails(comp, comp.login, comp.password, comp.type)
host_instances = conn.get_host_instances()
if host_instances:
all_host_vms[comp.id, comp.name] = host_instances
for vm, info in host_instances.items():
refresh_instance_database(comp, vm, info)
comp_node_info = conn.get_node_info()
comp_mem = conn.get_memory_usage()
comp_instances = conn.get_host_instances(True)
if comp_instances:
comp_info= {
"id": comp.id,
"name": comp.name,
"status": status,
"cpu": comp_node_info[3],
"mem_size": comp_node_info[2],
"mem_perc": comp_mem['percent']
}
all_host_vms[comp_info["id"], comp_info["name"], comp_info["status"], comp_info["cpu"],
comp_info["mem_size"], comp_info["mem_perc"]] = comp_instances
for vm, info in comp_instances.items():
refresh_instance_database(comp_info, vm, info)
conn.close()
except libvirtError as lib_err:

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

7
static/js/bootstrap.min.js_332 Executable file

File diff suppressed because one or more lines are too long

View file

@ -444,8 +444,8 @@ class wvmConnect(object):
def get_net_device(self):
netdevice = []
def get_info(ctx):
dev_type = util.get_xpath(ctx, '/device/capability/@type')
interface = util.get_xpath(ctx, '/device/capability/interface')
dev_type = util.get_xpath('/device/capability/@type')
interface = util.get_xpath('/device/capability/interface')
return (dev_type, interface)
for dev in self.wvm.listAllDevices(0):
xml = dev.XMLDesc(0)
@ -454,19 +454,21 @@ class wvmConnect(object):
netdevice.append(interface)
return netdevice
def get_host_instances(self):
def get_host_instances(self, raw_mem_size=False):
vname = {}
def get_info(ctx):
mem = util.get_xpath(ctx, "/domain/currentMemory")
def get_info(doc):
mem = util.get_xpath(doc, "/domain/currentMemory")
mem = int(mem) / 1024
cur_vcpu = util.get_xpath(ctx, "/domain/vcpu/@current")
if raw_mem_size:
mem = int(mem) * (1024*1024)
cur_vcpu = util.get_xpath(doc, "/domain/vcpu/@current")
if cur_vcpu:
vcpu = cur_vcpu
else:
vcpu = util.get_xpath(ctx, "/domain/vcpu")
title = util.get_xpath(ctx, "/domain/title")
vcpu = util.get_xpath(doc, "/domain/vcpu")
title = util.get_xpath(doc, "/domain/title")
title = title if title else ''
description = util.get_xpath(ctx, "/domain/description")
description = util.get_xpath(doc, "/domain/description")
description = description if description else ''
return (mem, vcpu, title, description)
for name in self.get_instances():

View file

@ -3,11 +3,11 @@ from vrtManager.connection import wvmConnect
from vrtManager.util import get_xml_path
def cpu_version(ctx):
for info in ctx.xpathEval('/sysinfo/processor/entry'):
elem = info.xpathEval('@name')[0].content
def cpu_version(doc):
for info in doc.xpath('/sysinfo/processor/entry'):
elem = info.xpath('@name')[0]
if elem == 'version':
return info.content
return info.text
return 'Unknown'
@ -59,12 +59,12 @@ class wvmHostDetails(wvmConnect):
Function return host server information: hostname, cpu, memory, ...
"""
info = []
info.append(self.wvm.getHostname())
info.append(self.wvm.getInfo()[0])
info.append(self.wvm.getInfo()[1] * 1048576)
info.append(self.wvm.getInfo()[2])
info.append(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version))
info.append(self.wvm.getURI())
info.append(self.wvm.getHostname()) # hostname
info.append(self.wvm.getInfo()[0]) # architecture
info.append(self.wvm.getInfo()[1] * 1048576) # memory
info.append(self.wvm.getInfo()[2]) # cpu core count
info.append(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version)) # cpu version
info.append(self.wvm.getURI()) #uri
return info
def hypervisor_type(self):

View file

@ -203,10 +203,10 @@ class wvmInstance(wvmConnect):
def get_net_device(self):
def get_mac_ipaddr(net, mac_host):
def fixed(ctx):
for net in ctx.xpathEval('/network/ip/dhcp/host'):
mac = net.xpathEval('@mac')[0].content
host = net.xpathEval('@ip')[0].content
def fixed(doc):
for net in doc.xpath('/network/ip/dhcp/host'):
mac = net.xpath('@mac')[0]
host = net.xpath('@ip')[0]
if mac == mac_host:
return host
return None
@ -215,9 +215,9 @@ class wvmInstance(wvmConnect):
def networks(ctx):
result = []
for net in ctx.xpathEval('/domain/devices/interface'):
mac_host = net.xpathEval('mac/@address')[0].content
nic_host = net.xpathEval('source/@network|source/@bridge|source/@dev|target/@dev')[0].content
for net in ctx.xpath('/domain/devices/interface'):
mac_host = net.xpath('mac/@address')[0]
nic_host = net.xpath('source/@network|source/@bridge|source/@dev|target/@dev')[0]
try:
net = self.get_network(nic_host)
ip = get_mac_ipaddr(net, mac_host)
@ -229,7 +229,7 @@ class wvmInstance(wvmConnect):
return util.get_xml_path(self._XMLDesc(0), func=networks)
def get_disk_device(self):
def disks(ctx):
def disks(doc):
result = []
dev = None
volume = None
@ -237,13 +237,14 @@ class wvmInstance(wvmConnect):
src_fl = None
disk_format = None
disk_size = None
for disk in ctx.xpathEval('/domain/devices/disk'):
device = disk.xpathEval('@device')[0].content
for disk in doc.xpath('/domain/devices/disk'):
device = disk.xpath('@device')[0]
if device == 'disk':
try:
dev = disk.xpathEval('target/@dev')[0].content
src_fl = disk.xpathEval('source/@file|source/@dev|source/@name|source/@volume')[0].content
disk_format = disk.xpathEval('driver/@type')[0].content
dev = disk.xpath('target/@dev')[0]
src_fl = disk.xpath('source/@file|source/@dev|source/@name|source/@volume')[0]
disk_format = disk.xpath('driver/@type')[0]
try:
vol = self.get_volume_by_path(src_fl)
volume = vol.name()
@ -263,19 +264,19 @@ class wvmInstance(wvmConnect):
return util.get_xml_path(self._XMLDesc(0), func=disks)
def get_media_device(self):
def disks(ctx):
def disks(doc):
result = []
dev = None
volume = None
storage = None
src_fl = None
for media in ctx.xpathEval('/domain/devices/disk'):
device = media.xpathEval('@device')[0].content
for media in doc.xpath('/domain/devices/disk'):
device = media.xpath('@device')[0]
if device == 'cdrom':
try:
dev = media.xpathEval('target/@dev')[0].content
dev = media.xpath('target/@dev')
try:
src_fl = media.xpathEval('source/@file')[0].content
src_fl = media.xpath('source/@file')
vol = self.get_volume_by_path(src_fl)
volume = vol.name()
stg = vol.storagePoolLookupByVolume()
@ -487,8 +488,7 @@ class wvmInstance(wvmConnect):
return socket
def get_console_type(self):
console_type = util.get_xml_path(self._XMLDesc(0),
"/domain/devices/graphics/@type")
console_type = util.get_xml_path(self._XMLDesc(0),"/domain/devices/graphics/@type")
return console_type
def set_console_type(self, console_type):

View file

@ -166,11 +166,11 @@ class wvmNetwork(wvmConnect):
return bool(util.get_xml_path(xml, "/network/ip/dhcp/bootp/@file"))
def get_mac_ipaddr(self):
def network(ctx):
def network(doc):
result = []
for net in ctx.xpathEval('/network/ip/dhcp/host'):
host = net.xpathEval('@ip')[0].content
mac = net.xpathEval('@mac')[0].content
for net in doc.xpath('/network/ip/dhcp/host'):
host = net.xpath('@ip')[0]
mac = net.xpathEval('@mac')[0]
result.append({'host': host, 'mac': mac})
return result

View file

@ -1,5 +1,5 @@
import random
import libxml2
import lxml.etree as etree
import libvirt
import string
@ -86,42 +86,44 @@ def get_xml_path(xml, path=None, func=None):
of a passed function (receives xpathContext as its only arg)
"""
doc = None
ctx = None
#ctx = None
result = None
try:
doc = libxml2.parseDoc(xml)
ctx = doc.xpathNewContext()
#try:
doc = etree.fromstring(xml)
#ctx = doc.xpathNewContext()
if path:
result = get_xpath(ctx, path)
result = get_xpath(doc, path)
elif func:
result = func(ctx)
result = func(doc)
else:
raise ValueError("'path' or 'func' is required.")
finally:
if doc:
doc.freeDoc()
if ctx:
ctx.xpathFreeContext()
#finally:
#if doc:
# doc.freeDoc()
#if ctx:
# ctx.xpathFreeContext()
return result
def get_xpath(ctx, path):
def get_xpath(doc, path):
result = None
ret = ctx.xpathEval(path)
ret = doc.xpath(path)
if ret is not None:
if type(ret) == list:
if len(ret) >= 1:
result = ret[0].content
if hasattr(ret[0],'text'):
result = ret[0].text
else:
result = ret[0]
else:
result = ret
return result
def pretty_mem(val):
val = int(val)
if val > (10 * 1024 * 1024):

View file

@ -1,9 +1,17 @@
from django.conf.urls import patterns, include, url
from django.conf.urls import include, url
from instances.views import instances, instance, index
from storages.views import storages, storage
from networks.views import networks, network
from secrets.views import secrets
from create.views import create_instance
from interfaces.views import interfaces, interface
from console.views import console
# from django.contrib import admin
urlpatterns = patterns('',
url(r'^$', 'instances.views.index', name='index'),
url(r'^instances/$', 'instances.views.instances', name='instances'),
urlpatterns = [
url(r'^$', index, name='index'),
url(r'^instances/$', instances, name='instances'),
url(r'^instance/', include('instances.urls')),
url(r'^accounts/', include('accounts.urls')),
@ -11,23 +19,15 @@ urlpatterns = patterns('',
url(r'^logs/', include('logs.urls')),
url(r'^datasource/', include('datasource.urls')),
url(r'^compute/(?P<compute_id>[0-9]+)/storages/$',
'storages.views.storages', name='storages'),
url(r'^compute/(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$',
'storages.views.storage', name='storage'),
url(r'^compute/(?P<compute_id>[0-9]+)/networks/$',
'networks.views.networks', name='networks'),
url(r'^compute/(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$',
'networks.views.network', name='network'),
url(r'^compute/(?P<compute_id>[0-9]+)/interfaces/$',
'interfaces.views.interfaces', name='interfaces'),
url(r'^compute/(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$',
'interfaces.views.interface', name='interface'),
url(r'^compute/(?P<compute_id>[0-9]+)/secrets/$',
'secrets.views.secrets', name='secrets'),
url(r'^compute/(?P<compute_id>[0-9]+)/create/$',
'create.views.create_instance', name='create_instance'),
url(r'^compute/(?P<compute_id>[0-9]+)/storages/$', storages, name='storages'),
url(r'^compute/(?P<compute_id>[0-9]+)/storage/(?P<pool>[\w\-\.\/]+)/$', storage, name='storage'),
url(r'^compute/(?P<compute_id>[0-9]+)/networks/$', networks, name='networks'),
url(r'^compute/(?P<compute_id>[0-9]+)/network/(?P<pool>[\w\-\.]+)/$', network, name='network'),
url(r'^compute/(?P<compute_id>[0-9]+)/interfaces/$', interfaces, name='interfaces'),
url(r'^compute/(?P<compute_id>[0-9]+)/interface/(?P<iface>[\w\-\.\:]+)/$', interface, name='interface'),
url(r'^compute/(?P<compute_id>[0-9]+)/secrets/$', secrets, name='secrets'),
url(r'^compute/(?P<compute_id>[0-9]+)/create/$', create_instance, name='create_instance'),
url(r'^console/$', 'console.views.console', name='console'),
url(r'^console/$', console, name='console'),
# (r'^admin/', include(admin.site.urls)),
)
]