1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2024-12-25 15:45:23 +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): class UserAddForm(forms.Form):
name = forms.CharField(label="Name", 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) max_length=20)
password = forms.CharField(required=not settings.ALLOW_EMPTY_PASSWORD, password = forms.CharField(required=not settings.ALLOW_EMPTY_PASSWORD,
error_messages={'required': _('No password has been entered')},) error_messages={'required': _('No password has been entered')},)

View file

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

View file

@ -8,7 +8,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_user_block.html' %} {% include 'create_user_block.html' %}
<div class="float-right search"> <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> </div>
<h2 class="page-header">{% trans "Users" %}</h1> <h2 class="page-header">{% trans "Users" %}</h1>
</div> </div>
@ -22,7 +22,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-warning alert-dismissable"> <div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <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>
</div> </div>
{% else %} {% else %}

View file

@ -18,7 +18,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
<div class="alert alert-warning alert-dismissable"> <div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <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>
</div> </div>
{% else %} {% else %}

View file

@ -17,7 +17,7 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label> <label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6"> <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> </div>
<div class="form-group row"> <div class="form-group row">

View file

@ -9,7 +9,6 @@ class Migration(migrations.Migration):
initial = True initial = True
dependencies = [ dependencies = [
('auth', '0011_update_proxy_permissions'),
] ]
operations = [ 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="col-lg-12">
<div class="alert alert-warning alert-dismissable"> <div class="alert alert-warning alert-dismissable">
<button type="button" class="close" data-dismiss="alert" aria-hidden="true">&times;</button> <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>
</div> </div>
{% else %} {% else %}
@ -35,7 +35,7 @@
<th span="col">{% trans "Staff" %}</th> <th span="col">{% trans "Staff" %}</th>
<th span="col">{% trans "Superuser" %}</th> <th span="col">{% trans "Superuser" %}</th>
<th span="col">{% trans "Can Clone" %}</th> <th span="col">{% trans "Can Clone" %}</th>
<th span="col">{% trans "" %}</th> <th span="col">{% trans "Actions" %}</th>
</tr> </tr>
</thead> </thead>
<tbody class="searchable"> <tbody class="searchable">

View file

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

View file

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

View file

@ -20,7 +20,7 @@ def appsettings(request):
:return: :return:
""" """
error_messages = [] error_messages = []
main_css = "wvc-main.min.css"
sass_dir = AppSettings.objects.get(key="SASS_DIR") sass_dir = AppSettings.objects.get(key="SASS_DIR")
bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME") bootstrap_theme = AppSettings.objects.get(key="BOOTSTRAP_THEME")
try: try:
@ -59,7 +59,7 @@ def appsettings(request):
main.write(scss_var + "\n" + scss_boot + "\n" + scss_bootswatch + "\n") 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') 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) css.write(css_compressed)
bootstrap_theme.value = theme bootstrap_theme.value = theme

View file

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

View file

@ -16,7 +16,7 @@
<div class="row"> <div class="row">
{% if computes_info %} {% if computes_info %}
{% for compute in 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 %} {% if compute.status is True %}
<div class="card border-success shadow h-100"> <div class="card border-success shadow h-100">
<div class="card-header bg-success"> <div class="card-header bg-success">
@ -37,17 +37,17 @@
</div> </div>
<div class="card-body"> <div class="card-body">
<dl class="row"> <dl class="row">
<dt class="col-4">{% trans "Status" %}</dt> <dt class="col-5">{% trans "Status" %}</dt>
{% if compute.status %} {% if compute.status %}
<dd class="col-8">{% trans "Connected" %}</dd> <dd class="col-7">{% trans "Connected" %}</dd>
{% else %} {% else %}
<dd class="col-8">{% trans "Not Connected" %}</dd> <dd class="col-7">{% trans "Not Connected" %}</dd>
{% endif %} {% endif %}
<dt class="col-4">{% trans "Details" %}</dt> <dt class="col-5">{% trans "Details" %}</dt>
{% if compute.details %} {% if compute.details %}
<dd class="col-8">{% trans compute.details %}</dd> <dd class="col-7">{% trans compute.details %}</dd>
{% else %} {% else %}
<dd class="col-8">{% trans "No details available" %}</dd> <dd class="col-7">{% trans "No details available" %}</dd>
{% endif %} {% endif %}
</dl> </dl>
@ -63,7 +63,7 @@
<form method="post" role="form" aria-label="Edit tcp host form">{% csrf_token %} <form method="post" role="form" aria-label="Edit tcp host form">{% csrf_token %}
<div class="modal-body"> <div class="modal-body">
<div class="form-group row"> <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"> <div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}"> <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\.\-_]+"> <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"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label> <label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6"> <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> </div></div>
<div class="modal-footer"> <div class="modal-footer">
@ -111,7 +111,7 @@
<div class="modal-body"> <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> <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"> <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"> <div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}"> <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\.\-_]+"> <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"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label> <label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6"> <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>
</div> </div>
@ -154,7 +154,7 @@
<form method="post" role="form" aria-label="Edit tls host form">{% csrf_token %} <form method="post" role="form" aria-label="Edit tls host form">{% csrf_token %}
<div class="modal-body"> <div class="modal-body">
<div class="form-group row"> <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"> <div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}"> <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\.\-_]+"> <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"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label> <label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6"> <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>
</div> </div>
@ -202,7 +202,7 @@
<form method="post" role="form" aria-label="Edit/delete host form">{% csrf_token %} <form method="post" role="form" aria-label="Edit/delete host form">{% csrf_token %}
<div class="modal-body"> <div class="modal-body">
<div class="form-group row"> <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"> <div class="col-sm-6">
<input type="hidden" name="host_id" value="{{ compute.id }}"> <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\.\-_]+"> <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"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Details" %}</label> <label class="col-sm-4 col-form-label">{% trans "Details" %}</label>
<div class="col-sm-6"> <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>
</div> </div>

View file

@ -21,4 +21,4 @@ def validate_hostname(value):
def validate_name(value): def validate_name(value):
have_symbol = wrong_name.match('[^a-zA-Z0-9._-]+') have_symbol = wrong_name.match('[^a-zA-Z0-9._-]+')
if have_symbol: if have_symbol:
raise ValidationError(_('The host name must not contain any special characters')) raise ValidationError(_('The hostname must not contain any special characters'))

View file

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

View file

@ -45,7 +45,7 @@ def console(request):
if console_type == 'vnc' or console_type == 'spice': if console_type == 'vnc' or console_type == 'spice':
response = render(request, console_page, locals()) response = render(request, console_page, locals())
else: 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 = render(request, 'console-vnc-lite.html', locals())
response.set_cookie('token', token) response.set_cookie('token', token)

View file

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

View file

@ -18,7 +18,7 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label> <label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6"> <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]+"> required pattern="[a-zA-Z0-9]+">
</div> </div>
</div> </div>

View file

@ -1,13 +1,15 @@
{% extends "base.html" %} {% extends "base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block title %}{% trans "Create new instanc" %} - {% trans "Select Type" %}{% endblock %} {% block title %}{% trans "Create new instance" %} - {% trans "Select Type" %}{% endblock %}
{% block content %} {% block content %}
<!-- Page Heading --> <!-- Page Heading -->
<div class="row"> <div class="row">
<div class="col-lg-12"> <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>
</div> </div>
<!-- /.row --> <!-- /.row -->

View file

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

View file

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

View file

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

View file

@ -14,7 +14,7 @@
{% endif %} {% endif %}
{% if all_host_vms or all_user_vms %} {% if all_host_vms or all_user_vms %}
<div class="float-right search"> <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> </div>
{% endif %} {% endif %}
<h2 class="page-header">{% trans "Instances" %}</h2> <h2 class="page-header">{% trans "Instances" %}</h2>

View file

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

View file

@ -16,7 +16,7 @@
{% endif %} {% endif %}
{% if all_host_vms or all_user_vms %} {% if all_host_vms or all_user_vms %}
<div class="float-right search"> <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> </div>
{% endif %} {% endif %}
<h2 class="page-header">{{ compute.name }}</h2> <h2 class="page-header">{{ compute.name }}</h2>

View file

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

View file

@ -22,36 +22,36 @@ class AddInterface(forms.Form):
ipv4_addr = self.cleaned_data['ipv4_addr'] ipv4_addr = self.cleaned_data['ipv4_addr']
have_symbol = re.match('^[0-9./]+$', ipv4_addr) have_symbol = re.match('^[0-9./]+$', ipv4_addr)
if not have_symbol: 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: 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 return ipv4_addr
def clean_ipv4_gw(self): def clean_ipv4_gw(self):
ipv4_gw = self.cleaned_data['ipv4_gw'] ipv4_gw = self.cleaned_data['ipv4_gw']
have_symbol = re.match('^[0-9.]+$', ipv4_gw) have_symbol = re.match('^[0-9.]+$', ipv4_gw)
if not have_symbol: 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: 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 return ipv4_gw
def clean_ipv6_addr(self): def clean_ipv6_addr(self):
ipv6_addr = self.cleaned_data['ipv6_addr'] ipv6_addr = self.cleaned_data['ipv6_addr']
have_symbol = re.match('^[0-9a-f./:]+$', ipv6_addr) have_symbol = re.match('^[0-9a-f./:]+$', ipv6_addr)
if not have_symbol: 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: 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 return ipv6_addr
def clean_ipv6_gw(self): def clean_ipv6_gw(self):
ipv6_gw = self.cleaned_data['ipv6_gw'] ipv6_gw = self.cleaned_data['ipv6_gw']
have_symbol = re.match('^[0-9.]+$', ipv6_gw) have_symbol = re.match('^[0-9.]+$', ipv6_gw)
if not have_symbol: 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: 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 return ipv6_gw
def clean_name(self): 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.db.models import Model, CharField, DateTimeField
from django.utils.translation import ugettext_lazy as _
class Logs(Model): class Logs(Model):
user = CharField(max_length=50) user = CharField(_('user'), max_length=50)
instance = CharField(max_length=50) instance = CharField(_('instance'), max_length=50)
message = CharField(max_length=255) message = CharField(_('message'), max_length=255)
date = DateTimeField(auto_now=True) date = DateTimeField(_('date'), auto_now=True)
def __unicode__(self): def __unicode__(self):
return self.instance return self.instance

View file

@ -30,18 +30,18 @@ class AddNetPool(forms.Form):
subnet = self.cleaned_data['subnet'] subnet = self.cleaned_data['subnet']
have_symbol = re.match('^[0-9./]+$', subnet if subnet else ".") have_symbol = re.match('^[0-9./]+$', subnet if subnet else ".")
if not have_symbol: 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: 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 return subnet
def clean_subnet6(self): def clean_subnet6(self):
subnet = self.cleaned_data['subnet6'] subnet = self.cleaned_data['subnet6']
have_symbol = re.match('^[0-9a-fA-F:/]+$', subnet if subnet else ":") have_symbol = re.match('^[0-9a-fA-F:/]+$', subnet if subnet else ":")
if not have_symbol: 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: 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 return subnet
def clean_bridge_name(self): def clean_bridge_name(self):

View file

@ -26,21 +26,21 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Average" %}:</label> <label class="col-sm-4 col-form-label">{% trans "Average" %}:</label>
<div class="col-sm-6"> <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]+"/> required pattern="[0-9]+"/>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Peak" %}:</label> <label class="col-sm-4 col-form-label">{% trans "Peak" %}:</label>
<div class="col-sm-6"> <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]+"/> pattern="[0-9]+"/>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Burst" %}:</label> <label class="col-sm-4 col-form-label">{% trans "Burst" %}:</label>
<div class="col-sm-6"> <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]+"/> pattern="[0-9]+"/>
</div> </div>
</div> </div>

View file

@ -17,7 +17,7 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-4 col-form-label">{% trans "Name" %}</label> <label class="col-sm-4 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6"> <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> </div>
<div class="form-group row"> <div class="form-group row">
@ -44,7 +44,7 @@
</div> </div>
</div> </div>
<div class="form-group row bridge_name_form_group_dhcp"> <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"> <div class="col-sm-6">
<input type="checkbox" name="fixed" value="true"> <input type="checkbox" name="fixed" value="true">
</div> </div>

View file

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

View file

@ -8,7 +8,7 @@
<div class="col-lg-12"> <div class="col-lg-12">
{% include 'create_nwfilter_block.html' %} {% include 'create_nwfilter_block.html' %}
<div class="float-right search"> <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> </div>
<h2 class="page-header">{{ compute.name }} - {% trans "NWFilters" %}</h2> <h2 class="page-header">{{ compute.name }} - {% trans "NWFilters" %}</h2>
</div> </div>

View file

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

View file

@ -45,9 +45,9 @@ class AddStgPool(forms.Form):
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 or path has been entered'))
if not have_symbol: 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 return source

View file

@ -41,7 +41,7 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label> <label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6"> <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> </div>
<div class="form-group row"> <div class="form-group row">
@ -70,7 +70,7 @@
<div class="form-group row"> <div class="form-group row">
<label class="col-sm-3 col-form-label">{% trans "Name" %}</label> <label class="col-sm-3 col-form-label">{% trans "Name" %}</label>
<div class="col-sm-6"> <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> </div>
<div class="form-group row"> <div class="form-group row">

View file

@ -86,7 +86,7 @@
<div class="row"> <div class="row">
<h5 class="page-header mr-auto">{% trans "Volumes" %}</h5> <h5 class="page-header mr-auto">{% trans "Volumes" %}</h5>
<div class="col-3 "> <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>
</div> </div>

View file

@ -162,7 +162,7 @@ def storage(request, compute_id, pool):
try: try:
vol = conn.get_volume(volname) vol = conn.get_volume(volname)
vol.delete(0) 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()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) error_messages.append(lib_err)
@ -172,7 +172,7 @@ def storage(request, compute_id, pool):
error_messages.append(error_msg) error_messages.append(error_msg)
else: else:
handle_uploaded_file(path, request.FILES['file']) 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()) return HttpResponseRedirect(request.get_full_path())
if 'cln_volume' in request.POST: if 'cln_volume' in request.POST:
form = CloneImage(request.POST) form = CloneImage(request.POST)
@ -192,7 +192,7 @@ def storage(request, compute_id, pool):
format = None format = None
try: try:
name = conn.clone_volume(data['image'], data['name'], format, meta_prealloc) 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()) return HttpResponseRedirect(request.get_full_path())
except libvirtError as lib_err: except libvirtError as lib_err:
error_messages.append(lib_err) error_messages.append(lib_err)

View file

@ -38,6 +38,10 @@
<i class="fa fa-fw fa-user"></i> {{ request.user.username }} <i class="fa fa-fw fa-user"></i> {{ request.user.username }}
</a> </a>
<div class="dropdown-menu" aria-labelledby="navbarUserDropdown"> <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> <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> <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> <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 = [ MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware', 'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware', 'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware',
@ -49,7 +50,6 @@ MIDDLEWARE = [
'django.contrib.auth.middleware.RemoteUserMiddleware', 'django.contrib.auth.middleware.RemoteUserMiddleware',
'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.locale.LocaleMiddleware',
] ]
ROOT_URLCONF = 'webvirtcloud.urls' ROOT_URLCONF = 'webvirtcloud.urls'
@ -111,6 +111,10 @@ STATICFILES_DIRS = [
os.path.join(BASE_DIR, "static"), os.path.join(BASE_DIR, "static"),
] ]
LOCALE_PATHS = [
'locale/',
]
LOGGING = { LOGGING = {
"version": 1, "version": 1,
"disable_existing_loggers": False, "disable_existing_loggers": False,