1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2025-03-13 13:35:17 +00:00

Migrate source code to python 3.7 and refine code style

This commit is contained in:
Gao Jiangmiao 2019-08-16 12:59:37 +08:00
parent 0e231a930d
commit a4d74a09a6
55 changed files with 192 additions and 306 deletions

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
from django.conf import settings from django.conf import settings

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations from django.db import migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
from django.conf import settings from django.conf import settings

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
from django.conf import settings from django.conf import settings

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,7 +1,4 @@
# -*- coding: utf-8 -*- from django.db import migrations
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -10,6 +7,3 @@ class Migration(migrations.Migration):
('accounts', '0004_userinstance_is_vnc'), ('accounts', '0004_userinstance_is_vnc'),
('accounts', '0007_auto_20160426_0635'), ('accounts', '0007_auto_20160426_0635'),
] ]
operations = [
]

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,7 +1,3 @@
# -*- 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 from django.db import migrations, models

View file

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 13:13
from __future__ import unicode_literals
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 13:31
from __future__ import unicode_literals
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import re import re

View file

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-06-25 13:58
from __future__ import unicode_literals
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models
import re import re

View file

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-08-08 11:36
from __future__ import unicode_literals
import django.core.validators import django.core.validators
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-08-08 11:49
from __future__ import unicode_literals
from django.conf import settings from django.conf import settings
from django.db import migrations, models from django.db import migrations, models
import django.db.models.deletion import django.db.models.deletion

View file

@ -24,10 +24,11 @@ class UserSSHKey(models.Model):
def __unicode__(self): def __unicode__(self):
return self.keyname return self.keyname
class UserAttributes(models.Model): class UserAttributes(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE) user = models.OneToOneField(User, on_delete=models.CASCADE)
can_clone_instances = models.BooleanField(default=True) can_clone_instances = models.BooleanField(default=True)
max_instances = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1),]) max_instances = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
max_cpus = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)]) max_cpus = models.IntegerField(default=1, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
max_memory = models.IntegerField(default=2048, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)]) max_memory = models.IntegerField(default=2048, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])
max_disk_size = models.IntegerField(default=20, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)]) max_disk_size = models.IntegerField(default=20, help_text="-1 for unlimited. Any integer value", validators=[MinValueValidator(-1)])

View file

@ -11,7 +11,6 @@ from django.conf import settings
from django.core.validators import ValidationError from django.core.validators import ValidationError
@login_required @login_required
def profile(request): def profile(request):
""" """
@ -70,6 +69,7 @@ def profile(request):
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
return render(request, 'profile.html', locals()) return render(request, 'profile.html', locals())
@login_required @login_required
def accounts(request): def accounts(request):
""" """
@ -103,7 +103,8 @@ def accounts(request):
user_pass = request.POST.get('user_pass', '') user_pass = request.POST.get('user_pass', '')
user_edit = User.objects.get(id=user_id) user_edit = User.objects.get(id=user_id)
if user_pass != '': user_edit.set_password(user_pass) 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_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.is_superuser = CHECKBOX_MAPPING.get(request.POST.get('user_is_superuser', 'off'))
user_edit.save() user_edit.save()

View file

@ -154,7 +154,7 @@ class ComputeAddSocketForm(forms.Form):
name = forms.CharField(error_messages={'required': _('No hostname has been entered')}, name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
max_length=20) max_length=20)
details = forms.CharField(error_messages={'required': _('No details has been entred')}, details = forms.CharField(error_messages={'required': _('No details has been entred')},
max_length=50) max_length=50)
def clean_name(self): def clean_name(self):
name = self.cleaned_data['name'] name = self.cleaned_data['name']

View file

@ -1,14 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [
]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Compute', name='Compute',
@ -20,8 +14,6 @@ class Migration(migrations.Migration):
('password', models.CharField(max_length=14, null=True, blank=True)), ('password', models.CharField(max_length=14, null=True, blank=True)),
('type', models.IntegerField()), ('type', models.IntegerField()),
], ],
options={
},
bases=(models.Model,), bases=(models.Model,),
), ),
] ]

View file

@ -1,8 +1,6 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [ dependencies = [

View file

@ -1,4 +1,3 @@
import time
import json import json
from django.utils import timezone from django.utils import timezone
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
@ -213,13 +212,12 @@ def get_compute_disk_buses(request, compute_id, disk):
if disk == 'disk': if disk == 'disk':
data['bus'] = sorted(disk_device_types) data['bus'] = sorted(disk_device_types)
elif disk == 'cdrom': elif disk == 'cdrom':
data['bus'] = ['ide', 'sata', 'scsi',] data['bus'] = ['ide', 'sata', 'scsi']
elif disk == 'floppy': elif disk == 'floppy':
data['bus'] = ['fdc',] data['bus'] = ['fdc']
elif disk == 'lun': elif disk == 'lun':
data['bus'] = ['scsi',] data['bus'] = ['scsi']
except libvirtError: except libvirtError:
pass pass
return HttpResponse(json.dumps(data)) return HttpResponse(json.dumps(data))

View file

@ -3,7 +3,7 @@
# gstfsd - WebVirtCloud daemon for managing VM's filesystem # gstfsd - WebVirtCloud daemon for managing VM's filesystem
# #
import SocketServer import socketserver
import json import json
import guestfs import guestfs
import re import re
@ -13,11 +13,11 @@ PORT = 16510
ADDRESS = "0.0.0.0" ADDRESS = "0.0.0.0"
class MyTCPServer(SocketServer.ThreadingTCPServer): class MyTCPServer(socketserver.ThreadingTCPServer):
allow_reuse_address = True allow_reuse_address = True
class MyTCPServerHandler(SocketServer.BaseRequestHandler): class MyTCPServerHandler(socketserver.BaseRequestHandler):
def handle(self): def handle(self):
# recive data # recive data
data = json.loads(self.request.recv(1024).strip()) data = json.loads(self.request.recv(1024).strip())
@ -42,17 +42,17 @@ class MyTCPServerHandler(SocketServer.BaseRequestHandler):
if data['action'] == 'publickey': if data['action'] == 'publickey':
if not gfs.is_dir('/root/.ssh'): if not gfs.is_dir('/root/.ssh'):
gfs.mkdir('/root/.ssh') gfs.mkdir('/root/.ssh')
gfs.chmod(0700, "/root/.ssh") gfs.chmod(0o700, "/root/.ssh")
gfs.write('/root/.ssh/authorized_keys', data['key']) gfs.write('/root/.ssh/authorized_keys', data['key'])
gfs.chmod(0600, '/root/.ssh/authorized_keys') gfs.chmod(0o600, '/root/.ssh/authorized_keys')
self.request.sendall(json.dumps({'return': 'success'})) self.request.sendall(json.dumps({'return': 'success'}))
gfs.umount(part) gfs.umount(part)
except RuntimeError: except RuntimeError:
pass pass
gfs.shutdown() gfs.shutdown()
gfs.close() gfs.close()
except RuntimeError, err: except RuntimeError as err:
self.request.sendall(json.dumps({'return': 'error', 'message': err.message})) self.request.sendall(json.dumps({'return': 'error', 'message': err}))
server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler) server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
server.serve_forever() server.serve_forever()

View file

@ -20,11 +20,11 @@ django.setup()
# sys.path.append(VENV_PATH) # sys.path.append(VENV_PATH)
import re import re
import Cookie import http.cookies
import socket import socket
from webvirtcloud.settings import WS_PORT, WS_HOST, WS_CERT from webvirtcloud.settings import WS_PORT, WS_HOST, WS_CERT
from vrtManager.connection import CONN_SSH, CONN_SOCKET from vrtManager.connection import CONN_SSH, CONN_SOCKET
from tunnel import Tunnel from console.tunnel import Tunnel
from optparse import OptionParser from optparse import OptionParser
parser = OptionParser() parser = OptionParser()
@ -120,7 +120,7 @@ def get_connection_infos(token):
console_host = conn.get_console_listen_addr() console_host = conn.get_console_listen_addr()
console_port = conn.get_console_port() console_port = conn.get_console_port()
console_socket = conn.get_console_socket() console_socket = conn.get_console_socket()
except Exception, e: except Exception as e:
logging.error('Fail to retrieve console connection infos for token %s : %s' % (token, e)) logging.error('Fail to retrieve console connection infos for token %s : %s' % (token, e))
raise raise
return (connhost, connport, connuser, conntype, console_host, return (connhost, connport, connuser, conntype, console_host,
@ -129,7 +129,7 @@ def get_connection_infos(token):
class CompatibilityMixIn(object): class CompatibilityMixIn(object):
def _new_client(self, daemon, socket_factory): def _new_client(self, daemon, socket_factory):
cookie = Cookie.SimpleCookie() cookie = http.cookies.SimpleCookie()
cookie.load(self.headers.getheader('cookie')) cookie.load(self.headers.getheader('cookie'))
if 'token' not in cookie: if 'token' not in cookie:
self.msg('No token cookie found !') self.msg('No token cookie found !')

View file

@ -27,6 +27,7 @@ import os
import socket import socket
import signal import signal
import logging import logging
from functools import reduce
class Tunnel(object): class Tunnel(object):

View file

@ -1,7 +1,5 @@
import re import re
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from instances.models import Instance from instances.models import Instance
from vrtManager.instance import wvmInstance from vrtManager.instance import wvmInstance

View file

@ -48,7 +48,7 @@ class NewVMForm(forms.Form):
virtio = forms.BooleanField(required=False) virtio = forms.BooleanField(required=False)
qemu_ga = forms.BooleanField(required=False) qemu_ga = forms.BooleanField(required=False)
mac = forms.CharField(required=False) mac = forms.CharField(required=False)
console_pass = forms.CharField(required=False,empty_value="", widget=forms.PasswordInput()) console_pass = forms.CharField(required=False, empty_value="", widget=forms.PasswordInput())
video = forms.CharField(error_messages={'required': _('Please select a graphic display')}) video = forms.CharField(error_messages={'required': _('Please select a graphic display')})
listener_addr = forms.ChoiceField(required=True, widget=forms.RadioSelect, choices=QEMU_CONSOLE_LISTEN_ADDRESSES) listener_addr = forms.ChoiceField(required=True, widget=forms.RadioSelect, choices=QEMU_CONSOLE_LISTEN_ADDRESSES)
@ -60,4 +60,3 @@ class NewVMForm(forms.Form):
elif len(name) > 20: elif len(name) > 20:
raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters')) raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
return name return name

View file

@ -1,14 +1,8 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
class Migration(migrations.Migration): class Migration(migrations.Migration):
dependencies = [
]
operations = [ operations = [
migrations.CreateModel( migrations.CreateModel(
name='Flavor', name='Flavor',
@ -19,8 +13,6 @@ class Migration(migrations.Migration):
('vcpu', models.IntegerField()), ('vcpu', models.IntegerField()),
('disk', models.IntegerField()), ('disk', models.IntegerField()),
], ],
options={
},
bases=(models.Model,), bases=(models.Model,),
), ),
] ]

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations from django.db import migrations

View file

@ -109,7 +109,7 @@ def create_instance(request, compute_id):
msg = _("A virtual machine with this name already exists") msg = _("A virtual machine with this name already exists")
error_messages.append(msg) error_messages.append(msg)
if Instance.objects.filter(name__exact=data['name']): if Instance.objects.filter(name__exact=data['name']):
messages.warning(request,_("There is an instance with same name. Are you sure?")) messages.warning(request, _("There is an instance with same name. Are you sure?"))
if not error_messages: if not error_messages:
if data['hdd_size']: if data['hdd_size']:
if not data['mac']: if not data['mac']:

View file

@ -1,4 +1,4 @@
-r ../conf/requirements.txt -r ../conf/requirements.txt
pep8==1.7.1 pycodestyle
pyflakes==2.1.1 pyflakes==2.1.1
pylint==1.9.4 pylint==1.9.4

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models
import datetime import datetime

View file

@ -1,7 +1,3 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.13 on 2018-07-24 11:36
from __future__ import unicode_literals
from django.db import migrations, models from django.db import migrations, models

View file

@ -1,14 +1,15 @@
from django.conf.urls import url from django.conf.urls import url
from . import views from . import views
urlpatterns = [ urlpatterns = [
url(r'^$', views.allinstances, name='allinstances'), url(r'^$', views.allinstances, name='allinstances'),
url(r'^(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.instance, name='instance'), url(r'^(?P<compute_id>[0-9]+)/(?P<vname>[\w\-.]+)/$', views.instance, name='instance'),
url(r'^statistics/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_graph, name='inst_graph'), url(r'^statistics/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-.]+)/$', views.inst_graph, name='inst_graph'),
url(r'^status/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-\.]+)/$', views.inst_status, name='inst_status'), url(r'^status/(?P<compute_id>[0-9]+)/(?P<vname>[\w\-.]+)/$', views.inst_status, name='inst_status'),
url(r'^guess_mac_address/(?P<vname>[\w\-\.]+)/$', views.guess_mac_address, name='guess_mac_address'), url(r'^guess_mac_address/(?P<vname>[\w\-.]+)/$', views.guess_mac_address, name='guess_mac_address'),
url(r'^guess_clone_name/$', views.guess_clone_name, name='guess_clone_name'), url(r'^guess_clone_name/$', views.guess_clone_name, name='guess_clone_name'),
url(r'^random_mac_address/$', views.random_mac_address, name='random_mac_address'), url(r'^random_mac_address/$', views.random_mac_address, name='random_mac_address'),
url(r'^check_instance/(?P<vname>[\w\-\.]+)/$', views.check_instance, name='check_instance'), url(r'^check_instance/(?P<vname>[\w\-.]+)/$', views.check_instance, name='check_instance'),
url(r'^sshkeys/(?P<vname>[\w\-\.]+)/$', views.sshkeys, name='sshkeys'), url(r'^sshkeys/(?P<vname>[\w\-.]+)/$', views.sshkeys, name='sshkeys'),
] ]

View file

@ -27,6 +27,7 @@ from logs.views import addlogmsg
from django.conf import settings from django.conf import settings
from django.contrib import messages from django.contrib import messages
@login_required @login_required
def index(request): def index(request):
""" """
@ -129,17 +130,17 @@ def instance(request, compute_id, vname):
return 0 return 0
size_str = size_str.encode('ascii', 'ignore').upper().translate(None, " B") size_str = size_str.encode('ascii', 'ignore').upper().translate(None, " B")
if 'K' == size_str[-1]: if 'K' == size_str[-1]:
return long(float(size_str[:-1])) << 10 return int(float(size_str[:-1])) << 10
elif 'M' == size_str[-1]: elif 'M' == size_str[-1]:
return long(float(size_str[:-1])) << 20 return int(float(size_str[:-1])) << 20
elif 'G' == size_str[-1]: elif 'G' == size_str[-1]:
return long(float(size_str[:-1])) << 30 return int(float(size_str[:-1])) << 30
elif 'T' == size_str[-1]: elif 'T' == size_str[-1]:
return long(float(size_str[:-1])) << 40 return int(float(size_str[:-1])) << 40
elif 'P' == size_str[-1]: elif 'P' == size_str[-1]:
return long(float(size_str[:-1])) << 50 return int(float(size_str[:-1])) << 50
else: else:
return long(float(size_str)) return int(float(size_str))
def get_clone_free_names(size=10): def get_clone_free_names(size=10):
prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
@ -213,7 +214,7 @@ def instance(request, compute_id, vname):
if media: if media:
existing_media_devs = [m['dev'] for m in media] existing_media_devs = [m['dev'] for m in media]
for l in string.lowercase: for l in string.ascii_lowercase:
dev = dev_base + l dev = dev_base + l
if dev not in existing_disk_devs and dev not in existing_media_devs: if dev not in existing_disk_devs and dev not in existing_media_devs:
return dev return dev
@ -495,7 +496,7 @@ def instance(request, compute_id, vname):
format = connCreate.get_volume_type(name) format = connCreate.get_volume_type(name)
path = connCreate.get_target_path() path = connCreate.get_target_path()
target = get_new_disk_dev(media, disks, bus) target = get_new_disk_dev(media, disks, bus)
source = path + "/" + name; source = path + "/" + name
conn.attach_disk(source, target, subdriver=format, cache=cache, targetbus=bus) conn.attach_disk(source, target, subdriver=format, cache=cache, targetbus=bus)
msg = _('Attach Existing disk: ' + target) msg = _('Attach Existing disk: ' + target)
@ -719,7 +720,8 @@ def instance(request, compute_id, vname):
conn.change_network(network_data) conn.change_network(network_data)
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
msg = _("Network Device Config is changed. Please shutdown instance to activate.") msg = _("Network Device Config is changed. Please shutdown instance to activate.")
if conn.get_status() != 5: messages.success(request, msg) if conn.get_status() != 5:
messages.success(request, msg)
return HttpResponseRedirect(request.get_full_path() + '#network') return HttpResponseRedirect(request.get_full_path() + '#network')
if 'add_network' in request.POST: if 'add_network' in request.POST:
@ -904,17 +906,17 @@ def get_host_instances(request, comp):
inst_on_db.save() inst_on_db.save()
all_host_vms[comp["id"], all_host_vms[comp["id"],
comp["name"], comp["name"],
comp["status"], comp["status"],
comp["cpu"], comp["cpu"],
comp["mem_size"], comp["mem_size"],
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
all_host_vms[comp["id"], all_host_vms[comp["id"],
comp["name"], comp["name"],
comp["status"], comp["status"],
comp["cpu"], comp["cpu"],
comp["mem_size"], comp["mem_size"],
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db) comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
except Instance.DoesNotExist: except Instance.DoesNotExist:
inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid']) inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid'])
inst_on_db.save() inst_on_db.save()
@ -1177,7 +1179,6 @@ def sshkeys(request, vname):
:param vm: :param vm:
:return: :return:
""" """
instance_keys = [] instance_keys = []
userinstances = UserInstance.objects.filter(instance__name=vname) userinstances = UserInstance.objects.filter(instance__name=vname)
@ -1213,7 +1214,7 @@ def delete_instance(instance, delete_disk=False):
print("Forcing shutdown") print("Forcing shutdown")
conn.force_shutdown() conn.force_shutdown()
if delete_disk: if delete_disk:
snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k:k['date']) snapshots = sorted(conn.get_snapshot(), reverse=True, key=lambda k: k['date'])
for snap in snapshots: for snap in snapshots:
print("Deleting snapshot {}".format(snap['name'])) print("Deleting snapshot {}".format(snap['name']))
conn.snapshot_delete(snap['name']) conn.snapshot_delete(snap['name'])
@ -1228,4 +1229,3 @@ def delete_instance(instance, delete_disk=False):
except libvirtError as lib_err: except libvirtError as lib_err:
print("Error removing instance {} on compute {}".format(instance_name, compute.hostname)) print("Error removing instance {} on compute {}".format(instance_name, compute.hostname))
raise lib_err raise lib_err

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
from django.conf import settings from django.conf import settings

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations
from django.conf import settings from django.conf import settings

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations from django.db import models, migrations

View file

@ -16,7 +16,7 @@ class AddNetPool(forms.Form):
def clean_name(self): def clean_name(self):
name = self.cleaned_data['name'] name = self.cleaned_data['name']
have_symbol = re.match('^[a-zA-Z0-9\.\_\-]+$', name) have_symbol = re.match('^[a-zA-Z0-9._-]+$', name)
if not have_symbol: if not have_symbol:
raise forms.ValidationError(_('The pool name must not contain any special characters')) raise forms.ValidationError(_('The pool name must not contain any special characters'))
elif len(name) > 20: elif len(name) > 20:
@ -35,7 +35,7 @@ class AddNetPool(forms.Form):
def clean_bridge_name(self): def clean_bridge_name(self):
bridge_name = self.cleaned_data['bridge_name'] bridge_name = self.cleaned_data['bridge_name']
if self.cleaned_data['forward'] == 'bridge': if self.cleaned_data['forward'] == 'bridge':
have_symbol = re.match('^[a-zA-Z0-9\.\_\:\-]+$', bridge_name) have_symbol = re.match('^[a-zA-Z0-9._:-]+$', bridge_name)
if not have_symbol: if not have_symbol:
raise forms.ValidationError(_('The pool bridge name must not contain any special characters')) raise forms.ValidationError(_('The pool bridge name must not contain any special characters'))
elif len(bridge_name) > 20: elif len(bridge_name) > 20:

View file

@ -153,13 +153,11 @@ def network(request, compute_id, pool):
edit_xml = request.POST.get('edit_xml', '') edit_xml = request.POST.get('edit_xml', '')
if edit_xml: if edit_xml:
try: try:
new_conn = wvmNetworks(compute.hostname, new_conn = wvmNetworks(compute.hostname, compute.login, compute.password, compute.type)
compute.login,
compute.password,
compute.type)
conn.define_network(edit_xml) conn.define_network(edit_xml)
if conn.is_active(): if conn.is_active():
messages.success(request, _("Network XML is changed. Stop and start network to activate new config.")) messages.success(request,
_("Network XML is changed. Stop and start network to activate new config."))
else: else:
messages.success(request, _("Network XML is changed.")) messages.success(request, _("Network XML is changed."))
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.apps import AppConfig from django.apps import AppConfig

View file

@ -1,6 +1,3 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404

View file

@ -42,7 +42,7 @@ class AddStgPool(forms.Form):
def clean_source(self): def clean_source(self):
storage_type = self.cleaned_data['stg_type'] storage_type = self.cleaned_data['stg_type']
source = self.cleaned_data['source'] source = self.cleaned_data['source']
have_symbol = re.match('^[a-zA-Z0-9\/]+$', source) have_symbol = re.match('^[a-zA-Z0-9/]+$', source)
if storage_type == 'logical' or storage_type == 'netfs': if storage_type == 'logical' or storage_type == 'netfs':
if not source: if not source:
raise forms.ValidationError(_('No device has been entered')) raise forms.ValidationError(_('No device has been entered'))

View file

@ -10,6 +10,7 @@ from libvirt import libvirtError
from django.contrib import messages from django.contrib import messages
import json import json
@login_required @login_required
def storages(request, compute_id): def storages(request, compute_id):
""" """

View file

@ -6,12 +6,11 @@ Further Information might be available at:
https://github.com/haypo/python-ipy https://github.com/haypo/python-ipy
""" """
__version__ = '0.83' __version__ = '1.00'
import bisect import bisect
import collections import collections
import sys
import types
# Definition of the Ranges for IPv4 IPs # Definition of the Ranges for IPv4 IPs
# this should include www.iana.org/assignments/ipv4-address-space # this should include www.iana.org/assignments/ipv4-address-space
@ -21,7 +20,7 @@ IPv4ranges = {
'00000000': 'PRIVATE', # 0/8 '00000000': 'PRIVATE', # 0/8
'00001010': 'PRIVATE', # 10/8 '00001010': 'PRIVATE', # 10/8
'0110010001': 'CARRIER_GRADE_NAT', # 100.64/10 '0110010001': 'CARRIER_GRADE_NAT', # 100.64/10
'01111111': 'PRIVATE', # 127.0/8 '01111111': 'LOOPBACK', # 127.0/8
'1': 'PUBLIC', # fall back '1': 'PUBLIC', # fall back
'1010100111111110': 'PRIVATE', # 169.254/16 '1010100111111110': 'PRIVATE', # 169.254/16
'101011000001': 'PRIVATE', # 172.16/12 '101011000001': 'PRIVATE', # 172.16/12
@ -121,14 +120,6 @@ MAX_IPV6_ADDRESS = 0xffffffffffffffffffffffffffffffff
IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000 IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000
IPV6_MAP_MASK = 0x00000000000000000000ffff00000000 IPV6_MAP_MASK = 0x00000000000000000000ffff00000000
if sys.version_info >= (3,):
INT_TYPES = (int,)
STR_TYPES = (str,)
xrange = range
else:
INT_TYPES = (int, long)
STR_TYPES = (str, unicode)
class IPint(object): class IPint(object):
"""Handling of IP addresses returning integers. """Handling of IP addresses returning integers.
@ -175,7 +166,7 @@ class IPint(object):
prefixlen = -1 prefixlen = -1
# handling of non string values in constructor # handling of non string values in constructor
if isinstance(data, INT_TYPES): if isinstance(data, int):
self.ip = int(data) self.ip = int(data)
if ipversion == 0: if ipversion == 0:
if self.ip <= MAX_IPV4_ADDRESS: if self.ip <= MAX_IPV4_ADDRESS:
@ -199,7 +190,7 @@ class IPint(object):
self._ipversion = data._ipversion self._ipversion = data._ipversion
self._prefixlen = data._prefixlen self._prefixlen = data._prefixlen
self.ip = data.ip self.ip = data.ip
elif isinstance(data, STR_TYPES): elif isinstance(data, str):
# TODO: refactor me! # TODO: refactor me!
# splitting of a string into IP and prefixlen et. al. # splitting of a string into IP and prefixlen et. al.
x = data.split('-') x = data.split('-')
@ -219,7 +210,7 @@ class IPint(object):
# make sure the broadcast is the same as the last ip # make sure the broadcast is the same as the last ip
# otherwise it will return /16 for something like: # otherwise it will return /16 for something like:
# 192.168.0.0-192.168.191.255 # 192.168.0.0-192.168.191.255
if IP('%s/%s' % (ip, 32 - netbits)).broadcast().int() != last: if IP('%s/%s' % (ip, 32-netbits)).broadcast().int() != last:
raise ValueError("the range %s is not on a network boundary." % data) raise ValueError("the range %s is not on a network boundary." % data)
elif len(x) == 1: elif len(x) == 1:
x = data.split('/') x = data.split('/')
@ -243,7 +234,7 @@ class IPint(object):
else: else:
raise ValueError("can't parse") raise ValueError("can't parse")
(self.ip, parsedVersion) = parseAddress(ip) (self.ip, parsedVersion) = parseAddress(ip, ipversion)
if ipversion == 0: if ipversion == 0:
ipversion = parsedVersion ipversion = parsedVersion
if prefixlen == -1: if prefixlen == -1:
@ -318,15 +309,15 @@ class IPint(object):
(self._ipversion == 6 and self._prefixlen == 128): (self._ipversion == 6 and self._prefixlen == 128):
if self.NoPrefixForSingleIp: if self.NoPrefixForSingleIp:
want = 0 want = 0
if want == None: if want is None:
want = self.WantPrefixLen want = self.WantPrefixLen
if want == None: if want is None:
want = 1 want = 1
if want: if want:
if want == 2: if want == 2:
# this should work with IP and IPint # this should work with IP and IPint
netmask = self.netmask() netmask = self.netmask()
if not isinstance(netmask, INT_TYPES): if not isinstance(netmask, int):
netmask = netmask.int() netmask = netmask.int()
return "/%s" % (intToIp(netmask, self._ipversion)) return "/%s" % (intToIp(netmask, self._ipversion))
elif want == 3: elif want == 3:
@ -354,7 +345,7 @@ class IPint(object):
""" """
bits = _ipVersionToLen(self._ipversion) bits = _ipVersionToLen(self._ipversion)
if self.WantPrefixLen == None and wantprefixlen == None: if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 0 wantprefixlen = 0
ret = _intToBin(self.ip) ret = _intToBin(self.ip)
return '0' * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen) return '0' * (bits - len(ret)) + ret + self._printPrefix(wantprefixlen)
@ -370,7 +361,7 @@ class IPint(object):
'ffff:ffff:ffff:ffff:ffff:f:f:fffc/127' 'ffff:ffff:ffff:ffff:ffff:f:f:fffc/127'
""" """
if self.WantPrefixLen == None and wantprefixlen == None: if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 1 wantprefixlen = 1
if self._ipversion == 4: if self._ipversion == 4:
@ -385,7 +376,7 @@ class IPint(object):
# every element of followingzeros will contain the number of zeros # every element of followingzeros will contain the number of zeros
# following the corresponding element of hextets # following the corresponding element of hextets
followingzeros = [0] * 8 followingzeros = [0] * 8
for i in xrange(len(hextets)): for i in range(len(hextets)):
followingzeros[i] = _countFollowingZeros(hextets[i:]) followingzeros[i] = _countFollowingZeros(hextets[i:])
# compressionpos is the position where we can start removing zeros # compressionpos is the position where we can start removing zeros
compressionpos = followingzeros.index(max(followingzeros)) compressionpos = followingzeros.index(max(followingzeros))
@ -413,7 +404,7 @@ class IPint(object):
2001:658:22a:cafe:200:0:0:1 2001:658:22a:cafe:200:0:0:1
""" """
if self.WantPrefixLen == None and wantprefixlen == None: if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 1 wantprefixlen = 1
if self._ipversion == 4: if self._ipversion == 4:
@ -434,7 +425,7 @@ class IPint(object):
2001:0658:022a:cafe:0200:0000:0000:0001 2001:0658:022a:cafe:0200:0000:0000:0001
""" """
if self.WantPrefixLen == None and wantprefixlen == None: if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 1 wantprefixlen = 1
return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen) return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen)
@ -448,7 +439,7 @@ class IPint(object):
0x20010658022acafe0200000000000001 0x20010658022acafe0200000000000001
""" """
if self.WantPrefixLen == None and wantprefixlen == None: if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 0 wantprefixlen = 0
x = '0x%x' % self.ip x = '0x%x' % self.ip
@ -463,7 +454,7 @@ class IPint(object):
42540616829182469433547762482097946625 42540616829182469433547762482097946625
""" """
if self.WantPrefixLen == None and wantprefixlen == None: if self.WantPrefixLen is None and wantprefixlen is None:
wantprefixlen = 0 wantprefixlen = 0
x = '%d' % self.ip x = '%d' % self.ip
@ -473,7 +464,7 @@ class IPint(object):
"""Return a description of the IP type ('PRIVATE', 'RESERVED', etc). """Return a description of the IP type ('PRIVATE', 'RESERVED', etc).
>>> print(IP('127.0.0.1').iptype()) >>> print(IP('127.0.0.1').iptype())
PRIVATE LOOPBACK
>>> print(IP('192.168.1.1').iptype()) >>> print(IP('192.168.1.1').iptype())
PRIVATE PRIVATE
>>> print(IP('195.185.1.2').iptype()) >>> print(IP('195.185.1.2').iptype())
@ -496,7 +487,7 @@ class IPint(object):
raise ValueError("only IPv4 and IPv6 supported") raise ValueError("only IPv4 and IPv6 supported")
bits = self.strBin() bits = self.strBin()
for i in xrange(len(bits), 0, -1): for i in range(len(bits), 0, -1):
if bits[:i] in iprange: if bits[:i] in iprange:
return iprange[bits[:i]] return iprange[bits[:i]]
return "unknown" return "unknown"
@ -553,6 +544,9 @@ class IPint(object):
""" """
return True return True
def __bool__(self):
return self.__nonzero__()
def __len__(self): def __len__(self):
""" """
Return the length of a subnet. Return the length of a subnet.
@ -606,8 +600,8 @@ class IPint(object):
""" """
if isinstance(key, slice): if isinstance(key, slice):
return [self.ip + int(x) for x in xrange(*key.indices(len(self)))] return [self.ip + int(x) for x in range(*key.indices(len(self)))]
if not isinstance(key, INT_TYPES): if not isinstance(key, int):
raise TypeError raise TypeError
if key < 0: if key < 0:
if abs(key) <= self.len(): if abs(key) <= self.len():
@ -848,13 +842,13 @@ class IP(IPint):
for x in self: for x in self:
ret.append(x.reverseName()) ret.append(x.reverseName())
elif self.len() < 2 ** 16: elif self.len() < 2 ** 16:
for i in xrange(0, self.len(), 2 ** 8): for i in range(0, self.len(), 2 ** 8):
ret.append(self[i].reverseName()[2:]) ret.append(self[i].reverseName()[2:])
elif self.len() < 2 ** 24: elif self.len() < 2 ** 24:
for i in xrange(0, self.len(), 2 ** 16): for i in range(0, self.len(), 2 ** 16):
ret.append(self[i].reverseName()[4:]) ret.append(self[i].reverseName()[4:])
else: else:
for i in xrange(0, self.len(), 2 ** 24): for i in range(0, self.len(), 2 ** 24):
ret.append(self[i].reverseName()[6:]) ret.append(self[i].reverseName()[6:])
return ret return ret
elif self._ipversion == 6: elif self._ipversion == 6:
@ -952,7 +946,7 @@ class IP(IPint):
127.0.0.3 127.0.0.3
""" """
if isinstance(key, slice): if isinstance(key, slice):
return [IP(IPint.__getitem__(self, x), ipversion=self._ipversion) for x in xrange(*key.indices(len(self)))] return [IP(IPint.__getitem__(self, x), ipversion=self._ipversion) for x in range(*key.indices(len(self)))]
return IP(IPint.__getitem__(self, key), ipversion=self._ipversion) return IP(IPint.__getitem__(self, key), ipversion=self._ipversion)
def __repr__(self): def __repr__(self):
@ -1183,7 +1177,7 @@ class IPSet(collections.MutableSet):
# prefix length and differ only on the last bit of the prefix # prefix length and differ only on the last bit of the prefix
addrlen = len(self.prefixes) addrlen = len(self.prefixes)
i = 0 i = 0
while i < addrlen - 1: while i < addrlen-1:
j = i + 1 j = i + 1
try: try:
@ -1328,7 +1322,7 @@ def _parseAddressIPv6(ipstr):
return value return value
def parseAddress(ipstr): def parseAddress(ipstr, ipversion=0):
""" """
Parse a string and return the corresponding IP address (as integer) Parse a string and return the corresponding IP address (as integer)
and a guess of the IP version. and a guess of the IP version.
@ -1397,7 +1391,7 @@ def parseAddress(ipstr):
# assume IPv6 in pure hexadecimal notation # assume IPv6 in pure hexadecimal notation
return (hexval, 6) return (hexval, 6)
elif ipstr.find('.') != -1 or (intval is not None and intval < 256): elif ipstr.find('.') != -1 or (intval is not None and intval < 256 and ipversion != 6):
# assume IPv4 ('127' gets interpreted as '127.0.0.0') # assume IPv4 ('127' gets interpreted as '127.0.0.0')
bytes = ipstr.split('.') bytes = ipstr.split('.')
if len(bytes) > 4: if len(bytes) > 4:
@ -1415,7 +1409,7 @@ def parseAddress(ipstr):
# will be interpreted as IPv4 first byte # will be interpreted as IPv4 first byte
if intval > MAX_IPV6_ADDRESS: if intval > MAX_IPV6_ADDRESS:
raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval)) raise ValueError("IP Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, intval))
if intval <= MAX_IPV4_ADDRESS: if intval <= MAX_IPV4_ADDRESS and ipversion != 6:
return (intval, 4) return (intval, 4)
else: else:
return (intval, 6) return (intval, 6)
@ -1436,7 +1430,7 @@ def intToIp(ip, version):
if version == 4: if version == 4:
if ip > MAX_IPV4_ADDRESS: if ip > MAX_IPV4_ADDRESS:
raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, ip)) raise ValueError("IPv4 Address can't be larger than %x: %x" % (MAX_IPV4_ADDRESS, ip))
for l in xrange(4): for l in range(4):
ret = str(ip & 0xff) + '.' + ret ret = str(ip & 0xff) + '.' + ret
ip = ip >> 8 ip = ip >> 8
ret = ret[:-1] ret = ret[:-1]
@ -1444,7 +1438,7 @@ def intToIp(ip, version):
if ip > MAX_IPV6_ADDRESS: if ip > MAX_IPV6_ADDRESS:
raise ValueError("IPv6 Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, ip)) raise ValueError("IPv6 Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, ip))
l = "%032x" % ip l = "%032x" % ip
for x in xrange(1, 33): for x in range(1, 33):
ret = l[-x] + ret ret = l[-x] + ret
if x % 4 == 0: if x % 4 == 0:
ret = ':' + ret ret = ':' + ret
@ -1617,7 +1611,7 @@ def _prefixlenToNetmask(prefixlen, version):
return 0 return 0
elif prefixlen < 0: elif prefixlen < 0:
raise ValueError("Prefixlen must be > 0") raise ValueError("Prefixlen must be > 0")
return ((2 << prefixlen - 1) - 1) << (_ipVersionToLen(version) - prefixlen) return ((2 << prefixlen-1) - 1) << (_ipVersionToLen(version) - prefixlen)
def _remove_subprefix(prefix, subprefix): def _remove_subprefix(prefix, subprefix):
@ -1631,8 +1625,8 @@ def _remove_subprefix(prefix, subprefix):
# Start cutting in half, recursively # Start cutting in half, recursively
prefixes = [ prefixes = [
IP('%s/%d' % (prefix[0], prefix._prefixlen + 1)), IP('%s/%d' % (prefix[0], prefix._prefixlen+1)),
IP('%s/%d' % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)), IP('%s/%d' % (prefix[int(prefix.len()/2)], prefix._prefixlen+1)),
] ]
if subprefix in prefixes[0]: if subprefix in prefixes[0]:
return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]]) return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]])

View file

@ -2,7 +2,7 @@ import libvirt
import threading import threading
import socket import socket
from vrtManager import util from vrtManager import util
from rwlock import ReadWriteLock from vrtManager.rwlock import ReadWriteLock
from django.conf import settings from django.conf import settings
from libvirt import libvirtError from libvirt import libvirtError
@ -216,18 +216,18 @@ class wvmConnection(object):
def __unicode__(self): def __unicode__(self):
if self.type == CONN_TCP: if self.type == CONN_TCP:
type_str = u'tcp' type_str = 'tcp'
elif self.type == CONN_SSH: elif self.type == CONN_SSH:
type_str = u'ssh' type_str = 'ssh'
elif self.type == CONN_TLS: elif self.type == CONN_TLS:
type_str = u'tls' type_str = 'tls'
else: else:
type_str = u'invalid_type' type_str = 'invalid_type'
return u'qemu+{type}://{user}@{host}/system'.format(type=type_str, user=self.login, host=self.host) return f'qemu+{type_str}://{self.login}@{self.host}/system'
def __repr__(self): def __repr__(self):
return '<wvmConnection {connection_str}>'.format(connection_str=unicode(self)) return '<wvmConnection {connection_str}>'.format(connection_str=str(self))
class wvmConnectionManager(object): class wvmConnectionManager(object):
@ -272,19 +272,19 @@ class wvmConnectionManager(object):
raises libvirtError if (re)connecting fails raises libvirtError if (re)connecting fails
""" """
# force all string values to unicode # force all string values to unicode
host = unicode(host) host = str(host)
login = unicode(login) login = str(login)
passwd = unicode(passwd) if passwd is not None else None passwd = str(passwd) if passwd is not None else None
connection = self._search_connection(host, login, passwd, conn) connection = self._search_connection(host, login, passwd, conn)
if (connection is None): if connection is None:
self._connections_lock.acquireWrite() self._connections_lock.acquireWrite()
try: try:
# we have to search for the connection again after aquireing the write lock # we have to search for the connection again after aquireing the write lock
# as the thread previously holding the write lock may have already added our connection # as the thread previously holding the write lock may have already added our connection
connection = self._search_connection(host, login, passwd, conn) connection = self._search_connection(host, login, passwd, conn)
if (connection is None): if connection is None:
# create a new connection if a matching connection does not already exist # create a new connection if a matching connection does not already exist
connection = wvmConnection(host, login, passwd, conn) connection = wvmConnection(host, login, passwd, conn)
@ -332,6 +332,7 @@ class wvmConnectionManager(object):
except Exception as err: except Exception as err:
return err return err
connection_manager = wvmConnectionManager( connection_manager = wvmConnectionManager(
settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, 'LIBVIRT_KEEPALIVE_INTERVAL') else 5, settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, 'LIBVIRT_KEEPALIVE_INTERVAL') else 5,
settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, 'LIBVIRT_KEEPALIVE_COUNT') else 5 settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, 'LIBVIRT_KEEPALIVE_COUNT') else 5
@ -368,7 +369,7 @@ class wvmConnect(object):
minor = ver / 1000 minor = ver / 1000
ver = ver % 1000 ver = ver % 1000
release = ver release = ver
return "%s.%s.%s" % (major,minor,release) return f"{major}.{minor}.{release}"
def get_lib_version(self): def get_lib_version(self):
ver = self.wvm.getLibVersion() ver = self.wvm.getLibVersion()
@ -377,7 +378,7 @@ class wvmConnect(object):
minor = ver / 1000 minor = ver / 1000
ver %= 1000 ver %= 1000
release = ver release = ver
return "%s.%s.%s" % (major,minor,release) return f"{major}.{minor}.{release}"
def is_kvm_supported(self): def is_kvm_supported(self):
"""Return KVM capabilities.""" """Return KVM capabilities."""
@ -432,7 +433,7 @@ class wvmConnect(object):
for arch in ctx.xpath('/capabilities/guest/arch'): for arch in ctx.xpath('/capabilities/guest/arch'):
domain_types = arch.xpath('domain/@type') domain_types = arch.xpath('domain/@type')
arch_name = arch.xpath('@name')[0] arch_name = arch.xpath('@name')[0]
result[arch_name]= domain_types result[arch_name] = domain_types
return result return result
return util.get_xml_path(self.get_cap_xml(), func=hypervisors) return util.get_xml_path(self.get_cap_xml(), func=hypervisors)
@ -446,7 +447,7 @@ class wvmConnect(object):
for arch in ctx.xpath('/capabilities/guest/arch'): for arch in ctx.xpath('/capabilities/guest/arch'):
emulator = arch.xpath('emulator') emulator = arch.xpath('emulator')
arch_name = arch.xpath('@name')[0] arch_name = arch.xpath('@name')[0]
result[arch_name]= emulator result[arch_name] = emulator
return result return result
return util.get_xml_path(self.get_cap_xml(), func=emulators) return util.get_xml_path(self.get_cap_xml(), func=emulators)
@ -460,8 +461,9 @@ class wvmConnect(object):
def get_bus_list(ctx): def get_bus_list(ctx):
result = [] result = []
for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'): for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'):
if disk_enum.xpath("@name")[0] == "bus": if disk_enum.xpath("@name")[0] == "bus":
for values in disk_enum: result.append(values.text) for values in disk_enum:
result.append(values.text)
return result return result
# return [ 'ide', 'scsi', 'usb', 'virtio' ] # return [ 'ide', 'scsi', 'usb', 'virtio' ]
@ -474,7 +476,8 @@ class wvmConnect(object):
result = [] result = []
for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'): for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'):
if disk_enum.xpath("@name")[0] == "diskDevice": if disk_enum.xpath("@name")[0] == "diskDevice":
for values in disk_enum: result.append(values.text) for values in disk_enum:
result.append(values.text)
return result return result
# return [ 'disk', 'cdrom', 'floppy', 'lun' ] # return [ 'disk', 'cdrom', 'floppy', 'lun' ]
@ -482,11 +485,11 @@ class wvmConnect(object):
def get_image_formats(self): def get_image_formats(self):
"""Get available image formats""" """Get available image formats"""
return [ 'raw', 'qcow', 'qcow2' ] return ['raw', 'qcow', 'qcow2']
def get_file_extensions(self): def get_file_extensions(self):
"""Get available image filename extensions""" """Get available image filename extensions"""
return [ 'img', 'qcow', 'qcow2' ] return ['img', 'qcow', 'qcow2']
def get_video(self): def get_video(self):
""" Get available graphics video types """ """ Get available graphics video types """
@ -494,9 +497,10 @@ class wvmConnect(object):
result = [] result = []
for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'): for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'):
if video_enum.xpath("@name")[0] == "modelType": if video_enum.xpath("@name")[0] == "modelType":
for values in video_enum: result.append(values.text) for values in video_enum:
result.append(values.text)
return result return result
return util.get_xml_path(self.get_dom_cap_xml(),func=get_video_list) return util.get_xml_path(self.get_dom_cap_xml(), func=get_video_list)
def get_iface(self, name): def get_iface(self, name):
return self.wvm.interfaceLookupByName(name) return self.wvm.interfaceLookupByName(name)
@ -560,6 +564,7 @@ class wvmConnect(object):
def get_host_instances(self, raw_mem_size=False): def get_host_instances(self, raw_mem_size=False):
vname = {} vname = {}
def get_info(doc): def get_info(doc):
mem = util.get_xpath(doc, "/domain/currentMemory") mem = util.get_xpath(doc, "/domain/currentMemory")
mem = int(mem) / 1024 mem = int(mem) / 1024
@ -592,6 +597,7 @@ class wvmConnect(object):
def get_user_instances(self, name): def get_user_instances(self, name):
dom = self.get_instance(name) dom = self.get_instance(name)
xml = dom.XMLDesc(0) xml = dom.XMLDesc(0)
def get_info(ctx): def get_info(ctx):
mem = util.get_xpath(ctx, "/domain/currentMemory") mem = util.get_xpath(ctx, "/domain/currentMemory")
mem = int(mem) / 1024 mem = int(mem) / 1024

View file

@ -2,7 +2,6 @@ import string
from vrtManager import util from vrtManager import util
from vrtManager.connection import wvmConnect from vrtManager.connection import wvmConnect
from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE from webvirtcloud.settings import QEMU_CONSOLE_DEFAULT_TYPE
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as default_owner from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as default_owner
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
@ -107,7 +106,7 @@ class wvmCreate(wvmConnect):
if not pool: if not pool:
storages = self.get_storages(only_actives=True) storages = self.get_storages(only_actives=True)
else: else:
storages = [pool,] storages = [pool]
for storage in storages: for storage in storages:
stg = self.get_storage(storage) stg = self.get_storage(storage)
if stg.info()[0] != 0: if stg.info()[0] != 0:
@ -204,12 +203,13 @@ class wvmCreate(wvmConnect):
hd_disk_letters = list(string.lowercase) hd_disk_letters = list(string.lowercase)
sd_disk_letters = list(string.lowercase) sd_disk_letters = list(string.lowercase)
add_cd = True add_cd = True
#for image, img_type in images.items(): # for image, img_type in images.items():
for volume in images: for volume in images:
stg = self.get_storage_by_vol_path(volume['path']) stg = self.get_storage_by_vol_path(volume['path'])
stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type") stg_type = util.get_xml_path(stg.XMLDesc(0), "/pool/@type")
if volume['device'] == 'cdrom': add_cd = False if volume['device'] == 'cdrom':
add_cd = False
if stg_type == 'rbd': if stg_type == 'rbd':
ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg) ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg)
@ -284,7 +284,4 @@ class wvmCreate(wvmConnect):
</devices> </devices>
</domain>""" % video </domain>""" % video
self._defineXML(xml) self._defineXML(xml)

View file

@ -19,9 +19,7 @@ class wvmHostDetails(wvmConnect):
all_mem = self.wvm.getInfo()[1] * 1048576 all_mem = self.wvm.getInfo()[1] * 1048576
freemem = self.wvm.getMemoryStats(-1, 0) freemem = self.wvm.getMemoryStats(-1, 0)
if type(freemem) == dict: if type(freemem) == dict:
free = (freemem.values()[0] + free = (freemem.values()[0] + freemem.values()[2] + freemem.values()[3]) * 1024
freemem.values()[2] +
freemem.values()[3]) * 1024
percent = (100 - ((free * 100) / all_mem)) percent = (100 - ((free * 100) / all_mem))
usage = (all_mem - free) usage = (all_mem - free)
mem_usage = {'total': all_mem, 'usage': usage, 'percent': percent} mem_usage = {'total': all_mem, 'usage': usage, 'percent': percent}
@ -59,14 +57,10 @@ class wvmHostDetails(wvmConnect):
Function return host server information: hostname, cpu, memory, ... Function return host server information: hostname, cpu, memory, ...
""" """
info = [] info = []
info.append(self.wvm.getHostname()) # hostname info.append(self.wvm.getHostname()) # hostname
info.append(self.wvm.getInfo()[0]) # architecture info.append(self.wvm.getInfo()[0]) # architecture
info.append(self.wvm.getInfo()[1] * 1048576) # memory info.append(self.wvm.getInfo()[1] * 1048576) # memory
info.append(self.wvm.getInfo()[2]) # cpu core count 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(get_xml_path(self.wvm.getSysinfo(0), func=cpu_version)) # cpu version
info.append(self.wvm.getURI()) #uri info.append(self.wvm.getURI()) # uri
return info return info

View file

@ -212,7 +212,7 @@ class wvmInstance(wvmConnect):
"""Get number of physical CPUs.""" """Get number of physical CPUs."""
hostinfo = self.wvm.getInfo() hostinfo = self.wvm.getInfo()
pcpus = hostinfo[4] * hostinfo[5] * hostinfo[6] * hostinfo[7] pcpus = hostinfo[4] * hostinfo[5] * hostinfo[6] * hostinfo[7]
range_pcpus = xrange(1, int(pcpus + 1)) range_pcpus = range(1, int(pcpus + 1))
return range_pcpus return range_pcpus
def get_net_device(self): def get_net_device(self):
@ -322,7 +322,7 @@ class wvmInstance(wvmConnect):
os = tree.find('os') os = tree.find('os')
menu = os.find("bootmenu") menu = os.find("bootmenu")
if menu == None: if menu is None:
bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>") bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>")
os.append(bootmenu) os.append(bootmenu)
menu = os.find("bootmenu") menu = os.find("bootmenu")
@ -365,7 +365,7 @@ class wvmInstance(wvmConnect):
for dev in devices: for dev in devices:
dev_target = dev_type = dev_device = dev_alias = None dev_target = dev_type = dev_device = dev_alias = None
boot_dev = dev.find('boot') boot_dev = dev.find('boot')
if boot_dev != None: if boot_dev is not None:
idx = boot_dev.get('order') idx = boot_dev.get('order')
dev_type = dev.get('type') dev_type = dev.get('type')
dev_device = dev.get('device') dev_device = dev.get('device')
@ -398,7 +398,7 @@ class wvmInstance(wvmConnect):
# Remove rest of them # Remove rest of them
for dev in tree.find('devices'): for dev in tree.find('devices'):
boot_dev = dev.find('boot') boot_dev = dev.find('boot')
if boot_dev != None: if boot_dev is not None:
dev.remove(boot_dev) dev.remove(boot_dev)
return tree return tree
@ -410,19 +410,19 @@ class wvmInstance(wvmConnect):
devices = tree.findall("./devices/disk[@device='disk']") devices = tree.findall("./devices/disk[@device='disk']")
for d in devices: for d in devices:
device = d.find("./target[@dev='{}']".format(dev['dev'])) device = d.find("./target[@dev='{}']".format(dev['dev']))
if device != None: if device is not None:
d.append(order) d.append(order)
elif dev['type'] == 'cdrom': elif dev['type'] == 'cdrom':
devices = tree.findall("./devices/disk[@device='cdrom']") devices = tree.findall("./devices/disk[@device='cdrom']")
for d in devices: for d in devices:
device = d.find("./target[@dev='{}']".format(dev['dev'])) device = d.find("./target[@dev='{}']".format(dev['dev']))
if device != None: if device is not None:
d.append(order) d.append(order)
elif dev['type'] == 'network': elif dev['type'] == 'network':
devices = tree.findall("./devices/interface[@type='network']") devices = tree.findall("./devices/interface[@type='network']")
for d in devices: for d in devices:
device = d.find("mac[@address='{}']".format(dev['dev'])) device = d.find("mac[@address='{}']".format(dev['dev']))
if device != None: if device is not None:
d.append(order) d.append(order)
else: else:
raise Exception('Invalid Device Type for boot order') raise Exception('Invalid Device Type for boot order')
@ -520,7 +520,7 @@ class wvmInstance(wvmConnect):
time.sleep(1) time.sleep(1)
cpu_use_now = self.instance.info()[4] cpu_use_now = self.instance.info()[4]
diff_usage = cpu_use_now - cpu_use_ago diff_usage = cpu_use_now - cpu_use_ago
cpu_usage['cpu'] = 100 * diff_usage / (1 * nbcore * 10 ** 9L) cpu_usage['cpu'] = 100 * diff_usage / (1 * nbcore * 10 ** 9)
else: else:
cpu_usage['cpu'] = 0 cpu_usage['cpu'] = 0
return cpu_usage return cpu_usage
@ -532,7 +532,8 @@ class wvmInstance(wvmConnect):
rss = mem_stats['rss'] if mem_stats['rss'] else 0 rss = mem_stats['rss'] if mem_stats['rss'] else 0
total = mem_stats['actual'] if mem_stats['actual'] else 0 total = mem_stats['actual'] if mem_stats['actual'] else 0
available = total - rss available = total - rss
if available < 0: available = 0 if available < 0:
available = 0
mem_usage['used'] = rss mem_usage['used'] = rss
mem_usage['total'] = total mem_usage['total'] = total
@ -622,7 +623,7 @@ class wvmInstance(wvmConnect):
if listen_addr is None: if listen_addr is None:
listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address") listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address")
if listen_addr is None: if listen_addr is None:
return "127.0.0.1" return "127.0.0.1"
return listen_addr return listen_addr
def set_console_listen_addr(self, listen_addr): def set_console_listen_addr(self, listen_addr):
@ -656,7 +657,7 @@ class wvmInstance(wvmConnect):
return socket return socket
def get_console_type(self): 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 return console_type
def set_console_type(self, console_type): def set_console_type(self, console_type):
@ -1007,13 +1008,15 @@ class wvmInstance(wvmConnect):
source = interface.find('filterref') source = interface.find('filterref')
if net_filter: if net_filter:
if source is not None: source.set('filter', net_filter) if source is not None:
source.set('filter', net_filter)
else: else:
element = ElementTree.Element("filterref") element = ElementTree.Element("filterref")
element.attrib['filter'] = net_filter element.attrib['filter'] = net_filter
interface.append(element) interface.append(element)
else: else:
if source is not None: interface.remove(source) if source is not None:
interface.remove(source)
elif interface.get('type') == 'network': elif interface.get('type') == 'network':
source = interface.find('mac') source = interface.find('mac')
source.set('address', net_mac) source.set('address', net_mac)
@ -1022,13 +1025,15 @@ class wvmInstance(wvmConnect):
source = interface.find('filterref') source = interface.find('filterref')
if net_filter: if net_filter:
if source is not None: source.set('filter', net_filter) if source is not None:
source.set('filter', net_filter)
else: else:
element = ElementTree.Element("filterref") element = ElementTree.Element("filterref")
element.attrib['filter'] = net_filter element.attrib['filter'] = net_filter
interface.append(element) interface.append(element)
else: else:
if source is not None: interface.remove(source) if source is not None:
interface.remove(source)
new_xml = ElementTree.tostring(tree) new_xml = ElementTree.tostring(tree)
self._defineXML(new_xml) self._defineXML(new_xml)
@ -1038,7 +1043,7 @@ class wvmInstance(wvmConnect):
option = tree.find(o) option = tree.find(o)
option_value = options.get(o, '').strip() option_value = options.get(o, '').strip()
if not option_value: if not option_value:
if not option is None: if option is not None:
tree.remove(option) tree.remove(option)
else: else:
if option is None: if option is None:
@ -1059,4 +1064,3 @@ class wvmInstance(wvmConnect):
def set_memory(self, size, flags=0): def set_memory(self, size, flags=0):
self.instance.setMemoryFlags(size, flags) self.instance.setMemoryFlags(size, flags)

View file

@ -204,14 +204,14 @@ class wvmNetwork(wvmConnect):
break break
if host is None: if host is None:
self.update(VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml, self.update(VIR_NETWORK_UPDATE_COMMAND_ADD_LAST, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG) VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
else: else:
# change the host # change the host
if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'): if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'):
return False return False
else: else:
self.update(VIR_NETWORK_UPDATE_COMMAND_MODIFY, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml, self.update(VIR_NETWORK_UPDATE_COMMAND_MODIFY, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG) VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
def delete_fixed_address(self, mac): def delete_fixed_address(self, mac):
util.validate_macaddr(mac) util.validate_macaddr(mac)
@ -222,7 +222,7 @@ class wvmNetwork(wvmConnect):
if h.get('mac') == mac: if h.get('mac') == mac:
new_xml = '<host mac="{}" name="{}" ip="{}"/>'.format(mac, h.get('name'), h.get('ip')) new_xml = '<host mac="{}" name="{}" ip="{}"/>'.format(mac, h.get('name'), h.get('ip'))
self.update(VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml, self.update(VIR_NETWORK_UPDATE_COMMAND_DELETE, VIR_NETWORK_SECTION_IP_DHCP_HOST, -1, new_xml,
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG) VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
break break
def modify_dhcp_range(self, range_start, range_end): def modify_dhcp_range(self, range_start, range_end):

View file

@ -12,7 +12,7 @@ class wvmNWFilters(wvmConnect):
def create_nwfilter(self, xml): def create_nwfilter(self, xml):
self.wvm.nwfilterDefineXML(xml) self.wvm.nwfilterDefineXML(xml)
def clone_nwfilter(self,name, cln_name): def clone_nwfilter(self, name, cln_name):
nwfilter = self.get_nwfilter(name) nwfilter = self.get_nwfilter(name)
if nwfilter: if nwfilter:
tree = ElementTree.fromstring(nwfilter.XMLDesc(0)) tree = ElementTree.fromstring(nwfilter.XMLDesc(0))

View file

@ -143,13 +143,13 @@ class wvmStorage(wvmConnect):
return util.get_xml_path(self._XMLDesc(0), "/pool/target/path") return util.get_xml_path(self._XMLDesc(0), "/pool/target/path")
def get_allocation(self): def get_allocation(self):
return long(util.get_xml_path(self._XMLDesc(0), "/pool/allocation")) return int(util.get_xml_path(self._XMLDesc(0), "/pool/allocation"))
def get_available(self): def get_available(self):
return long(util.get_xml_path(self._XMLDesc(0), "/pool/available")) return int(util.get_xml_path(self._XMLDesc(0), "/pool/available"))
def get_capacity(self): def get_capacity(self):
return long(util.get_xml_path(self._XMLDesc(0), "/pool/capacity")) return int(util.get_xml_path(self._XMLDesc(0), "/pool/capacity"))
def get_pretty_allocation(self): def get_pretty_allocation(self):
return util.pretty_bytes(self.get_allocation()) return util.pretty_bytes(self.get_allocation())

View file

@ -34,9 +34,9 @@ def randomUUID():
"%02x" * 6]) % tuple(u) "%02x" * 6]) % tuple(u)
def randomPasswd(length=12, alphabet=string.letters + string.digits): def randomPasswd(length=12, alphabet=string.ascii_letters + string.digits):
"""Generate a random password""" """Generate a random password"""
return ''.join([random.choice(alphabet) for i in xrange(length)]) return ''.join([random.choice(alphabet) for i in range(length)])
def get_max_vcpus(conn, type=None): def get_max_vcpus(conn, type=None):
@ -75,7 +75,7 @@ def compareMAC(p, q):
else: else:
return -1 return -1
for i in xrange(len(pa)): for i in range(len(pa)):
n = int(pa[i], 0x10) - int(qa[i], 0x10) n = int(pa[i], 0x10) - int(qa[i], 0x10)
if n > 0: if n > 0:
return 1 return 1
@ -110,7 +110,7 @@ def get_xpath(doc, path):
if ret is not None: if ret is not None:
if type(ret) == list: if type(ret) == list:
if len(ret) >= 1: if len(ret) >= 1:
if hasattr(ret[0],'text'): if hasattr(ret[0], 'text'):
result = ret[0].text result = ret[0].text
else: else:
result = ret[0] result = ret[0]
@ -119,6 +119,7 @@ def get_xpath(doc, path):
return result return result
def pretty_mem(val): def pretty_mem(val):
val = int(val) val = int(val)
if val > (10 * 1024 * 1024): if val > (10 * 1024 * 1024):
@ -145,13 +146,11 @@ def validate_uuid(val):
form = re.match("[a-fA-F0-9]{32}$", val) form = re.match("[a-fA-F0-9]{32}$", val)
if form is None: if form is None:
raise ValueError( raise ValueError(
"UUID must be a 32-digit hexadecimal number. It may take " "UUID must be a 32-digit hexadecimal number. It may take the form "
"the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may " "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may omit hyphens altogether.")
"omit hyphens altogether.")
else: # UUID had no dashes, so add them in else: # UUID had no dashes, so add them in
val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] + val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] + "-" + val[16:20] + "-" + val[20:32])
"-" + val[16:20] + "-" + val[20:32])
return val return val
@ -159,7 +158,7 @@ def validate_macaddr(val):
if val is None: if val is None:
return return
if not (isinstance(val, str) or isinstance(val, basestring)): if not (isinstance(val, str) or isinstance(val, str)):
raise ValueError("MAC address must be a string.") raise ValueError("MAC address must be a string.")
form = re.match("^([0-9a-fA-F]{1,2}:){5}[0-9a-fA-F]{1,2}$", val) form = re.match("^([0-9a-fA-F]{1,2}:){5}[0-9a-fA-F]{1,2}$", val)