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

Merge pull request #1 from retspen/master

sync
This commit is contained in:
savichev 2015-05-22 12:10:36 +05:00
commit 9d6cc70614
11 changed files with 216 additions and 19 deletions

View file

@ -1,8 +1,13 @@
## WebVirtCloud ## WebVirtCloud Beta
## Features
* User can change root password in Virtual Machine (Tested only Ubuntu)
### Description ### Description
WebVirtMgr is a libvirt-based Web interface for managing virtual machines for admins and users. It allows you to create and configure new domains, and adjust a domain's resource allocation. A noVNC viewer presents a full graphical console to the guest domain. KVM is currently the only hypervisor supported. WebVirtMgr is a libvirt-based Web interface for managing virtual machines. It can delegate Virtual Machine's to users. A noVNC viewer presents a full graphical console to the guest domain. KVM is currently the only hypervisor supported.
### Install WebVirtCloud panel ### Install WebVirtCloud panel
@ -29,7 +34,7 @@ sudo service supervisor restart
### Setup libvirt and KVM on server ### Setup libvirt and KVM on server
```bash ```bash
wget -O - https://clck.ru/9Sz6S | sudo sh wget -O - https://clck.ru/9V9fH | sudo sh
``` ```
### Default credentials ### Default credentials

47
conf/daemon/gstfsd Normal file
View file

@ -0,0 +1,47 @@
#!/usr/bin/env python
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
data = json.loads(self.request.recv(1024).strip())
# 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'):
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')
gfs.umount(part)
self.request.sendall(json.dumps({'return': 'success'}))
except RuntimeError:
pass
gfs.shutdown()
gfs.close()
except RuntimeError, err:
self.request.sendall(json.dumps({'return': 'error', 'message': err.message}))
server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler)
server.serve_forever()

3
conf/requirements.txt Normal file
View file

@ -0,0 +1,3 @@
Django==1.8.1
websockify==0.6.0
gunicorn==19.3.0

View file

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

View file

@ -3,13 +3,13 @@
# vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=81 # vim: softtabstop=4 shiftwidth=4 expandtab fenc=utf-8 spell spelllang=en cc=81
#=============================================================================== #===============================================================================
# #
# FILE: bootstrap-webvirtmgr.sh # FILE: libvirt-bootstrap.sh
# #
# DESCRIPTION: Bootstrap webvirtmgr installation for various distributions # DESCRIPTION: Bootstrap webvirtmgr installation for various distributions
# #
# BUGS: https://github.com/retspen/webvirtmgr-boostrap/issues # BUGS: https://github.com/retspen/webvirtmgr/issues
# #
# COPYRIGHT: (c) 2013 by the WebVirtMgr Team # COPYRIGHT: (c) 2015 by the WebVirtMgr Team
# #
# LICENSE: Apache 2.0 # LICENSE: Apache 2.0
# ORGANIZATION: WebVirtMgr (webvirtmgr.net) # ORGANIZATION: WebVirtMgr (webvirtmgr.net)
@ -375,7 +375,7 @@ __check_end_of_life_versions
# #
install_centos() { install_centos() {
if [ $DISTRO_MAJOR_VERSION -ge 6 ]; then if [ $DISTRO_MAJOR_VERSION -ge 6 ]; then
yum -y install qemu-kvm libvirt bridge-utils || return 1 yum -y install qemu-kvm libvirt bridge-utils python-libguestfs supervisor || return 1
fi fi
return 0 return 0
} }
@ -401,6 +401,25 @@ install_centos_post() {
echoerror "/etc/libvirt/qemu.conf not found. Exiting..." echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1 exit 1
fi 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/supervisor.d/gstfsd.ini
else
echoerror "Supervisor not found. Exiting..."
exit 1
fi
fi
return 0 return 0
} }
@ -421,6 +440,14 @@ daemons_running_centos() {
systemctl stop libvirt-guests.service > /dev/null 2>&1 systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service systemctl start libvirt-guests.service
fi 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 return 0
} }
# #
@ -433,7 +460,7 @@ daemons_running_centos() {
# Fedora Install Functions # Fedora Install Functions
# #
install_fedora() { install_fedora() {
yum -y install kvm libvirt bridge-utils || return 1 yum -y install kvm libvirt bridge-utils python-libguestfs supervisor || return 1
return 0 return 0
} }
@ -458,6 +485,14 @@ install_fedora_post() {
echoerror "/etc/libvirt/qemu.conf not found. Exiting..." echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1 exit 1
fi 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 return 0
} }
@ -470,6 +505,10 @@ daemons_running_fedora() {
systemctl stop libvirt-guests.service > /dev/null 2>&1 systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service systemctl start libvirt-guests.service
fi 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 return 0
} }
# #
@ -482,7 +521,7 @@ daemons_running_fedora() {
# Opensuse Install Functions # Opensuse Install Functions
# #
install_opensuse() { install_opensuse() {
zypper -n install -l kvm libvirt bridge-utils || return 1 zypper -n install -l kvm libvirt bridge-utils python-libguestfs supervisor || return 1
return 0 return 0
} }
@ -507,6 +546,14 @@ install_opensuse_post() {
echoerror "/etc/libvirt/qemu.conf not found. Exiting..." echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1 exit 1
fi 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 return 0
} }
@ -519,6 +566,10 @@ daemons_running_opensuse() {
systemctl stop libvirt-guests.service > /dev/null 2>&1 systemctl stop libvirt-guests.service > /dev/null 2>&1
systemctl start libvirt-guests.service systemctl start libvirt-guests.service
fi 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 return 0
} }
# #
@ -532,7 +583,7 @@ daemons_running_opensuse() {
# #
install_ubuntu() { install_ubuntu() {
apt-get update || return 1 apt-get update || return 1
apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin || return 1 apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1
return 0 return 0
} }
@ -561,6 +612,14 @@ install_ubuntu_post() {
echoerror "/etc/libvirt/qemu.conf not found. Exiting..." echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1 exit 1
fi 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 return 0
} }
@ -570,6 +629,11 @@ daemons_running_ubuntu() {
service libvirt-bin stop > /dev/null 2>&1 service libvirt-bin stop > /dev/null 2>&1
service libvirt-bin start service libvirt-bin start
fi 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 return 0
} }
# #
@ -583,7 +647,7 @@ daemons_running_ubuntu() {
# #
install_debian() { install_debian() {
apt-get update || return 1 apt-get update || return 1
apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin || return 1 apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1
return 0 return 0
} }
@ -619,6 +683,14 @@ install_debian_post() {
echoerror "/etc/libvirt/qemu.conf not found. Exiting..." echoerror "/etc/libvirt/qemu.conf not found. Exiting..."
exit 1 exit 1
fi 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 return 0
} }
@ -632,6 +704,10 @@ daemons_running_debian() {
/etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1 /etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1
/etc/init.d/$LIBVIRTSVC start /etc/init.d/$LIBVIRTSVC start
fi fi
if [ -f /etc/init.d/supervisor ]; then
service supervisor stop > /dev/null 2>&1
service supervisor start
fi
return 0 return 0
} }
# #

View file

@ -1,4 +1,4 @@
-r ../requirements.txt -r ../conf/requirements.txt
pep8==1.6.2 pep8==1.6.2
pyflakes==0.8.1 pyflakes==0.8.1
pylint==1.4.3 pylint==1.4.3

View file

@ -39,6 +39,8 @@
<!-- /.row --> <!-- /.row -->
{% include 'errors_block.html' %} {% include 'errors_block.html' %}
{% include 'messages_block.html' %}
<div class="row" id="max-width-page"> <div class="row" id="max-width-page">
<div class="col-lg-12"> <div class="col-lg-12">
@ -215,6 +217,11 @@
{% trans "Console" %} {% trans "Console" %}
</a> </a>
</li> </li>
<li role="presentation">
<a href="#rootpasswd" aria-controls="rootpasswd" role="tab" data-toggle="tab">
{% trans "Root Password" %}
</a>
</li>
</ul> </ul>
<!-- Tab panes --> <!-- Tab panes -->
<div class="tab-content"> <div class="tab-content">
@ -227,6 +234,22 @@
{% endifequal %} {% endifequal %}
<div class="clearfix"></div> <div class="clearfix"></div>
</div> </div>
<div role="tabpanel" class="tab-pane tab-pane-bordered" id="rootpasswd">
<p>{% trans "You need shut down your instance and enter a new root password." %}</p>
<form class="form-inline" method="post" role="form">{% csrf_token %}
<div class="form-group">
<div class="col-sm-12">
<input type="text" class="form-control input-lg" name="passwd" placeholder="{% trans "Enter Password" %}" maxlength="24">
</div>
</div>
{% ifequal status 5 %}
<input type="submit" class="btn btn-lg btn-success pull-right" name="rootpasswd" value="{% trans "Reset Root Password" %}">
{% else %}
<button class="btn btn-lg btn-success pull-right disabled">{% trans "Reset Root Password" %}</button>
{% endifequal %}
</form>
<div class="clearfix"></div>
</div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -203,7 +203,7 @@
<button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')"> <button class="btn btn-sm btn-default" type="submit" name="powercycle" title="{% trans "Power Cycle" %}" onclick="return confirm('Are you sure?')">
<span class="glyphicon glyphicon-refresh"></span> <span class="glyphicon glyphicon-refresh"></span>
</button> </button>
<a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ host.0 }}-{{ vm.uuid }}")' title="{% trans "Console" %}"> <a href="#" class="btn btn-sm btn-default" onclick='open_console("{{ vm.compute_id }}-{{ vm.uuid }}")' title="{% trans "Console" %}">
<span class="glyphicon glyphicon-eye-open"></span> <span class="glyphicon glyphicon-eye-open"></span>
</a> </a>
{% endifequal %} {% endifequal %}

View file

@ -1,5 +1,7 @@
import time import time
import json import json
import socket
import crypt
from string import letters, digits from string import letters, digits
from random import choice from random import choice
from bisect import insort from bisect import insort
@ -45,7 +47,7 @@ def instances(request):
computes = Compute.objects.all() computes = Compute.objects.all()
if not request.user.is_superuser: if not request.user.is_superuser:
user_instances = UserInstance.objects.all() user_instances = UserInstance.objects.filter(user_id=request.user.id)
for usr_inst in user_instances: for usr_inst in user_instances:
if connection_manager.host_is_up(usr_inst.instance.compute.type, if connection_manager.host_is_up(usr_inst.instance.compute.type,
usr_inst.instance.compute.hostname): usr_inst.instance.compute.hostname):
@ -261,6 +263,29 @@ def instance(request, compute_id, vname):
conn.delete() conn.delete()
return HttpResponseRedirect(reverse('instances')) return HttpResponseRedirect(reverse('instances'))
if 'rootpasswd' in request.POST:
passwd = request.POST.get('passwd', '')
passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy')
data = {'passwd': passwd_hash, 'vname': vname}
if conn.get_status() == 5:
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((compute.hostname, 16510))
s.send(json.dumps(data))
result = json.loads(s.recv(1024))
s.close()
msg = _("Reset root password")
addlogmsg(request.user.username, instance.name, msg)
if result['return'] == 'success':
messages.append(msg)
else:
error_messages.append(msg)
else:
msg = _("Please shutdow down your instance and then try again")
error_messages.append(msg)
if 'resize' in request.POST: if 'resize' in request.POST:
vcpu = request.POST.get('vcpu', '') vcpu = request.POST.get('vcpu', '')
cur_vcpu = request.POST.get('cur_vcpu', '') cur_vcpu = request.POST.get('cur_vcpu', '')
@ -298,7 +323,7 @@ def instance(request, compute_id, vname):
conn.create_snapshot(name) conn.create_snapshot(name)
msg = _("New snapshot") msg = _("New snapshot")
addlogmsg(request.user.username, instance.name, msg) addlogmsg(request.user.username, instance.name, msg)
return HttpResponseRedirect(request.get_full_path() + '#takesnapshot') return HttpResponseRedirect(request.get_full_path() + '#restoresnapshot')
if 'delete_snapshot' in request.POST: if 'delete_snapshot' in request.POST:
snap_name = request.POST.get('name', '') snap_name = request.POST.get('name', '')

View file

@ -1,3 +0,0 @@
Django==1.8
websockify==0.6.0
gunicorn==19.3.0

View file

@ -0,0 +1,14 @@
{% if messages %}
{% for message in messages %}
<!-- Success Messages -->
<div class="row">
<div class="col-lg-12">
<div class="alert alert-success alert-dismissible" role="susses">
<button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<strong>Success:</strong> {{ message }}
</div>
</div>
</div>
<!-- /.row -->
{% endfor %}
{% endif %}