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

Merge pull request #321 from catborise/master

Translation and locale file updates
This commit is contained in:
Anatoliy Guskov 2020-06-13 16:55:19 +03:00 committed by GitHub
commit ad4b417695
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
57 changed files with 13088 additions and 5644 deletions

View file

@ -7,7 +7,7 @@ from django.conf import settings
class UserAddForm(forms.Form):
name = forms.CharField(label="Name",
error_messages={'required': _('No User name has been entered')},
error_messages={'required': _('No username has been entered')},
max_length=20)
password = forms.CharField(required=not settings.ALLOW_EMPTY_PASSWORD,
error_messages={'required': _('No password has been entered')},)

View file

@ -19,8 +19,8 @@ class UserInstance(models.Model):
class UserSSHKey(models.Model):
user = models.ForeignKey(User, on_delete=models.DO_NOTHING)
keyname = models.CharField(max_length=25)
keypublic = models.CharField(max_length=500)
keyname = models.CharField(_('key name'), max_length=25)
keypublic = models.CharField(_('public key'), max_length=500)
def __unicode__(self):
return self.keyname
@ -29,24 +29,28 @@ class UserSSHKey(models.Model):
class UserAttributes(models.Model):
user = models.OneToOneField(User, on_delete=models.CASCADE)
can_clone_instances = models.BooleanField(default=True)
max_instances = models.IntegerField(default=2,
help_text="-1 for unlimited. Any integer value",
max_instances = models.IntegerField(_('max instances'),
default=2,
help_text=_("-1 for unlimited. Any integer value"),
validators=[
MinValueValidator(-1),
])
max_cpus = models.IntegerField(
_('max CPUs'),
default=2,
help_text="-1 for unlimited. Any integer value",
help_text=_("-1 for unlimited. Any integer value"),
validators=[MinValueValidator(-1)],
)
max_memory = models.IntegerField(
_('max memory'),
default=2048,
help_text="-1 for unlimited. Any integer value",
help_text=_("-1 for unlimited. Any integer value"),
validators=[MinValueValidator(-1)],
)
max_disk_size = models.IntegerField(
_('max disk size'),
default=20,
help_text="-1 for unlimited. Any integer value",
help_text=_("-1 for unlimited. Any integer value"),
validators=[MinValueValidator(-1)],
)

View file

@ -8,7 +8,7 @@
<div class="col-lg-12">
{% include 'create_user_block.html' %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="Search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
<h2 class="page-header">{% trans "Users" %}</h1>
</div>
@ -22,7 +22,7 @@
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any User" %}
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any user" %}
</div>
</div>
{% else %}

View file

@ -18,7 +18,7 @@
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any User" %}
<i class="fa fa-exclamation-triangle"></i> <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any user" %}
</div>
</div>
{% else %}

View file

@ -17,7 +17,7 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="john" required pattern="[a-z0-9]+">
<input type="text" class="form-control" name="name" placeholder="{% trans "john" %}" required pattern="[a-z0-9]+">
</div>
</div>
<div class="form-group row">

View file

@ -9,7 +9,6 @@ class Migration(migrations.Migration):
initial = True
dependencies = [
('auth', '0011_update_proxy_permissions'),
]
operations = [

View file

@ -0,0 +1,14 @@
# Generated by Django 2.2.12 on 2020-06-09 08:30
from django.db import migrations
class Migration(migrations.Migration):
dependencies = [
('admin', '0001_initial'),
('auth', '0011_update_proxy_permissions'),
]
operations = [
]

View file

@ -22,7 +22,7 @@
<div class="col-lg-12">
<div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button>
{% icon 'exclamation-triangle '%} <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any users" %}
{% icon 'exclamation-triangle '%} <strong>{% trans "Warning" %}:</strong> {% trans "You don't have any user" %}
</div>
</div>
{% else %}
@ -35,7 +35,7 @@
<th span="col">{% trans "Staff" %}</th>
<th span="col">{% trans "Superuser" %}</th>
<th span="col">{% trans "Can Clone" %}</th>
<th span="col">{% trans "" %}</th>
<th span="col">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody class="searchable">

View file

@ -1,65 +1,38 @@
# Generated by Django 2.2.12 on 2020-05-23 12:05
from django.db import migrations
from django.utils.translation import ugettext_lazy as _
def add_default_settings(apps, schema_editor):
setting = apps.get_model("appsettings", "AppSettings")
db_alias = schema_editor.connection.alias
setting.objects.using(db_alias).bulk_create([
setting(1, "Theme", "BOOTSTRAP_THEME", "flaty",
"", "Bootstrap CSS & Bootswatch Theme"),
setting(2, "Theme SASS Path", "SASS_DIR", "dev/scss/",
"", "Bootstrap SASS & Bootswatch SASS Directory"),
setting(3, "All Instances View Style", "VIEW_INSTANCES_LIST_STYLE",
"grouped", "grouped,nongrouped", "All instances list style"),
setting(4, "Logs per Page", "LOGS_PER_PAGE",
"100", "", "Pagination for logs"),
setting(5, "Multiple Owner for VM ", "ALLOW_INSTANCE_MULTIPLE_OWNER",
"True", "True,False", "Allow to have multiple owner for instance"),
setting(6, "Quota Debug", "QUOTA_DEBUG", "True",
"True,False", "Debug for user quotas"),
setting(7, "Disk Format", "INSTANCE_VOLUME_DEFAULT_FORMAT",
"qcow2", "raw,qcow,qcow2", "Instance disk format"),
setting(8, "Disk Bus", "INSTANCE_VOLUME_DEFAULT_BUS", "virtio",
"virtio,scsi,ide,usb,sata", "Instance disk bus type"),
setting(9, "Disk SCSI Controller", "INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER",
"virtio-scsi", "virtio-scsi, lsilogic, virtio-blk", "SCSI controller type"),
setting(10, "Disk Cache", "INSTANCE_VOLUME_DEFAULT_CACHE", "directsync",
"default,directsync,none,unsafe,writeback,writethrough", "Disk volume cache type"),
setting(11, "Disk IO Type", "INSTANCE_VOLUME_DEFAULT_IO",
"default", "default,native,threads", "Volume io modes"),
setting(12, "Disk Detect Zeroes", "INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES",
"default", "default,on,off,unmap", "Volume detect zeroes mode"),
setting(13, "Disk Discard", "INSTANCE_VOLUME_DEFAULT_DISCARD",
"default", "default,unmap,ignore", "Volume discard mode"),
setting(14, "Disk Owner UID", "INSTANCE_VOLUME_DEFAULT_OWNER_UID", "0",
"", "Owner UID: up to os, 0=root, 107=qemu or libvirt-bin(for ubuntu)"),
setting(15, "Disk Owner GID", "INSTANCE_VOLUME_DEFAULT_OWNER_GID", "0",
"", "Owner GID: up to os, 0=root, 107=qemu or libvirt-bin(for ubuntu)"),
setting(16, "VM CPU Mode", "INSTANCE_CPU_DEFAULT_MODE", "host-model",
"no-model,host-model,host-passthrough,custom", "Cpu modes"),
setting(17, "VM Machine Type", "INSTANCE_MACHINE_DEFAULT_TYPE",
"q35", "q35,x86_64", "Chipset/Machine type"),
setting(18, "VM Firmware Type", "INSTANCE_FIRMWARE_DEFAULT_TYPE",
"BIOS", "BIOS,UEFI", "Firmware type for x86_64"),
setting(19, "VM Architecture Type", "INSTANCE_ARCH_DEFAULT_TYPE",
"x86_64", "x86_64,i686", "Architecture type: x86_64, i686, etc"),
setting(20, "VM Console Type", "QEMU_CONSOLE_DEFAULT_TYPE",
"vnc", "vnc,spice", "Default console type"),
setting(21, "VM Clone Name Prefix", "CLONE_INSTANCE_DEFAULT_PREFIX",
"instance", "True,False", "Prefix for cloned instance name"),
setting(22, "VM Clone Auto Name", "CLONE_INSTANCE_AUTO_NAME",
"False", "True,False", "Generated name for cloned instance"),
setting(23, "VM Clone Auto Migrate", "CLONE_INSTANCE_AUTO_MIGRATE",
"False", "True,False", "Auto migrate instance after clone"),
setting(24, "VM Bottom Bar", "VIEW_INSTANCE_DETAIL_BOTTOM_BAR",
"True", "True,False", "Bottom navbar for instance details"),
setting(25, "Show Access Root Pass", "SHOW_ACCESS_ROOT_PASSWORD",
"False", "True,False", "Show access root password"),
setting(26, "Show Access SSH Keys", "SHOW_ACCESS_SSH_KEYS",
"False", "True,False", "Show access ssh keys"),
setting(1, _("Theme"), "BOOTSTRAP_THEME", "flaty", "", _("Bootstrap CSS & Bootswatch Theme")),
setting(2, _("Theme SASS Path"), "SASS_DIR", "dev/scss/", "", _("Bootstrap SASS & Bootswatch SASS Directory")),
setting(3, _("All Instances View Style"), "VIEW_INSTANCES_LIST_STYLE", "grouped", "grouped,nongrouped", _("All instances list style")),
setting(4, _("Logs per Page"), "LOGS_PER_PAGE", "100", "", _("Pagination for logs")),
setting(5, _("Multiple Owner for VM"), "ALLOW_INSTANCE_MULTIPLE_OWNER", "True", "True,False", _("Allow to have multiple owner for instance")),
setting(6, _("Quota Debug"), "QUOTA_DEBUG", "True", "True,False", _("Debug for user quotas")),
setting(7, _("Disk Format"), "INSTANCE_VOLUME_DEFAULT_FORMAT", "qcow2", "raw,qcow,qcow2", _("Instance disk format")),
setting(8, _("Disk Bus"), "INSTANCE_VOLUME_DEFAULT_BUS", "virtio", "virtio,scsi,ide,usb,sata", _("Instance disk bus type")),
setting(9, _("Disk SCSI Controller"), "INSTANCE_VOLUME_DEFAULT_SCSI_CONTROLLER", "virtio-scsi", "virtio-scsi, lsilogic, virtio-blk", _("SCSI controller type")),
setting(10, _("Disk Cache"), "INSTANCE_VOLUME_DEFAULT_CACHE", "directsync", "default,directsync,none,unsafe,writeback,writethrough", _("Disk volume cache type")),
setting(11, _("Disk IO Type"), "INSTANCE_VOLUME_DEFAULT_IO", "default", "default,native,threads", _("Volume io modes")),
setting(12, _("Disk Detect Zeroes"), "INSTANCE_VOLUME_DEFAULT_DETECT_ZEROES", "default", "default,on,off,unmap", _("Volume detect zeroes mode")),
setting(13, _("Disk Discard"), "INSTANCE_VOLUME_DEFAULT_DISCARD", "default", "default,unmap,ignore", _("Volume discard mode")),
setting(14, _("Disk Owner UID"), "INSTANCE_VOLUME_DEFAULT_OWNER_UID", "0", "", _("Owner UID: up to os, 0=root, 107=qemu or libvirt-bin(for ubuntu)")),
setting(15, _("Disk Owner GID"), "INSTANCE_VOLUME_DEFAULT_OWNER_GID", "0", "", _("Owner GID: up to os, 0=root, 107=qemu or libvirt-bin(for ubuntu)")),
setting(16, _("VM CPU Mode"), "INSTANCE_CPU_DEFAULT_MODE", "host-model", "no-model,host-model,host-passthrough,custom", _("Cpu modes")),
setting(17, _("VM Machine Type"), "INSTANCE_MACHINE_DEFAULT_TYPE", "q35", "q35,x86_64", _("Chipset/Machine type")),
setting(18, _("VM Firmware Type"), "INSTANCE_FIRMWARE_DEFAULT_TYPE", "BIOS", "BIOS,UEFI", _("Firmware type for x86_64")),
setting(19, _("VM Architecture Type"), "INSTANCE_ARCH_DEFAULT_TYPE", "x86_64", "x86_64,i686", _("Architecture type: x86_64, i686, etc")),
setting(20, _("VM Console Type"), "QEMU_CONSOLE_DEFAULT_TYPE", "vnc", "vnc,spice", _("Default console type")),
setting(21, _("VM Clone Name Prefix"), "CLONE_INSTANCE_DEFAULT_PREFIX", "instance", "True,False", _("Prefix for cloned instance name")),
setting(22, _("VM Clone Auto Name"), "CLONE_INSTANCE_AUTO_NAME", "False", "True,False", _("Generated name for cloned instance")),
setting(23, _("VM Clone Auto Migrate"), "CLONE_INSTANCE_AUTO_MIGRATE", "False", "True,False", _("Auto migrate instance after clone")),
setting(24, _("VM Bottom Bar"), "VIEW_INSTANCE_DETAIL_BOTTOM_BAR", "True", "True,False", _("Bottom navbar for instance details")),
setting(25, _("Show Access Root Pass"), "SHOW_ACCESS_ROOT_PASSWORD", "False", "True,False", _("Show access root password")),
setting(26, _("Show Access SSH Keys"), "SHOW_ACCESS_SSH_KEYS", "False", "True,False", _("Show access ssh keys")),
])

View file

@ -1,13 +1,13 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
class AppSettings(models.Model):
def choices_as_list(self):
return self.choices.split(',')
name = models.CharField(max_length=25, null=False)
key = models.CharField(db_index=True, max_length=50, unique=True)
value = models.CharField(max_length=25)
choices = models.CharField(max_length=50)
description = models.CharField(max_length=100, null=True)
name = models.CharField(_('name'), max_length=25, null=False)
key = models.CharField(_('key'), db_index=True, max_length=50, unique=True)
value = models.CharField(_('value'), max_length=25)
choices = models.CharField(_('choices'), max_length=50)
description = models.CharField(_('description'), max_length=100, null=True)

View file

@ -37,9 +37,9 @@
{% if request.user.is_superuser %}
<form method="post" action="" role="form" aria-label="Edit sass directory settings form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ sass_dir.name }}</label>
<label class="col-sm-3 col-form-label">{% trans sass_dir.name %}</label>
<div class="col-sm-6">
<input class="form-control" name="{{ sass_dir.key }}" value="{{ sass_dir.value }}" onchange="this.form.submit()"/>
<input class="form-control" name="{{ sass_dir.key }}" value="{{ sass_dir.value }}" onchange="this.form.submit()" title="{% trans sass_dir.description %}"/>
</div>
</div>
</form>
@ -47,7 +47,7 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans bootstrap_theme.name %}</label>
<div class="col-sm-6">
<select class="form-control" name="{{ bootstrap_theme.key }}" onchange="this.form.submit()">
<select class="form-control" name="{{ bootstrap_theme.key }}" onchange="this.form.submit()" title="{% trans bootstrap_theme.description %}">
{% for theme in themes_list %}
<option {% if bootstrap_theme.value == theme %}selected{% endif %} value="{{ theme }}">{{ theme }}</option>
{% endfor %}
@ -61,16 +61,16 @@
{% for setting in appsettings %}
<form method="post" action="" role="form" aria-label="{{setting.name}} form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{{ setting.name }}</label>
<label class="col-sm-3 col-form-label">{% trans setting.name %}</label>
<div class="col-sm-6">
{% if setting.choices %}
<select class="form-control" name="{{ setting.key }}" onchange="this.form.submit()" title="{{ setting.description }}">
<select class="form-control" name="{{ setting.key }}" onchange="this.form.submit()" title="{% trans setting.description %}">
{% for choice in setting.choices_as_list %}
<option {% if setting.value == choice %} selected {% endif %} value={{ choice }}>{% trans choice %}</option>
{% endfor %}
</select>
{% else %}
<input class="form-control" name="{{ setting.key }}" value="{{ setting.value }}" title="{{ setting.description }}" onchange="this.form.submit()"/>
<input class="form-control" name="{{ setting.key }}" value="{{ setting.value }}" title="{% trans setting.description %}" onchange="this.form.submit()"/>
{% endif%}
</div>
</div>

View file

@ -20,7 +20,7 @@ def appsettings(request):
:return:
"""
error_messages = []
main_css = "wvc-main.min.css"
sass_dir = AppSettings.objects.get(key="SASS_DIR")
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
try:
@ -59,7 +59,7 @@ def appsettings(request):
main.write(scss_var + "\n" + scss_boot + "\n" + scss_bootswatch + "\n")
css_compressed = sass.compile(string=scss_var + "\n"+ scss_boot + "\n" + scss_bootswatch, output_style='compressed')
with open("static/" + "css/wvc-main.min.css", "w") as css:
with open("static/css/" + main_css, "w") as css:
css.write(css_compressed)
bootstrap_theme.value = theme

View file

@ -1,12 +1,12 @@
from django.db.models import Model, CharField, IntegerField
from django.utils.translation import ugettext_lazy as _
class Compute(Model):
name = CharField(max_length=64, unique=True)
hostname = CharField(max_length=64)
login = CharField(max_length=20)
password = CharField(max_length=14, blank=True, null=True)
details = CharField(max_length=64, null=True, blank=True)
name = CharField(_('name'), max_length=64, unique=True)
hostname = CharField(_('hostname'), max_length=64)
login = CharField(_('login'), max_length=20)
password = CharField(_('password'), max_length=14, blank=True, null=True)
details = CharField(_('details'), max_length=64, null=True, blank=True)
type = IntegerField()
def __unicode__(self):

View file

@ -16,7 +16,7 @@
<div class="row">
{% if computes_info %}
{% for compute in computes_info %}
<div id="{{ compute.name }}" class="col-12 col-sm-4">
<div id="{{ compute.name }}" class="mb-3 col-12 col-sm-4">
{% if compute.status is True %}
<div class="card border-success shadow h-100">
<div class="card-header bg-success">
@ -37,17 +37,17 @@
</div>
<div class="card-body">
<dl class="row">
<dt class="col-4">{% trans "Status" %}</dt>
<dt class="col-5">{% trans "Status" %}</dt>
{% if compute.status %}
<dd class="col-8">{% trans "Connected" %}</dd>
<dd class="col-7">{% trans "Connected" %}</dd>
{% else %}
<dd class="col-8">{% trans "Not Connected" %}</dd>
<dd class="col-7">{% trans "Not Connected" %}</dd>
{% endif %}
<dt class="col-4">{% trans "Details" %}</dt>
<dt class="col-5">{% trans "Details" %}</dt>
{% if compute.details %}
<dd class="col-8">{% trans compute.details %}</dd>
<dd class="col-7">{% trans compute.details %}</dd>
{% else %}
<dd class="col-8">{% trans "No details available" %}</dd>
<dd class="col-7">{% trans "No details available" %}</dd>
{% endif %}
</dl>
@ -63,7 +63,7 @@
<form method="post" role="form" aria-label="Edit tcp host form">{% csrf_token %}
<div class="modal-body">
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
@ -90,7 +90,7 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}" value="{{ compute.details }}">
</div>
</div></div>
<div class="modal-footer">
@ -111,7 +111,7 @@
<div class="modal-body">
<p class="modal-body">{% trans "Need create ssh <a href='https://github.com/retspen/webvirtmgr/wiki/Setup-SSH-Authorization'>authorization key</a>. If you have another SSH port on your server, you can add IP:PORT like '192.168.1.1:2222'." %}</p>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
@ -133,7 +133,7 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}" value="{{ compute.details }}">
</div>
</div>
</div>
@ -154,7 +154,7 @@
<form method="post" role="form" aria-label="Edit tls host form">{% csrf_token %}
<div class="modal-body">
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
@ -181,7 +181,7 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
<input type="text" name="details" class="form-control" placeholder="{% trans "Details" %}" value="{{ compute.details }}">
</div>
</div>
</div>
@ -202,7 +202,7 @@
<form method="post" role="form" aria-label="Edit/delete host form">{% csrf_token %}
<div class="modal-body">
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Label" %}</label>
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}">
<input type="text" name="name" class="form-control" value="{{ compute.name }}" maxlength="20" required pattern="[a-z0-9\.\-_]+">
@ -211,7 +211,7 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6">
<input type="text" name="details" class="form-control" placeholder="Details" value="{{ compute.details }}">
<input type="text" name="details" class="form-control" placeholder="{% trans 'Details' %}" value="{{ compute.details }}">
</div>
</div>
</div>

View file

@ -111,7 +111,7 @@
var path = spice_query_var('path', 'websockify');
if ((!host) || (!port)) {
console.log("must specify host and port in URL");
console.log(_("must specify host and port in URL"));
return;
}
@ -222,4 +222,3 @@
<!-- If DUMPXXX is turned on, dumped images will go here -->
</div>
{% endblock %}

View file

@ -45,7 +45,7 @@ def console(request):
if console_type == 'vnc' or console_type == 'spice':
response = render(request, console_page, locals())
else:
console_error = "Console type: %s no support" % console_type
console_error = f"Console type: {console_type} no support"
response = render(request, 'console-vnc-lite.html', locals())
response.set_cookie('token', token)

View file

@ -1,11 +1,11 @@
from django.db.models import Model, CharField, IntegerField
from django.utils.translation import ugettext_lazy as _
class Flavor(Model):
label = CharField(max_length=12)
memory = IntegerField()
vcpu = IntegerField()
disk = IntegerField()
label = CharField(_('label'), max_length=12)
memory = IntegerField(_('memory'))
vcpu = IntegerField(_('vcpu'))
disk = IntegerField(_('disk'))
def __unicode__(self):
return self.name

View file

@ -18,7 +18,7 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" name="label" class="form-control" placeholder="Micro" maxlength="20"
<input type="text" name="label" class="form-control" placeholder="{% trans "Micro" %}" maxlength="20"
required pattern="[a-zA-Z0-9]+">
</div>
</div>

View file

@ -1,13 +1,15 @@
{% extends "base.html" %}
{% load i18n %}
{% load staticfiles %}
{% block title %}{% trans "Create new instanc" %} - {% trans "Select Type" %}{% endblock %}
{% block title %}{% trans "Create new instance" %} - {% trans "Select Type" %}{% endblock %}
{% block content %}
<!-- Page Heading -->
<div class="row">
<div class="col-lg-12">
<h3 class="page-header">{% trans "New instance on" %} {{ compute.name }}</h3>
<h3 class="page-header">
{% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}
</h3>
</div>
</div>
<!-- /.row -->

View file

@ -10,7 +10,7 @@
<div class="row">
<div class="col-lg-12">
<h3 class="page-header">
{% trans "New instance on" %} {{ compute.name }}
{% blocktrans with host=compute.name %}New instance on {{ host }} {% endblocktrans %}</h3>
</h3>
</div>
</div>
@ -104,8 +104,8 @@
<div class="modal-body">
<form method="post" role="form" aria-label="Create instance from flavor form">{% csrf_token %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-7">
<input type="text" class="form-control" name="name"
placeholder="{% trans "Name" %}" maxlength="64" required
pattern="[a-zA-Z0-9\.\-_]+">
@ -116,9 +116,9 @@
</div>
{% if firmwares %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Firmware" %}</label>
<div class="col-sm-6">
<select class="custom-select" id="select_firmware" name="firmware">
<label class="col-sm-4 col-form-label">{% trans "Firmware" %}</label>
<div class="col-sm-7">
<select class="form-control" id="select_firmware" name="firmware">
{% for frm in firmwares %}
<option value="{{ frm }}" {% if frm in default_firmware %}selected{% endif %}>{{ frm }}</option>
{% endfor %}
@ -128,9 +128,9 @@
{% endif %}
{% if dom_caps.cpu_modes %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "VCPU Config" %}</label>
<div class="col-sm-6">
<select id="vcpu_mode" name="vcpu_mode" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "VCPU Config" %}</label>
<div class="col-sm-7">
<select class="form-control" id="vcpu_mode" name="vcpu_mode">
<option value=""> {% trans 'no-mode' %}</option>
{% for mode in dom_caps.cpu_modes %}
{% if mode == 'custom' %}
@ -150,10 +150,10 @@
</div>
{% endif %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Storage" %}</label>
<div class="col-sm-6">
<label class="col-sm-4 col-form-label">{% trans "Storage" %}</label>
<div class="col-sm-7">
<input type="hidden" name="cache_mode" value="default">
<select name="storage" class="custom-select">
<select class="form-control" name="storage">
{% if storages %}
{% for storage in storages %}
<option value="{{ storage }}">{{ storage }}</option>
@ -165,9 +165,9 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Network" %}</label>
<div class="col-sm-6">
<select name="networks" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "Network" %}</label>
<div class="col-sm-7">
<select class="form-control" name="networks">
{% for network in networks %}
<option value="{{ network }}">{{ network }}</option>
{% endfor %}
@ -175,8 +175,8 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Advanced" %}</label>
<div class="col-sm-6">
<label class="col-sm-4 col-form-label">{% trans "Advanced" %}</label>
<div class="col-sm-7">
<button class="btn btn-block btn-outline-light" type="button" data-toggle="collapse" data-target="#flavAddCollapse" aria-expanded="false" aria-controls="collapseExample">
<span class="fa fa-caret-down"></span>
</button>
@ -184,9 +184,9 @@
</div>
<div class="collapse" id="flavAddCollapse">
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "NWFilter" %}</label>
<div class="col-sm-6">
<select name="nwfilter" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "NWFilter" %}</label>
<div class="col-sm-7">
<select class="form-control" name="nwfilter">
<option value="">{% trans "None" %}</option>
{% for nwfilter in nwfilters %}
<option value="{{ nwfilter }}">{{ nwfilter }}</option>
@ -195,9 +195,9 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "HDD cache mode" %}</label>
<div class="col-sm-6">
<select id="cache_mode" name="cache_mode" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "HDD cache mode" %}</label>
<div class="col-sm-7">
<select class="form-control" id="cache_mode" name="cache_mode">
{% for mode, name in cache_modes %}
<option value="{{ mode }}" {% if mode == default_cache %}selected {% endif %}>
{% trans name %}</option>
@ -206,16 +206,16 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "MAC" %}</label>
<div class="col-sm-6">
<label class="col-sm-4 col-form-label">{% trans "MAC" %}</label>
<div class="col-sm-7">
<input type="text" class="form-control" name="mac" maxlength="17" value="{{ mac_auto }}" required pattern="[a-zA-Z0-9:]+">
</div>
</div>
{% if dom_caps.graphics_support == 'yes' %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Graphics" %}</label>
<div class="col-sm-6">
<select name="graphics" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "Graphics" %}</label>
<div class="col-sm-7">
<select class="form-control" name="graphics">
{% for graphics in dom_caps.graphics_types %}
<option value="{{ graphics }}" {% if default_graphics == graphics %}selected{% endif %}>{{ graphics }}</option>
{% endfor %}
@ -224,9 +224,9 @@
</div>
{% endif %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Video" %}</label>
<div class="col-sm-6">
<select name="video" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "Video" %}</label>
<div class="col-sm-7">
<select class="form-control" name="video">
{% if not videos %}
<option value="vga">vga</option>
<option value="cirrus">cirrus</option>
@ -238,9 +238,9 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Console Access" %}</label>
<div class="col-sm-6">
<select name="listener_addr" class="custom-select">
<label class="col-sm-4 col-form-label">{% trans "Console Access" %}</label>
<div class="col-sm-7">
<select class="custom-select" name="listener_addr">
{% for addr, label in listener_addr %}
<option value="{{ addr }}" {% if addr == "0.0.0.0" %} selected {% endif %}>{{ label }}</option>
{% endfor %}
@ -248,21 +248,21 @@
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Console Password" %}</label>
<div class="col-sm-6">
<input type="password" class="form-control" name="console_pass" placeholder="{% trans "Console Password" %}" maxlength="64">
<label class="col-sm-4 col-form-label">{% trans "Console Password" %}</label>
<div class="col-sm-7">
<input class="form-control" type="password" name="console_pass" placeholder="{% trans "Console Password" %}" maxlength="64">
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Guest Agent" %}</label>
<div class="col-sm-6">
<label class="col-sm-4 col-form-label">{% trans "Guest Agent" %}</label>
<div class="col-sm-7">
<input type="checkbox" name="qemu_ga" value="true" checked>
</div>
</div>
{% if virtio_support %}
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "VirtIO" %}</label>
<div class="col-sm-6">
<label class="col-sm-4 col-form-label">{% trans "VirtIO" %}</label>
<div class="col-sm-7">
<input type="checkbox" name="virtio" value="{{ virtio_support }}" checked>
</div>
</div>
@ -414,7 +414,7 @@
<div class="form-group row meta-prealloc">
<label class="col-sm-3 col-form-label">{% trans "Disk Metadata" %}</label>
<div class="col-sm-7">
<input type="checkbox" name="meta_prealloc" title="{% trans "Metadata Preallocation" %}" value="true">
<input type="checkbox" name="meta_prealloc" title="{% trans "Metadata preallocation" %}" value="true">
</div>
<label class="col-lg-1 col-form-label">{% trans "Image" %}</label>
</div>

View file

@ -34,7 +34,7 @@ def os_metadata_json(request, version):
response = {'uuid': OS_UUID, 'hostname': hostname}
return HttpResponse(json.dumps(response))
else:
err = 'Invalid version: {}'.format(version)
err = f"Invalid version: {version}"
raise Http404(err)
@ -59,7 +59,7 @@ def os_userdata(request, version):
return render(request, 'user_data', locals())
else:
err = 'Invalid version: {}'.format(version)
err = f"Invalid version: {version}"
raise Http404(err)
@ -108,5 +108,5 @@ def get_vdi_url(request, compute_id, vname):
response = url
return HttpResponse(response)
except libvirtError as lib_err:
err = f"Error getting vdi url for {vname}"
err = f"Error getting VDI URL for {vname}"
raise Http404(err)

View file

@ -7,10 +7,10 @@ from computes.models import Compute
class Instance(Model):
compute = ForeignKey(Compute, on_delete=CASCADE)
name = CharField(max_length=120)
uuid = CharField(max_length=36)
is_template = BooleanField(default=False)
created = DateField(auto_now_add=True)
name = CharField(_('name'), max_length=120)
uuid = CharField(_('uuid'), max_length=36)
is_template = BooleanField(_('is template'), default=False)
created = DateField(_('created'), auto_now_add=True)
def __unicode__(self):
return self.name

View file

@ -14,7 +14,7 @@
{% endif %}
{% if all_host_vms or all_user_vms %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="Search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
{% endif %}
<h2 class="page-header">{% trans "Instances" %}</h2>

View file

@ -229,7 +229,7 @@
{% endif %}
{% if status == 5 %}
<div role="tabpanel" class="tab-pane tab-pane-bordered active" id="boot">
<p>{% trans "Click on Boot button to start this instance." %}</p>
<p>{% trans "Click on Power On button to start this instance." %}</p>
<form action="" method="post" role="form" aria-label="Start instance form">{% csrf_token %}
{% if instance.is_template %}
<p>{% trans "Template instance cannot be started." %}</p>
@ -447,7 +447,7 @@
<form method="post" role="form" aria-label="Resize instance memory form">{% csrf_token %}
<p class="font-weight-bold">{% trans "Total host memory" %}: {{ memory_host|filesizeformat }}</p>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Current allocation" %} ({% trans "MB" %})</label>
<label class="col-sm-4 col-form-label">{% trans "Current Allocation" %} ({% trans "MB" %})</label>
<div class="col-sm-4 js-custom__container">
<select name="cur_memory" class="custom-select js-custom__toggle">
{% for mem in memory_range %}
@ -460,7 +460,7 @@
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">
{% trans "Maximum allocation" %} ({% trans "MB" %})
{% trans "Maximum Allocation" %} ({% trans "MB" %})
</label>
<div class="col-sm-4 js-custom__container">
<select name="memory" class="form-control js-custom__toggle">
@ -487,7 +487,7 @@
<p class="font-weight-bold">{% trans "Disk allocation (GB)" %}:</p>
{% for disk in disks %}
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Current allocation" %} ({{ disk.dev }})</label>
<label class="col-sm-4 col-form-label">{% trans "Current Allocation" %} ({{ disk.dev }})</label>
<div class="col-sm-4 js-custom__container">
<input type="text" name="disk_size_{{ disk.dev }}" class="form-control" value="{{ disk.size|filesizeformat }}" />
</div>
@ -761,7 +761,7 @@
data-toggle="popover"
data-html="true"
data-content="<strong>{% trans 'Bus' %}:</strong> {{ cd.bus }} <br/>
<strong>{% trans 'Dev' %}:</strong> {{ cd.dev }}">
<strong>{% trans 'Device' %}:</strong> {{ cd.dev }}">
{% trans "CD-ROM" %} {{ forloop.counter }}
</a>
{% if not cd.image %}
@ -1036,33 +1036,34 @@
</div>
{% if qos %}
<div class="col-10 col-sm-10">
<div class="row mt-3">
<div class="col-sm-10">
<p><strong>{% trans "QoS Configuration" %}</strong></p>
</div>
<div class="col-12 col-sm-12">
<table class="table table-hover">
<thead>
<tr>
<th scope="col">{% trans "MAC" %}/{% trans "Direction" %}</th>
<th scope="col">{% trans "Average" %}</th>
<th scope="col">{% trans "Peak" %}</th>
<th scope="col">{% trans "Burst" %}</th>
<th scope="col">{% trans "Actions" %}</th>
<tr class="d-flex">
<th scope="col" class="col-2">{% trans "MAC" %}/{% trans "Direction" %}</th>
<th scope="col" class="col-2">{% trans "Average" %}</th>
<th scope="col" class="col-3">{% trans "Peak" %}</th>
<th scope="col" class="col-3">{% trans "Burst" %}</th>
<th scope="col" class="col-2">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for q, attrs in qos.items %}
{% for att in attrs %}
<form method="post" role="form" aria-label="Instance Qos configuration form">{% csrf_token %}
<tr>
<td><label class="col-form-label">{{ q }} {{ att.direction | capfirst }}</label></td>
<td><input id="qos_average" class="form-control" name="qos_average"
<form method="post" role="form" aria-label="Instance QoS configuration form">{% csrf_token %}
<tr class="d-flex">
<td class="col-2"><label class="col-form-label">{{ q }} {{ att.direction | capfirst }}</label></td>
<td class="col-2"><input id="qos_average" class="form-control" name="qos_average"
value="{{ att.average|default:'' }}"/>
</td>
<td><input id="qos_peak" class="form-control" name="qos_peak"
<td class="col-3"><input id="qos_peak" class="form-control" name="qos_peak"
value="{{ att.peak|default:'' }}"/>
</td>
<td><input id="qos_burst" class="form-control" name="qos_burst"
<td class="col-3"><input id="qos_burst" class="form-control" name="qos_burst"
value="{{ att.burst|default:'' }}"/>
</td>
<td class="col-sm-2">
@ -1086,6 +1087,7 @@
</tbody>
</table>
</div>
</div>
{% endif %}
<div class="clearfix"></div>
</div>
@ -1177,7 +1179,7 @@
<div class="clearfix"></div>
</div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="xmledit">
<p>{% trans "If you need to edit xml please Power Off the instance" %}</p>
<p>{% trans "If you need to edit XML please Power Off the instance" %}</p>
<form method="post" role="form" aria-label="Edit instance XML form">{% csrf_token %}
<div class="col-sm-12" id="xmlheight">
<textarea id="editor">{{ inst_xml }}</textarea>
@ -1620,7 +1622,7 @@
{% for disk in disks %}
<div class="mb-1 card border-warning">
<div class="card-header">
<h3 class="card-title"><i class="fa fa-long-arrow-right"></i> {% trans "Disk I/O device" %}: {{ disk.dev }}</h3>
<h5 class="card-title"><i class="fa fa-long-arrow-right"></i> {% trans "Disk I/O device" %}: {{ disk.dev }}</h5>
</div>
<div class="card-body">
<div class="flot-chart">
@ -1682,7 +1684,7 @@
<div class="ml-3 form-row">
<div class="custom-control custom-switch">
<input class="custom-control-input" type="checkbox" name="delete_nvram" value="true" id="delete_nvram" checked>
<label class="custom-control-label font-weight-bold" for="delete_nvram" {% trans "Remove Instance's NVRAM" %}</label>
<label class="custom-control-label font-weight-bold" for="delete_nvram">{% trans "Remove Instance's NVRAM" %}</label>
</div>
</div>
{% endif %}

View file

@ -16,7 +16,7 @@
{% endif %}
{% if all_host_vms or all_user_vms %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="Search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
{% endif %}
<h2 class="page-header">{{ compute.name }}</h2>

View file

@ -257,7 +257,7 @@ def instance(request, compute_id, vname):
if autostart:
conn_new.set_autostart(1)
conn_new.close()
msg = _("Migrate to %s" % new_compute.hostname)
msg = _(f"Migrate to {new_compute.hostname}")
addlogmsg(request.user.username, instance.name, msg)
try:
@ -337,12 +337,12 @@ def instance(request, compute_id, vname):
if instance.uuid != uuid:
instance.uuid = uuid
instance.save()
msg = _("Fixing uuid %s" % uuid)
msg = _(f"Fixing UUID {uuid}")
addlogmsg(request.user.username, instance.name, msg)
except Instance.DoesNotExist:
instance = Instance(compute_id=compute_id, name=vname, uuid=uuid)
instance.save()
msg = _("Instance.DoesNotExist: Creating new instance")
msg = _("Instance does not exist: Creating new instance")
addlogmsg(request.user.username, instance.name, msg)
userinstances = UserInstance.objects.filter(instance=instance).order_by('user__username')
@ -456,7 +456,7 @@ def instance(request, compute_id, vname):
s.send(json.dumps(data))
result = json.loads(s.recv(1024))
s.close()
msg = _("Installed new ssh public key %s" % publickey.keyname)
msg = _(f"Installed new SSH public key {publickey.keyname}")
addlogmsg(request.user.username, instance.name, msg)
if result['return'] == 'success':
@ -565,10 +565,10 @@ def instance(request, compute_id, vname):
driver_type = conn_create.get_volume_type(name)
path = conn_create.get_target_path()
target_dev = get_new_disk_dev(media, disks, bus)
source = path + "/" + name
source = f"{path}/{name}"
conn.attach_disk(target_dev, source, target_bus=bus, driver_type=driver_type, cache_mode=cache)
msg = _('Attach Existing disk: ' + target_dev)
msg = _(f"Attach Existing disk: {target_dev}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
@ -600,11 +600,11 @@ def instance(request, compute_id, vname):
cache, io, discard, zeroes)
if not conn.get_status() == 5:
messages.success(request, _("Disk changes changes are applied. " +
messages.success(request, _("Volume changes are applied. " +
"But it will be activated after shutdown"))
else:
messages.success(request, _("Disk is changed successfully."))
msg = _('Edit disk: ' + target_dev)
messages.success(request, _("Volume is changed successfully."))
msg = _(f"Edit disk: {target_dev}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
@ -620,12 +620,12 @@ def instance(request, compute_id, vname):
path = request.POST.get('path', '')
name = request.POST.get('name', '')
msg = _('Delete disk: ' + dev)
msg = _(f"Delete disk: {dev}")
conn.detach_disk(dev)
try:
conn_delete.del_volume(name)
except libvirtError as err:
msg = _('The disk: ' + dev + ' is detached but not deleted. ' + err)
msg = _(f"The disk: {dev} is detached but not deleted. Error: {err}")
messages.warning(request, msg)
addlogmsg(request.user.username, instance.name, msg)
@ -635,7 +635,7 @@ def instance(request, compute_id, vname):
dev = request.POST.get('detach_vol', '')
path = request.POST.get('path', '')
conn.detach_disk(dev)
msg = _('Detach disk: ' + dev)
msg = _(f"Detach disk: {dev}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
@ -643,14 +643,14 @@ def instance(request, compute_id, vname):
bus = request.POST.get('bus', 'ide' if machine == 'pc' else 'sata')
target = get_new_disk_dev(media, disks, bus)
conn.attach_disk(target, "", disk_device='cdrom', cache_mode='none', target_bus=bus, readonly=True)
msg = _('Add CD-ROM: ' + target)
msg = _(f"Add CD-ROM: {target}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
if 'detach_cdrom' in request.POST and allow_admin_or_not_template:
dev = request.POST.get('detach_cdrom', '')
conn.detach_disk(dev)
msg = _('Detach CD-ROM: ' + dev)
msg = _(f'Detach CD-ROM: {dev}')
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
@ -658,7 +658,7 @@ def instance(request, compute_id, vname):
image = request.POST.get('path', '')
dev = request.POST.get('umount_iso', '')
conn.umount_iso(dev, image)
msg = _("Mount media: " + dev)
msg = _(f"Mount media: {dev}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
@ -666,21 +666,21 @@ def instance(request, compute_id, vname):
image = request.POST.get('media', '')
dev = request.POST.get('mount_iso', '')
conn.mount_iso(dev, image)
msg = _("Umount media: " + dev)
msg = _(f"Umount media: {dev}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#disks')
if 'snapshot' in request.POST and allow_admin_or_not_template:
name = request.POST.get('name', '')
conn.create_snapshot(name)
msg = _("New snapshot :" + name)
msg = _(f"New snapshot : {name}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
if 'delete_snapshot' in request.POST and allow_admin_or_not_template:
snap_name = request.POST.get('name', '')
conn.snapshot_delete(snap_name)
msg = _("Delete snapshot :" + snap_name)
msg = _(f"Delete snapshot : {snap_name}")
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#managesnapshot')
@ -713,14 +713,14 @@ def instance(request, compute_id, vname):
conn.set_vcpu(id, 1)
else:
conn.set_vcpu(id, 0)
msg = _("vCPU {} is enabled={}".format(id, enabled))
msg = _(f"VCPU {id} is enabled={enabled}")
messages.success(request, msg)
addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#resize')
if 'set_vcpu_hotplug' in request.POST:
status = request.POST.get('vcpu_hotplug', '')
msg = _("VCPU Hot-plug is enabled={}".format(status))
msg = _(f"VCPU Hot-plug is enabled={status}")
try:
conn.set_vcpu_hotplug(eval(status))
except libvirtError as lib_err:
@ -943,8 +943,8 @@ def instance(request, compute_id, vname):
messages.success(request, _(f"{qos_dir.capitalize()} QoS is deleted"))
else:
messages.success(request,
f"{qos_dir.capitalize()} QoS is deleted. Network XML is changed. " +
"Stop and start network to activate new config.")
_(f"{qos_dir.capitalize()} QoS is deleted. Network XML is changed. ") +
_("Stop and start network to activate new config."))
return HttpResponseRedirect(request.get_full_path() + '#network')
if 'add_owner' in request.POST:
@ -956,7 +956,7 @@ def instance(request, compute_id, vname):
check_inst = UserInstance.objects.filter(instance=instance)
if check_inst:
msg = _("One owner is allowed and owner already added")
msg = _("Only one owner is allowed and the one already added")
error_messages.append(msg)
else:
add_user_inst = UserInstance(instance=instance, user_id=user_id)
@ -993,7 +993,7 @@ def instance(request, compute_id, vname):
clone_data['name'] = auto_vname
clone_data['clone-net-mac-0'] = _get_dhcp_mac_address(auto_vname)
for disk in disks:
disk_dev = "disk-{}".format(disk['dev'])
disk_dev = f"disk-{disk['dev']}"
disk_name = get_clone_disk_name(disk, vname, auto_vname)
clone_data[disk_dev] = disk_name
@ -1024,7 +1024,7 @@ def instance(request, compute_id, vname):
user_instance = UserInstance(instance_id=new_instance.id, user_id=request.user.id, is_delete=True)
user_instance.save()
msg = _("Clone of '%s'" % instance.name)
msg = _(f"Clone of '{instance.name}'")
addlogmsg(request.user.username, new_instance.name, msg)
if appsettings.get(key="CLONE_INSTANCE_AUTO_MIGRATE").value == 'True':
@ -1157,7 +1157,7 @@ def get_host_instances(request, comp):
conn.close()
else:
raise libvirtError("Problem occurred with host: {} - {}".format(comp.name, status))
raise libvirtError(_(f"Problem occurred with host: {comp.name} - {status}"))
return all_host_vms
@ -1343,7 +1343,7 @@ def guess_clone_name(request):
with open(dhcp_file, 'r') as f:
for line in f:
line = line.strip()
if "host %s" % prefix in line:
if f"host {prefix}" in line:
fqdn = line.split(' ')[1]
hostname = fqdn.split('.')[0]
if hostname.startswith(prefix) and hostname not in instance_names:
@ -1364,12 +1364,12 @@ def get_clone_disk_name(disk, prefix, clone_name=''):
return None
if disk['image'].startswith(prefix) and clone_name:
suffix = disk['image'][len(prefix):]
image = "{}{}".format(clone_name, suffix)
image = f"{clone_name}{suffix}"
elif "." in disk['image'] and len(disk['image'].rsplit(".", 1)[1]) <= 7:
name, suffix = disk['image'].rsplit(".", 1)
image = "{}-clone.{}".format(name, suffix)
image = f"{name}-clone.{suffix}"
else:
image = "{}-clone".format(disk['image'])
image = f"{disk['image']}-clone"
return image
@ -1441,7 +1441,7 @@ def delete_instance(instance, delete_disk=False):
del_userinstance = UserInstance.objects.filter(instance=instance)
if del_userinstance:
print("Deleting UserInstances")
print("Deleting user instances")
print(del_userinstance)
del_userinstance.delete()
@ -1459,8 +1459,8 @@ def delete_instance(instance, delete_disk=False):
conn.delete()
instance.delete()
print("Instance {} on compute {} successfully deleted".format(instance_name, compute.hostname))
print(f"Instance {instance_name} on compute {compute.hostname} successfully deleted")
except libvirtError as lib_err:
print("Error removing instance {} on compute {}".format(instance_name, compute.hostname))
print(f"Error removing instance {instance_name} on compute {compute.hostname}")
raise lib_err

View file

@ -22,36 +22,36 @@ class AddInterface(forms.Form):
ipv4_addr = self.cleaned_data['ipv4_addr']
have_symbol = re.match('^[0-9./]+$', ipv4_addr)
if not have_symbol:
raise forms.ValidationError(_('The ipv4 must not contain any special characters'))
raise forms.ValidationError(_('The IPv4 address must not contain any special characters'))
elif len(ipv4_addr) > 20:
raise forms.ValidationError(_('The ipv4 must not exceed 20 characters'))
raise forms.ValidationError(_('The IPv4 address must not exceed 20 characters'))
return ipv4_addr
def clean_ipv4_gw(self):
ipv4_gw = self.cleaned_data['ipv4_gw']
have_symbol = re.match('^[0-9.]+$', ipv4_gw)
if not have_symbol:
raise forms.ValidationError(_('The ipv4 gateway must not contain any special characters'))
raise forms.ValidationError(_('The IPv4 gateway must not contain any special characters'))
elif len(ipv4_gw) > 20:
raise forms.ValidationError(_('The ipv4 gateway must not exceed 20 characters'))
raise forms.ValidationError(_('The IPv4 gateway must not exceed 20 characters'))
return ipv4_gw
def clean_ipv6_addr(self):
ipv6_addr = self.cleaned_data['ipv6_addr']
have_symbol = re.match('^[0-9a-f./:]+$', ipv6_addr)
if not have_symbol:
raise forms.ValidationError(_('The ipv6 must not contain any special characters'))
raise forms.ValidationError(_('The IPv6 address must not contain any special characters'))
elif len(ipv6_addr) > 100:
raise forms.ValidationError(_('The ipv6 must not exceed 100 characters'))
raise forms.ValidationError(_('The IPv6 address must not exceed 100 characters'))
return ipv6_addr
def clean_ipv6_gw(self):
ipv6_gw = self.cleaned_data['ipv6_gw']
have_symbol = re.match('^[0-9.]+$', ipv6_gw)
if not have_symbol:
raise forms.ValidationError(_('The ipv6 gateway must not contain any special characters'))
raise forms.ValidationError(_('The IPv6 gateway must not contain any special characters'))
elif len(ipv6_gw) > 100:
raise forms.ValidationError(_('The ipv6 gateway must not exceed 100 characters'))
raise forms.ValidationError(_('The IPv6 gateway must not exceed 100 characters'))
return ipv6_gw
def clean_name(self):

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

Binary file not shown.

File diff suppressed because it is too large Load diff

View file

@ -1,11 +1,11 @@
from django.db.models import Model, CharField, DateTimeField
from django.utils.translation import ugettext_lazy as _
class Logs(Model):
user = CharField(max_length=50)
instance = CharField(max_length=50)
message = CharField(max_length=255)
date = DateTimeField(auto_now=True)
user = CharField(_('user'), max_length=50)
instance = CharField(_('instance'), max_length=50)
message = CharField(_('message'), max_length=255)
date = DateTimeField(_('date'), auto_now=True)
def __unicode__(self):
return self.instance

View file

@ -30,18 +30,18 @@ class AddNetPool(forms.Form):
subnet = self.cleaned_data['subnet']
have_symbol = re.match('^[0-9./]+$', subnet if subnet else ".")
if not have_symbol:
raise forms.ValidationError(_('The pool subnet must not contain any special characters'))
raise forms.ValidationError(_('The IPv4 subnet must not contain any special characters'))
elif len(subnet) > 20:
raise forms.ValidationError(_('The pool subnet must not exceed 20 characters'))
raise forms.ValidationError(_('The IPv4 subnet must not exceed 20 characters'))
return subnet
def clean_subnet6(self):
subnet = self.cleaned_data['subnet6']
have_symbol = re.match('^[0-9a-fA-F:/]+$', subnet if subnet else ":")
if not have_symbol:
raise forms.ValidationError(_('The pool subnet must not contain any special characters'))
raise forms.ValidationError(_('The IPv6 subnet must not contain any special characters'))
elif len(subnet) > 42:
raise forms.ValidationError(_('The pool subnet must not exceed 42 characters'))
raise forms.ValidationError(_('The IPv6 subnet must not exceed 42 characters'))
return subnet
def clean_bridge_name(self):

View file

@ -26,21 +26,21 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Average" %}:</label>
<div class="col-sm-6">
<input class="form-control" name="qos_average" placeholder="kilobytes"
<input class="form-control" name="qos_average" placeholder="{% trans "kilobytes" %}"
required pattern="[0-9]+"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Peak" %}:</label>
<div class="col-sm-6">
<input class="form-control" name="qos_peak" placeholder="kilobytes"
<input class="form-control" name="qos_peak" placeholder="{% trans "kilobytes" %}"
pattern="[0-9]+"/>
</div>
</div>
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Burst" %}:</label>
<div class="col-sm-6">
<input class="form-control" name="qos_burst" placeholder="kilobytes"
<input class="form-control" name="qos_burst" placeholder="{% trans "kilobytes" %}"
pattern="[0-9]+"/>
</div>
</div>

View file

@ -17,7 +17,7 @@
<div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="default" required pattern="[a-zA-Z0-9_]+">
<input type="text" class="form-control" name="name" placeholder="{% trans "default" %}" required pattern="[a-zA-Z0-9_]+">
</div>
</div>
<div class="form-group row">
@ -44,7 +44,7 @@
</div>
</div>
<div class="form-group row bridge_name_form_group_dhcp">
<label class="col-sm-4 col-form-label">{% trans "Fixed Address" %}</label>
<label class="col-sm-4 col-form-label">{% trans "Fixed Addresses" %}</label>
<div class="col-sm-6">
<input type="checkbox" name="fixed" value="true">
</div>

View file

@ -149,7 +149,7 @@
{% include 'modify_ipv4_fixed_address.html' %}
{% endif %}
<h5 class="page-header">{% trans "IPv4 Fixed Address" %}</h5>
<h5 class="page-header">{% trans "IPv4 Fixed Addresses" %}</h5>
{% endif %}
@ -261,7 +261,7 @@
{% if state %}
{% include 'modify_ipv6_fixed_address.html' %}
{% endif %}
<h5 class="page-header">{% trans "IPv6 Fixed Address" %}</h5>
<h5 class="page-header">{% trans "IPv6 Fixed Addresses" %}</h5>
{% endif %}
{% if ipv6_fixed_address %}

View file

@ -8,7 +8,7 @@
<div class="col-lg-12">
{% include 'create_nwfilter_block.html' %}
<div class="float-right search">
<input id="filter" class="form-control" type="text" placeholder="Search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
<h2 class="page-header">{{ compute.name }} - {% trans "NWFilters" %}</h2>
</div>

View file

@ -43,7 +43,7 @@ def nwfilters(request, compute_id):
error_msg = _("A network filter with this name already exists")
raise Exception(error_msg)
if uuid == nwf.UUIDString():
error_msg = _("A network filter with this uuid already exists")
error_msg = _("A network filter with this UUID already exists")
raise Exception(error_msg)
else:
try:

View file

@ -45,9 +45,9 @@ class AddStgPool(forms.Form):
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'))
raise forms.ValidationError(_('No device or path has been entered'))
if not have_symbol:
raise forms.ValidationError(_('The source must not contain any special characters'))
raise forms.ValidationError(_('The disk source must not contain any special characters'))
return source

View file

@ -41,7 +41,7 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="default" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
<input type="text" class="form-control" name="name" placeholder="{% trans "default" %}" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
</div>
</div>
<div class="form-group row">
@ -70,7 +70,7 @@
<div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6">
<input type="text" class="form-control" name="name" placeholder="default" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
<input type="text" class="form-control" name="name" placeholder="{% trans "default" %}" maxlength="20" required pattern="[a-zA-Z0-9\.\-_]+">
</div>
</div>
<div class="form-group row">

View file

@ -86,7 +86,7 @@
<div class="row">
<h5 class="page-header mr-auto">{% trans "Volumes" %}</h5>
<div class="col-3 ">
<input id="filter" class="form-control" type="text" placeholder="Search">
<input id="filter" class="form-control" type="text" placeholder="{% trans 'Search' %}">
</div>
</div>

View file

@ -162,7 +162,7 @@ def storage(request, compute_id, pool):
try:
vol = conn.get_volume(volname)
vol.delete(0)
messages.success(request, _('Volume: {} is deleted.'.format(volname)))
messages.success(request, _(f"Volume: {volname} is deleted."))
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)
@ -172,7 +172,7 @@ def storage(request, compute_id, pool):
error_messages.append(error_msg)
else:
handle_uploaded_file(path, request.FILES['file'])
messages.success(request, _('ISO: {} is uploaded.'.format(request.FILES['file'])))
messages.success(request, _(f"ISO: {request.FILES['file']} is uploaded."))
return HttpResponseRedirect(request.get_full_path())
if 'cln_volume' in request.POST:
form = CloneImage(request.POST)
@ -192,7 +192,7 @@ def storage(request, compute_id, pool):
format = None
try:
name = conn.clone_volume(data['image'], data['name'], format, meta_prealloc)
messages.success(request, _("{} image cloned as {} successfully".format(data['image'], name)))
messages.success(request, _(f"{data['image']} image cloned as {name} successfully"))
return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err:
error_messages.append(lib_err)

View file

@ -38,6 +38,10 @@
<i class="fa fa-fw fa-user"></i> {{ request.user.username }}
</a>
<div class="dropdown-menu" aria-labelledby="navbarUserDropdown">
{% get_current_language as LANGUAGE_CODE %}
<a class="dropdown-item disabled" href="#">
{% trans "Language" %}: <span class="badge badge-secondary">{{ LANGUAGE_CODE }}</span>
</a>
<a class="dropdown-item {% view_active request 'profile' %}" href="{% url 'profile' %}"><i class="fa fa-fw fa-pencil-square-o"></i> {% trans "Profile" %}</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="{% url 'logout' %}"><i class="fa fa-fw fa-power-off"></i> {% trans "Log Out" %}</a>

View file

@ -42,6 +42,7 @@ INSTALLED_APPS = [
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -49,7 +50,6 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
]
ROOT_URLCONF = 'webvirtcloud.urls'
@ -111,6 +111,10 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"),
]
LOCALE_PATHS = [
'locale/',
]
LOGGING = {
"version": 1,
"disable_existing_loggers": False,