From e312fafc3caa2b5eedfca854c1c3962e88ac06b0 Mon Sep 17 00:00:00 2001 From: Retspen Date: Wed, 20 May 2015 16:44:30 +0300 Subject: [PATCH 1/4] User can change root password in instance --- dev/gstfsd | 53 +++++++++++++++++++++++++++++++ instances/templates/instance.html | 23 ++++++++++++++ instances/views.py | 24 +++++++++++++- templates/messages_block.html | 14 ++++++++ 4 files changed, 113 insertions(+), 1 deletion(-) create mode 100755 dev/gstfsd create mode 100644 templates/messages_block.html diff --git a/dev/gstfsd b/dev/gstfsd new file mode 100755 index 0000000..008223c --- /dev/null +++ b/dev/gstfsd @@ -0,0 +1,53 @@ +#!/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): + try: + # recive data + data = json.loads(self.request.recv(1024).strip()) + dom_name = data['vname'] + passwd_hash = data['passwd'] + + # GuestFS + gfs = guestfs.GuestFS (python_return_dict=True) + try: + gfs.add_domain(dom_name) + 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:" + passwd_hash + ":" + 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})) + + except Exception, e: + print "Exception wile receiving message: ", e + +server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler) +server.serve_forever() diff --git a/instances/templates/instance.html b/instances/templates/instance.html index c9811b1..6c82eb5 100644 --- a/instances/templates/instance.html +++ b/instances/templates/instance.html @@ -39,6 +39,8 @@ {% include 'errors_block.html' %} + {% include 'messages_block.html' %} +
@@ -215,6 +217,11 @@ {% trans "Console" %} +
  • + + {% trans "Root Password" %} + +
  • @@ -227,6 +234,22 @@ {% endifequal %}
    +
    +

    {% trans "You need shut down your instance and enter a new root password." %}

    +
    {% csrf_token %} +
    +
    + +
    +
    + {% ifequal status 5 %} + + {% else %} + + {% endifequal %} +
    +
    +
    diff --git a/instances/views.py b/instances/views.py index df48504..f7fccef 100644 --- a/instances/views.py +++ b/instances/views.py @@ -1,5 +1,7 @@ import time import json +import socket +import crypt from string import letters, digits from random import choice from bisect import insort @@ -261,6 +263,26 @@ def instance(request, compute_id, vname): conn.delete() 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} + + 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(msg) + if 'resize' in request.POST: vcpu = request.POST.get('vcpu', '') cur_vcpu = request.POST.get('cur_vcpu', '') @@ -298,7 +320,7 @@ def instance(request, compute_id, vname): conn.create_snapshot(name) msg = _("New snapshot") 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: snap_name = request.POST.get('name', '') diff --git a/templates/messages_block.html b/templates/messages_block.html new file mode 100644 index 0000000..cb2aef6 --- /dev/null +++ b/templates/messages_block.html @@ -0,0 +1,14 @@ +{% if messages %} + {% for message in messages %} + +
    +
    +
    + + Success: {{ message }} +
    +
    +
    + + {% endfor %} +{% endif %} \ No newline at end of file From 23b4d22a72fba8fb93a6be654c6a0a7bde0210a4 Mon Sep 17 00:00:00 2001 From: Retspen Date: Thu, 21 May 2015 11:52:10 +0300 Subject: [PATCH 2/4] Rebuilt bootstrap libvirt --- conf/daemon/gstfsd | 47 +++++++++++++++++++++ conf/supervisor/gstfsd.conf | 7 ++++ dev/gstfsd | 53 ----------------------- dev/libvirt-bootstrap.sh | 84 ++++++++++++++++++++++++++++++++++--- instances/views.py | 25 ++++++----- 5 files changed, 147 insertions(+), 69 deletions(-) create mode 100644 conf/daemon/gstfsd create mode 100644 conf/supervisor/gstfsd.conf delete mode 100755 dev/gstfsd diff --git a/conf/daemon/gstfsd b/conf/daemon/gstfsd new file mode 100644 index 0000000..ceb01cb --- /dev/null +++ b/conf/daemon/gstfsd @@ -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() diff --git a/conf/supervisor/gstfsd.conf b/conf/supervisor/gstfsd.conf new file mode 100644 index 0000000..2834b30 --- /dev/null +++ b/conf/supervisor/gstfsd.conf @@ -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 \ No newline at end of file diff --git a/dev/gstfsd b/dev/gstfsd deleted file mode 100755 index 008223c..0000000 --- a/dev/gstfsd +++ /dev/null @@ -1,53 +0,0 @@ -#!/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): - try: - # recive data - data = json.loads(self.request.recv(1024).strip()) - dom_name = data['vname'] - passwd_hash = data['passwd'] - - # GuestFS - gfs = guestfs.GuestFS (python_return_dict=True) - try: - gfs.add_domain(dom_name) - 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:" + passwd_hash + ":" - 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})) - - except Exception, e: - print "Exception wile receiving message: ", e - -server = MyTCPServer((ADDRESS, PORT), MyTCPServerHandler) -server.serve_forever() diff --git a/dev/libvirt-bootstrap.sh b/dev/libvirt-bootstrap.sh index 7877811..21e90be 100644 --- a/dev/libvirt-bootstrap.sh +++ b/dev/libvirt-bootstrap.sh @@ -375,7 +375,7 @@ __check_end_of_life_versions # install_centos() { 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 return 0 } @@ -401,6 +401,23 @@ install_centos_post() { echoerror "/etc/libvirt/qemu.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 + 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 return 0 } @@ -421,6 +438,14 @@ daemons_running_centos() { 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 } # @@ -433,7 +458,7 @@ daemons_running_centos() { # Fedora Install Functions # 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 } @@ -458,6 +483,14 @@ install_fedora_post() { 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 } @@ -470,6 +503,10 @@ daemons_running_fedora() { 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 } # @@ -482,7 +519,7 @@ daemons_running_fedora() { # Opensuse Install Functions # 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 } @@ -507,6 +544,14 @@ install_opensuse_post() { 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 } @@ -519,6 +564,10 @@ daemons_running_opensuse() { 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 } # @@ -532,7 +581,7 @@ daemons_running_opensuse() { # install_ubuntu() { 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 || return 1 return 0 } @@ -561,6 +610,14 @@ install_ubuntu_post() { echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 fi + if [ -f /etc/supervisor/supervisor.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 } @@ -570,6 +627,11 @@ daemons_running_ubuntu() { service libvirt-bin stop > /dev/null 2>&1 service libvirt-bin start fi + if [ -f /etc/supervisor/supervisord.conf ]; then + # Still in SysV init!? + service supervisor stop > /dev/null 2>&1 + service supervisor start + fi return 0 } # @@ -583,7 +645,7 @@ daemons_running_ubuntu() { # install_debian() { 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 } @@ -619,6 +681,14 @@ install_debian_post() { echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 fi + if [ -f /etc/supervisor/supervisor.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 } @@ -632,6 +702,10 @@ daemons_running_debian() { /etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1 /etc/init.d/$LIBVIRTSVC start fi + if [ -f /etc/supervisor/supervisord.conf ]; then + service supervisor stop > /dev/null 2>&1 + service supervisor start + fi return 0 } # diff --git a/instances/views.py b/instances/views.py index f7fccef..07a2720 100644 --- a/instances/views.py +++ b/instances/views.py @@ -269,19 +269,22 @@ def instance(request, compute_id, vname): passwd_hash = crypt.crypt(passwd, '$6$kgPoiREy') data = {'passwd': passwd_hash, 'vname': vname} - 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() + 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) - msg = _("Reset root password") - addlogmsg(request.user.username, instance.name, msg) - - if result['return'] == 'success': - messages.append(msg) + if result['return'] == 'success': + messages.append(msg) + else: + error_messages.append(msg) else: - error_messages(msg) + msg = _("Please shutdow down your instance and then try again") + error_messages.append(msg) if 'resize' in request.POST: vcpu = request.POST.get('vcpu', '') From b201399655167707ae61fc7b41d057063e339819 Mon Sep 17 00:00:00 2001 From: Retspen Date: Thu, 21 May 2015 15:01:06 +0300 Subject: [PATCH 3/4] Fixed some bugs --- dev/libvirt-bootstrap.sh | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/dev/libvirt-bootstrap.sh b/dev/libvirt-bootstrap.sh index 21e90be..4b31ee4 100644 --- a/dev/libvirt-bootstrap.sh +++ b/dev/libvirt-bootstrap.sh @@ -408,15 +408,17 @@ install_centos_post() { curl https://raw.githubusercontent.com/retspen/webvirtcloud/master/conf/supervisor/gstfsd.conf >> /etc/supervisor.conf else echoerror "Supervisor not found. Exiting..." - exit 1 - else: + 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 + exit 1 + fi fi return 0 } @@ -487,7 +489,7 @@ install_fedora_post() { 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: + else echoerror "Supervisor not found. Exiting..." exit 1 fi @@ -548,7 +550,7 @@ install_opensuse_post() { 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: + else echoerror "Supervisor not found. Exiting..." exit 1 fi @@ -581,7 +583,7 @@ daemons_running_opensuse() { # install_ubuntu() { apt-get update || return 1 - apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs || return 1 + apt-get -y install kvm libvirt-bin bridge-utils sasl2-bin python-guestfs supervisor || return 1 return 0 } @@ -610,11 +612,11 @@ install_ubuntu_post() { echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 fi - if [ -f /etc/supervisor/supervisor.conf ]; then + 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: + else echoerror "Supervisor not found. Exiting..." exit 1 fi @@ -627,7 +629,7 @@ daemons_running_ubuntu() { service libvirt-bin stop > /dev/null 2>&1 service libvirt-bin start fi - if [ -f /etc/supervisor/supervisord.conf ]; then + if [ -f /etc/init.d/supervisor ]; then # Still in SysV init!? service supervisor stop > /dev/null 2>&1 service supervisor start @@ -681,11 +683,11 @@ install_debian_post() { echoerror "/etc/libvirt/qemu.conf not found. Exiting..." exit 1 fi - if [ -f /etc/supervisor/supervisor.conf ]; then + 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: + else echoerror "Supervisor not found. Exiting..." exit 1 fi @@ -702,7 +704,7 @@ daemons_running_debian() { /etc/init.d/$LIBVIRTSVC stop > /dev/null 2>&1 /etc/init.d/$LIBVIRTSVC start fi - if [ -f /etc/supervisor/supervisord.conf ]; then + if [ -f /etc/init.d/supervisor ]; then service supervisor stop > /dev/null 2>&1 service supervisor start fi From e067982b515da99210972d67f740799b36c9d16b Mon Sep 17 00:00:00 2001 From: Retspen Date: Thu, 21 May 2015 15:07:55 +0300 Subject: [PATCH 4/4] Updated --- README.md | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 3109bb9..f391f67 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,13 @@ -## WebVirtCloud +## WebVirtCloud Beta + + +## Features + +* User can change root password (Test only Ubuntu) ### 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