1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2025-07-31 12:41:08 +00:00

Merge pull request #1 from dropnas/migrate/to/python3

Migrate to python3 and django 2.x
This commit is contained in:
Gao Jiangmiao 2019-08-18 22:26:41 +08:00 committed by GitHub
commit 1a9a140da6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
113 changed files with 257 additions and 557 deletions

View file

@ -8,37 +8,37 @@ RUN DEBIAN_FRONTEND=noninteractive apt-get -qyy install \
-o APT::Install-Suggests=false \ -o APT::Install-Suggests=false \
git python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev nginx libsasl2-modules git python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev nginx libsasl2-modules
ADD . /srv/webvirtcloud ADD . /srv/webvirt
RUN chown -R www-data:www-data /srv/webvirtcloud RUN chown -R www-data:www-data /srv/webvirt
# Setup webvirtcloud # Setup webvirt
RUN cd /srv/webvirtcloud && \ RUN cd /srv/webvirt && \
virtualenv venv && \ virtualenv venv && \
. venv/bin/activate && \ . venv/bin/activate && \
pip install -U pip && \ pip install -U pip && \
pip install -r conf/requirements.txt && \ pip install -r conf/requirements.txt && \
chown -R www-data:www-data /srv/webvirtcloud chown -R www-data:www-data /srv/webvirt
RUN cd /srv/webvirtcloud && . venv/bin/activate && \ RUN cd /srv/webvirt && . venv/bin/activate && \
python manage.py migrate && \ python manage.py migrate && \
chown -R www-data:www-data /srv/webvirtcloud chown -R www-data:www-data /srv/webvirt
# Setup Nginx # Setup Nginx
RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf && \ RUN echo "\ndaemon off;" >> /etc/nginx/nginx.conf && \
rm /etc/nginx/sites-enabled/default && \ rm /etc/nginx/sites-enabled/default && \
chown -R www-data:www-data /var/lib/nginx chown -R www-data:www-data /var/lib/nginx
ADD conf/nginx/webvirtcloud.conf /etc/nginx/conf.d/ ADD conf/nginx/webvirt.conf /etc/nginx/conf.d/
# Register services to runit # Register services to runit
RUN mkdir /etc/service/nginx && \ RUN mkdir /etc/service/nginx && \
mkdir /etc/service/nginx-log-forwarder && \ mkdir /etc/service/nginx-log-forwarder && \
mkdir /etc/service/webvirtcloud && \ mkdir /etc/service/webvirt && \
mkdir /etc/service/novnc mkdir /etc/service/novnc
ADD conf/runit/nginx /etc/service/nginx/run ADD conf/runit/nginx /etc/service/nginx/run
ADD conf/runit/nginx-log-forwarder /etc/service/nginx-log-forwarder/run ADD conf/runit/nginx-log-forwarder /etc/service/nginx-log-forwarder/run
ADD conf/runit/novncd.sh /etc/service/novnc/run ADD conf/runit/novncd.sh /etc/service/novnc/run
ADD conf/runit/webvirtcloud.sh /etc/service/webvirtcloud/run ADD conf/runit/webvirt.sh /etc/service/webvirt/run
EXPOSE 80 EXPOSE 80
EXPOSE 6080 EXPOSE 6080

53
Vagrantfile vendored
View file

@ -1,53 +0,0 @@
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure(2) do |config|
# Default machine, if name not specified...
config.vm.define "dev", primary: true do |dev|
dev.vm.box = "ubuntu/bionic64"
dev.vm.hostname = "webvirtcloud"
dev.vm.network "private_network", ip: "192.168.33.10"
dev.vm.provision "shell", inline: <<-SHELL
sudo sh /vagrant/dev/libvirt-bootstrap.sh
sudo sed -i 's/auth_tcp = \"sasl\"/auth_tcp = \"none\"/g' /etc/libvirt/libvirtd.conf
sudo service libvirt-bin restart
sudo adduser vagrant libvirtd
sudo apt-get -y install python-virtualenv python-dev python-lxml libvirt-dev zlib1g-dev
virtualenv /vagrant/venv
source /vagrant/venv/bin/activate
pip install -r /vagrant/dev/requirements.txt
SHELL
end
# To start this machine run "vagrant up prod"
# To enter this machine run "vagrant ssh prod"
config.vm.define "prod", autostart: false do |prod|
prod.vm.box = "ubuntu/bionic64"
prod.vm.hostname = "webvirtcloud"
prod.vm.network "private_network", ip: "192.168.33.11"
#prod.vm.synced_folder ".", "/srv/webvirtcloud"
prod.vm.provision "shell", inline: <<-SHELL
sudo mkdir /srv/webvirtcloud
sudo cp -R /vagrant/* /srv/webvirtcloud
sudo sh /srv/webvirtcloud/dev/libvirt-bootstrap.sh
sudo sed -i 's/auth_tcp = \"sasl\"/auth_tcp = \"none\"/g' /etc/libvirt/libvirtd.conf
sudo service libvirt-bin restart
sudo adduser vagrant libvirtd
sudo chown -R vagrant:vagrant /srv/webvirtcloud
sudo apt-get -y install python-virtualenv python-dev python-lxml python-pip libvirt-dev zlib1g-dev libxslt1-dev nginx supervisor libsasl2-modules gcc pkg-config python-guestfs
virtualenv /srv/webvirtcloud/venv
source /srv/webvirtcloud/venv/bin/activate
pip install -r /srv/webvirtcloud/dev/requirements.txt
sudo cp /srv/webvirtcloud/conf/supervisor/webvirtcloud.conf /etc/supervisor/conf.d
sudo cp /srv/webvirtcloud/conf/nginx/webvirtcloud.conf /etc/nginx/conf.d
sudo cp /srv/webvirtcloud/webvirtcloud/settings.py.template /srv/webvirtcloud/webvirtcloud/settings.py
sudo sed "s/SECRET_KEY = ''/SECRET_KEY = '"`python /srv/webvirtcloud/conf/runit/secret_generator.py`"'/" -i /srv/webvirtcloud/webvirtcloud/settings.py
python /srv/webvirtcloud/manage.py migrate
sudo rm /etc/nginx/sites-enabled/default
sudo chown -R www-data:www-data /srv/webvirtcloud
sudo service nginx restart
sudo service supervisor restart
SHELL
end
end

View file

@ -1 +0,0 @@
theme: jekyll-theme-cayman

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,13 +0,0 @@
from django.contrib.auth.backends import RemoteUserBackend
from accounts.models import UserInstance, UserAttributes
from instances.models import Instance
class MyRemoteUserBackend(RemoteUserBackend):
#create_unknown_user = True
def configure_user(self, user):
#user.is_superuser = True
UserAttributes.configure_user(user)
return user

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
from django.conf import settings from django.conf import settings
from django.db.models import CASCADE
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -19,8 +17,8 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('is_change', models.BooleanField(default=False)), ('is_change', models.BooleanField(default=False)),
('is_delete', models.BooleanField(default=False)), ('is_delete', models.BooleanField(default=False)),
('instance', models.ForeignKey(to='instances.Instance')), ('instance', models.ForeignKey(to='instances.Instance', on_delete=CASCADE)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=CASCADE)),
], ],
options={ options={
}, },

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,8 +1,6 @@
# -*- 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
from django.db.models import CASCADE
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -19,7 +17,7 @@ class Migration(migrations.Migration):
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('keyname', models.CharField(max_length=25)), ('keyname', models.CharField(max_length=25)),
('keypublic', models.CharField(max_length=500)), ('keypublic', models.CharField(max_length=500)),
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL)), ('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=CASCADE)),
], ],
), ),
] ]

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
from django.conf import settings from django.conf import settings
from django.db.models import CASCADE
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -20,7 +18,7 @@ class Migration(migrations.Migration):
('max_instances', models.IntegerField(default=0)), ('max_instances', models.IntegerField(default=0)),
('max_cpus', models.IntegerField(default=0)), ('max_cpus', models.IntegerField(default=0)),
('max_memory', models.IntegerField(default=0)), ('max_memory', models.IntegerField(default=0)),
('user', models.OneToOneField(to=settings.AUTH_USER_MODEL)), ('user', models.OneToOneField(to=settings.AUTH_USER_MODEL, on_delete=CASCADE)),
], ],
), ),
] ]

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,10 +1,6 @@
# -*- 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 from django.db.models import DO_NOTHING
class Migration(migrations.Migration): class Migration(migrations.Migration):
@ -17,6 +13,6 @@ class Migration(migrations.Migration):
migrations.AlterField( migrations.AlterField(
model_name='usersshkey', model_name='usersshkey',
name='user', name='user',
field=models.ForeignKey(on_delete=django.db.models.deletion.DO_NOTHING, to=settings.AUTH_USER_MODEL), field=models.ForeignKey(to=settings.AUTH_USER_MODEL, on_delete=DO_NOTHING),
), ),
] ]

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)])
@ -48,7 +49,7 @@ class UserAttributes(models.Model):
instance = Instance.objects.get(name=instance_name) instance = Instance.objects.get(name=instance_name)
user_instance = UserInstance(user=user, instance=instance) user_instance = UserInstance(user=user, instance=instance)
user_instance.save() user_instance.save()
@staticmethod @staticmethod
def configure_user(user): def configure_user(user):
UserAttributes.create_missing_userattributes(user) UserAttributes.create_missing_userattributes(user)

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,6 +1,6 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse from django.urls import reverse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -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()
@ -185,12 +186,12 @@ def account(request, user_id):
return HttpResponseRedirect(request.get_full_path()) return HttpResponseRedirect(request.get_full_path())
if 'add' in request.POST: if 'add' in request.POST:
inst_id = request.POST.get('inst_id', '') inst_id = request.POST.get('inst_id', '')
if settings.ALLOW_INSTANCE_MULTIPLE_OWNER: if settings.ALLOW_INSTANCE_MULTIPLE_OWNER:
check_inst = UserInstance.objects.filter(instance_id=int(inst_id), user_id=int(user_id)) check_inst = UserInstance.objects.filter(instance_id=int(inst_id), user_id=int(user_id))
else: else:
check_inst = UserInstance.objects.filter(instance_id=int(inst_id)) check_inst = UserInstance.objects.filter(instance_id=int(inst_id))
if check_inst: if check_inst:
msg = _("Instance already added") msg = _("Instance already added")
error_messages.append(msg) error_messages.append(msg)

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

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,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,8 +1,7 @@
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
from django.core.urlresolvers import reverse from django.urls import reverse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
@ -44,7 +43,7 @@ def computes(request):
error_messages = [] error_messages = []
computes = Compute.objects.filter().order_by('name') computes = Compute.objects.filter().order_by('name')
computes_info = get_hosts_status(computes) computes_info = get_hosts_status(computes)
if request.method == 'POST': if request.method == 'POST':
if 'host_del' in request.POST: if 'host_del' in request.POST:
compute_id = request.POST.get('host_id', '') compute_id = request.POST.get('host_id', '')
@ -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

@ -1,7 +1,6 @@
Django==1.11.21 Django==2.2.4
websockify==0.8.0 websockify==0.8.0
gunicorn==19.9.0 gunicorn==19.9.0
lxml==4.2.5 lxml==4.2.5
libvirt-python==5.3.0 libvirt-python==5.3.0
pytz pytz
rwlock

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

@ -7,7 +7,7 @@ import django
DIR_PATH = os.path.dirname(os.path.abspath(__file__)) DIR_PATH = os.path.dirname(os.path.abspath(__file__))
ROOT_PATH = os.path.abspath(os.path.join(DIR_PATH, '..', '')) ROOT_PATH = os.path.abspath(os.path.join(DIR_PATH, '..', ''))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirtcloud.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirt.settings")
CERT = DIR_PATH + '/cert.pem' CERT = DIR_PATH + '/cert.pem'
if ROOT_PATH not in sys.path: if ROOT_PATH not in sys.path:
@ -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 webvirt.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

@ -6,7 +6,7 @@
<link rel="shortcut icon" href="{% static "favicon.ico" %}"> <link rel="shortcut icon" href="{% static "favicon.ico" %}">
<meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="{% static "css/bootstrap.min.css" %}"> <link rel="stylesheet" href="{% static "css/bootstrap.min.css" %}">
<link href="{% static "css/webvirtcloud.css" %}" rel="stylesheet"> <link href="{% static "css/webvirt.css" %}" rel="stylesheet">
<style> <style>
body { body {

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

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,12 +1,10 @@
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
from webvirtcloud.settings import WS_PORT from webvirt.settings import WS_PORT
from webvirtcloud.settings import WS_PUBLIC_HOST from webvirt.settings import WS_PUBLIC_HOST
from libvirt import libvirtError from libvirt import libvirtError

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -2,7 +2,7 @@ import re
from django import forms from django import forms
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from create.models import Flavor from create.models import Flavor
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES from webvirt.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
class FlavorAddForm(forms.Form): class FlavorAddForm(forms.Form):
@ -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

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from create.models import Flavor from create.models import Flavor
@ -10,9 +10,9 @@ from instances.models import Instance
from vrtManager.create import wvmCreate from vrtManager.create import wvmCreate
from vrtManager import util from vrtManager import util
from libvirt import libvirtError from libvirt import libvirtError
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES from webvirt.settings import QEMU_CONSOLE_LISTEN_ADDRESSES
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_CACHE from webvirt.settings import INSTANCE_VOLUME_DEFAULT_CACHE
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_BUS from webvirt.settings import INSTANCE_VOLUME_DEFAULT_BUS
from django.contrib import messages from django.contrib import messages
from logs.views import addlogmsg from logs.views import addlogmsg
@ -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,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

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

@ -20,7 +20,6 @@ import os
# range. # range.
# #
#bind = 'unix:/srv/webvirtcloud/venv/wvcloud.socket'
bind = '127.0.0.1:8000' bind = '127.0.0.1:8000'
backlog = 2048 backlog = 2048

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

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,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

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

@ -8,7 +8,7 @@ import string
import random import random
from bisect import insort from bisect import insort
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse from django.urls import reverse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
@ -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()
@ -1075,7 +1077,7 @@ def inst_graph(request, compute_id, vname):
def _get_dhcp_mac_address(vname): def _get_dhcp_mac_address(vname):
dhcp_file = '/srv/webvirtcloud/dhcpd.conf' dhcp_file = '/srv/webvirt/dhcpd.conf'
mac = '' mac = ''
if os.path.isfile(dhcp_file): if os.path.isfile(dhcp_file):
with open(dhcp_file, 'r') as f: with open(dhcp_file, 'r') as f:
@ -1117,7 +1119,7 @@ def random_mac_address(request):
@login_required @login_required
def guess_clone_name(request): def guess_clone_name(request):
dhcp_file = '/srv/webvirtcloud/dhcpd.conf' dhcp_file = '/srv/webvirt/dhcpd.conf'
prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX prefix = settings.CLONE_INSTANCE_DEFAULT_PREFIX
if os.path.isfile(dhcp_file): if os.path.isfile(dhcp_file):
instance_names = [i.name for i in Instance.objects.filter(name__startswith=prefix)] instance_names = [i.name for i in Instance.objects.filter(name__startswith=prefix)]
@ -1177,10 +1179,9 @@ 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)
for ui in userinstances: for ui in userinstances:
keys = UserSSHKey.objects.filter(user=ui.user) keys = UserSSHKey.objects.filter(user=ui.user)
for k in keys: for k in keys:
@ -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,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,6 +1,6 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from interfaces.forms import AddInterface from interfaces.forms import AddInterface

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

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

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,6 +1,6 @@
from django.shortcuts import render from django.shortcuts import render
from django.http import HttpResponse, HttpResponseRedirect from django.http import HttpResponse, HttpResponseRedirect
from django.core.urlresolvers import reverse from django.urls 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 logs.models import Logs from logs.models import Logs

View file

@ -3,7 +3,7 @@ import os
import sys import sys
if __name__ == "__main__": if __name__ == "__main__":
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirtcloud.settings") os.environ.setdefault("DJANGO_SETTINGS_MODULE", "webvirt.settings")
from django.core.management import execute_from_command_line from django.core.management import execute_from_command_line

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

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

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from networks.forms import AddNetPool from networks.forms import AddNetPool
@ -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 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.contrib import admin
# Register your models here.

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 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models
# Create your models here.

View file

@ -1,6 +0,0 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.test import TestCase
# Create your tests here.

View file

@ -1,11 +1,8 @@
# -*- 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
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from vrtManager import util from vrtManager import util
@ -208,4 +205,4 @@ def nwfilter(request, compute_id, nwfltr):
except Exception as error_msg: except Exception as error_msg:
error_messages.append(error_msg) error_messages.append(error_msg)
return render(request, 'nwfilter.html', locals()) return render(request, 'nwfilter.html', locals())

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

View file

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,6 +1,6 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.core.urlresolvers import reverse from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from secrets.forms import AddSecret from secrets.forms import AddSecret

View file

@ -1,3 +0,0 @@
from django.contrib import admin
# Register your models here.

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

@ -1,3 +0,0 @@
from django.db import models
# Create your models here.

View file

@ -1,3 +0,0 @@
from django.test import TestCase
# Create your tests here.

View file

@ -1,7 +1,7 @@
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
from django.http import HttpResponseRedirect, HttpResponse from django.http import HttpResponseRedirect, HttpResponse
from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ugettext_lazy as _
from django.core.urlresolvers import reverse from django.urls import reverse
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from computes.models import Compute from computes.models import Compute
from storages.forms import AddStgPool, AddImage, CloneImage from storages.forms import AddStgPool, AddImage, CloneImage
@ -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):
""" """
@ -225,4 +226,4 @@ def get_volumes(request, compute_id, pool):
except libvirtError: except libvirtError:
pass pass
data['vols'] = sorted(conn.get_volumes()) data['vols'] = sorted(conn.get_volumes())
return HttpResponse(json.dumps(data)) return HttpResponse(json.dumps(data))

View file

@ -14,7 +14,7 @@
<link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet"> <link href="{% static "css/bootstrap.min.css" %}" rel="stylesheet">
<!-- WebVirtCloud CSS --> <!-- WebVirtCloud CSS -->
<link href="{% static "css/webvirtcloud.css" %}" rel="stylesheet"> <link href="{% static "css/webvirt.css" %}" rel="stylesheet">
<!-- Aditional CSS --> <!-- Aditional CSS -->
{% block style %}{% endblock %} {% block style %}{% endblock %}

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

@ -1,10 +1,9 @@
import string 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 webvirt.settings import QEMU_CONSOLE_DEFAULT_TYPE
from webvirtcloud.settings import QEMU_CONSOLE_LISTEN_ADDRESSES from webvirt.settings import INSTANCE_VOLUME_DEFAULT_OWNER as default_owner
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_OWNER as default_owner from webvirt.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
from webvirtcloud.settings import INSTANCE_VOLUME_DEFAULT_FORMAT
def get_rbd_storage_data(stg): def get_rbd_storage_data(stg):
@ -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

Some files were not shown because too many files have changed in this diff Show more