1
0
Fork 0
mirror of https://github.com/retspen/webvirtcloud synced 2026-03-21 18:14:51 +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.
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 apt-get update -qqy \
@ -20,7 +23,7 @@ RUN apt-get update -qqy \
zlib1g-dev \
nginx \
pkg-config \
gcc \
gcc g++ sudo \
libsasl2-modules \
&& 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
RUN python3 -m venv venv && \
. venv/bin/activate && \
pip3 install -U pip && \
pip3 install wheel && \
pip3 install -r conf/requirements.txt && \
pip3 install -i https://pypi.doubanio.com/simple -U pip && \
pip3 install -i https://pypi.doubanio.com/simple wheel && \
pip3 install -i https://pypi.doubanio.com/simple -r conf/requirements.txt && \
chown -R www-data:www-data /srv/webvirtcloud
RUN . venv/bin/activate && \
@ -60,4 +63,11 @@ COPY conf/runit/webvirtcloud.sh /etc/service/webvirtcloud/run
# Define mountable directories.
#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

View file

@ -3,9 +3,9 @@
{% load static %}
{% 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 %}
<div class="row">
@ -27,4 +27,4 @@
</div>
</div>
</div>
{% endblock content %}
{% endblock content %}

View file

@ -10,7 +10,8 @@
{% block content %}
<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 class="col-12" role="main">
{% if form.errors %}
@ -27,4 +28,4 @@
<button class="btn btn-lg btn-success btn-block" type="submit">{% trans "Sign In" %}</button>
</form>
</div>
{% endblock %}
{% endblock %}

View file

@ -6,7 +6,8 @@
{% block content %}
<div>
<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 class="col-12" role="main">
<div class="logout">
@ -14,4 +15,4 @@
</div>
</div>
</div>
{% endblock %}
{% endblock %}

View file

@ -29,7 +29,7 @@
</disk>
<disk type="file" device="cdrom">
<driver name="qemu" type="raw" />
<target dev="sda" bus="sata" />
<target dev="sda" bus="scsi" />
<readonly />
<address type="drive" controller="0" bus="0" target="0" unit="0" />
</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" %}
{% load i18n %}
{% load staticfiles %}
{% 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" %}" />
<!-- ES2015/ES6 modules polyfill -->
@ -228,4 +204,4 @@
{% block foot %}
{% endblock %}
{% endblock %}

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" %}
{% load i18n %}
{% load staticfiles %}
{% 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" %}" />
<!-- ES2015/ES6 modules polyfill -->
@ -229,4 +205,4 @@
<div id="debug-div">
<!-- If DUMPXXX is turned on, dumped images will go here -->
</div>
{% endblock %}
{% endblock %}

View file

@ -3,17 +3,8 @@
{% load staticfiles %}
{% block head %}
<!--
noVNC example: simple example using default UI
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>
<title>{% trans "WebVirtCloud" %} - noVNC</title>
<meta charset="utf-8" />
@ -326,4 +317,4 @@
<source src="{% static "js/novnc/app/sounds/bell.oga" %}" type="audio/ogg">
<source src="{% static "js/novnc/app/sounds/bell.mp3" %}" type="audio/mpeg">
</audio>
{% endblock %}
{% endblock %}

View file

@ -3,16 +3,8 @@
{% load staticfiles %}
{% block head %}
<!--
noVNC example: lightweight example using minimal UI and features
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>
<title>{% trans "WebVirtCloud" %} - noVNC - Lite</title>
<meta charset="utf-8">
@ -231,4 +223,4 @@
<div id="noVNC_container">
<!-- This is where the remote screen will appear -->
</div>
{% endblock %}
{% endblock %}

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):
name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=64)
firmware = forms.CharField(max_length=50, required=False)
name = forms.CharField(error_messages={'required': _('No Virtual Machine name has been entered')}, max_length=200)
firmware = forms.CharField(max_length=200, required=False)
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)
memory = forms.IntegerField(error_messages={'required': _('No RAM size has been entered')})
networks = forms.CharField(error_messages={'required': _('No Network pool has been choosen')})
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)
images = forms.CharField(required=False)
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(
reverse('instances:add_cdrom', args=[self.instance.id]),
{
'bus': 'sata',
#'bus': 'sata',
'bus': 'scsi',
},
HTTP_REFERER=reverse('index'),
)

View file

@ -691,7 +691,8 @@ def add_cdrom(request, 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
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)
instance.proxy.attach_disk(target, "", disk_device="cdrom", cache_mode="none", target_bus=bus, readonly=True)
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 "登录"
#: 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"
msgstr "私有云平台"
msgstr "信创国产化私有云平台"
#: accounts/templates/login.html:19
msgid "Incorrect username or password."
@ -372,12 +379,10 @@ msgstr "用户组"
#: admin/forms.py:81 admin/forms.py:79
msgid ""
"Raw passwords are not stored, so there is no way to see\n"
" this user's password, but you can change the password using "
"<a href='{}'>this form</a>."
" this user's password, but you can change the password using <a href='{}'>this form</a>."
msgstr ""
"原始密码未存储,因此无法查看\n"
" 该用户的密码,但是您可以使用 <a href='{}'>此表单</a>更改密"
"码。"
" 该用户的密码,但是您可以使用 <a href='{}'>此表单</a>更改密码。"
#: admin/templates/admin/group_list.html:5 admin/views.py:87
#: 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
#: storages/templates/storage.html:31 storages/templates/storages.html:28
msgid "Interfaces"
msgstr "实例"
msgstr "接口"
#: computes/templates/computes/instances.html:44
#: computes/templates/overview.html:31 interfaces/templates/interface.html:28
@ -1066,6 +1071,7 @@ msgstr "基本细节"
#: computes/templates/overview.html:44
#: storages/templates/create_stg_block.html:171
#: instances/templates/instances/info_tab.html:5
msgid "Hostname"
msgstr "主机名"
@ -1082,6 +1088,7 @@ msgid "Emulator"
msgstr "模拟器"
#: computes/templates/overview.html:75
#: instances/templates/instances/info_tab.html:11
msgid "Version"
msgstr "版本"
@ -1125,8 +1132,7 @@ msgid "RAM Utilization"
msgstr "内存利用率"
#: computes/validators.py:16
msgid ""
"Hostname must contain only numbers, or the domain name separated by \".\""
msgid "Hostname must contain only numbers, or the domain name separated by \".\""
msgstr "主机名必须仅包含数字,或以 \".\" 分隔的域名格式。"
#: computes/validators.py:18
@ -1868,9 +1874,7 @@ msgstr "VDI"
#: instances/templates/instances/access_tab.html:39
#, python-format
msgid ""
" This action opens a new window with a %(type)s connection to the console of "
"the instance."
msgid " This action opens a new window with a %(type)s connection to the console of the instance."
msgstr " 该操作将打开一个新窗口,并使用 %(type)s 类型的控制台连接到实例。"
#: instances/templates/instances/access_tab.html:47
@ -1929,9 +1933,7 @@ msgid "Add Public Key"
msgstr "添加公钥"
#: instances/templates/instances/access_tab.html:152
msgid ""
"This action opens a remote viewer with a connection to the console of the "
"instance."
msgid "This action opens a remote viewer with a connection to the console of the instance."
msgstr "该操作将打开一个远程查看器来连接到实例控制台。"
#: instances/templates/instances/access_tab.html:159
@ -1983,15 +1985,12 @@ msgid "This action sends an ACPI shutdown signal to the instance."
msgstr "此操作将ACPI关闭信号发送到实例。"
#: instances/templates/instances/power_tab.html:64
msgid ""
"This action forcibly powers off and start the instance and may cause data "
"corruption."
msgid "This action forcibly powers off and start the instance and may cause data corruption."
msgstr "该操作将强制关闭电源并启动实例,并可能导致数据损坏。"
#: instances/templates/instances/power_tab.html:71
#: instances/templates/instances/power_tab.html:98
msgid ""
"This action forcibly powers off the instance and may cause data corruption."
msgid "This action forcibly powers off the instance and may cause data corruption."
msgstr "该操作将强制关闭实例电源,并可能导致数据损坏。"
#: instances/templates/instances/power_tab.html:80
@ -2278,9 +2277,7 @@ msgid "QoS"
msgstr "QoS 流量控制"
#: instances/templates/instances/settings_tab.html:468
msgid ""
"In most configurations, macvtap does not work for host to guest network "
"communication"
msgid "In most configurations, macvtap does not work for host to guest network communication"
msgstr "在大多数配置中macvtap不适用于主机与客户机之间的网络通信"
#: instances/templates/instances/settings_tab.html:481
@ -2488,10 +2485,8 @@ msgid "Manage Snapshots"
msgstr "管理快照"
#: instances/templates/instances/snapshots_tab.html:22
msgid ""
"This may take more than an hour, depending on how much content is on your "
"instance and how large the disk is."
msgstr "这可能需要一个多小时,具体取决于实例上已使用的容量和磁盘大小。"
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.."
msgstr "这可能需要一个多小时,具体取决于实例上的内容量和磁盘的大小。 这可能会导致Web服务器超时。"
#: instances/templates/instances/snapshots_tab.html:27
msgid "Enter Snapshot Name"
@ -2575,10 +2570,8 @@ msgstr "安装了新的 SSH 公钥 %(keyname)s"
#: instances/views.py:422 instances/views.py:416
#, python-format
msgid ""
"User %(quota_msg)s quota reached, cannot resize CPU of '%(instance_name)s'!"
msgstr ""
"已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的 CPU 大小!"
msgid "User %(quota_msg)s quota reached, cannot resize CPU of '%(instance_name)s'!"
msgstr "已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的 CPU 大小!"
#: instances/views.py:431
#, python-format
@ -2591,20 +2584,13 @@ msgstr "调整 CPU"
#: instances/views.py:453
#, python-format
msgid ""
"User %(quota_msg)s quota reached, cannot resize memory of "
"'%(instance_name)s'!"
msgstr ""
"已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的内存大小!"
msgid "User %(quota_msg)s quota reached, cannot resize memory of '%(instance_name)s'!"
msgstr "已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的内存大小!"
#: instances/views.py:466
#, python-format
msgid ""
"Memory is resized: current/max: %(old_cur)s/%(old_max)s to %(new_cur)s/"
"%(new_max)s"
msgstr ""
"内存大小已调整:当前/最大值: %(old_cur)s/%(old_max)s 至 %(new_cur)s/"
"%(new_max)s"
msgid "Memory is resized: current/max: %(old_cur)s/%(old_max)s to %(new_cur)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
msgid "Resize Memory"
@ -2612,10 +2598,8 @@ msgstr "调整内存"
#: instances/views.py:491
#, python-format
msgid ""
"User %(quota_msg)s quota reached, cannot resize disks of '%(instance_name)s'!"
msgstr ""
"已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的磁盘大小!"
msgid "User %(quota_msg)s quota reached, cannot resize disks of '%(instance_name)s'!"
msgstr "已达到用户 %(quota_msg)s 的配额,无法调整 '%(instance_name)s' 的磁盘大小!"
#: instances/views.py:507
#, python-format
@ -2809,12 +2793,8 @@ msgstr "%(qos_dir)s 已设置"
#: instances/views.py:971 instances/views.py:956
#, python-format
msgid ""
"%(qos_dir)s QoS is set. Network XML is changed. Stop and "
"start network to activate new config."
msgstr ""
"%(qos_dir)s QoS 已设置。网络XML已更改。 停止并启动网络以激活"
"新的配置。"
msgid "%(qos_dir)s QoS is set. Network XML is changed. Stop and start network to activate new config."
msgstr "%(qos_dir)s QoS 已设置。网络XML已更改。 停止并启动网络以激活新的配置。"
#: instances/views.py:988 networks/views.py:246 instances/views.py:970
#, python-format
@ -2823,12 +2803,8 @@ msgstr "%(qos_dir)s QoS 已删除"
#: instances/views.py:993 instances/views.py:974
#, python-format
msgid ""
"%(qos_dir)s QoS is deleted. Network XML is changed. Stop and "
"start network to activate new config."
msgstr ""
"%(qos_dir)s QoS 已删除。网络XML已更改。 停止并启动网络以激活"
"新的配置。"
msgid "%(qos_dir)s QoS is deleted. Network XML is changed. Stop and start network to activate new config."
msgstr "%(qos_dir)s QoS 已删除。网络XML已更改。 停止并启动网络以激活新的配置。"
#: instances/views.py:1012 instances/views.py:1017 instances/views.py:990
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' 的克隆"
#: instances/views.py:1093
msgid ""
"Error setting console password. You should check that your instance have an "
"graphic device."
msgid "Error setting console password. You should check that your instance have an graphic device."
msgstr "设置控制台密码时出错。 您应检查实例是否具有图形设备。"
#: 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 范围已更改。"
#: networks/views.py:203
msgid ""
"Network XML is changed. \\Stop and start network to activate new config."
msgid "Network XML is changed. \\Stop and start network to activate new config."
msgstr "网络XML已更改。\\停止并启动网络以激活新配置。"
#: networks/views.py:215 networks/views.py:242 networks/views.py:205
@ -3439,9 +3412,7 @@ msgstr "网络XML已更改。"
#: networks/views.py:228
#, python-format
msgid ""
"%(qos_dir)s QoS is updated. Network XML is changed. Stop and start network "
"to activate new config"
msgid "%(qos_dir)s QoS is updated. Network XML is changed. Stop and start network to activate new config"
msgstr "%(qos_dir)s 的 QoS 已更新。 网络XML已更改。 停止并启动网络以激活新配置"
#: networks/views.py:218
@ -3863,9 +3834,7 @@ msgid "500 Internal Server Error"
msgstr "500 服务器内部错误"
#: templates/500.html:11
msgid ""
"The server encountered an internal error or misconfiguration and was unable "
"to complete you request."
msgid "The server encountered an internal error or misconfiguration and was unable to complete you request."
msgstr "服务器遇到内部错误或配置错误,无法完成您的请求。"
#: templates/common/confirm_delete.html:16
@ -3946,15 +3915,12 @@ msgstr "请输入有效的电子邮件地址。"
#. Translators: "letters" means latin letters: a-z and A-Z.
#: venv/lib/python3.6/site-packages/django/core/validators.py:239
#: venv2/lib/python2.7/site-packages/django/core/validators.py:245
msgid ""
"Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgid "Enter a valid 'slug' consisting of letters, numbers, underscores or hyphens."
msgstr "请输入由字母,数字,下划线或连字符组成的有效“字段”。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:246
#: venv2/lib/python2.7/site-packages/django/core/validators.py:252
msgid ""
"Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or "
"hyphens."
msgid "Enter a valid 'slug' consisting of Unicode letters, numbers, underscores, or hyphens."
msgstr "请输入由 Unicode 字母,数字,下划线或连字符组成的有效“字段”。"
#: 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
#: venv2/lib/python2.7/site-packages/django/core/validators.py:364
#, python-format
msgid ""
"Ensure this value has at least %(limit_value)d character (it has "
"%(show_value)d)."
msgid_plural ""
"Ensure this value has at least %(limit_value)d characters (it has "
"%(show_value)d)."
msgid "Ensure this value has at least %(limit_value)d character (it has %(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 个)。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:376
#: venv2/lib/python2.7/site-packages/django/core/validators.py:379
#, python-format
msgid ""
"Ensure this value has at most %(limit_value)d character (it has "
"%(show_value)d)."
msgid_plural ""
"Ensure this value has at most %(limit_value)d characters (it has "
"%(show_value)d)."
msgid "Ensure this value has at most %(limit_value)d character (it has %(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 个)。"
#: 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
#: venv2/lib/python2.7/site-packages/django/core/validators.py:409
#, python-format
msgid ""
"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 "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."
msgstr[0] "确保小数点前的位数不超过 %(max)s 个。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:469
#: venv2/lib/python2.7/site-packages/django/core/validators.py:463
#, python-format
msgid ""
"File extension '%(extension)s' is not allowed. Allowed extensions are: "
"'%(allowed_extensions)s'."
msgstr ""
"不允许文件扩展名 '%(extension)s' 。 允许的扩展名"
"是:'%(allowed_extensions)s' 。"
msgid "File extension '%(extension)s' is not allowed. Allowed extensions are: '%(allowed_extensions)s'."
msgstr "不允许文件扩展名 '%(extension)s' 。 允许的扩展名是:'%(allowed_extensions)s' 。"
#: venv/lib/python3.6/site-packages/django/core/validators.py:521
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
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:123
#, python-format
msgid ""
"%(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 必须是唯一的。"
msgid "%(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 必须是唯一的。"
#: 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
@ -4172,9 +4122,7 @@ msgstr "逗号分隔的整数"
#: 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
#, python-format
msgid ""
"'%(value)s' value has an invalid date format. It must be in YYYY-MM-DD "
"format."
msgid "'%(value)s' value has an invalid date format. It must be in YYYY-MM-DD format."
msgstr "'%(value)s' 值的日期格式无效。 必须为 YYYY-MM-DD 格式。"
#: 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:1319
#, python-format
msgid ""
"'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid "
"date."
msgid "'%(value)s' value has the correct format (YYYY-MM-DD) but it is an invalid date."
msgstr "'%(value)s' 值具有正确的格式YYYY-MM-DD但它是无效的日期。"
#: 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
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1317
#, python-format
msgid ""
"'%(value)s' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[."
"uuuuuu]][TZ] format."
msgstr ""
"'%(value)s' 值的格式无效。 它必须采用 YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] 格"
"式。"
msgid "'%(value)s' value has an invalid format. It must be in YYYY-MM-DD HH:MM[:ss[.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
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1321
#, python-format
msgid ""
"'%(value)s' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]]"
"[TZ]) but it is an invalid date/time."
msgstr ""
"'%(value)s' 值具有正确的格式YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ]),但它是无"
"效的日期/时间。"
msgid "'%(value)s' value has the correct format (YYYY-MM-DD HH:MM[:ss[.uuuuuu]][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
#: 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
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:1628
#, python-format
msgid ""
"'%(value)s' value has an invalid format. It must be in [DD] [HH:[MM:]]ss[."
"uuuuuu] format."
msgid "'%(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] 格式。"
#: 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
#: venv2/lib/python2.7/site-packages/django/db/models/fields/__init__.py:2163
#, python-format
msgid ""
"'%(value)s' value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] "
"format."
msgid "'%(value)s' value has an invalid format. It must be in HH:MM[:ss[.uuuuuu]] format."
msgstr "'%(value)s' 值的格式无效。 它必须为 HH:MM[:ss[.uuuuuu]] 格式。"
#: 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
#, python-format
msgid ""
"'%(value)s' value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an "
"invalid time."
msgid "'%(value)s' value has the correct format (HH:MM[:ss[.uuuuuu]]) but it is an invalid time."
msgstr "'%(value)s' 值具有正确的格式HH:MM[:ss[.uuuuuu]]),但时间无效。"
#: 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
#, python-format
msgid "Ensure this filename has at most %(max)d character (it has %(length)d)."
msgid_plural ""
"Ensure this filename has at most %(max)d characters (it has %(length)d)."
msgid_plural "Ensure this filename has at most %(max)d characters (it has %(length)d)."
msgstr[0] "确保此文件名最多具有 %(max)d 个字符(具有 %(length)d 个)。"
#: 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
#: venv2/lib/python2.7/site-packages/django/forms/fields.py:619
msgid ""
"Upload a valid image. The file you uploaded was either not an image or a "
"corrupted image."
msgid "Upload a valid image. The file you uploaded was either not an image or a corrupted image."
msgstr "上载有效镜像。 您上传的文件不是镜像或镜像已损坏。"
#: 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
#: venv2/lib/python2.7/site-packages/django/forms/models.py:754
#, python-format
msgid ""
"Please correct the duplicate data for %(field_name)s which must be unique "
"for the %(lookup)s in %(date_field)s."
msgstr ""
"请更正 %(field_name)s 的重复数据,该数据对于 %(date_field)s 中的 %(lookup)s "
"必须是唯一的。"
msgid "Please correct the duplicate data for %(field_name)s which must be unique 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
#: 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
#: venv2/lib/python2.7/site-packages/django/forms/utils.py:172
#, python-format
msgid ""
"%(datetime)s couldn't be interpreted in time zone %(current_timezone)s; it "
"may be ambiguous or it may not exist."
msgstr ""
"%(datetime)s 无法在时区 %(current_timezone)s 中解释; 它可能是模棱两可的,也"
"可能不存在。"
msgid "%(datetime)s couldn't be interpreted in time zone %(current_timezone)s; it 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
#: 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
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:114
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."
msgstr ""
"您正在看到此消息,因为此 HTTPS 站点要求 Web 浏览器发送 “ Referer 标头”,但没"
"有发送。 出于安全原因,此标头是必需的,以确保您的浏览器不会被第三方劫持。"
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."
msgstr "您正在看到此消息,因为此 HTTPS 站点要求 Web 浏览器发送 “ Referer 标头”,但没有发送。 出于安全原因,此标头是必需的,以确保您的浏览器不会被第三方劫持。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:120
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:119
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."
msgstr ""
"如果您已将浏览器配置为禁用 'Referer' 标头请至少对本站点HTTPS 连接或 “相同"
"来源” 请求重新启用标头。"
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."
msgstr "如果您已将浏览器配置为禁用 'Referer' 标头请至少对本站点HTTPS 连接或 “相同来源” 请求重新启用标头。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:124
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."
msgstr ""
"如果您使用的是 <meta name=\"referrer\" content=\"no-referrer\"> 标记或包含 "
"'Referrer-Policy: no-referrer' 标头,请删除它们。 CSRF保护要求 'Referer' 标头"
"进行严格的引用检查。 如果您担心隐私问题,请使用 <a rel=\"noreferrer\" ...> 之"
"类的替代方法来链接到第三方网站。"
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."
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
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:124
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."
msgstr ""
"您看到此消息是因为提交表单时此站点需要 CSRF cookie 。 出于安全原因,此 "
"cookie 是必需的,以确保您的浏览器不会被第三方劫持。"
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."
msgstr "您看到此消息是因为提交表单时此站点需要 CSRF cookie 。 出于安全原因,此 cookie 是必需的,以确保您的浏览器不会被第三方劫持。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:137
#: venv2/lib/python2.7/site-packages/django/views/csrf.py:129
msgid ""
"If you have configured your browser to disable cookies, please re-enable "
"them, at least for this site, or for 'same-origin' requests."
msgstr ""
"如果您已将浏览器配置为禁用 Cookie ,请至少针对此站点或“相同来源”请求重新启用"
"它们。"
msgid "If you have configured your browser to disable cookies, please re-enable them, at least for this site, or for 'same-origin' requests."
msgstr "如果您已将浏览器配置为禁用 Cookie ,请至少针对此站点或“相同来源”请求重新启用它们。"
#: venv/lib/python3.6/site-packages/django/views/csrf.py:142
#: 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
#: venv2/lib/python2.7/site-packages/django/views/generic/dates.py:669
#, python-format
msgid ""
"Future %(verbose_name_plural)s not available because %(class_name)s."
"allow_future is False."
msgstr ""
"将来的 %(verbose_name_plural)s 不可用,因为 %(class_name)s.allow_future 为"
"False。"
msgid "Future %(verbose_name_plural)s not available because %(class_name)s.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
#: 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
#, python-format
msgid ""
"View <a href=\"https://docs.djangoproject.com/en/%(version)s/releases/\" "
"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>"
msgid "View <a href=\"https://docs.djangoproject.com/en/%(version)s/releases/\" 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
msgid "The install worked successfully! Congratulations!"
@ -5262,15 +5146,8 @@ msgstr "安装成功! 恭喜您!"
#: venv/lib/python3.6/site-packages/django/views/templates/default_urlconf.html:368
#, python-format
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."
msgstr ""
"您之所以会看到此页面,是因为 <a href=\"https://docs.djangoproject.com/en/"
"%(version)s/ref/settings/#debug\" target=\"_blank\" rel=\"noopener"
"\">DEBUG=True</a> 位于您的设置文件中并且您尚未配置任何URL 。"
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."
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
msgid "Django Documentation"
@ -5333,20 +5210,12 @@ msgid "Congratulations on your first Django-powered page."
msgstr "恭喜,您的第一个 Django 驱动页面。"
#: venv2/lib/python2.7/site-packages/django/views/debug.py:524
msgid ""
"Next, start your first app by running <code>python manage.py startapp "
"[app_label]</code>."
msgstr ""
"接下来,通过运行 <code>python manage.py startapp [app_label]</code> 启动您的"
"第一个应用程序。"
msgid "Next, start your first app by running <code>python manage.py startapp [app_label]</code>."
msgstr "接下来,通过运行 <code>python manage.py startapp [app_label]</code> 启动您的第一个应用程序。"
#: venv2/lib/python2.7/site-packages/django/views/debug.py:527
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!"
msgstr ""
"您之所以会看到此消息是因为Django设置文件中有 <code>DEBUG = True</code>,并"
"且尚未配置任何URL。 开始工作!"
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!"
msgstr "您之所以会看到此消息是因为Django设置文件中有 <code>DEBUG = True</code>并且尚未配置任何URL。 开始工作!"
#: venv2/lib/python2.7/site-packages/gunicorn/argparse_compat.py:313
msgid "usage: "
@ -5500,3 +5369,27 @@ msgstr "%s: 错误: %s\n"
#, python-format
msgid "libvirt Error - %(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 http-equiv="X-UA-Compatible" content="IE=edge">
<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">
<title>{% block title %}{% endblock %}</title>

View file

@ -4,7 +4,7 @@
<!-- Fixed navbar -->
<nav class="navbar navbar-expand-md navbar-dark bg-primary mb-3" aria-label="Main top navbar">
<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">
<span class="navbar-toggler-icon"></span>
</button>
@ -50,4 +50,4 @@
</ul>
</div><!--/.nav-collapse -->
</div>
</nav>
</nav>

View file

@ -176,7 +176,7 @@ class wvmCreate(wvmConnect):
graphics,
virtio,
listen_addr,
video="vga",
video="virtio",
console_pass="random",
mac=None,
qemu_ga=True,
@ -222,7 +222,8 @@ class wvmCreate(wvmConnect):
if caps["features"]:
xml += """<features>"""
if "acpi" in caps["features"]:
xml += """<acpi/>"""
#xml += """<acpi/>"""
xml += """<acpi/> <gic version='3'/>"""
if "apic" in caps["features"]:
xml += """<apic/>"""
if "pae" in caps["features"]:
@ -234,7 +235,8 @@ class wvmCreate(wvmConnect):
if vcpu_mode == "host-model":
xml += """<cpu mode='host-model'/>"""
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 == "":
pass
else:
@ -259,10 +261,14 @@ class wvmCreate(wvmConnect):
for volume in volumes:
disk_opts = ""
if volume["cache_mode"] is not None and volume["cache_mode"] != "default":
disk_opts += f"cache='{volume['cache_mode']}' "
if volume["io_mode"] is not None and volume["io_mode"] != "default":
disk_opts += f"io='{volume['io_mode']}' "
#if volume["cache_mode"] is not None and volume["cache_mode"] != "default":
if volume["cache_mode"] is not None or volume["cache_mode"] == "default":
#disk_opts += f"cache='{volume['cache_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":
disk_opts += f"discard='{volume['discard_mode']}' "
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":
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:
xml += """<disk type='file' device='cdrom'>
<driver name='qemu' type='raw'/>
@ -365,7 +376,7 @@ class wvmCreate(wvmConnect):
xml += """<input type='tablet'/>"""
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'/> """
if qemu_ga and virtio: