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:
parent
0e231a930d
commit
a4d74a09a6
55 changed files with 192 additions and 306 deletions
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
@ -10,6 +7,3 @@ class Migration(migrations.Migration):
|
|||
('accounts', '0004_userinstance_is_vnc'),
|
||||
('accounts', '0007_auto_20160426_0635'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
]
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
from django.db import migrations, models
|
||||
|
||||
|
|
|
@ -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
|
||||
from django.db import migrations, models
|
||||
import re
|
||||
|
|
|
@ -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
|
||||
from django.db import migrations, models
|
||||
import re
|
||||
|
|
|
@ -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
|
||||
from django.db import migrations, models
|
||||
|
||||
|
|
|
@ -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.db import migrations, models
|
||||
import django.db.models.deletion
|
||||
|
|
|
@ -24,10 +24,11 @@ class UserSSHKey(models.Model):
|
|||
def __unicode__(self):
|
||||
return self.keyname
|
||||
|
||||
|
||||
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, 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_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)])
|
||||
|
@ -48,7 +49,7 @@ class UserAttributes(models.Model):
|
|||
instance = Instance.objects.get(name=instance_name)
|
||||
user_instance = UserInstance(user=user, instance=instance)
|
||||
user_instance.save()
|
||||
|
||||
|
||||
@staticmethod
|
||||
def configure_user(user):
|
||||
UserAttributes.create_missing_userattributes(user)
|
||||
|
|
|
@ -11,7 +11,6 @@ from django.conf import settings
|
|||
from django.core.validators import ValidationError
|
||||
|
||||
|
||||
|
||||
@login_required
|
||||
def profile(request):
|
||||
"""
|
||||
|
@ -70,6 +69,7 @@ def profile(request):
|
|||
return HttpResponseRedirect(request.get_full_path())
|
||||
return render(request, 'profile.html', locals())
|
||||
|
||||
|
||||
@login_required
|
||||
def accounts(request):
|
||||
"""
|
||||
|
@ -103,7 +103,8 @@ def accounts(request):
|
|||
user_pass = request.POST.get('user_pass', '')
|
||||
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_superuser = CHECKBOX_MAPPING.get(request.POST.get('user_is_superuser', 'off'))
|
||||
user_edit.save()
|
||||
|
@ -185,12 +186,12 @@ def account(request, user_id):
|
|||
return HttpResponseRedirect(request.get_full_path())
|
||||
if 'add' in request.POST:
|
||||
inst_id = request.POST.get('inst_id', '')
|
||||
|
||||
|
||||
if settings.ALLOW_INSTANCE_MULTIPLE_OWNER:
|
||||
check_inst = UserInstance.objects.filter(instance_id=int(inst_id), user_id=int(user_id))
|
||||
else:
|
||||
check_inst = UserInstance.objects.filter(instance_id=int(inst_id))
|
||||
|
||||
|
||||
if check_inst:
|
||||
msg = _("Instance already added")
|
||||
error_messages.append(msg)
|
||||
|
|
|
@ -154,7 +154,7 @@ class ComputeAddSocketForm(forms.Form):
|
|||
name = forms.CharField(error_messages={'required': _('No hostname has been entered')},
|
||||
max_length=20)
|
||||
details = forms.CharField(error_messages={'required': _('No details has been entred')},
|
||||
max_length=50)
|
||||
max_length=50)
|
||||
|
||||
def clean_name(self):
|
||||
name = self.cleaned_data['name']
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Compute',
|
||||
|
@ -20,8 +14,6 @@ class Migration(migrations.Migration):
|
|||
('password', models.CharField(max_length=14, null=True, blank=True)),
|
||||
('type', models.IntegerField()),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import time
|
||||
import json
|
||||
from django.utils import timezone
|
||||
from django.http import HttpResponse, HttpResponseRedirect
|
||||
|
@ -44,7 +43,7 @@ def computes(request):
|
|||
error_messages = []
|
||||
computes = Compute.objects.filter().order_by('name')
|
||||
computes_info = get_hosts_status(computes)
|
||||
|
||||
|
||||
if request.method == 'POST':
|
||||
if 'host_del' in request.POST:
|
||||
compute_id = request.POST.get('host_id', '')
|
||||
|
@ -213,13 +212,12 @@ def get_compute_disk_buses(request, compute_id, disk):
|
|||
if disk == 'disk':
|
||||
data['bus'] = sorted(disk_device_types)
|
||||
elif disk == 'cdrom':
|
||||
data['bus'] = ['ide', 'sata', 'scsi',]
|
||||
data['bus'] = ['ide', 'sata', 'scsi']
|
||||
elif disk == 'floppy':
|
||||
data['bus'] = ['fdc',]
|
||||
data['bus'] = ['fdc']
|
||||
elif disk == 'lun':
|
||||
data['bus'] = ['scsi',]
|
||||
data['bus'] = ['scsi']
|
||||
except libvirtError:
|
||||
pass
|
||||
|
||||
return HttpResponse(json.dumps(data))
|
||||
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
# gstfsd - WebVirtCloud daemon for managing VM's filesystem
|
||||
#
|
||||
|
||||
import SocketServer
|
||||
import socketserver
|
||||
import json
|
||||
import guestfs
|
||||
import re
|
||||
|
@ -13,11 +13,11 @@ PORT = 16510
|
|||
ADDRESS = "0.0.0.0"
|
||||
|
||||
|
||||
class MyTCPServer(SocketServer.ThreadingTCPServer):
|
||||
class MyTCPServer(socketserver.ThreadingTCPServer):
|
||||
allow_reuse_address = True
|
||||
|
||||
|
||||
class MyTCPServerHandler(SocketServer.BaseRequestHandler):
|
||||
class MyTCPServerHandler(socketserver.BaseRequestHandler):
|
||||
def handle(self):
|
||||
# recive data
|
||||
data = json.loads(self.request.recv(1024).strip())
|
||||
|
@ -42,17 +42,17 @@ class MyTCPServerHandler(SocketServer.BaseRequestHandler):
|
|||
if data['action'] == 'publickey':
|
||||
if not gfs.is_dir('/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.chmod(0600, '/root/.ssh/authorized_keys')
|
||||
gfs.chmod(0o600, '/root/.ssh/authorized_keys')
|
||||
self.request.sendall(json.dumps({'return': 'success'}))
|
||||
gfs.umount(part)
|
||||
except RuntimeError:
|
||||
pass
|
||||
gfs.shutdown()
|
||||
gfs.close()
|
||||
except RuntimeError, err:
|
||||
self.request.sendall(json.dumps({'return': 'error', 'message': err.message}))
|
||||
except RuntimeError as err:
|
||||
self.request.sendall(json.dumps({'return': 'error', 'message': err}))
|
||||
|
||||
server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
|
||||
server.serve_forever()
|
||||
|
|
|
@ -20,11 +20,11 @@ django.setup()
|
|||
# sys.path.append(VENV_PATH)
|
||||
|
||||
import re
|
||||
import Cookie
|
||||
import http.cookies
|
||||
import socket
|
||||
from webvirtcloud.settings import WS_PORT, WS_HOST, WS_CERT
|
||||
from vrtManager.connection import CONN_SSH, CONN_SOCKET
|
||||
from tunnel import Tunnel
|
||||
from console.tunnel import Tunnel
|
||||
|
||||
from optparse import OptionParser
|
||||
parser = OptionParser()
|
||||
|
@ -120,7 +120,7 @@ def get_connection_infos(token):
|
|||
console_host = conn.get_console_listen_addr()
|
||||
console_port = conn.get_console_port()
|
||||
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))
|
||||
raise
|
||||
return (connhost, connport, connuser, conntype, console_host,
|
||||
|
@ -129,7 +129,7 @@ def get_connection_infos(token):
|
|||
|
||||
class CompatibilityMixIn(object):
|
||||
def _new_client(self, daemon, socket_factory):
|
||||
cookie = Cookie.SimpleCookie()
|
||||
cookie = http.cookies.SimpleCookie()
|
||||
cookie.load(self.headers.getheader('cookie'))
|
||||
if 'token' not in cookie:
|
||||
self.msg('No token cookie found !')
|
||||
|
|
|
@ -27,6 +27,7 @@ import os
|
|||
import socket
|
||||
import signal
|
||||
import logging
|
||||
from functools import reduce
|
||||
|
||||
|
||||
class Tunnel(object):
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
import re
|
||||
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 instances.models import Instance
|
||||
from vrtManager.instance import wvmInstance
|
||||
|
|
|
@ -48,7 +48,7 @@ class NewVMForm(forms.Form):
|
|||
virtio = forms.BooleanField(required=False)
|
||||
qemu_ga = forms.BooleanField(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')})
|
||||
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:
|
||||
raise forms.ValidationError(_('The name of the virtual machine must not exceed 20 characters'))
|
||||
return name
|
||||
|
||||
|
|
|
@ -1,14 +1,8 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='Flavor',
|
||||
|
@ -19,8 +13,6 @@ class Migration(migrations.Migration):
|
|||
('vcpu', models.IntegerField()),
|
||||
('disk', models.IntegerField()),
|
||||
],
|
||||
options={
|
||||
},
|
||||
bases=(models.Model,),
|
||||
),
|
||||
]
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
|
|
|
@ -109,7 +109,7 @@ def create_instance(request, compute_id):
|
|||
msg = _("A virtual machine with this name already exists")
|
||||
error_messages.append(msg)
|
||||
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 data['hdd_size']:
|
||||
if not data['mac']:
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
-r ../conf/requirements.txt
|
||||
pep8==1.7.1
|
||||
pycodestyle
|
||||
pyflakes==2.1.1
|
||||
pylint==1.9.4
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
import datetime
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
from django.conf.urls import url
|
||||
from . import views
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url(r'^$', views.allinstances, name='allinstances'),
|
||||
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'^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'^(?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'^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_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'^check_instance/(?P<vname>[\w\-\.]+)/$', views.check_instance, name='check_instance'),
|
||||
url(r'^sshkeys/(?P<vname>[\w\-\.]+)/$', views.sshkeys, name='sshkeys'),
|
||||
url(r'^check_instance/(?P<vname>[\w\-.]+)/$', views.check_instance, name='check_instance'),
|
||||
url(r'^sshkeys/(?P<vname>[\w\-.]+)/$', views.sshkeys, name='sshkeys'),
|
||||
]
|
||||
|
|
|
@ -27,6 +27,7 @@ from logs.views import addlogmsg
|
|||
from django.conf import settings
|
||||
from django.contrib import messages
|
||||
|
||||
|
||||
@login_required
|
||||
def index(request):
|
||||
"""
|
||||
|
@ -129,17 +130,17 @@ def instance(request, compute_id, vname):
|
|||
return 0
|
||||
size_str = size_str.encode('ascii', 'ignore').upper().translate(None, " B")
|
||||
if 'K' == size_str[-1]:
|
||||
return long(float(size_str[:-1])) << 10
|
||||
return int(float(size_str[:-1])) << 10
|
||||
elif 'M' == size_str[-1]:
|
||||
return long(float(size_str[:-1])) << 20
|
||||
return int(float(size_str[:-1])) << 20
|
||||
elif 'G' == size_str[-1]:
|
||||
return long(float(size_str[:-1])) << 30
|
||||
return int(float(size_str[:-1])) << 30
|
||||
elif 'T' == size_str[-1]:
|
||||
return long(float(size_str[:-1])) << 40
|
||||
return int(float(size_str[:-1])) << 40
|
||||
elif 'P' == size_str[-1]:
|
||||
return long(float(size_str[:-1])) << 50
|
||||
return int(float(size_str[:-1])) << 50
|
||||
else:
|
||||
return long(float(size_str))
|
||||
return int(float(size_str))
|
||||
|
||||
def get_clone_free_names(size=10):
|
||||
prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
|
||||
|
@ -213,7 +214,7 @@ def instance(request, compute_id, vname):
|
|||
if 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
|
||||
if dev not in existing_disk_devs and dev not in existing_media_devs:
|
||||
return dev
|
||||
|
@ -495,7 +496,7 @@ def instance(request, compute_id, vname):
|
|||
format = connCreate.get_volume_type(name)
|
||||
path = connCreate.get_target_path()
|
||||
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)
|
||||
msg = _('Attach Existing disk: ' + target)
|
||||
|
@ -719,7 +720,8 @@ def instance(request, compute_id, vname):
|
|||
conn.change_network(network_data)
|
||||
addlogmsg(request.user.username, instance.name, msg)
|
||||
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')
|
||||
|
||||
if 'add_network' in request.POST:
|
||||
|
@ -904,17 +906,17 @@ def get_host_instances(request, comp):
|
|||
inst_on_db.save()
|
||||
|
||||
all_host_vms[comp["id"],
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][inst_name]['is_template'] = inst_on_db.is_template
|
||||
all_host_vms[comp["id"],
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
|
||||
comp["name"],
|
||||
comp["status"],
|
||||
comp["cpu"],
|
||||
comp["mem_size"],
|
||||
comp["mem_perc"]][inst_name]['userinstances'] = get_userinstances_info(inst_on_db)
|
||||
except Instance.DoesNotExist:
|
||||
inst_on_db = Instance(compute_id=comp["id"], name=inst_name, uuid=info['uuid'])
|
||||
inst_on_db.save()
|
||||
|
@ -1177,10 +1179,9 @@ def sshkeys(request, vname):
|
|||
:param vm:
|
||||
:return:
|
||||
"""
|
||||
|
||||
instance_keys = []
|
||||
userinstances = UserInstance.objects.filter(instance__name=vname)
|
||||
|
||||
|
||||
for ui in userinstances:
|
||||
keys = UserSSHKey.objects.filter(user=ui.user)
|
||||
for k in keys:
|
||||
|
@ -1213,7 +1214,7 @@ def delete_instance(instance, delete_disk=False):
|
|||
print("Forcing shutdown")
|
||||
conn.force_shutdown()
|
||||
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:
|
||||
print("Deleting snapshot {}".format(snap['name']))
|
||||
conn.snapshot_delete(snap['name'])
|
||||
|
@ -1228,4 +1229,3 @@ def delete_instance(instance, delete_disk=False):
|
|||
except libvirtError as lib_err:
|
||||
print("Error removing instance {} on compute {}".format(instance_name, compute.hostname))
|
||||
raise lib_err
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
from django.conf import settings
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import models, migrations
|
||||
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ class AddNetPool(forms.Form):
|
|||
|
||||
def clean_name(self):
|
||||
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:
|
||||
raise forms.ValidationError(_('The pool name must not contain any special characters'))
|
||||
elif len(name) > 20:
|
||||
|
@ -35,7 +35,7 @@ class AddNetPool(forms.Form):
|
|||
def clean_bridge_name(self):
|
||||
bridge_name = self.cleaned_data['bridge_name']
|
||||
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:
|
||||
raise forms.ValidationError(_('The pool bridge name must not contain any special characters'))
|
||||
elif len(bridge_name) > 20:
|
||||
|
|
|
@ -153,13 +153,11 @@ def network(request, compute_id, pool):
|
|||
edit_xml = request.POST.get('edit_xml', '')
|
||||
if edit_xml:
|
||||
try:
|
||||
new_conn = wvmNetworks(compute.hostname,
|
||||
compute.login,
|
||||
compute.password,
|
||||
compute.type)
|
||||
new_conn = wvmNetworks(compute.hostname, compute.login, compute.password, compute.type)
|
||||
conn.define_network(edit_xml)
|
||||
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:
|
||||
messages.success(request, _("Network XML is changed."))
|
||||
return HttpResponseRedirect(request.get_full_path())
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.apps import AppConfig
|
||||
|
||||
|
||||
|
|
|
@ -1,6 +1,3 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.shortcuts import render
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.shortcuts import render, get_object_or_404
|
||||
|
@ -208,4 +205,4 @@ def nwfilter(request, compute_id, nwfltr):
|
|||
except Exception as error_msg:
|
||||
error_messages.append(error_msg)
|
||||
|
||||
return render(request, 'nwfilter.html', locals())
|
||||
return render(request, 'nwfilter.html', locals())
|
||||
|
|
|
@ -42,7 +42,7 @@ class AddStgPool(forms.Form):
|
|||
def clean_source(self):
|
||||
storage_type = self.cleaned_data['stg_type']
|
||||
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 not source:
|
||||
raise forms.ValidationError(_('No device has been entered'))
|
||||
|
|
|
@ -10,6 +10,7 @@ from libvirt import libvirtError
|
|||
from django.contrib import messages
|
||||
import json
|
||||
|
||||
|
||||
@login_required
|
||||
def storages(request, compute_id):
|
||||
"""
|
||||
|
@ -225,4 +226,4 @@ def get_volumes(request, compute_id, pool):
|
|||
except libvirtError:
|
||||
pass
|
||||
data['vols'] = sorted(conn.get_volumes())
|
||||
return HttpResponse(json.dumps(data))
|
||||
return HttpResponse(json.dumps(data))
|
||||
|
|
|
@ -6,12 +6,11 @@ Further Information might be available at:
|
|||
https://github.com/haypo/python-ipy
|
||||
"""
|
||||
|
||||
__version__ = '0.83'
|
||||
__version__ = '1.00'
|
||||
|
||||
import bisect
|
||||
import collections
|
||||
import sys
|
||||
import types
|
||||
|
||||
|
||||
# Definition of the Ranges for IPv4 IPs
|
||||
# this should include www.iana.org/assignments/ipv4-address-space
|
||||
|
@ -21,7 +20,7 @@ IPv4ranges = {
|
|||
'00000000': 'PRIVATE', # 0/8
|
||||
'00001010': 'PRIVATE', # 10/8
|
||||
'0110010001': 'CARRIER_GRADE_NAT', # 100.64/10
|
||||
'01111111': 'PRIVATE', # 127.0/8
|
||||
'01111111': 'LOOPBACK', # 127.0/8
|
||||
'1': 'PUBLIC', # fall back
|
||||
'1010100111111110': 'PRIVATE', # 169.254/16
|
||||
'101011000001': 'PRIVATE', # 172.16/12
|
||||
|
@ -121,14 +120,6 @@ MAX_IPV6_ADDRESS = 0xffffffffffffffffffffffffffffffff
|
|||
IPV6_TEST_MAP = 0xffffffffffffffffffffffff00000000
|
||||
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):
|
||||
"""Handling of IP addresses returning integers.
|
||||
|
@ -175,7 +166,7 @@ class IPint(object):
|
|||
prefixlen = -1
|
||||
|
||||
# handling of non string values in constructor
|
||||
if isinstance(data, INT_TYPES):
|
||||
if isinstance(data, int):
|
||||
self.ip = int(data)
|
||||
if ipversion == 0:
|
||||
if self.ip <= MAX_IPV4_ADDRESS:
|
||||
|
@ -199,7 +190,7 @@ class IPint(object):
|
|||
self._ipversion = data._ipversion
|
||||
self._prefixlen = data._prefixlen
|
||||
self.ip = data.ip
|
||||
elif isinstance(data, STR_TYPES):
|
||||
elif isinstance(data, str):
|
||||
# TODO: refactor me!
|
||||
# splitting of a string into IP and prefixlen et. al.
|
||||
x = data.split('-')
|
||||
|
@ -219,7 +210,7 @@ class IPint(object):
|
|||
# make sure the broadcast is the same as the last ip
|
||||
# otherwise it will return /16 for something like:
|
||||
# 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)
|
||||
elif len(x) == 1:
|
||||
x = data.split('/')
|
||||
|
@ -243,7 +234,7 @@ class IPint(object):
|
|||
else:
|
||||
raise ValueError("can't parse")
|
||||
|
||||
(self.ip, parsedVersion) = parseAddress(ip)
|
||||
(self.ip, parsedVersion) = parseAddress(ip, ipversion)
|
||||
if ipversion == 0:
|
||||
ipversion = parsedVersion
|
||||
if prefixlen == -1:
|
||||
|
@ -318,15 +309,15 @@ class IPint(object):
|
|||
(self._ipversion == 6 and self._prefixlen == 128):
|
||||
if self.NoPrefixForSingleIp:
|
||||
want = 0
|
||||
if want == None:
|
||||
if want is None:
|
||||
want = self.WantPrefixLen
|
||||
if want == None:
|
||||
if want is None:
|
||||
want = 1
|
||||
if want:
|
||||
if want == 2:
|
||||
# this should work with IP and IPint
|
||||
netmask = self.netmask()
|
||||
if not isinstance(netmask, INT_TYPES):
|
||||
if not isinstance(netmask, int):
|
||||
netmask = netmask.int()
|
||||
return "/%s" % (intToIp(netmask, self._ipversion))
|
||||
elif want == 3:
|
||||
|
@ -354,7 +345,7 @@ class IPint(object):
|
|||
"""
|
||||
|
||||
bits = _ipVersionToLen(self._ipversion)
|
||||
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
||||
wantprefixlen = 0
|
||||
ret = _intToBin(self.ip)
|
||||
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'
|
||||
"""
|
||||
|
||||
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
||||
wantprefixlen = 1
|
||||
|
||||
if self._ipversion == 4:
|
||||
|
@ -385,7 +376,7 @@ class IPint(object):
|
|||
# every element of followingzeros will contain the number of zeros
|
||||
# following the corresponding element of hextets
|
||||
followingzeros = [0] * 8
|
||||
for i in xrange(len(hextets)):
|
||||
for i in range(len(hextets)):
|
||||
followingzeros[i] = _countFollowingZeros(hextets[i:])
|
||||
# compressionpos is the position where we can start removing zeros
|
||||
compressionpos = followingzeros.index(max(followingzeros))
|
||||
|
@ -413,7 +404,7 @@ class IPint(object):
|
|||
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
|
||||
|
||||
if self._ipversion == 4:
|
||||
|
@ -434,7 +425,7 @@ class IPint(object):
|
|||
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
|
||||
|
||||
return intToIp(self.ip, self._ipversion) + self._printPrefix(wantprefixlen)
|
||||
|
@ -448,7 +439,7 @@ class IPint(object):
|
|||
0x20010658022acafe0200000000000001
|
||||
"""
|
||||
|
||||
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
||||
wantprefixlen = 0
|
||||
|
||||
x = '0x%x' % self.ip
|
||||
|
@ -463,7 +454,7 @@ class IPint(object):
|
|||
42540616829182469433547762482097946625
|
||||
"""
|
||||
|
||||
if self.WantPrefixLen == None and wantprefixlen == None:
|
||||
if self.WantPrefixLen is None and wantprefixlen is None:
|
||||
wantprefixlen = 0
|
||||
|
||||
x = '%d' % self.ip
|
||||
|
@ -473,7 +464,7 @@ class IPint(object):
|
|||
"""Return a description of the IP type ('PRIVATE', 'RESERVED', etc).
|
||||
|
||||
>>> print(IP('127.0.0.1').iptype())
|
||||
PRIVATE
|
||||
LOOPBACK
|
||||
>>> print(IP('192.168.1.1').iptype())
|
||||
PRIVATE
|
||||
>>> print(IP('195.185.1.2').iptype())
|
||||
|
@ -496,7 +487,7 @@ class IPint(object):
|
|||
raise ValueError("only IPv4 and IPv6 supported")
|
||||
|
||||
bits = self.strBin()
|
||||
for i in xrange(len(bits), 0, -1):
|
||||
for i in range(len(bits), 0, -1):
|
||||
if bits[:i] in iprange:
|
||||
return iprange[bits[:i]]
|
||||
return "unknown"
|
||||
|
@ -553,6 +544,9 @@ class IPint(object):
|
|||
"""
|
||||
return True
|
||||
|
||||
def __bool__(self):
|
||||
return self.__nonzero__()
|
||||
|
||||
def __len__(self):
|
||||
"""
|
||||
Return the length of a subnet.
|
||||
|
@ -606,8 +600,8 @@ class IPint(object):
|
|||
"""
|
||||
|
||||
if isinstance(key, slice):
|
||||
return [self.ip + int(x) for x in xrange(*key.indices(len(self)))]
|
||||
if not isinstance(key, INT_TYPES):
|
||||
return [self.ip + int(x) for x in range(*key.indices(len(self)))]
|
||||
if not isinstance(key, int):
|
||||
raise TypeError
|
||||
if key < 0:
|
||||
if abs(key) <= self.len():
|
||||
|
@ -848,13 +842,13 @@ class IP(IPint):
|
|||
for x in self:
|
||||
ret.append(x.reverseName())
|
||||
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:])
|
||||
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:])
|
||||
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:])
|
||||
return ret
|
||||
elif self._ipversion == 6:
|
||||
|
@ -952,7 +946,7 @@ class IP(IPint):
|
|||
127.0.0.3
|
||||
"""
|
||||
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)
|
||||
|
||||
def __repr__(self):
|
||||
|
@ -1183,7 +1177,7 @@ class IPSet(collections.MutableSet):
|
|||
# prefix length and differ only on the last bit of the prefix
|
||||
addrlen = len(self.prefixes)
|
||||
i = 0
|
||||
while i < addrlen - 1:
|
||||
while i < addrlen-1:
|
||||
j = i + 1
|
||||
|
||||
try:
|
||||
|
@ -1328,7 +1322,7 @@ def _parseAddressIPv6(ipstr):
|
|||
return value
|
||||
|
||||
|
||||
def parseAddress(ipstr):
|
||||
def parseAddress(ipstr, ipversion=0):
|
||||
"""
|
||||
Parse a string and return the corresponding IP address (as integer)
|
||||
and a guess of the IP version.
|
||||
|
@ -1397,7 +1391,7 @@ def parseAddress(ipstr):
|
|||
# assume IPv6 in pure hexadecimal notation
|
||||
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')
|
||||
bytes = ipstr.split('.')
|
||||
if len(bytes) > 4:
|
||||
|
@ -1415,7 +1409,7 @@ def parseAddress(ipstr):
|
|||
# will be interpreted as IPv4 first byte
|
||||
if intval > MAX_IPV6_ADDRESS:
|
||||
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)
|
||||
else:
|
||||
return (intval, 6)
|
||||
|
@ -1436,7 +1430,7 @@ def intToIp(ip, version):
|
|||
if version == 4:
|
||||
if ip > MAX_IPV4_ADDRESS:
|
||||
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
|
||||
ip = ip >> 8
|
||||
ret = ret[:-1]
|
||||
|
@ -1444,7 +1438,7 @@ def intToIp(ip, version):
|
|||
if ip > MAX_IPV6_ADDRESS:
|
||||
raise ValueError("IPv6 Address can't be larger than %x: %x" % (MAX_IPV6_ADDRESS, ip))
|
||||
l = "%032x" % ip
|
||||
for x in xrange(1, 33):
|
||||
for x in range(1, 33):
|
||||
ret = l[-x] + ret
|
||||
if x % 4 == 0:
|
||||
ret = ':' + ret
|
||||
|
@ -1617,7 +1611,7 @@ def _prefixlenToNetmask(prefixlen, version):
|
|||
return 0
|
||||
elif prefixlen < 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):
|
||||
|
@ -1631,8 +1625,8 @@ def _remove_subprefix(prefix, subprefix):
|
|||
|
||||
# Start cutting in half, recursively
|
||||
prefixes = [
|
||||
IP('%s/%d' % (prefix[0], prefix._prefixlen + 1)),
|
||||
IP('%s/%d' % (prefix[int(prefix.len() / 2)], prefix._prefixlen + 1)),
|
||||
IP('%s/%d' % (prefix[0], prefix._prefixlen+1)),
|
||||
IP('%s/%d' % (prefix[int(prefix.len()/2)], prefix._prefixlen+1)),
|
||||
]
|
||||
if subprefix in prefixes[0]:
|
||||
return _remove_subprefix(prefixes[0], subprefix) + IPSet([prefixes[1]])
|
||||
|
|
|
@ -2,7 +2,7 @@ import libvirt
|
|||
import threading
|
||||
import socket
|
||||
from vrtManager import util
|
||||
from rwlock import ReadWriteLock
|
||||
from vrtManager.rwlock import ReadWriteLock
|
||||
from django.conf import settings
|
||||
from libvirt import libvirtError
|
||||
|
||||
|
@ -216,18 +216,18 @@ class wvmConnection(object):
|
|||
|
||||
def __unicode__(self):
|
||||
if self.type == CONN_TCP:
|
||||
type_str = u'tcp'
|
||||
type_str = 'tcp'
|
||||
elif self.type == CONN_SSH:
|
||||
type_str = u'ssh'
|
||||
type_str = 'ssh'
|
||||
elif self.type == CONN_TLS:
|
||||
type_str = u'tls'
|
||||
type_str = 'tls'
|
||||
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):
|
||||
return '<wvmConnection {connection_str}>'.format(connection_str=unicode(self))
|
||||
return '<wvmConnection {connection_str}>'.format(connection_str=str(self))
|
||||
|
||||
|
||||
class wvmConnectionManager(object):
|
||||
|
@ -272,19 +272,19 @@ class wvmConnectionManager(object):
|
|||
raises libvirtError if (re)connecting fails
|
||||
"""
|
||||
# force all string values to unicode
|
||||
host = unicode(host)
|
||||
login = unicode(login)
|
||||
passwd = unicode(passwd) if passwd is not None else None
|
||||
host = str(host)
|
||||
login = str(login)
|
||||
passwd = str(passwd) if passwd is not None else None
|
||||
|
||||
connection = self._search_connection(host, login, passwd, conn)
|
||||
|
||||
if (connection is None):
|
||||
if connection is None:
|
||||
self._connections_lock.acquireWrite()
|
||||
try:
|
||||
# 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
|
||||
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
|
||||
connection = wvmConnection(host, login, passwd, conn)
|
||||
|
||||
|
@ -332,6 +332,7 @@ class wvmConnectionManager(object):
|
|||
except Exception as err:
|
||||
return err
|
||||
|
||||
|
||||
connection_manager = wvmConnectionManager(
|
||||
settings.LIBVIRT_KEEPALIVE_INTERVAL if hasattr(settings, 'LIBVIRT_KEEPALIVE_INTERVAL') else 5,
|
||||
settings.LIBVIRT_KEEPALIVE_COUNT if hasattr(settings, 'LIBVIRT_KEEPALIVE_COUNT') else 5
|
||||
|
@ -368,7 +369,7 @@ class wvmConnect(object):
|
|||
minor = ver / 1000
|
||||
ver = ver % 1000
|
||||
release = ver
|
||||
return "%s.%s.%s" % (major,minor,release)
|
||||
return f"{major}.{minor}.{release}"
|
||||
|
||||
def get_lib_version(self):
|
||||
ver = self.wvm.getLibVersion()
|
||||
|
@ -377,7 +378,7 @@ class wvmConnect(object):
|
|||
minor = ver / 1000
|
||||
ver %= 1000
|
||||
release = ver
|
||||
return "%s.%s.%s" % (major,minor,release)
|
||||
return f"{major}.{minor}.{release}"
|
||||
|
||||
def is_kvm_supported(self):
|
||||
"""Return KVM capabilities."""
|
||||
|
@ -432,7 +433,7 @@ class wvmConnect(object):
|
|||
for arch in ctx.xpath('/capabilities/guest/arch'):
|
||||
domain_types = arch.xpath('domain/@type')
|
||||
arch_name = arch.xpath('@name')[0]
|
||||
result[arch_name]= domain_types
|
||||
result[arch_name] = domain_types
|
||||
return result
|
||||
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'):
|
||||
emulator = arch.xpath('emulator')
|
||||
arch_name = arch.xpath('@name')[0]
|
||||
result[arch_name]= emulator
|
||||
result[arch_name] = emulator
|
||||
return result
|
||||
return util.get_xml_path(self.get_cap_xml(), func=emulators)
|
||||
|
||||
|
@ -460,8 +461,9 @@ class wvmConnect(object):
|
|||
def get_bus_list(ctx):
|
||||
result = []
|
||||
for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'):
|
||||
if disk_enum.xpath("@name")[0] == "bus":
|
||||
for values in disk_enum: result.append(values.text)
|
||||
if disk_enum.xpath("@name")[0] == "bus":
|
||||
for values in disk_enum:
|
||||
result.append(values.text)
|
||||
return result
|
||||
|
||||
# return [ 'ide', 'scsi', 'usb', 'virtio' ]
|
||||
|
@ -474,7 +476,8 @@ class wvmConnect(object):
|
|||
result = []
|
||||
for disk_enum in ctx.xpath('/domainCapabilities/devices/disk/enum'):
|
||||
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 [ 'disk', 'cdrom', 'floppy', 'lun' ]
|
||||
|
@ -482,11 +485,11 @@ class wvmConnect(object):
|
|||
|
||||
def get_image_formats(self):
|
||||
"""Get available image formats"""
|
||||
return [ 'raw', 'qcow', 'qcow2' ]
|
||||
return ['raw', 'qcow', 'qcow2']
|
||||
|
||||
def get_file_extensions(self):
|
||||
"""Get available image filename extensions"""
|
||||
return [ 'img', 'qcow', 'qcow2' ]
|
||||
return ['img', 'qcow', 'qcow2']
|
||||
|
||||
def get_video(self):
|
||||
""" Get available graphics video types """
|
||||
|
@ -494,9 +497,10 @@ class wvmConnect(object):
|
|||
result = []
|
||||
for video_enum in ctx.xpath('/domainCapabilities/devices/video/enum'):
|
||||
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 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):
|
||||
return self.wvm.interfaceLookupByName(name)
|
||||
|
@ -560,6 +564,7 @@ class wvmConnect(object):
|
|||
|
||||
def get_host_instances(self, raw_mem_size=False):
|
||||
vname = {}
|
||||
|
||||
def get_info(doc):
|
||||
mem = util.get_xpath(doc, "/domain/currentMemory")
|
||||
mem = int(mem) / 1024
|
||||
|
@ -592,6 +597,7 @@ class wvmConnect(object):
|
|||
def get_user_instances(self, name):
|
||||
dom = self.get_instance(name)
|
||||
xml = dom.XMLDesc(0)
|
||||
|
||||
def get_info(ctx):
|
||||
mem = util.get_xpath(ctx, "/domain/currentMemory")
|
||||
mem = int(mem) / 1024
|
||||
|
|
|
@ -2,7 +2,6 @@ import string
|
|||
from vrtManager import util
|
||||
from vrtManager.connection import wvmConnect
|
||||
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_FORMAT
|
||||
|
||||
|
@ -107,7 +106,7 @@ class wvmCreate(wvmConnect):
|
|||
if not pool:
|
||||
storages = self.get_storages(only_actives=True)
|
||||
else:
|
||||
storages = [pool,]
|
||||
storages = [pool]
|
||||
for storage in storages:
|
||||
stg = self.get_storage(storage)
|
||||
if stg.info()[0] != 0:
|
||||
|
@ -204,12 +203,13 @@ class wvmCreate(wvmConnect):
|
|||
hd_disk_letters = list(string.lowercase)
|
||||
sd_disk_letters = list(string.lowercase)
|
||||
add_cd = True
|
||||
#for image, img_type in images.items():
|
||||
# for image, img_type in images.items():
|
||||
for volume in images:
|
||||
stg = self.get_storage_by_vol_path(volume['path'])
|
||||
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':
|
||||
ceph_user, secret_uuid, ceph_hosts = get_rbd_storage_data(stg)
|
||||
|
@ -284,7 +284,4 @@ class wvmCreate(wvmConnect):
|
|||
</devices>
|
||||
</domain>""" % video
|
||||
|
||||
|
||||
|
||||
|
||||
self._defineXML(xml)
|
||||
|
|
|
@ -19,9 +19,7 @@ class wvmHostDetails(wvmConnect):
|
|||
all_mem = self.wvm.getInfo()[1] * 1048576
|
||||
freemem = self.wvm.getMemoryStats(-1, 0)
|
||||
if type(freemem) == dict:
|
||||
free = (freemem.values()[0] +
|
||||
freemem.values()[2] +
|
||||
freemem.values()[3]) * 1024
|
||||
free = (freemem.values()[0] + freemem.values()[2] + freemem.values()[3]) * 1024
|
||||
percent = (100 - ((free * 100) / all_mem))
|
||||
usage = (all_mem - free)
|
||||
mem_usage = {'total': all_mem, 'usage': usage, 'percent': percent}
|
||||
|
@ -59,14 +57,10 @@ class wvmHostDetails(wvmConnect):
|
|||
Function return host server information: hostname, cpu, memory, ...
|
||||
"""
|
||||
info = []
|
||||
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
|
||||
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
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -212,7 +212,7 @@ class wvmInstance(wvmConnect):
|
|||
"""Get number of physical CPUs."""
|
||||
hostinfo = self.wvm.getInfo()
|
||||
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
|
||||
|
||||
def get_net_device(self):
|
||||
|
@ -249,7 +249,7 @@ class wvmInstance(wvmConnect):
|
|||
result = []
|
||||
dev = volume = storage = src_file = None
|
||||
disk_format = used_size = disk_size = disk_cache = None
|
||||
|
||||
|
||||
for disk in doc.xpath('/domain/devices/disk'):
|
||||
device = disk.xpath('@device')[0]
|
||||
if device == 'disk':
|
||||
|
@ -322,7 +322,7 @@ class wvmInstance(wvmConnect):
|
|||
os = tree.find('os')
|
||||
menu = os.find("bootmenu")
|
||||
|
||||
if menu == None:
|
||||
if menu is None:
|
||||
bootmenu = ElementTree.fromstring("<bootmenu enable='yes'/>")
|
||||
os.append(bootmenu)
|
||||
menu = os.find("bootmenu")
|
||||
|
@ -365,7 +365,7 @@ class wvmInstance(wvmConnect):
|
|||
for dev in devices:
|
||||
dev_target = dev_type = dev_device = dev_alias = None
|
||||
boot_dev = dev.find('boot')
|
||||
if boot_dev != None:
|
||||
if boot_dev is not None:
|
||||
idx = boot_dev.get('order')
|
||||
dev_type = dev.get('type')
|
||||
dev_device = dev.get('device')
|
||||
|
@ -398,7 +398,7 @@ class wvmInstance(wvmConnect):
|
|||
# Remove rest of them
|
||||
for dev in tree.find('devices'):
|
||||
boot_dev = dev.find('boot')
|
||||
if boot_dev != None:
|
||||
if boot_dev is not None:
|
||||
dev.remove(boot_dev)
|
||||
return tree
|
||||
|
||||
|
@ -410,19 +410,19 @@ class wvmInstance(wvmConnect):
|
|||
devices = tree.findall("./devices/disk[@device='disk']")
|
||||
for d in devices:
|
||||
device = d.find("./target[@dev='{}']".format(dev['dev']))
|
||||
if device != None:
|
||||
if device is not None:
|
||||
d.append(order)
|
||||
elif dev['type'] == 'cdrom':
|
||||
devices = tree.findall("./devices/disk[@device='cdrom']")
|
||||
for d in devices:
|
||||
device = d.find("./target[@dev='{}']".format(dev['dev']))
|
||||
if device != None:
|
||||
if device is not None:
|
||||
d.append(order)
|
||||
elif dev['type'] == 'network':
|
||||
devices = tree.findall("./devices/interface[@type='network']")
|
||||
for d in devices:
|
||||
device = d.find("mac[@address='{}']".format(dev['dev']))
|
||||
if device != None:
|
||||
if device is not None:
|
||||
d.append(order)
|
||||
else:
|
||||
raise Exception('Invalid Device Type for boot order')
|
||||
|
@ -520,7 +520,7 @@ class wvmInstance(wvmConnect):
|
|||
time.sleep(1)
|
||||
cpu_use_now = self.instance.info()[4]
|
||||
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:
|
||||
cpu_usage['cpu'] = 0
|
||||
return cpu_usage
|
||||
|
@ -532,7 +532,8 @@ class wvmInstance(wvmConnect):
|
|||
rss = mem_stats['rss'] if mem_stats['rss'] else 0
|
||||
total = mem_stats['actual'] if mem_stats['actual'] else 0
|
||||
available = total - rss
|
||||
if available < 0: available = 0
|
||||
if available < 0:
|
||||
available = 0
|
||||
|
||||
mem_usage['used'] = rss
|
||||
mem_usage['total'] = total
|
||||
|
@ -622,7 +623,7 @@ class wvmInstance(wvmConnect):
|
|||
if listen_addr is None:
|
||||
listen_addr = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/listen/@address")
|
||||
if listen_addr is None:
|
||||
return "127.0.0.1"
|
||||
return "127.0.0.1"
|
||||
return listen_addr
|
||||
|
||||
def set_console_listen_addr(self, listen_addr):
|
||||
|
@ -650,13 +651,13 @@ class wvmInstance(wvmConnect):
|
|||
pass
|
||||
newxml = ElementTree.tostring(root)
|
||||
return self._defineXML(newxml)
|
||||
|
||||
|
||||
def get_console_socket(self):
|
||||
socket = util.get_xml_path(self._XMLDesc(0), "/domain/devices/graphics/@socket")
|
||||
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):
|
||||
|
@ -765,7 +766,7 @@ class wvmInstance(wvmConnect):
|
|||
source_dev = disk['path']
|
||||
vol = self.get_volume_by_path(source_dev)
|
||||
vol.resize(disk['size_new'])
|
||||
|
||||
|
||||
new_xml = ElementTree.tostring(tree)
|
||||
self._defineXML(new_xml)
|
||||
|
||||
|
@ -901,7 +902,7 @@ class wvmInstance(wvmConnect):
|
|||
|
||||
stg = vol.storagePoolLookupByVolume()
|
||||
stg.createXMLFrom(vol_clone_xml, vol, meta_prealloc)
|
||||
|
||||
|
||||
source_protocol = elm.get('protocol')
|
||||
if source_protocol == 'rbd':
|
||||
source_name = elm.get('name')
|
||||
|
@ -927,13 +928,13 @@ class wvmInstance(wvmConnect):
|
|||
if source_dev:
|
||||
clone_path = os.path.join(os.path.dirname(source_dev), target_file)
|
||||
elm.set('dev', clone_path)
|
||||
|
||||
|
||||
vol = self.get_volume_by_path(source_dev)
|
||||
stg = vol.storagePoolLookupByVolume()
|
||||
|
||||
|
||||
vol_name = util.get_xml_path(vol.XMLDesc(0), "/volume/name")
|
||||
pool_name = util.get_xml_path(stg.XMLDesc(0), "/pool/name")
|
||||
|
||||
|
||||
storage = self.get_wvmStorage(pool_name)
|
||||
storage.clone_volume(vol_name, target_file)
|
||||
|
||||
|
@ -954,7 +955,7 @@ class wvmInstance(wvmConnect):
|
|||
net = self.get_network(source)
|
||||
bridge_name = net.bridgeName()
|
||||
return bridge_name
|
||||
|
||||
|
||||
def add_network(self, mac_address, source, source_type='net', interface_type='bridge', model='virtio', nwfilter=None):
|
||||
tree = ElementTree.fromstring(self._XMLDesc(0))
|
||||
bridge_name = self.get_bridge_name(source, source_type)
|
||||
|
@ -1007,13 +1008,15 @@ class wvmInstance(wvmConnect):
|
|||
source = interface.find('filterref')
|
||||
|
||||
if net_filter:
|
||||
if source is not None: source.set('filter', net_filter)
|
||||
if source is not None:
|
||||
source.set('filter', net_filter)
|
||||
else:
|
||||
element = ElementTree.Element("filterref")
|
||||
element.attrib['filter'] = net_filter
|
||||
interface.append(element)
|
||||
else:
|
||||
if source is not None: interface.remove(source)
|
||||
if source is not None:
|
||||
interface.remove(source)
|
||||
elif interface.get('type') == 'network':
|
||||
source = interface.find('mac')
|
||||
source.set('address', net_mac)
|
||||
|
@ -1022,13 +1025,15 @@ class wvmInstance(wvmConnect):
|
|||
source = interface.find('filterref')
|
||||
|
||||
if net_filter:
|
||||
if source is not None: source.set('filter', net_filter)
|
||||
if source is not None:
|
||||
source.set('filter', net_filter)
|
||||
else:
|
||||
element = ElementTree.Element("filterref")
|
||||
element.attrib['filter'] = net_filter
|
||||
interface.append(element)
|
||||
else:
|
||||
if source is not None: interface.remove(source)
|
||||
if source is not None:
|
||||
interface.remove(source)
|
||||
|
||||
new_xml = ElementTree.tostring(tree)
|
||||
self._defineXML(new_xml)
|
||||
|
@ -1038,7 +1043,7 @@ class wvmInstance(wvmConnect):
|
|||
option = tree.find(o)
|
||||
option_value = options.get(o, '').strip()
|
||||
if not option_value:
|
||||
if not option is None:
|
||||
if option is not None:
|
||||
tree.remove(option)
|
||||
else:
|
||||
if option is None:
|
||||
|
@ -1059,4 +1064,3 @@ class wvmInstance(wvmConnect):
|
|||
|
||||
def set_memory(self, size, flags=0):
|
||||
self.instance.setMemoryFlags(size, flags)
|
||||
|
||||
|
|
|
@ -185,7 +185,7 @@ class wvmNetwork(wvmConnect):
|
|||
return result
|
||||
|
||||
return util.get_xml_path(self._XMLDesc(0), func=network)
|
||||
|
||||
|
||||
def modify_fixed_address(self, name, address, mac):
|
||||
util.validate_macaddr(mac)
|
||||
if name:
|
||||
|
@ -204,14 +204,14 @@ class wvmNetwork(wvmConnect):
|
|||
break
|
||||
if host is None:
|
||||
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:
|
||||
# change the host
|
||||
if host.get('name') == new_host_xml.get('name') and host.get('ip') == new_host_xml.get('ip'):
|
||||
return False
|
||||
else:
|
||||
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):
|
||||
util.validate_macaddr(mac)
|
||||
|
@ -222,7 +222,7 @@ class wvmNetwork(wvmConnect):
|
|||
if h.get('mac') == mac:
|
||||
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,
|
||||
VIR_NETWORK_UPDATE_AFFECT_LIVE|VIR_NETWORK_UPDATE_AFFECT_CONFIG)
|
||||
VIR_NETWORK_UPDATE_AFFECT_LIVE | VIR_NETWORK_UPDATE_AFFECT_CONFIG)
|
||||
break
|
||||
|
||||
def modify_dhcp_range(self, range_start, range_end):
|
||||
|
|
|
@ -12,7 +12,7 @@ class wvmNWFilters(wvmConnect):
|
|||
def create_nwfilter(self, xml):
|
||||
self.wvm.nwfilterDefineXML(xml)
|
||||
|
||||
def clone_nwfilter(self,name, cln_name):
|
||||
def clone_nwfilter(self, name, cln_name):
|
||||
nwfilter = self.get_nwfilter(name)
|
||||
if nwfilter:
|
||||
tree = ElementTree.fromstring(nwfilter.XMLDesc(0))
|
||||
|
|
|
@ -143,13 +143,13 @@ class wvmStorage(wvmConnect):
|
|||
return util.get_xml_path(self._XMLDesc(0), "/pool/target/path")
|
||||
|
||||
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):
|
||||
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):
|
||||
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):
|
||||
return util.pretty_bytes(self.get_allocation())
|
||||
|
|
|
@ -34,9 +34,9 @@ def randomUUID():
|
|||
"%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"""
|
||||
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):
|
||||
|
@ -75,7 +75,7 @@ def compareMAC(p, q):
|
|||
else:
|
||||
return -1
|
||||
|
||||
for i in xrange(len(pa)):
|
||||
for i in range(len(pa)):
|
||||
n = int(pa[i], 0x10) - int(qa[i], 0x10)
|
||||
if n > 0:
|
||||
return 1
|
||||
|
@ -110,7 +110,7 @@ def get_xpath(doc, path):
|
|||
if ret is not None:
|
||||
if type(ret) == list:
|
||||
if len(ret) >= 1:
|
||||
if hasattr(ret[0],'text'):
|
||||
if hasattr(ret[0], 'text'):
|
||||
result = ret[0].text
|
||||
else:
|
||||
result = ret[0]
|
||||
|
@ -119,6 +119,7 @@ def get_xpath(doc, path):
|
|||
|
||||
return result
|
||||
|
||||
|
||||
def pretty_mem(val):
|
||||
val = int(val)
|
||||
if val > (10 * 1024 * 1024):
|
||||
|
@ -145,13 +146,11 @@ def validate_uuid(val):
|
|||
form = re.match("[a-fA-F0-9]{32}$", val)
|
||||
if form is None:
|
||||
raise ValueError(
|
||||
"UUID must be a 32-digit hexadecimal number. It may take "
|
||||
"the form xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may "
|
||||
"omit hyphens altogether.")
|
||||
"UUID must be a 32-digit hexadecimal number. It may take the form "
|
||||
"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx or may omit hyphens altogether.")
|
||||
|
||||
else: # UUID had no dashes, so add them in
|
||||
val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] +
|
||||
"-" + val[16:20] + "-" + val[20:32])
|
||||
val = (val[0:8] + "-" + val[8:12] + "-" + val[12:16] + "-" + val[16:20] + "-" + val[20:32])
|
||||
return val
|
||||
|
||||
|
||||
|
@ -159,7 +158,7 @@ def validate_macaddr(val):
|
|||
if val is None:
|
||||
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.")
|
||||
|
||||
form = re.match("^([0-9a-fA-F]{1,2}:){5}[0-9a-fA-F]{1,2}$", val)
|
||||
|
|
Loading…
Reference in a new issue