mirror of
https://github.com/retspen/webvirtcloud
synced 2026-03-21 18:14:51 +00:00
dev
This commit is contained in:
parent
cd798eb9b7
commit
156cfb40dd
22 changed files with 1069 additions and 319 deletions
18
Dockerfile
18
Dockerfile
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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 %}
|
||||
|
|
|
|||
|
|
@ -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
6
genpass.sh
Executable 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
59
gstfsd
Normal 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
7
gstfsd.conf
Normal 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
|
||||
|
|
@ -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')})
|
||||
|
|
|
|||
|
|
@ -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'),
|
||||
)
|
||||
|
|
|
|||
|
|
@ -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
821
libvirt-bootstrap.sh
Normal 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.
|
|
@ -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
4
sources.list
Normal 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
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue