From e25535e64c94c1de6dc67f6c5cdde2409ef38efb Mon Sep 17 00:00:00 2001 From: Suman Chakravartula Date: Thu, 2 Jul 2015 21:10:13 -0700 Subject: [PATCH] refactor update and install. #697 --- src/rockstor/storageadmin/views/rockon.py | 33 ++++++++------ .../storageadmin/views/rockon_helpers.py | 43 +++++++++++++------ src/rockstor/storageadmin/views/rockon_id.py | 38 ++++++---------- .../storageadmin/views/rockon_json.py | 11 ++--- .../storageadmin/views/serializers.py | 29 ------------- 5 files changed, 68 insertions(+), 86 deletions(-) delete mode 100644 src/rockstor/storageadmin/views/serializers.py diff --git a/src/rockstor/storageadmin/views/rockon.py b/src/rockstor/storageadmin/views/rockon.py index 72879b727..79e9f03b3 100644 --- a/src/rockstor/storageadmin/views/rockon.py +++ b/src/rockstor/storageadmin/views/rockon.py @@ -123,34 +123,39 @@ def post(self, request, command=None): ports = containers[c]['ports'] for p in ports.keys(): p_d = ports[p] + p = int(p) po = None - if (DPort.objects.filter(hostp=p).exists()): - po = DPort.objects.get(hostp=p) - po.container = co - po.containerp_default = p_d['default'] - po.description = p_d['description'] - po.uiport = p_d['ui'] - po.protocol = p_d['protocol'] - po.label = p_d['label'] - elif (DPort.objects.filter(containerp=p, container=co).exists()): + if (DPort.objects.filter(containerp=p, container=co).exists()): po = DPort.objects.get(containerp=p, container=co) - po.hostp = p - po.containerp_default = p_d['default'] + po.hostp_default = p_d['host_default'] po.description = p_d['description'] po.uiport = p_d['ui'] + if (po.uiport): + ro.ui = True + ro.save() po.protocol = p_d['protocol'] po.label = p_d['label'] else: + #let's find next available default if default is already taken + def_hostp = p_d['host_default'] + while (True): + if (DPort.objects.filter(hostp=def_hostp).exists()): + def_hostp += 1 + else: + break po = DPort(description=p_d['description'], - hostp=p, containerp=p_d['default'], - containerp_default=p_d['default'], + hostp=def_hostp, containerp=p, + hostp_default=def_hostp, container=co, uiport=p_d['ui'], protocol=p_d['protocol'], label=p_d['label']) + if (po.uiport): + ro.ui = True + ro.save() po.save() else: ports = {} - ports = [int(p) for p in ports.keys()] + ports = [int(p) for p in ports] for po in DPort.objects.filter(container=co): if (po.containerp not in ports): po.delete() diff --git a/src/rockstor/storageadmin/views/rockon_helpers.py b/src/rockstor/storageadmin/views/rockon_helpers.py index 8869bbb64..afd7a9d34 100644 --- a/src/rockstor/storageadmin/views/rockon_helpers.py +++ b/src/rockstor/storageadmin/views/rockon_helpers.py @@ -16,6 +16,7 @@ along with this program. If not, see . """ +import time from system.osi import run_command from django.conf import settings from django_ztask.decorators import task @@ -44,9 +45,12 @@ def mount_share(name, mnt): btrfs.mount_share(share, disk, mnt) def rockon_status(name): + ro = RockOn.objects.get(name=name) state = 'unknown error' + co = DContainer.objects.filter(rockon=ro).order_by('-launch_order')[0] try: - o, e, rc = run_command([DOCKER, 'inspect', '-f', '{{range $key, $value := .State}}{{$key}}:{{$value}},{{ end }}', name]) + o, e, rc = run_command([DOCKER, 'inspect', '-f', + '{{range $key, $value := .State}}{{$key}}:{{$value}},{{ end }}', co.name]) state_d = {} for i in o[0].split(','): fields = i.split(':') @@ -94,12 +98,11 @@ def stop(rid): new_status = 'stopped' try: rockon = RockOn.objects.get(id=rid) - run_command([DOCKER, 'stop', rockon.name]) - if (rockon.name == 'OpenVPN'): - run_command([DOCKER, 'stop', 'ovpn-data']) - if (rockon.name == 'OwnCloud'): - run_command([DOCKER, 'stop', 'owncloud-postgres']) - except: + for c in DContainer.objects.filter(rockon=rockon).order_by('-launch_order'): + run_command([DOCKER, 'stop', c.name]) + except Exception, e: + logger.debug('exception while stopping the rockon(%s)' % rid) + logger.exception(e) new_status = 'stop_failed' finally: url = ('%s/%d/status_update' % (ROCKON_URL, rid)) @@ -144,11 +147,8 @@ def install(rid): def uninstall(rid, new_state='available'): try: rockon = RockOn.objects.get(id=rid) - rm_container(rockon.name) - if (rockon.name == 'OpenVPN'): - rm_container('ovpn-data') - if (rockon.name == 'OwnCloud'): - rm_container('owncloud-postgres') + for c in DContainer.objects.filter(rockon=rockon): + rm_container(c.name) except Exception, e: logger.debug('exception while uninstalling rockon') logger.exception(e) @@ -286,9 +286,9 @@ def owncloud_install(rockon): for c in DContainer.objects.filter(rockon=rockon).order_by('launch_order'): cmd = [DOCKER, 'run', '-d', '--name', c.name, ] + db_user = DCustomConfig.objects.get(rockon=rockon, key='db_user').val + db_pw = DCustomConfig.objects.get(rockon=rockon, key='db_pw').val if (c.dimage.name == 'postgres'): - db_user = DCustomConfig.objects.get(rockon=rockon, key='db_user') - db_pw = DCustomConfig.objects.get(rockon=rockon, key='db_pw') cmd.extend(['-e', 'POSTGRES_USER=%s' % db_user, '-e', 'POSTGRES_PASSWORD=%s' % db_pw]) for po in DPort.objects.filter(container=c): @@ -305,6 +305,21 @@ def owncloud_install(rockon): cmd.extend(['-v', '%s/rockstor.key:/etc/ssl/private/owncloud.key' % settings.CERTDIR, '-v', '%s/rockstor.cert:/etc/ssl/certs/owncloud.crt' % settings.CERTDIR, '-e', 'HTTPS_ENABLED=true']) + cmd.extend(['-e', 'DB_USER=%s' % db_user, '-e', 'DB_PASS=%s' % db_pw,]) cmd.append(c.dimage.name) logger.debug('docker cmd = %s' % cmd) run_command(cmd) + if (c.dimage.name == 'postgres'): + #make sure postgres is setup + cur_wait = 0; + while (True): + o, e, rc = run_command([DOCKER, 'exec', c.name, 'psql', '-U', + 'postgres', '-c', "\l"], throw=False) + if (rc == 0): + break + if (cur_wait > 300): + logger.error('Waited too long(300 seconds) for ' + 'postgres to initialize for owncloud. giving up.') + break + time.sleep(1) + cur_wait += 1 diff --git a/src/rockstor/storageadmin/views/rockon_id.py b/src/rockstor/storageadmin/views/rockon_id.py index 932554a15..130cc8e90 100644 --- a/src/rockstor/storageadmin/views/rockon_id.py +++ b/src/rockstor/storageadmin/views/rockon_id.py @@ -98,32 +98,22 @@ def post(self, request, rid, command): dest_dir=s) vo.share = so vo.save() + # {'host_port' : 'container_port', ... } for p in port_map.keys(): - if (not DPort.objects.filter(containerp=p).exists()): - e_msg = ('Invalid Port(%s).' % p) - handle_exception(Exception(e_msg), request) - po = DPort.objects.get(containerp=p) - if (po.hostp != port_map[p] and - DPort.objects.filter(Q(hostp=port_map[p]) & ~Q(id=po.id)).exists()): - opo = DPort.objects.filter(Q(hostp=port_map[p]) & ~Q(id=po.id))[0] - if (opo.container.rockon.state != 'available' or - opo.hostp == opo.containerp): - e_msg = ('Rockstor port(%s) is dedicated ' - 'to another rockon(%s) and cannot' - ' be changed. ' - 'Choose a different one' % - (port_map[p], opo.container.rockon.name)) + if (DPort.objects.filter(hostp=p).exists()): + po = DPort.objects.get(hostp=p) + if (po.container.rockon.id != rockon.id): + e_msg = ('Rockon port(%s) is dedicated to ' + 'another Rock-On(%s) and cannot ' + 'be changed. Choose a different name' + % (p, po.container.rockon.name)) handle_exception(Exception(e_msg), request) - else: - opo.hostp = opo.containerp - opo.save() - po.hostp = port_map[p] - po.save() - if (po.uiport is True and rockon.link is not None): - if (len(rockon.link) > 0 and rockon.link[0] != ':'): - rockon.link = (':%s/%s' % (po.hostp, rockon.link)) - else: - rockon.link = (':%s' % po.hostp) + else: + for co2 in DContainer.objects.filter(rockon=rockon): + if (DPort.objects.filter(container=co2, containerp=port_map[p]).exists()): + po = DPort.objects.get(container=co2, containerp=port_map[p]) + po.hostp = p + po.save() for c in cc_map.keys(): if (not DCustomConfig.objects.filter(rockon=rockon, key=c).exists()): e_msg = ('Invalid custom config key(%s)' % c) diff --git a/src/rockstor/storageadmin/views/rockon_json.py b/src/rockstor/storageadmin/views/rockon_json.py index 451b625a2..c2bea1b0f 100644 --- a/src/rockstor/storageadmin/views/rockon_json.py +++ b/src/rockstor/storageadmin/views/rockon_json.py @@ -43,11 +43,12 @@ 'OwnCloud': {'ui': {'slug': '', 'https': True,}, 'containers': {'owncloud': {'image': 'pschmitt/owncloud', - 'ports': {'443': {'ui': True, - 'default': 8080, - 'protocol': 'tcp', - 'label': 'UI port', - 'description': 'OwnCloud UI port. Since Rockstor WebUI runs on 443, choose a different port or the suggested default.',},}, + 'ports': {'443': + {'ui': True, + 'host_default': 8080, + 'protocol': 'tcp', + 'label': 'UI port', + 'description': 'OwnCloud UI port. Since Rockstor WebUI runs on 443, choose a different port or the suggested default.',},}, 'volumes': {'/var/www/owncloud/data': {'description': 'Choose a dedicated Share for OwnCloud data. Eg: create a Share called owncloud-data for this purpose alone.', 'min_size': 1073741824, diff --git a/src/rockstor/storageadmin/views/serializers.py b/src/rockstor/storageadmin/views/serializers.py deleted file mode 100644 index c7a0cde07..000000000 --- a/src/rockstor/storageadmin/views/serializers.py +++ /dev/null @@ -1,29 +0,0 @@ -""" -Copyright (c) 2012-2013 RockStor, Inc. -This file is part of RockStor. - -RockStor is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published -by the Free Software Foundation; either version 2 of the License, -or (at your option) any later version. - -RockStor 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 -General Public License for more details. - -You should have received a copy of the GNU General Public License -along with this program. If not, see . -""" - -from rest_framework import serializers -from storageadmin.models import (Disk, Pool,) - - -class DiskInfoSerializer(serializers.ModelSerializer): - class Meta: - model = Disk - -class PoolInfoSerializer(serializers.ModelSerializer): - class Meta: - model = Pool