1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-03-22 02:24:56 +00:00
This commit is contained in:
aiminick 2021-04-12 02:17:48 +08:00
parent cd798eb9b7
commit 156cfb40dd
22 changed files with 1069 additions and 319 deletions

View file

@ -6,7 +6,10 @@ EXPOSE 6080
# Use baseimage-docker's init system. # Use baseimage-docker's init system.
CMD ["/sbin/my_init"] CMD ["/sbin/my_init"]
RUN rm -rf /etc/apt/sources.list
ADD sources.list /etc/apt/sources.list
RUN apt clean all ; apt update ; apt upgrade -y
RUN echo 'APT::Get::Clean=always;' >> /etc/apt/apt.conf.d/99AutomaticClean RUN echo 'APT::Get::Clean=always;' >> /etc/apt/apt.conf.d/99AutomaticClean
RUN apt-get update -qqy \ RUN apt-get update -qqy \
@ -20,7 +23,7 @@ RUN apt-get update -qqy \
zlib1g-dev \ zlib1g-dev \
nginx \ nginx \
pkg-config \ pkg-config \
gcc \ gcc g++ sudo \
libsasl2-modules \ libsasl2-modules \
&& rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*
@ -31,9 +34,9 @@ RUN chown -R www-data:www-data /srv/webvirtcloud
WORKDIR /srv/webvirtcloud WORKDIR /srv/webvirtcloud
RUN python3 -m venv venv && \ RUN python3 -m venv venv && \
. venv/bin/activate && \ . venv/bin/activate && \
pip3 install -U pip && \ pip3 install -i https://pypi.doubanio.com/simple -U pip && \
pip3 install wheel && \ pip3 install -i https://pypi.doubanio.com/simple wheel && \
pip3 install -r conf/requirements.txt && \ pip3 install -i https://pypi.doubanio.com/simple -r conf/requirements.txt && \
chown -R www-data:www-data /srv/webvirtcloud chown -R www-data:www-data /srv/webvirtcloud
RUN . venv/bin/activate && \ RUN . venv/bin/activate && \
@ -60,4 +63,11 @@ COPY conf/runit/webvirtcloud.sh /etc/service/webvirtcloud/run
# Define mountable directories. # Define mountable directories.
#VOLUME [] #VOLUME []
RUN mkdir -p ~www-data/.ssh ; mkdir -p /var/www/.ssh ; chown www-data -R ~www-data
RUN echo 'Host *' >> ~www-data/.ssh/config ; echo 'StrictHostKeyChecking no' >> ~www-data/.ssh/config ; chown www-data -R ~www-data/.ssh/config
RUN sudo -u www-data ssh-keygen -t rsa -P "" -f ~www-data/.ssh/id_rsa
RUN rm -rf /root/.ssh ; ln -sf /var/www/.ssh /root/.ssh ; chgrp www-data /root ; chmod 770 /root
RUN echo 'sudo -u www-data ssh-copy-id $1' > /usr/bin/sudo-ssh-copy-id ; chmod +x /usr/bin/sudo-ssh-copy-id
RUN cp /usr/bin/sudo-ssh-copy-id / ; cp /usr/bin/sudo-ssh-copy-id /root/
WORKDIR /srv/webvirtcloud WORKDIR /srv/webvirtcloud

View file

@ -3,9 +3,9 @@
{% load static %} {% load static %}
{% load bootstrap4 %} {% load bootstrap4 %}
{% block title %}WebVirtCloud{% endblock title %} {% block title %}{% trans "WebVirtCloud" %}{% endblock title %}
{% block page_heading %}WebVirtCloud{% endblock page_heading %} {% block page_heading %}{% trans "WebVirtCloud" %}{% endblock page_heading %}
{% block content %} {% block content %}
<div class="row"> <div class="row">

View file

@ -10,7 +10,8 @@
{% block content %} {% block content %}
<div class="page-header"> <div class="page-header">
<a class="" href="/"><h1>WebVirtCloud</h1></a> <div style="text-align:center;color:black"><h2>{% trans "WebVirtCloud" %}</h2></div>
<!-- <a class="" href="/"><h1>WebVirtCloud</h1></a> -->
</div> </div>
<div class="col-12" role="main"> <div class="col-12" role="main">
{% if form.errors %} {% if form.errors %}

View file

@ -6,7 +6,8 @@
{% block content %} {% block content %}
<div> <div>
<div class="page-header"> <div class="page-header">
<a href="/"><h1>WebVirtCloud</h1></a> <div style="text-align:center;color:black"><h2>{% trans "WebVirtCloud" %}</h2></div>
<!-- <a href="/"><h1>WebVirtCloud</h1></a> -->
</div> </div>
<div class="col-12" role="main"> <div class="col-12" role="main">
<div class="logout"> <div class="logout">

View file

@ -29,7 +29,7 @@
</disk> </disk>
<disk type="file" device="cdrom"> <disk type="file" device="cdrom">
<driver name="qemu" type="raw" /> <driver name="qemu" type="raw" />
<target dev="sda" bus="sata" /> <target dev="sda" bus="scsi" />
<readonly /> <readonly />
<address type="drive" controller="0" bus="0" target="0" unit="0" /> <address type="drive" controller="0" bus="0" target="0" unit="0" />
</disk> </disk>

View file

@ -1,33 +1,9 @@
<!--
Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
This file is part of spice-html5.
spice-html5 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
spice-html5 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
--------------------------------------------------
Spice Javascript client template.
Refer to main.js for more detailed information
--------------------------------------------------
-->
{% extends "console-base.html" %} {% extends "console-base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<title>WebVirtCloud - Spice Client - Full</title> <title>{% trans "WebVirtCloud" %} - Spice Client - Full</title>
<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" /> <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
<!-- ES2015/ES6 modules polyfill --> <!-- ES2015/ES6 modules polyfill -->

View file

@ -1,33 +1,9 @@
<!--
Copyright (C) 2012 by Jeremy P. White <jwhite@codeweavers.com>
This file is part of spice-html5.
spice-html5 is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
spice-html5 is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with spice-html5. If not, see <http://www.gnu.org/licenses/>.
--------------------------------------------------
Spice Javascript client template.
Refer to main.js for more detailed information
--------------------------------------------------
-->
{% extends "console-base.html" %} {% extends "console-base.html" %}
{% load i18n %} {% load i18n %}
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<title>WebVirtCloud - Spice - Lite</title> <title>{% trans "WebVirtCloud" %} - Spice - Lite</title>
<link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" /> <link rel="stylesheet" type="text/css" href="{% static "js/spice-html5/spice.css" %}" />
<!-- ES2015/ES6 modules polyfill --> <!-- ES2015/ES6 modules polyfill -->

View file

@ -3,17 +3,8 @@
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<!--
noVNC example: simple example using default UI <title>{% trans "WebVirtCloud" %} - noVNC</title>
Copyright (C) 2018 The noVNC Authors
noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
Connect parameters are provided in query string:
http://example.com/?host=HOST&port=PORT&encrypt=1
or the fragment:
http://example.com/#host=HOST&port=PORT&encrypt=1
-->
<title>WebVirtCloud - noVNC</title>
<meta charset="utf-8" /> <meta charset="utf-8" />

View file

@ -3,16 +3,8 @@
{% load staticfiles %} {% load staticfiles %}
{% block head %} {% block head %}
<!--
noVNC example: lightweight example using minimal UI and features <title>{% trans "WebVirtCloud" %} - noVNC - Lite</title>
This is a self-contained file which doesn't import WebUtil or external CSS.
Copyright (C) 2019 The noVNC Authors
noVNC is licensed under the MPL 2.0 (see LICENSE.txt)
This file is licensed under the 2-Clause BSD license (see LICENSE.txt).
Connect parameters are provided in query string:
http://example.com/?host=HOST&port=PORT&scale=true
-->
<title>WebVirtCloud - noVNC - Lite</title>
<meta charset="utf-8"> <meta charset="utf-8">

6
genpass.sh Executable file
View file

@ -0,0 +1,6 @@
#!/bin/bash
rm -rf webvirtcloud/settings.py
cp -arpf webvirtcloud/settings.py.template webvirtcloud/settings.py
python conf/runit/secret_generator.py
sed -r "s/SECRET_KEY = \"\"/SECRET_KEY = \"`python3 conf/runit/secret_generator.py`\"/" -i webvirtcloud/settings.py; cat webvirtcloud/settings.py|grep SECRET_KEY

59
gstfsd Normal file
View file

@ -0,0 +1,59 @@
#!/usr/bin/env python
#
# gstfsd - WebVirtCloud daemon for managing VM's filesystem
#
import socketserver
import json
import guestfs
import re
PORT = 16510
ADDRESS = "0.0.0.0"
class MyTCPServer(socketserver.ThreadingTCPServer):
allow_reuse_address = True
class MyTCPServerHandler(socketserver.BaseRequestHandler):
def handle(self):
# recive data
d = self.request.recv(1024).strip()
data = json.loads(d)
# GuestFS
gfs = guestfs.GuestFS(python_return_dict=True)
try:
gfs.add_domain(data['vname'])
gfs.launch()
parts = gfs.list_partitions()
for part in parts:
try:
gfs.mount(part, '/')
if gfs.is_file('/etc/shadow'):
if data['action'] == 'password':
file_shadow = gfs.cat('/etc/shadow')
new_root_hash = "root:" + data['passwd'] + ":"
file_shadow_new = re.sub('^root:.*?:', new_root_hash, file_shadow)
gfs.write('/etc/shadow', file_shadow_new)
gfs.chmod(640, '/etc/shadow')
self.request.sendall(json.dumps({'return': 'success'}))
if data['action'] == 'publickey':
if not gfs.is_dir('/root/.ssh'):
gfs.mkdir('/root/.ssh')
gfs.chmod(700, "/root/.ssh")
gfs.write('/root/.ssh/authorized_keys', data['key'])
gfs.chmod(600, '/root/.ssh/authorized_keys')
self.request.sendall(json.dumps({'return': 'success'}))
gfs.umount(part)
except RuntimeError:
pass
gfs.shutdown()
gfs.close()
except Exception as err:
self.request.sendall(bytes(json.dumps({'return': 'error', 'message': str(err)}).encode()))
server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
server.serve_forever()

7
gstfsd.conf Normal file
View file

@ -0,0 +1,7 @@
[program:gstfsd]
command=/srv/webvirtcloud/venv/bin/python3 /usr/local/bin/gstfsd
directory=/usr/local/bin
user=root
autostart=true
autorestart=true
redirect_stderr=true

View file

@ -34,15 +34,15 @@ class ConsoleForm(forms.Form):
class NewVMForm(forms.Form): class NewVMForm(forms.Form):
name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=64) name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=200)
firmware = forms.CharField(max_length=50, required=False) firmware = forms.CharField(max_length=200, required=False)
vcpu = forms.IntegerField(error_messages={'required': _('No VCPU has been entered')}) vcpu = forms.IntegerField(error_messages={'required': _('No VCPU has been entered')})
vcpu_mode = forms.CharField(max_length=20, required=False) vcpu_mode = forms.CharField(max_length=5136, required=False)
disk = forms.IntegerField(required=False) disk = forms.IntegerField(required=False)
memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')}) memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')})
networks = forms.CharField(error_messages={'required': _('No Network pool has been choosen')}) networks = forms.CharField(error_messages={'required': _('No Network pool has been choosen')})
nwfilter = forms.CharField(required=False) nwfilter = forms.CharField(required=False)
storage = forms.CharField(max_length=20, required=False) storage = forms.CharField(max_length=200, required=False)
template = forms.CharField(required=False) template = forms.CharField(required=False)
images = forms.CharField(required=False) images = forms.CharField(required=False)
cache_mode = forms.CharField(error_messages={'required': _('Please select HDD cache mode')}) cache_mode = forms.CharField(error_messages={'required': _('Please select HDD cache mode')})

View file

@ -390,7 +390,8 @@ class InstancesTestCase(TestCase):
response = self.client.post( response = self.client.post(
reverse('instances:add_cdrom', args=[self.instance.id]), reverse('instances:add_cdrom', args=[self.instance.id]),
{ {
'bus': 'sata', #'bus': 'sata',
'bus': 'scsi',
}, },
HTTP_REFERER=reverse('index'), HTTP_REFERER=reverse('index'),
) )

View file

@ -691,7 +691,8 @@ def add_cdrom(request, pk):
instance = get_instance(request.user, pk) instance = get_instance(request.user, pk)
allow_admin_or_not_template = request.user.is_superuser or request.user.is_staff or not instance.is_template allow_admin_or_not_template = request.user.is_superuser or request.user.is_staff or not instance.is_template
if allow_admin_or_not_template: if allow_admin_or_not_template:
bus = request.POST.get("bus", "ide" if instance.machine == "pc" else "sata") #bus = request.POST.get("bus", "ide" if instance.machine == "pc" else "sata")
bus = request.POST.get("bus", "ide" if instance.machine == "pc" else "scsi")
target = utils.get_new_disk_dev(instance.media, instance.disks, bus) target = utils.get_new_disk_dev(instance.media, instance.disks, bus)
instance.proxy.attach_disk(target, "", disk_device="cdrom", cache_mode="none", target_bus=bus, readonly=True) instance.proxy.attach_disk(target, "", disk_device="cdrom", cache_mode="none", target_bus=bus, readonly=True)
msg = _("Add CD-ROM: %(target)s") % {"target": target} msg = _("Add CD-ROM: %(target)s") % {"target": target}

821
libvirt-bootstrap.sh Normal file
View file

@ -0,0 +1,821 @@
#!/bin/sh -
#===============================================================================
# vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=81
#===============================================================================
#
# FILE: libvirt-bootstrap.sh
#
# DESCRIPTION: Bootstrap webvirtcloud installation for various distributions
#
# BUGS: https://github.com/retspen/webvirtcloud/issues
#
# COPYRIGHT: (c) 2015 by the WebVirtCloud Team
#
# LICENSE: Apache 2.0
# ORGANIZATION: WebVirtCloud (webvirtcloud.net)
# CREATED: 11/11/2013 11:00:00 EET
#===============================================================================
#--- FUNCTION ----------------------------------------------------------------
# NAME: echoerr
# DESCRIPTION: Echo errors to stderr.
#-------------------------------------------------------------------------------
echoerror() {
printf "${RC} * ERROR${EC}: %s\n" "$@" 1>&2;
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: echoinfo
# DESCRIPTION: Echo information to stdout.
#-------------------------------------------------------------------------------
echoinfo() {
printf "${GC} * INFO${EC}: %s\n" "$@";
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: echowarn
# DESCRIPTION: Echo warning informations to stdout.
#-------------------------------------------------------------------------------
echowarn() {
printf "${YC} * WARN${EC}: %s\n" "$@";
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: echodebug
# DESCRIPTION: Echo debug information to stdout.
#-------------------------------------------------------------------------------
echodebug() {
if [ "$_ECHO_DEBUG" -eq "$BS_TRUE" ]; then
printf "${BC} * DEBUG${EC}: %s\n" "$@";
fi
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __test_distro_arch
# DESCRIPTION: Echo errors to stderr.
#-------------------------------------------------------------------------------
__test_distro_arch() {
ARCH=$(uname -m | sed 's/x86_//;s/i[3-6]86/32/')
if [ "$ARCH" = 32 ]; then
echoerror "32-bit Arch kernel does not support"
exit 1
fi
}
__test_distro_arch
#--- FUNCTION ----------------------------------------------------------------
# NAME: __strip_duplicates
# DESCRIPTION: Strip duplicate strings
#-------------------------------------------------------------------------------
__strip_duplicates() {
echo "$@" | tr -s '[:space:]' '\n' | awk '!x[$0]++'
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __function_defined
# DESCRIPTION: Checks if a function is defined within this scripts scope
# PARAMETERS: function name
# RETURNS: 0 or 1 as in defined or not defined
#-------------------------------------------------------------------------------
__function_defined() {
FUNC_NAME=$1
if [ "$(command -v "$FUNC_NAME")x" != "x" ]; then
echoinfo "Found function $FUNC_NAME"
return 0
fi
echodebug "$FUNC_NAME not found...."
return 1
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __parse_version_string
# DESCRIPTION: Parse version strings ignoring the revision.
# MAJOR.MINOR.REVISION becomes MAJOR.MINOR
#-------------------------------------------------------------------------------
__parse_version_string() {
VERSION_STRING="$1"
PARSED_VERSION=$(
echo "$VERSION_STRING" |
sed -e 's/^/#/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\)\(\.[0-9][0-9]*\).*$/\1/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\.[0-9][0-9]*\).*$/\1/' \
-e 's/^#[^0-9]*\([0-9][0-9]*\).*$/\1/' \
-e 's/^#.*$//'
)
echo "$PARSED_VERSION"
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __sort_release_files
# DESCRIPTION: Custom sort function. Alphabetical or numerical sort is not
# enough.
#-------------------------------------------------------------------------------
__sort_release_files() {
KNOWN_RELEASE_FILES=$(echo "(arch|centos|debian|ubuntu|fedora|redhat|suse|\
mandrake|mandriva|gentoo|slackware|turbolinux|unitedlinux|lsb|system|\
os)(-|_)(release|version)" | sed -r 's:[[:space:]]::g')
primary_release_files=""
secondary_release_files=""
# Sort know VS un-known files first
for release_file in $(echo "$@" | sed -r 's:[[:space:]]:\n:g' | sort --unique --ignore-case); do
match=$(echo "$release_file" | grep -E -i "${KNOWN_RELEASE_FILES}")
if [ "x${match}" != "x" ]; then
primary_release_files="${primary_release_files} ${release_file}"
else
secondary_release_files="${secondary_release_files} ${release_file}"
fi
done
# Now let's sort by know files importance, max important goes last in the max_prio list
max_prio="redhat-release centos-release"
for entry in $max_prio; do
if [ "x$(echo "${primary_release_files}" | grep "$entry")" != "x" ]; then
primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\(.*\)\($entry\)\(.*\):\2 \1 \3:g")
fi
done
# Now, least important goes last in the min_prio list
min_prio="lsb-release"
for entry in $min_prio; do
if [ "x$(echo "${primary_release_files}" | grep "$entry")" != "x" ]; then
primary_release_files=$(echo "${primary_release_files}" | sed -e "s:\(.*\)\($entry\)\(.*\):\1 \3 \2:g")
fi
done
# Echo the results collapsing multiple white-space into a single white-space
echo "${primary_release_files} ${secondary_release_files}" | sed -r 's:[[:space:]]:\n:g'
}
#--- FUNCTION ----------------------------------------------------------------
# NAME: __gather_linux_system_info
# DESCRIPTION: Discover Linux system information
#-------------------------------------------------------------------------------
__gather_linux_system_info() {
DISTRO_NAME=""
DISTRO_VERSION=""
# Let's test if the lsb_release binary is available
rv=$(lsb_release >/dev/null 2>&1)
if [ $? -eq 0 ]; then
DISTRO_NAME=$(lsb_release -si)
if [ "x$(echo "$DISTRO_NAME" | grep RedHat)" != "x" ]; then
# Let's convert CamelCase to Camel Case
DISTRO_NAME=$(__camelcase_split "$DISTRO_NAME")
fi
if [ "${DISTRO_NAME}" = "openSUSE project" ]; then
# lsb_release -si returns "openSUSE project" on openSUSE 12.3
DISTRO_NAME="opensuse"
fi
if [ "${DISTRO_NAME}" = "SUSE LINUX" ]; then
# lsb_release -si returns "SUSE LINUX" on SLES 11 SP3
DISTRO_NAME="suse"
fi
rv=$(lsb_release -sr)
[ "${rv}x" != "x" ] && DISTRO_VERSION=$(__parse_version_string "$rv")
elif [ -f /etc/lsb-release ]; then
# We don't have the lsb_release binary, though, we do have the file it parses
DISTRO_NAME=$(grep DISTRIB_ID /etc/lsb-release | sed -e 's/.*=//')
rv=$(grep DISTRIB_RELEASE /etc/lsb-release | sed -e 's/.*=//')
[ "${rv}x" != "x" ] && DISTRO_VERSION=$(__parse_version_string "$rv")
fi
if [ "x$DISTRO_NAME" != "x" ] && [ "x$DISTRO_VERSION" != "x" ]; then
# We already have the distribution name and version
return
fi
for rsource in $(__sort_release_files "$(
cd /etc && find ./*[_-]release ./*[_-]version -printf "%f\n" 2>/dev/null | env -i sort | \
sed -e '/^redhat-release$/d' -e '/^lsb-release$/d'; \
echo redhat-release lsb-release
)"); do
[ -L "/etc/${rsource}" ] && continue # Don't follow symlinks
[ ! -f "/etc/${rsource}" ] && continue # Does not exist
n=$(echo "${rsource}" | sed -e 's/[_-]release$//' -e 's/[_-]version$//')
rv=$( (grep VERSION /etc/"${rsource}"; cat /etc/"${rsource}") | grep '[0-9]' | sed -e 'q' )
[ "${rv}x" = "x" ] && continue # There's no version information. Continue to next rsource
v=$(__parse_version_string "$rv")
case $(echo "${n}" | tr '[:upper:]' '[:lower:]') in
redhat )
if [ ".$(grep -E 'CentOS' /etc/"${rsource}")" != . ]; then
n="CentOS"
elif [ ".$(grep -E 'Red Hat Enterprise Linux' /etc/"${rsource}")" != . ]; then
n="<R>ed <H>at <E>nterprise <L>inux"
else
n="<R>ed <H>at <L>inux"
fi
;;
arch ) n="Arch Linux" ;;
centos ) n="CentOS" ;;
debian ) n="Debian" ;;
ubuntu ) n="Ubuntu" ;;
fedora ) n="Fedora" ;;
suse ) n="SUSE" ;;
system )
while read -r line; do
[ "${n}x" != "systemx" ] && break
case "$line" in
*Amazon*Linux*AMI*)
n="Amazon Linux AMI"
break
esac
done < /etc/"${rsource}"
;;
os )
nn=$(grep '^ID=' /etc/os-release | sed -e 's/^ID=\(.*\)$/\1/g')
rv=$(grep '^VERSION_ID=' /etc/os-release | sed -e 's/^VERSION_ID=\(.*\)$/\1/g')
[ "${rv}x" != "x" ] && v=$(__parse_version_string "$rv") || v=""
case $(echo "${nn}" | tr '[:upper:]' '[:lower:]') in
arch )
n="Arch Linux"
v="" # Arch Linux does not provide a version.
;;
debian )
n="Debian"
if [ "${v}x" = "x" ]; then
if [ "$(cat /etc/debian_version)" = "wheezy/sid" ]; then
# I've found an EC2 wheezy image which did not tell its version
v=$(__parse_version_string "7.0")
fi
else
echowarn "Unable to parse the Debian Version"
fi
;;
* )
n=${nn}
;;
esac
;;
* ) n="${n}" ;
esac
DISTRO_NAME=$n
DISTRO_VERSION=$v
break
done
}
__gather_linux_system_info
# Simplify distro name naming on functions
DISTRO_NAME_L=$(echo "$DISTRO_NAME" | tr '[:upper:]' '[:lower:]' | sed 's/[^a-zA-Z0-9_ ]//g' | sed -re 's/([[:space:]])+/_/g')
DISTRO_MAJOR_VERSION="$(echo "$DISTRO_VERSION" | sed 's/^\([0-9]*\).*/\1/g')"
DISTRO_MINOR_VERSION="$(echo "$DISTRO_VERSION" | sed 's/^\([0-9]*\).\([0-9]*\).*/\2/g')"
PREFIXED_DISTRO_MAJOR_VERSION="_${DISTRO_MAJOR_VERSION}"
if [ "${PREFIXED_DISTRO_MAJOR_VERSION}" = "_" ]; then
PREFIXED_DISTRO_MAJOR_VERSION=""
fi
PREFIXED_DISTRO_MINOR_VERSION="_${DISTRO_MINOR_VERSION}"
if [ "${PREFIXED_DISTRO_MINOR_VERSION}" = "_" ]; then
PREFIXED_DISTRO_MINOR_VERSION=""
fi
#--- FUNCTION ----------------------------------------------------------------
# NAME: __check_end_of_life_versions
# DESCRIPTION: Check for end of life distribution versions
#-------------------------------------------------------------------------------
__check_end_of_life_versions() {
case "${DISTRO_NAME_L}" in
debian)
# Debian versions bellow 6 are not supported
if [ "$DISTRO_MAJOR_VERSION" -lt 6 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://wiki.debian.org/DebianReleases"
exit 1
fi
;;
ubuntu)
# Ubuntu versions not supported
#
# < 10
# = 10.10
# = 11.04
# = 11.10
if { [ "$DISTRO_MAJOR_VERSION" -eq 10 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \
{ [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$DISTRO_MINOR_VERSION" -eq 04 ]; } || \
{ [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$DISTRO_MINOR_VERSION" -eq 10 ]; } || \
[ "$DISTRO_MAJOR_VERSION" -lt 10 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://wiki.ubuntu.com/Releases"
exit 1
fi
;;
opensuse)
# openSUSE versions not supported
#
# <= 12.1
if { [ "$DISTRO_MAJOR_VERSION" -eq 12 ] && [ "$DISTRO_MINOR_VERSION" -eq 1 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 12 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " http://en.opensuse.org/Lifetime"
exit 1
fi
;;
suse)
# SuSE versions not supported
#
# < 11 SP2
SUSE_PATCHLEVEL=$(awk '/PATCHLEVEL/ {print $3}' /etc/SuSE-release )
if [ "x${SUSE_PATCHLEVEL}" = "x" ]; then
SUSE_PATCHLEVEL="00"
fi
if { [ "$DISTRO_MAJOR_VERSION" -eq 11 ] && [ "$SUSE_PATCHLEVEL" -lt 02 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 11 ]; then
echoerror "Versions lower than SuSE 11 SP2 are not supported."
echoerror "Please consider upgrading to the next stable"
exit 1
fi
;;
fedora)
# Fedora lower than 18 are no longer supported
if [ "$DISTRO_MAJOR_VERSION" -lt 18 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://fedoraproject.org/wiki/Releases"
exit 1
fi
;;
centos)
# CentOS versions lower than 5 are no longer supported
if { [ "$DISTRO_MAJOR_VERSION" -eq 6 ] && [ "$DISTRO_MINOR_VERSION" -lt 3 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 5 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " http://wiki.centos.org/Download"
exit 1
fi
;;
red_hat*linux)
# Red Hat (Enterprise) Linux versions lower than 5 are no longer supported
if { [ "$DISTRO_MAJOR_VERSION" -eq 6 ] && [ "$DISTRO_MINOR_VERSION" -lt 3 ]; } || [ "$DISTRO_MAJOR_VERSION" -lt 5 ]; then
echoerror "End of life distributions are not supported."
echoerror "Please consider upgrading to the next stable. See:"
echoerror " https://access.redhat.com/support/policy/updates/errata/"
exit 1
fi
;;
*)
;;
esac
}
# Fail soon for end of life versions
__check_end_of_life_versions
##############################################################################
#
# CentOS Install Functions
#
install_centos() {
if [ "$DISTRO_MAJOR_VERSION" -ge 6 ]; then
yum -y install qemu-kvm libvirt bridge-utils python-libguestfs libguestfs-tools supervisor cyrus-sasl-md5 epel-release || return 1
fi
return 0
}
install_centos_post() {
if [ -f /etc/sysconfig/libvirtd ]; then
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
else
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/sasl2/libvirt.conf ]; then
sed -i 's/: gssapi/: digest-md5/g' /etc/sasl2/libvirt.conf
sed -i 's/#sasldb_path/sasldb_path/g' /etc/sasl2/libvirt.conf
else
echoerror "/etc/sasl2/libvirt.conf not found. Exiting..."
exit 1
fi
if [ "$DISTRO_MAJOR_VERSION" -lt 7 ]; then
if [ -f /etc/supervisord.conf ]; then
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd
chmod +x /usr/local/bin/gstfsd
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf >> /etc/supervisor.conf
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
else
if [ -f /etc/supervisord.conf ]; then
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd
chmod +x /usr/local/bin/gstfsd
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf > /etc/supervisord.d/gstfsd.ini
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
fi
return 0
}
daemons_running_centos() {
if [ -f /etc/init.d/libvirtd ]; then
service libvirtd stop > /dev/null 2>&1
service libvirtd start
fi
if [ -f /etc/init.d/libvirt-guests ]; then
service libvirt-guests stop > /dev/null 2>&1
service libvirt-guests start
fi
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
systemctl stop libvirtd.service > /dev/null 2>&1
systemctl start libvirtd.service
fi
if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then
systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service
fi
if [ -f /etc/init.d/supervisord ]; then
service supervisord stop > /dev/null 2>&1
service supervisord start
fi
if [ -f /usr/lib/systemd/system/supervisord.service ]; then
systemctl stop supervisord.service > /dev/null 2>&1
systemctl start supervisord.service
fi
return 0
}
#
# Ended CentOS Install Functions
#
##############################################################################
##############################################################################
#
# Fedora Install Functions
#
install_fedora() {
yum -y install kvm libvirt bridge-utils python3-libguestfs supervisor || return 1
return 0
}
install_fedora_post() {
if [ -f /etc/sysconfig/libvirtd ]; then
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
else
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/supervisord.conf ]; then
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd
chmod +x /usr/local/bin/gstfsd
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf > /etc/supervisord.d/gstfsd.ini
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
return 0
}
daemons_running_fedora() {
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
systemctl stop libvirtd.service > /dev/null 2>&1
systemctl start libvirtd.service
fi
if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then
systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service
fi
if [ -f /usr/lib/systemd/system/supervisord.service ]; then
systemctl stop supervisord.service > /dev/null 2>&1
systemctl start supervisord.service
fi
return 0
}
#
# Ended Fedora Install Functions
#
##############################################################################
##############################################################################
#
# Opensuse Install Functions
#
install_opensuse() {
zypper -n install -l kvm libvirt bridge-utils python3-libguestfs supervisor || return 1
return 0
}
install_opensuse_post() {
if [ -f /etc/sysconfig/libvirtd ]; then
sed -i 's/#LIBVIRTD_ARGS/LIBVIRTD_ARGS/g' /etc/sysconfig/libvirtd
else
echoerror "/etc/sysconfig/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/supervisord.conf ]; then
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd > /usr/local/bin/gstfsd
chmod +x /usr/local/bin/gstfsd
curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf > /etc/supervisor.d/gstfsd.ini
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
return 0
}
daemons_running_opensuse() {
if [ -f /usr/lib/systemd/system/libvirtd.service ]; then
systemctl stop libvirtd.service > /dev/null 2>&1
systemctl start libvirtd.service
fi
if [ -f /usr/lib/systemd/system/libvirt-guests.service ]; then
systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service
fi
if [ -f /usr/lib/systemd/system/supervisord.service ]; then
systemctl stop supervisord.service > /dev/null 2>&1
systemctl start supervisord.service
fi
return 0
}
#
# Ended openSUSE Install Functions
#
##############################################################################
##############################################################################
#
# Ubuntu Install Functions
#
install_ubuntu() {
apt-get update || return 1
if [ "$DISTRO_MAJOR_VERSION" -lt 18 ]; then
apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1
else
apt install -y qemu-kvm libvirt-bin bridge-utils virt-manager sasl2-bin python3-guestfs supervisor || return 1
fi
return 0
}
install_ubuntu_post() {
if [ -f /etc/default/libvirt-bin ]; then
sed -i 's/libvirtd_opts="-d"/libvirtd_opts="-d -l"/g' /etc/default/libvirt-bin
elif [ -f /etc/default/libvirtd ]; then
sed -i 's/libvirtd_opts="-d"/libvirtd_opts="-d -l"/g' /etc/default/libvirtd
else
echoerror "/etc/default/libvirt-bin or /etc/default/libvirtd not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/supervisor/supervisord.conf ]; then
wget -O /usr/local/bin/gstfsd https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd
chmod +x /usr/local/bin/gstfsd
wget -O /etc/supervisor/conf.d/gstfsd.conf https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
return 0
}
daemons_running_ubuntu() {
if [ -f /etc/init.d/libvirt-bin ]; then
# Still in SysV init!?
service libvirt-bin stop > /dev/null 2>&1
service libvirt-bin start
fi
if [ -f /etc/init.d/supervisor ]; then
# Still in SysV init!?
service supervisor stop > /dev/null 2>&1
service supervisor start
fi
return 0
}
#
# Ended Ubuntu Install Functions
#
##############################################################################
##############################################################################
#
# Debian Install Functions
#
install_debian() {
apt-get update || return 1
if [ "$DISTRO_MAJOR_VERSION" -lt 10 ]; then
apt-get -y install qemu-kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1
else
apt-get -y install qemu qemu-kvm qemu-system qemu-utils libvirt-clients libvirt-daemon-system sasl2-bin virtinst supervisor || return 1
fi
return 0
}
install_debian_post() {
if [ "$DISTRO_MAJOR_VERSION" -ge 8 ]; then
LIBVIRTSVC=libvirtd
else
LIBVIRTSVC=libvirt-bin
fi
if [ -f /etc/default/$LIBVIRTSVC ]; then
if [ "$( grep -c '^libvirtd_opts *=' /etc/default/$LIBVIRTSVC )" -gt 0 ]; then
if [ "$( grep -c '^libvirtd_opts *=.*-l' /etc/default/$LIBVIRTSVC )" -eq 0 ]; then
sed -i 's/^libvirtd_opts="\([^"]*\)"/libvirtd_opts="\1 -l"/g' /etc/default/$LIBVIRTSVC
fi
else
sed -i 's/^#libvirtd_opts=.*$/libvirtd_opts="-l"/g' /etc/default/$LIBVIRTSVC
fi
else
echoerror "/etc/default/$LIBVIRTSVC not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/libvirtd.conf ]; then
sed -i 's/#listen_tls/listen_tls/g' /etc/libvirt/libvirtd.conf
sed -i 's/#listen_tcp/listen_tcp/g' /etc/libvirt/libvirtd.conf
sed -i 's/#auth_tcp/auth_tcp/g' /etc/libvirt/libvirtd.conf
else
echoerror "/etc/libvirt/libvirtd.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/libvirt/qemu.conf ]; then
sed -i 's/#[ ]*vnc_listen.*/vnc_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
sed -i 's/#[ ]*spice_listen.*/spice_listen = "0.0.0.0"/g' /etc/libvirt/qemu.conf
else
echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/sasl2/libvirt.conf ]; then
sed -i 's/: gssapi/: digest-md5/g' /etc/sasl2/libvirt.conf
sed -i 's/#sasldb_path/sasldb_path/g' /etc/sasl2/libvirt.conf
else
echoerror "/etc/sasl2/libvirt.conf not found. Exiting..."
exit 1
fi
if [ -f /etc/supervisor/supervisord.conf ]; then
wget -O /usr/local/bin/gstfsd https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/daemon/gstfsd
chmod +x /usr/local/bin/gstfsd
wget -O /etc/supervisor/conf.d/gstfsd.conf https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
return 0
}
daemons_running_debian() {
if [ "$DISTRO_MAJOR_VERSION" -ge 8 ]; then
LIBVIRTSVC=libvirtd
else
LIBVIRTSVC=libvirt-bin
fi
if [ -f /etc/init.d/$LIBVIRTSVC ]; then
/etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1
/etc/init.d/$LIBVIRTSVC start
fi
if [ -f /etc/init.d/supervisor ]; then
service supervisor stop > /dev/null 2>&1
service supervisor start
fi
return 0
}
#
# Ended Debian Install Functions
#
##############################################################################
#=============================================================================
# INSTALLATION
#=============================================================================
# Let's get the install function
INSTALL_FUNC_NAMES="install_${DISTRO_NAME_L}"
INSTALL_FUNC="null"
for FUNC_NAME in $(__strip_duplicates "$INSTALL_FUNC_NAMES"); do
if __function_defined "$FUNC_NAME"; then
INSTALL_FUNC=$FUNC_NAME
break
fi
done
echodebug "INSTALL_FUNC=${INSTALL_FUNC}"
if [ "$INSTALL_FUNC" = "null" ]; then
echoerror "No installation function found. Exiting..."
exit 1
else
echoinfo "Running ${INSTALL_FUNC}()"
$INSTALL_FUNC
if [ $? -ne 0 ]; then
echoerror "Failed to run ${INSTALL_FUNC}()!!!"
exit 1
fi
fi
# Let's get the post install function
POST_FUNC_NAMES="install_${DISTRO_NAME_L}_post"
POST_INSTALL_FUNC="null"
for FUNC_NAME in $(__strip_duplicates "$POST_FUNC_NAMES"); do
if __function_defined "$FUNC_NAME"; then
POST_INSTALL_FUNC=$FUNC_NAME
break
fi
done
echodebug "POST_INSTALL_FUNC=${POST_INSTALL_FUNC}"
if [ "$POST_INSTALL_FUNC" = "null" ]; then
echoerror "No installation function found. Exiting..."
exit 1
else
echoinfo "Running ${POST_INSTALL_FUNC}()"
$POST_INSTALL_FUNC
if [ $? -ne 0 ]; then
echoerror "Failed to run ${POST_INSTALL_FUNC}()!!!"
exit 1
fi
fi
# Let's get the daemons running check function.
DAEMONS_RUNNING_FUNC_NAMES="daemons_running_${DISTRO_NAME_L}"
DAEMONS_RUNNING_FUNC="null"
for FUNC_NAME in $(__strip_duplicates "$DAEMONS_RUNNING_FUNC_NAMES"); do
if __function_defined "$FUNC_NAME"; then
DAEMONS_RUNNING_FUNC=$FUNC_NAME
break
fi
done
echodebug "DAEMONS_RUNNING_FUNC=${DAEMONS_RUNNING_FUNC}"
if [ "$DAEMONS_RUNNING_FUNC" = "null" ]; then
echoerror "No installation function found. Exiting..."
exit 1
else
echoinfo "Running ${DAEMONS_RUNNING_FUNC}()"
$DAEMONS_RUNNING_FUNC
if [ $? -ne 0 ]; then
echoerror "Failed to run ${DAEMONS_RUNNING_FUNC}()!!!"
exit 1
fi
fi
exit 0

Binary file not shown.

View file

@ -229,8 +229,15 @@ msgid "Sign In"
msgstr "登录" msgstr "登录"
#: accounts/templates/login.html:5 accounts/templates/logout.html:4 #: accounts/templates/login.html:5 accounts/templates/logout.html:4
#: console/templates/console-vnc-lite.html:5
#: console/templates/console-vnc-full.html:5
#: console/templates/console-spice-lite.html:5
#: console/templates/console-spice-full.html:5 templates/navbar.html:6
#: accounts/templates/login.html:10 accounts/templates/logout.html:9
#: accounts/templates/accounts/otp_login.html:5
#: accounts/templates/accounts/otp_login.html:6
msgid "WebVirtCloud" msgid "WebVirtCloud"
msgstr "私有云平台" msgstr "信创国产化私有云平台"
#: accounts/templates/login.html:19 #: accounts/templates/login.html:19
msgid "Incorrect username or password." msgid "Incorrect username or password."
@ -372,12 +379,10 @@ msgstr "用户组"
#: admin/forms.py:81 admin/forms.py:79 #: admin/forms.py:81 admin/forms.py:79
msgid "" msgid ""
"Raw passwords are not stored, so there is no way to see\n" "Raw passwords are not stored, so there is no way to see\n"
" this user's password, but you can change the password using " " this user's password, but you can change the password using <a href='{}'>this form</a>."
"<a href='{}'>this form</a>."
msgstr "" msgstr ""
"原始密码未存储,因此无法查看\n" "原始密码未存储,因此无法查看\n"
" 该用户的密码,但是您可以使用 <a href='{}'>此表单</a>更改密" " 该用户的密码,但是您可以使用 <a href='{}'>此表单</a>更改密码。"
"码。"
#: admin/templates/admin/group_list.html:5 admin/views.py:87 #: admin/templates/admin/group_list.html:5 admin/views.py:87
#: instances/templates/instances/settings_tab.html:63 templates/navbar.html:29 #: instances/templates/instances/settings_tab.html:63 templates/navbar.html:29
@ -914,7 +919,7 @@ msgstr "网络"
#: nwfilters/templates/nwfilters.html:34 secrets/templates/secrets.html:32 #: nwfilters/templates/nwfilters.html:34 secrets/templates/secrets.html:32
#: storages/templates/storage.html:31 storages/templates/storages.html:28 #: storages/templates/storage.html:31 storages/templates/storages.html:28
msgid "Interfaces" msgid "Interfaces"
msgstr "实例" msgstr "接口"
#: computes/templates/computes/instances.html:44 #: computes/templates/computes/instances.html:44
#: computes/templates/overview.html:31 interfaces/templates/interface.html:28 #: computes/templates/overview.html:31 interfaces/templates/interface.html:28
@ -1066,6 +1071,7 @@ msgstr "基本细节"
#: computes/templates/overview.html:44 #: computes/templates/overview.html:44
#: storages/templates/create_stg_block.html:171 #: storages/templates/create_stg_block.html:171
#: instances/templates/instances/info_tab.html:5
msgid "Hostname" msgid "Hostname"
msgstr "主机名" msgstr "主机名"
@ -1082,6 +1088,7 @@ msgid "Emulator"
msgstr "模拟器" msgstr "模拟器"
#: computes/templates/overview.html:75 #: computes/templates/overview.html:75
#: instances/templates/instances/info_tab.html:11
msgid "Version" msgid "Version"
msgstr "版本" msgstr "版本"
@ -1125,8 +1132,7 @@ msgid "RAM Utilization"
msgstr "内存利用率" msgstr "内存利用率"
#: computes/validators.py:16 #: computes/validators.py:16
msgid "" msgid "Hostname must contain only numbers, or the domain name separated by \".\""
"Hostname must contain only numbers, or the domain name separated by \".\""
msgstr "主机名必须仅包含数字,或以 \".\" 分隔的域名格式。" msgstr "主机名必须仅包含数字,或以 \".\" 分隔的域名格式。"
#: computes/validators.py:18 #: computes/validators.py:18
@ -1868,9 +1874,7 @@ msgstr "VDI"
#: instances/templates/instances/access_tab.html:39 #: instances/templates/instances/access_tab.html:39
#, python-format #, python-format
msgid "" msgid " This action opens a new window with a %(type)s connection to the console of the instance."
" This action opens a new window with a %(type)s connection to the console of "
"the instance."
msgstr " 该操作将打开一个新窗口,并使用 %(type)s 类型的控制台连接到实例。" msgstr " 该操作将打开一个新窗口,并使用 %(type)s 类型的控制台连接到实例。"
#: instances/templates/instances/access_tab.html:47 #: instances/templates/instances/access_tab.html:47
@ -1929,9 +1933,7 @@ msgid "Add Public Key"
msgstr "添加公钥" msgstr "添加公钥"
#: instances/templates/instances/access_tab.html:152 #: instances/templates/instances/access_tab.html:152
msgid "" msgid "This action opens a remote viewer with a connection to the console of the instance."
"This action opens a remote viewer with a connection to the console of the "
"instance."
msgstr "该操作将打开一个远程查看器来连接到实例控制台。" msgstr "该操作将打开一个远程查看器来连接到实例控制台。"
#: instances/templates/instances/access_tab.html:159 #: instances/templates/instances/access_tab.html:159
@ -1983,15 +1985,12 @@ msgid "This action sends an ACPI shutdown signal to the instance."
msgstr "此操作将ACPI关闭信号发送到实例。" msgstr "此操作将ACPI关闭信号发送到实例。"
#: instances/templates/instances/power_tab.html:64 #: instances/templates/instances/power_tab.html:64
msgid "" msgid "This action forcibly powers off and start the instance and may cause data corruption."
"This action forcibly powers off and start the instance and may cause data "
"corruption."
msgstr "该操作将强制关闭电源并启动实例,并可能导致数据损坏。" msgstr "该操作将强制关闭电源并启动实例,并可能导致数据损坏。"
#: instances/templates/instances/power_tab.html:71 #: instances/templates/instances/power_tab.html:71
#: instances/templates/instances/power_tab.html:98 #: instances/templates/instances/power_tab.html:98
msgid "" msgid "This action forcibly powers off the instance and may cause data corruption."
"This action forcibly powers off the instance and may cause data corruption."
msgstr "该操作将强制关闭实例电源,并可能导致数据损坏。" msgstr "该操作将强制关闭实例电源,并可能导致数据损坏。"
#: instances/templates/instances/power_tab.html:80 #: instances/templates/instances/power_tab.html:80
@ -2278,9 +2277,7 @@ msgid "QoS"
msgstr "QoS 流量控制" msgstr "QoS 流量控制"
#: instances/templates/instances/settings_tab.html:468 #: instances/templates/instances/settings_tab.html:468
msgid "" msgid "In most configurations, macvtap does not work for host to guest network communication"
"In most configurations, macvtap does not work for host to guest network "
"communication"
msgstr "在大多数配置中macvtap不适用于主机与客户机之间的网络通信" msgstr "在大多数配置中macvtap不适用于主机与客户机之间的网络通信"
#: instances/templates/instances/settings_tab.html:481 #: instances/templates/instances/settings_tab.html:481
@ -2488,10 +2485,8 @@ msgid "Manage Snapshots"
msgstr "管理快照" msgstr "管理快照"
#: instances/templates/instances/snapshots_tab.html:22 #: instances/templates/instances/snapshots_tab.html:22
msgid "" msgid "This may take more than an hour, depending on how much content is on your instance and how large the disk is. It could cause web server timeout.."
"This may take more than an hour, depending on how much content is on your " msgstr "这可能需要一个多小时,具体取决于实例上的内容量和磁盘的大小。 这可能会导致Web服务器超时。"
"instance and how large the disk is."
msgstr "这可能需要一个多小时,具体取决于实例上已使用的容量和磁盘大小。"
#: instances/templates/instances/snapshots_tab.html:27 #: instances/templates/instances/snapshots_tab.html:27
msgid "Enter Snapshot Name" msgid "Enter Snapshot Name"
@ -2575,10 +2570,8 @@ msgstr "安装了新的 SSH 公钥 %(keyname)s"
#: instances/views.py:422 instances/views.py:416 #: instances/views.py:422 instances/views.py:416
#, python-format #, python-format
msgid "" msgid "User %(quota_msg)s quota reached, cannot resize CPU of '%(instance_name)s'!"
"User %(quota_msg)s quota reached, cannot resize CPU of '%(instance_name)s'!" msgstr "已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的 CPU 大小!"
msgstr ""
"已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的 CPU 大小!"
#: instances/views.py:431 #: instances/views.py:431
#, python-format #, python-format
@ -2591,20 +2584,13 @@ msgstr "调整 CPU"
#: instances/views.py:453 #: instances/views.py:453
#, python-format #, python-format
msgid "" msgid "User %(quota_msg)s quota reached, cannot resize memory of '%(instance_name)s'!"
"User %(quota_msg)s quota reached, cannot resize memory of " msgstr "已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的内存大小!"
"'%(instance_name)s'!"
msgstr ""
"已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的内存大小!"
#: instances/views.py:466 #: instances/views.py:466
#, python-format #, python-format
msgid "" msgid "Memory is resized: current/max: %(old_cur)s/%(old_max)s to %(new_cur)s/%(new_max)s"
"Memory is resized: current/max: %(old_cur)s/%(old_max)s to %(new_cur)s/" msgstr "内存大小已调整:当前/最大值: %(old_cur)s/%(old_max)s 至 %(new_cur)s/%(new_max)s"
"%(new_max)s"
msgstr ""
"内存大小已调整:当前/最大值: %(old_cur)s/%(old_max)s 至 %(new_cur)s/"
"%(new_max)s"
#: instances/views.py:500 instances/views.py:462 #: instances/views.py:500 instances/views.py:462
msgid "Resize Memory" msgid "Resize Memory"
@ -2612,10 +2598,8 @@ msgstr "调整内存"
#: instances/views.py:491 #: instances/views.py:491
#, python-format #, python-format
msgid "" msgid "User %(quota_msg)s quota reached, cannot resize disks of '%(instance_name)s'!"
"User %(quota_msg)s quota reached, cannot resize disks of '%(instance_name)s'!" msgstr "已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的磁盘大小!"
msgstr ""
"已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的磁盘大小!"
#: instances/views.py:507 #: instances/views.py:507
#, python-format #, python-format
@ -2809,12 +2793,8 @@ msgstr "%(qos_dir)s 已设置"
#: instances/views.py:971 instances/views.py:956 #: instances/views.py:971 instances/views.py:956
#, python-format #, python-format
msgid "" msgid "%(qos_dir)s QoS is set. Network XML is changed. Stop and start network to activate new config."
"%(qos_dir)s QoS is set. Network XML is changed. Stop and " msgstr "%(qos_dir)s QoS 已设置。网络XML已更改。 停止并启动网络以激活新的配置。"
"start network to activate new config."
msgstr ""
"%(qos_dir)s QoS 已设置。网络XML已更改。 停止并启动网络以激活"
"新的配置。"
#: instances/views.py:988 networks/views.py:246 instances/views.py:970 #: instances/views.py:988 networks/views.py:246 instances/views.py:970
#, python-format #, python-format
@ -2823,12 +2803,8 @@ msgstr "%(qos_dir)s QoS 已删除"
#: instances/views.py:993 instances/views.py:974 #: instances/views.py:993 instances/views.py:974
#, python-format #, python-format
msgid "" msgid "%(qos_dir)s QoS is deleted. Network XML is changed. Stop and start network to activate new config."
"%(qos_dir)s QoS is deleted. Network XML is changed. Stop and " msgstr "%(qos_dir)s QoS 已删除。网络XML已更改。 停止并启动网络以激活新的配置。"
"start network to activate new config."
msgstr ""
"%(qos_dir)s QoS 已删除。网络XML已更改。 停止并启动网络以激活"
"新的配置。"
#: instances/views.py:1012 instances/views.py:1017 instances/views.py:990 #: instances/views.py:1012 instances/views.py:1017 instances/views.py:990
msgid "Only one owner is allowed and the one already added" msgid "Only one owner is allowed and the one already added"
@ -2884,9 +2860,7 @@ msgid "Clone of '%(instance_name)s'"
msgstr "'%(instance_name)s' 的克隆" msgstr "'%(instance_name)s' 的克隆"
#: instances/views.py:1093 #: instances/views.py:1093
msgid "" msgid "Error setting console password. You should check that your instance have an graphic device."
"Error setting console password. You should check that your instance have an "
"graphic device."
msgstr "设置控制台密码时出错。 您应检查实例是否具有图形设备。" msgstr "设置控制台密码时出错。 您应检查实例是否具有图形设备。"
#: instances/views.py:1126 instances/views.py:1512 instances/views.py:1096 #: instances/views.py:1126 instances/views.py:1512 instances/views.py:1096
@ -3428,8 +3402,7 @@ msgid "{family.upper()} DHCP Range is Changed."
msgstr "{family.upper()} DHCP 范围已更改。" msgstr "{family.upper()} DHCP 范围已更改。"
#: networks/views.py:203 #: networks/views.py:203
msgid "" msgid "Network XML is changed. \\Stop and start network to activate new config."
"Network XML is changed. \\Stop and start network to activate new config."
msgstr "网络XML已更改。\\停止并启动网络以激活新配置。" msgstr "网络XML已更改。\\停止并启动网络以激活新配置。"
#: networks/views.py:215 networks/views.py:242 networks/views.py:205 #: networks/views.py:215 networks/views.py:242 networks/views.py:205
@ -3439,9 +3412,7 @@ msgstr "网络XML已更改。"
#: networks/views.py:228 #: networks/views.py:228
#, python-format #, python-format
msgid "" msgid "%(qos_dir)s QoS is updated. Network XML is changed. Stop and start network to activate new config"
"%(qos_dir)s QoS is updated. Network XML is changed. Stop and start network "
"to activate new config"
msgstr "%(qos_dir)s 的 QoS 已更新。 网络XML已更改。 停止并启动网络以激活新配置" msgstr "%(qos_dir)s 的 QoS 已更新。 网络XML已更改。 停止并启动网络以激活新配置"
#: networks/views.py:218 #: networks/views.py:218
@ -3863,9 +3834,7 @@ msgid "500 Internal Server Error"
msgstr "500 服务器内部错误" msgstr "500 服务器内部错误"
#: templates/500.html:11 #: templates/500.html:11
msgid "" msgid "The server encountered an internal error or misconfiguration and was unable to complete you request."
"The server encountered an internal error or misconfiguration and was unable "
"to complete you request."
msgstr "服务器遇到内部错误或配置错误,无法完成您的请求。" msgstr "服务器遇到内部错误或配置错误,无法完成您的请求。"
#: templates/common/confirm_delete.html:16 #: templates/common/confirm_delete.html:16
@ -3946,15 +3915,12 @@ msgstr "请输入有效的电子邮件地址。"
#. Translators: "letters" means latin letters: a-z and A-Z. #. Translators: "letters" means latin letters: a-z and A-Z.
#: venv/lib/python3.6/site-packages/django/core/validators.py:239 #: venv/lib/python3.6/site-packages/django/core/validators.py:239
#: venv2/lib/python2.7/site-packages/django/core/validators.py:245 #: venv2/lib/python2.7/site-packages/django/core/validators.py:245
msgid "" msgid "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgstr "请输入由字母,数字,下划线或连字符组成的有效“字段”。" msgstr "请输入由字母,数字,下划线或连字符组成的有效“字段”。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:246 #: venv/lib/python3.6/site-packages/django/core/validators.py:246
#: venv2/lib/python2.7/site-packages/django/core/validators.py:252 #: venv2/lib/python2.7/site-packages/django/core/validators.py:252
msgid "" msgid "Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or hyphens."
"Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or "
"hyphens."
msgstr "请输入由 Unicode 字母,数字,下划线或连字符组成的有效“字段”。" msgstr "请输入由 Unicode 字母,数字,下划线或连字符组成的有效“字段”。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:255 #: venv/lib/python3.6/site-packages/django/core/validators.py:255
@ -4005,23 +3971,15 @@ msgstr "确保此值大于或等于 %(limit_value)s 。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:361 #: venv/lib/python3.6/site-packages/django/core/validators.py:361
#: venv2/lib/python2.7/site-packages/django/core/validators.py:364 #: venv2/lib/python2.7/site-packages/django/core/validators.py:364
#, python-format #, python-format
msgid "" msgid "Ensure this value has at least %(limit_value)d character (it has %(show_value)d)."
"Ensure this value has at least %(limit_value)d character (it has " msgid_plural "Ensure this value has at least %(limit_value)d characters (it has %(show_value)d)."
"%(show_value)d)."
msgid_plural ""
"Ensure this value has at least %(limit_value)d characters (it has "
"%(show_value)d)."
msgstr[0] "确保此值至少具有 %(limit_value)d 个字符(具有 %(show_value)d 个)。" msgstr[0] "确保此值至少具有 %(limit_value)d 个字符(具有 %(show_value)d 个)。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:376 #: venv/lib/python3.6/site-packages/django/core/validators.py:376
#: venv2/lib/python2.7/site-packages/django/core/validators.py:379 #: venv2/lib/python2.7/site-packages/django/core/validators.py:379
#, python-format #, python-format
msgid "" msgid "Ensure this value has at most %(limit_value)d character (it has %(show_value)d)."
"Ensure this value has at most %(limit_value)d character (it has " msgid_plural "Ensure this value has at most %(limit_value)d characters (it has %(show_value)d)."
"%(show_value)d)."
msgid_plural ""
"Ensure this value has at most %(limit_value)d characters (it has "
"%(show_value)d)."
msgstr[0] "确保此值最多具有 %(limit_value)d 个字符(具有 %(show_value)d 个)。" msgstr[0] "确保此值最多具有 %(limit_value)d 个字符(具有 %(show_value)d 个)。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:395 #: venv/lib/python3.6/site-packages/django/core/validators.py:395
@ -4049,21 +4007,15 @@ msgstr[0] "确保不超过 %(max)s 个小数位。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:407 #: venv/lib/python3.6/site-packages/django/core/validators.py:407
#: venv2/lib/python2.7/site-packages/django/core/validators.py:409 #: venv2/lib/python2.7/site-packages/django/core/validators.py:409
#, python-format #, python-format
msgid "" msgid "Ensure that there are no more than %(max)s digit before the decimal point."
"Ensure that there are no more than %(max)s digit before the decimal point." msgid_plural "Ensure that there are no more than %(max)s digits before the decimal point."
msgid_plural ""
"Ensure that there are no more than %(max)s digits before the decimal point."
msgstr[0] "确保小数点前的位数不超过 %(max)s 个。" msgstr[0] "确保小数点前的位数不超过 %(max)s 个。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:469 #: venv/lib/python3.6/site-packages/django/core/validators.py:469
#: venv2/lib/python2.7/site-packages/django/core/validators.py:463 #: venv2/lib/python2.7/site-packages/django/core/validators.py:463
#, python-format #, python-format
msgid "" msgid "File extension '%(extension)s' is not allowed. Allowed extensions are: '%(allowed_extensions)s'."
"File extension '%(extension)s' is not allowed. Allowed extensions are: " msgstr "不允许文件扩展名 '%(extension)s' 。 允许的扩展名是:'%(allowed_extensions)s' 。"
"'%(allowed_extensions)s'."
msgstr ""
"不允许文件扩展名 '%(extension)s' 。 允许的扩展名"
"是:'%(allowed_extensions)s' 。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:521 #: venv/lib/python3.6/site-packages/django/core/validators.py:521
msgid "Null characters are not allowed." msgid "Null characters are not allowed."
@ -4109,10 +4061,8 @@ msgstr "具有此 %(field_label)s 的 %(model_name)s 已存在。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:111 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:111
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:123 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:123
#, python-format #, python-format
msgid "" msgid "%(field_label)s must be unique for %(date_field_label)s %(lookup_type)s."
"%(field_label)s must be unique for %(date_field_label)s %(lookup_type)s." msgstr "%(field_label)s 对于 %(date_field_label)s %(lookup_type)s 必须是唯一的。"
msgstr ""
"%(field_label)s 对于 %(date_field_label)s %(lookup_type)s 必须是唯一的。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:128 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:128
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:140 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:140
@ -4172,9 +4122,7 @@ msgstr "逗号分隔的整数"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1153 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1153
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1172 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1172
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has an invalid date format. It must be in YYYY-MM-DD format."
"'%(value)s' value has an invalid date format. It must be in YYYY-MM-DD "
"format."
msgstr "'%(value)s' 值的日期格式无效。 必须为 YYYY-MM-DD 格式。" msgstr "'%(value)s' 值的日期格式无效。 必须为 YYYY-MM-DD 格式。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1155 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1155
@ -4182,9 +4130,7 @@ msgstr "'%(value)s' 值的日期格式无效。 必须为 YYYY-MM-DD 格式。"
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1174 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1174
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1319 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1319
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid date."
"'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid "
"date."
msgstr "'%(value)s' 值具有正确的格式YYYY-MM-DD但它是无效的日期。" msgstr "'%(value)s' 值具有正确的格式YYYY-MM-DD但它是无效的日期。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1158 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1158
@ -4195,22 +4141,14 @@ msgstr "日期(不包含时间)"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1296 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1296
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1317 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1317
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."
"'%(value)s' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[." msgstr "'%(value)s' 值的格式无效。 它必须采用 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 格式。"
"uuuuuu]][TZ] format."
msgstr ""
"'%(value)s' 值的格式无效。 它必须采用 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 格"
"式。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1300 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1300
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1321 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1321
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]) but it is an invalid date/time."
"'%(value)s' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]]" msgstr "'%(value)s' 值具有正确的格式YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]),但它是无效的日期/时间。"
"[TZ]) but it is an invalid date/time."
msgstr ""
"'%(value)s' 值具有正确的格式YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]),但它是无"
"效的日期/时间。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1304 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1304
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1325 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1325
@ -4231,9 +4169,7 @@ msgstr "小数"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1593 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1593
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1628 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1628
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has an invalid format. It must be in [DD] [HH:[MM:]]ss[.uuuuuu] format."
"'%(value)s' value has an invalid format. It must be in [DD] [HH:[MM:]]ss[."
"uuuuuu] format."
msgstr "'%(value)s' 值的格式无效。 它必须为 [DD] [HH:[MM:]]ss[.uuuuuu] 格式。" msgstr "'%(value)s' 值的格式无效。 它必须为 [DD] [HH:[MM:]]ss[.uuuuuu] 格式。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1596 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:1596
@ -4313,17 +4249,13 @@ msgstr "文本"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:2109 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:2109
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:2163 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:2163
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] format."
"'%(value)s' value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] "
"format."
msgstr "'%(value)s' 值的格式无效。 它必须为 HH:MM[:ss[.uuuuuu]] 格式。" msgstr "'%(value)s' 值的格式无效。 它必须为 HH:MM[:ss[.uuuuuu]] 格式。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:2111 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:2111
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:2165 #: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:2165
#, python-format #, python-format
msgid "" msgid "'%(value)s' value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an invalid time."
"'%(value)s' value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an "
"invalid time."
msgstr "'%(value)s' 值具有正确的格式HH:MM[:ss[.uuuuuu]]),但时间无效。" msgstr "'%(value)s' 值具有正确的格式HH:MM[:ss[.uuuuuu]]),但时间无效。"
#: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:2114 #: venv/lib/python3.6/site-packages/django/db/models/fields/__init__.py:2114
@ -4454,8 +4386,7 @@ msgstr "提交的文件为空。"
#: venv2/lib/python2.7/site-packages/django/forms/fields.py:551 #: venv2/lib/python2.7/site-packages/django/forms/fields.py:551
#, python-format #, python-format
msgid "Ensure this filename has at most %(max)d character (it has %(length)d)." msgid "Ensure this filename has at most %(max)d character (it has %(length)d)."
msgid_plural "" msgid_plural "Ensure this filename has at most %(max)d characters (it has %(length)d)."
"Ensure this filename has at most %(max)d characters (it has %(length)d)."
msgstr[0] "确保此文件名最多具有 %(max)d 个字符(具有 %(length)d 个)。" msgstr[0] "确保此文件名最多具有 %(max)d 个字符(具有 %(length)d 个)。"
#: venv/lib/python3.6/site-packages/django/forms/fields.py:539 #: venv/lib/python3.6/site-packages/django/forms/fields.py:539
@ -4465,9 +4396,7 @@ msgstr "请提交文件或选中清除复选框,不能两者都选。"
#: venv/lib/python3.6/site-packages/django/forms/fields.py:600 #: venv/lib/python3.6/site-packages/django/forms/fields.py:600
#: venv2/lib/python2.7/site-packages/django/forms/fields.py:619 #: venv2/lib/python2.7/site-packages/django/forms/fields.py:619
msgid "" msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
msgstr "上载有效镜像。 您上传的文件不是镜像或镜像已损坏。" msgstr "上载有效镜像。 您上传的文件不是镜像或镜像已损坏。"
#: venv/lib/python3.6/site-packages/django/forms/fields.py:762 #: venv/lib/python3.6/site-packages/django/forms/fields.py:762
@ -4552,12 +4481,8 @@ msgstr "请更正 %(field)s 的重复数据,该数据必须唯一。"
#: venv/lib/python3.6/site-packages/django/forms/models.py:761 #: venv/lib/python3.6/site-packages/django/forms/models.py:761
#: venv2/lib/python2.7/site-packages/django/forms/models.py:754 #: venv2/lib/python2.7/site-packages/django/forms/models.py:754
#, python-format #, python-format
msgid "" msgid "Please correct the duplicate data for %(field_name)s which must be unique for the %(lookup)s in %(date_field)s."
"Please correct the duplicate data for %(field_name)s which must be unique " msgstr "请更正 %(field_name)s 的重复数据,该数据对于 %(date_field)s 中的 %(lookup)s 必须是唯一的。"
"for the %(lookup)s in %(date_field)s."
msgstr ""
"请更正 %(field_name)s 的重复数据,该数据对于 %(date_field)s 中的 %(lookup)s "
"必须是唯一的。"
#: venv/lib/python3.6/site-packages/django/forms/models.py:770 #: venv/lib/python3.6/site-packages/django/forms/models.py:770
#: venv2/lib/python2.7/site-packages/django/forms/models.py:763 #: venv2/lib/python2.7/site-packages/django/forms/models.py:763
@ -4581,12 +4506,8 @@ msgstr "\"%(pk)s\" 不是有效值。"
#: venv/lib/python3.6/site-packages/django/forms/utils.py:162 #: venv/lib/python3.6/site-packages/django/forms/utils.py:162
#: venv2/lib/python2.7/site-packages/django/forms/utils.py:172 #: venv2/lib/python2.7/site-packages/django/forms/utils.py:172
#, python-format #, python-format
msgid "" msgid "%(datetime)s couldn't be interpreted in time zone %(current_timezone)s; it may be ambiguous or it may not exist."
"%(datetime)s couldn't be interpreted in time zone %(current_timezone)s; it " msgstr "%(datetime)s 无法在时区 %(current_timezone)s 中解释; 它可能是模棱两可的,也可能不存在。"
"may be ambiguous or it may not exist."
msgstr ""
"%(datetime)s 无法在时区 %(current_timezone)s 中解释; 它可能是模棱两可的,也"
"可能不存在。"
#: venv/lib/python3.6/site-packages/django/forms/widgets.py:396 #: venv/lib/python3.6/site-packages/django/forms/widgets.py:396
#: venv2/lib/python2.7/site-packages/django/forms/widgets.py:378 #: venv2/lib/python2.7/site-packages/django/forms/widgets.py:378
@ -5094,56 +5015,27 @@ msgstr "CSRF验证失败。 请求中止。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:115 #: venv/lib/python3.6/site-packages/django/views/csrf.py:115
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:114 #: venv2/lib/python2.7/site-packages/django/views/csrf.py:114
msgid "" msgid "You are seeing this message because this HTTPS site requires a 'Referer header' to be sent by your Web browser, but none was sent. This header is required for security reasons, to ensure that your browser is not being hijacked by third parties."
"You are seeing this message because this HTTPS site requires a 'Referer " msgstr "您正在看到此消息,因为此 HTTPS 站点要求 Web 浏览器发送 “ Referer 标头”,但没有发送。 出于安全原因,此标头是必需的,以确保您的浏览器不会被第三方劫持。"
"header' to be sent by your Web browser, but none was sent. This header is "
"required for security reasons, to ensure that your browser is not being "
"hijacked by third parties."
msgstr ""
"您正在看到此消息,因为此 HTTPS 站点要求 Web 浏览器发送 “ Referer 标头”,但没"
"有发送。 出于安全原因,此标头是必需的,以确保您的浏览器不会被第三方劫持。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:120 #: venv/lib/python3.6/site-packages/django/views/csrf.py:120
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:119 #: venv2/lib/python2.7/site-packages/django/views/csrf.py:119
msgid "" msgid "If you have configured your browser to disable 'Referer' headers, please re-enable them, at least for this site, or for HTTPS connections, or for 'same-origin' requests."
"If you have configured your browser to disable 'Referer' headers, please re-" msgstr "如果您已将浏览器配置为禁用 'Referer' 标头请至少对本站点HTTPS 连接或 “相同来源” 请求重新启用标头。"
"enable them, at least for this site, or for HTTPS connections, or for 'same-"
"origin' requests."
msgstr ""
"如果您已将浏览器配置为禁用 'Referer' 标头请至少对本站点HTTPS 连接或 “相同"
"来源” 请求重新启用标头。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:124 #: venv/lib/python3.6/site-packages/django/views/csrf.py:124
msgid "" msgid "If you are using the <meta name=\"referrer\" content=\"no-referrer\"> tag or including the 'Referrer-Policy: no-referrer' header, please remove them. The CSRF protection requires the 'Referer' header to do strict referer checking. If you're concerned about privacy, use alternatives like <a rel=\"noreferrer\" ...> for links to third-party sites."
"If you are using the <meta name=\"referrer\" content=\"no-referrer\"> tag or " msgstr "如果您使用的是 <meta name=\"referrer\" content=\"no-referrer\"> 标记或包含 'Referrer-Policy: no-referrer' 标头,请删除它们。 CSRF保护要求 'Referer' 标头进行严格的引用检查。 如果您担心隐私问题,请使用 <a rel=\"noreferrer\" ...> 之类的替代方法来链接到第三方网站。"
"including the 'Referrer-Policy: no-referrer' header, please remove them. The "
"CSRF protection requires the 'Referer' header to do strict referer checking. "
"If you're concerned about privacy, use alternatives like <a rel=\"noreferrer"
"\" ...> for links to third-party sites."
msgstr ""
"如果您使用的是 <meta name=\"referrer\" content=\"no-referrer\"> 标记或包含 "
"'Referrer-Policy: no-referrer' 标头,请删除它们。 CSRF保护要求 'Referer' 标头"
"进行严格的引用检查。 如果您担心隐私问题,请使用 <a rel=\"noreferrer\" ...> 之"
"类的替代方法来链接到第三方网站。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:132 #: venv/lib/python3.6/site-packages/django/views/csrf.py:132
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:124 #: venv2/lib/python2.7/site-packages/django/views/csrf.py:124
msgid "" msgid "You are seeing this message because this site requires a CSRF cookie when submitting forms. This cookie is required for security reasons, to ensure that your browser is not being hijacked by third parties."
"You are seeing this message because this site requires a CSRF cookie when " msgstr "您看到此消息是因为提交表单时此站点需要 CSRF cookie 。 出于安全原因,此 cookie 是必需的,以确保您的浏览器不会被第三方劫持。"
"submitting forms. This cookie is required for security reasons, to ensure "
"that your browser is not being hijacked by third parties."
msgstr ""
"您看到此消息是因为提交表单时此站点需要 CSRF cookie 。 出于安全原因,此 "
"cookie 是必需的,以确保您的浏览器不会被第三方劫持。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:137 #: venv/lib/python3.6/site-packages/django/views/csrf.py:137
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:129 #: venv2/lib/python2.7/site-packages/django/views/csrf.py:129
msgid "" msgid "If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for 'same-origin' requests."
"If you have configured your browser to disable cookies, please re-enable " msgstr "如果您已将浏览器配置为禁用 Cookie ,请至少针对此站点或“相同来源”请求重新启用它们。"
"them, at least for this site, or for 'same-origin' requests."
msgstr ""
"如果您已将浏览器配置为禁用 Cookie ,请至少针对此站点或“相同来源”请求重新启用"
"它们。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:142 #: venv/lib/python3.6/site-packages/django/views/csrf.py:142
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:134 #: venv2/lib/python2.7/site-packages/django/views/csrf.py:134
@ -5190,12 +5082,8 @@ msgstr "没有可用的 %(verbose_name_plural)s"
#: venv/lib/python3.6/site-packages/django/views/generic/dates.py:589 #: venv/lib/python3.6/site-packages/django/views/generic/dates.py:589
#: venv2/lib/python2.7/site-packages/django/views/generic/dates.py:669 #: venv2/lib/python2.7/site-packages/django/views/generic/dates.py:669
#, python-format #, python-format
msgid "" msgid "Future %(verbose_name_plural)s not available because %(class_name)s.allow_future is False."
"Future %(verbose_name_plural)s not available because %(class_name)s." msgstr "将来的 %(verbose_name_plural)s 不可用,因为 %(class_name)s.allow_future 为False。"
"allow_future is False."
msgstr ""
"将来的 %(verbose_name_plural)s 不可用,因为 %(class_name)s.allow_future 为"
"False。"
#: venv/lib/python3.6/site-packages/django/views/generic/dates.py:623 #: venv/lib/python3.6/site-packages/django/views/generic/dates.py:623
#: venv2/lib/python2.7/site-packages/django/views/generic/dates.py:703 #: venv2/lib/python2.7/site-packages/django/views/generic/dates.py:703
@ -5249,12 +5137,8 @@ msgstr "Django完美主义者的Web框架有最后期限。"
#: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:345 #: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:345
#, python-format #, python-format
msgid "" msgid "View <a href=\"https://docs.djangoproject.com/en/%(version)s/releases/\" target=\"_blank\" rel=\"noopener\">release notes</a> for Django %(version)s"
"View <a href=\"https://docs.djangoproject.com/en/%(version)s/releases/\" " msgstr "查看 Django %(version)s 的<a href=\"https://docs.djangoproject.com/en/%(version)s/releases/\" target=\"_blank\" rel=\"noopener\">发行说明</a>"
"target=\"_blank\" rel=\"noopener\">release notes</a> for Django %(version)s"
msgstr ""
"查看 Django %(version)s 的<a href=\"https://docs.djangoproject.com/en/"
"%(version)s/releases/\" target=\"_blank\" rel=\"noopener\">发行说明</a>"
#: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:367 #: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:367
msgid "The install worked successfully! Congratulations!" msgid "The install worked successfully! Congratulations!"
@ -5262,15 +5146,8 @@ msgstr "安装成功! 恭喜您!"
#: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:368 #: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:368
#, python-format #, python-format
msgid "" msgid "You are seeing this page because <a href=\"https://docs.djangoproject.com/en/%(version)s/ref/settings/#debug\" target=\"_blank\" rel=\"noopener\">DEBUG=True</a> is in your settings file and you have not configured any URLs."
"You are seeing this page because <a href=\"https://docs.djangoproject.com/en/" msgstr "您之所以会看到此页面,是因为 <a href=\"https://docs.djangoproject.com/en/%(version)s/ref/settings/#debug\" target=\"_blank\" rel=\"noopener\">DEBUG=True</a> 位于您的设置文件中并且您尚未配置任何URL 。"
"%(version)s/ref/settings/#debug\" target=\"_blank\" rel=\"noopener"
"\">DEBUG=True</a> is in your settings file and you have not configured any "
"URLs."
msgstr ""
"您之所以会看到此页面,是因为 <a href=\"https://docs.djangoproject.com/en/"
"%(version)s/ref/settings/#debug\" target=\"_blank\" rel=\"noopener"
"\">DEBUG=True</a> 位于您的设置文件中并且您尚未配置任何URL 。"
#: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:383 #: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:383
msgid "Django Documentation" msgid "Django Documentation"
@ -5333,20 +5210,12 @@ msgid "Congratulations on your first Django-powered page."
msgstr "恭喜,您的第一个 Django 驱动页面。" msgstr "恭喜,您的第一个 Django 驱动页面。"
#: venv2/lib/python2.7/site-packages/django/views/debug.py:524 #: venv2/lib/python2.7/site-packages/django/views/debug.py:524
msgid "" msgid "Next, start your first app by running <code>python manage.py startapp [app_label]</code>."
"Next, start your first app by running <code>python manage.py startapp " msgstr "接下来,通过运行 <code>python manage.py startapp [app_label]</code> 启动您的第一个应用程序。"
"[app_label]</code>."
msgstr ""
"接下来,通过运行 <code>python manage.py startapp [app_label]</code> 启动您的"
"第一个应用程序。"
#: venv2/lib/python2.7/site-packages/django/views/debug.py:527 #: venv2/lib/python2.7/site-packages/django/views/debug.py:527
msgid "" msgid "You're seeing this message because you have <code>DEBUG = True</code> in your Django settings file and you haven't configured any URLs. Get to work!"
"You're seeing this message because you have <code>DEBUG = True</code> in " msgstr "您之所以会看到此消息是因为Django设置文件中有 <code>DEBUG = True</code>并且尚未配置任何URL。 开始工作!"
"your Django settings file and you haven't configured any URLs. Get to work!"
msgstr ""
"您之所以会看到此消息是因为Django设置文件中有 <code>DEBUG = True</code>,并"
"且尚未配置任何URL。 开始工作!"
#: venv2/lib/python2.7/site-packages/gunicorn/argparse_compat.py:313 #: venv2/lib/python2.7/site-packages/gunicorn/argparse_compat.py:313
msgid "usage: " msgid "usage: "
@ -5500,3 +5369,27 @@ msgstr "%s: 错误: %s\n"
#, python-format #, python-format
msgid "libvirt Error - %(exception)s" msgid "libvirt Error - %(exception)s"
msgstr "libvirt 错误- %(exception)s" msgstr "libvirt 错误- %(exception)s"
#: instances/templates/instances/info_tab.html:3
msgid "Guest Info"
msgstr "客户机信息"
#: instances/templates/instances/info_tab.html:7
msgid "OS Name"
msgstr "系统名称"
#: instances/templates/instances/info_tab.html:9
msgid "OS Pretty-Name"
msgstr "系统详细名称"
#: instances/templates/instances/info_tab.html:13
msgid "Kernel Release"
msgstr "内核发布版本"
#: instances/templates/instances/info_tab.html:15
msgid "Kernel Version"
msgstr "内核版本时间"
#: instances/templates/instances/info_tab.html:17
msgid "Timezone / Offset"
msgstr "时区/偏移"

4
sources.list Normal file
View file

@ -0,0 +1,4 @@
deb http://mirrors4.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic main restricted universe multiverse
deb http://mirrors4.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-updates main restricted universe multiverse
deb http://mirrors4.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-backports main restricted universe multiverse
deb http://mirrors4.tuna.tsinghua.edu.cn/ubuntu-ports/ bionic-security main restricted universe multiverse

View file

@ -6,7 +6,7 @@
<meta charset="utf-8"> <meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"> <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="description" content="WebVirtCloud panel for manage virtual machine"> <meta name="description" content="Private Cloud Platform panel for manage virtual machine">
<meta name="author" content="anatoliy.guskov@gmail.com"> <meta name="author" content="anatoliy.guskov@gmail.com">
<title>{% block title %}{% endblock %}</title> <title>{% block title %}{% endblock %}</title>

View file

@ -4,7 +4,7 @@
<!-- Fixed navbar --> <!-- Fixed navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-primary mb-3" aria-label="Main top navbar"> <nav class="navbar navbar-expand-md navbar-dark bg-primary mb-3" aria-label="Main top navbar">
<div class="container"> <div class="container">
<a class="navbar-brand" href="{% url 'index' %}">WebVirtCloud</a> <a class="navbar-brand" href="{% url 'index' %}">{% trans "WebVirtCloud" %}</a>
<button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-label="Toggle navigation"> <button type="button" class="navbar-toggler" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span> <span class="navbar-toggler-icon"></span>
</button> </button>

View file

@ -176,7 +176,7 @@ class wvmCreate(wvmConnect):
graphics, graphics,
virtio, virtio,
listen_addr, listen_addr,
video="vga", video="virtio",
console_pass="random", console_pass="random",
mac=None, mac=None,
qemu_ga=True, qemu_ga=True,
@ -222,7 +222,8 @@ class wvmCreate(wvmConnect):
if caps["features"]: if caps["features"]:
xml += """<features>""" xml += """<features>"""
if "acpi" in caps["features"]: if "acpi" in caps["features"]:
xml += """<acpi/>""" #xml += """<acpi/>"""
xml += """<acpi/> <gic version='3'/>"""
if "apic" in caps["features"]: if "apic" in caps["features"]:
xml += """<apic/>""" xml += """<apic/>"""
if "pae" in caps["features"]: if "pae" in caps["features"]:
@ -234,7 +235,8 @@ class wvmCreate(wvmConnect):
if vcpu_mode == "host-model": if vcpu_mode == "host-model":
xml += """<cpu mode='host-model'/>""" xml += """<cpu mode='host-model'/>"""
elif vcpu_mode == "host-passthrough": elif vcpu_mode == "host-passthrough":
xml += """<cpu mode='host-passthrough'/>""" #xml += """<cpu mode='host-passthrough'/>"""
xml += """<cpu mode='host-passthrough' check='none'/>"""
elif vcpu_mode == "": elif vcpu_mode == "":
pass pass
else: else:
@ -259,10 +261,14 @@ class wvmCreate(wvmConnect):
for volume in volumes: for volume in volumes:
disk_opts = "" disk_opts = ""
if volume["cache_mode"] is not None and volume["cache_mode"] != "default": #if volume["cache_mode"] is not None and volume["cache_mode"] != "default":
disk_opts += f"cache='{volume['cache_mode']}' " if volume["cache_mode"] is not None or volume["cache_mode"] == "default":
if volume["io_mode"] is not None and volume["io_mode"] != "default": #disk_opts += f"cache='{volume['cache_mode']}' "
disk_opts += f"io='{volume['io_mode']}' " disk_opts += f"cache='writeback' "
#if volume["io_mode"] is not None and volume["io_mode"] != "default":
if volume["io_mode"] is not None or volume["io_mode"] == "default":
#disk_opts += f"io='{volume['io_mode']}' "
disk_opts += f"io='threads' "
if volume["discard_mode"] is not None and volume["discard_mode"] != "default": if volume["discard_mode"] is not None and volume["discard_mode"] != "default":
disk_opts += f"discard='{volume['discard_mode']}' " disk_opts += f"discard='{volume['discard_mode']}' "
if volume["detect_zeroes_mode"] is not None and volume["detect_zeroes_mode"] != "default": if volume["detect_zeroes_mode"] is not None and volume["detect_zeroes_mode"] != "default":
@ -323,6 +329,11 @@ class wvmCreate(wvmConnect):
if volume.get("bus") == "scsi": if volume.get("bus") == "scsi":
xml += f"""<controller type='scsi' model='{volume.get('scsi_model')}'/>""" xml += f"""<controller type='scsi' model='{volume.get('scsi_model')}'/>"""
## add usb dom support with mode qemu-xhci
xml += f"""<controller type='usb' model='qemu-xhci'/>"""
xml += f"""<input type='mouse' bus='usb'/>"""
xml += f"""<input type='keyboard' bus='usb'/>"""
if add_cd: if add_cd:
xml += """<disk type='file' device='cdrom'> xml += """<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/> <driver name='qemu' type='raw'/>
@ -365,7 +376,7 @@ class wvmCreate(wvmConnect):
xml += """<input type='tablet'/>""" xml += """<input type='tablet'/>"""
xml += f""" xml += f"""
<graphics type='{graphics}' port='-1' autoport='yes' {console_pass} listen='{listen_addr}'/> <graphics type='{graphics}' port='-1' autoport='yes' {console_pass} listen='{listen_addr}' keymap='en-us'/>
<console type='pty'/> """ <console type='pty'/> """
if qemu_ga and virtio: if qemu_ga and virtio: