def post(self, request, rid, command): with self._handle_exception(request): if (not docker_status()): e_msg = ('Docker service is not running. Start it and try ' 'again.') handle_exception(Exception(e_msg), request) try: rockon = RockOn.objects.get(id=rid) except: e_msg = ('Rock-on(%d) does not exist' % rid) handle_exception(Exception(e_msg), request) try: dname = 'ztask-daemon' e_msg = ('ztask daemon is not running and could not be ' 'started') o, e, rc = superctl(dname, 'status') if (rc == 1): superctl(dname, 'restart') time.sleep(5) except Exception as e: logger.exception(e) handle_exception(Exception(e_msg), request) finally: if (rc == 1): o, e, rc = superctl(dname, 'status') if (rc == 1): handle_exception(Exception(e_msg), request) if (command == 'install'): self._pending_check(request) share_map = request.data.get('shares', {}) port_map = request.data.get('ports', {}) cc_map = request.data.get('cc', {}) env_map = request.data.get('environment', {}) containers = DContainer.objects.filter(rockon=rockon) for co in containers: for sname in share_map.keys(): dest_dir = share_map[sname] if (not Share.objects.filter(name=sname).exists()): e_msg = ('Invalid Share(%s).' % sname) handle_exception(Exception(e_msg), request) if (DVolume.objects.filter( container=co, dest_dir=dest_dir).exists()): so = Share.objects.get(name=sname) vo = DVolume.objects.get(container=co, dest_dir=dest_dir) vo.share = so vo.save() # {'host_port' : 'container_port', ... } for p in port_map.keys(): if (DPort.objects.filter(hostp=p).exists()): dup_po = DPort.objects.get(hostp=p) if (dup_po.container.rockon.id != rockon.id): if (dup_po.container.rockon.state in ('installed', 'pending_install')): # cannot claim from a rock-on that's # installed. conf_ro = dup_po.container.rockon.name e_msg = ( 'Port(%s) belongs to another ' 'Rock-n(%s). Choose a different ' 'port. If you must choose the same ' 'port, uninstall %s first and try ' 'again.' % (p, conf_ro, conf_ro)) handle_exception(Exception(e_msg), request) # change the host port to next available. dup_po.hostp = self._next_available_default_hostp( dup_po.hostp) # noqa E501 dup_po.save() for co2 in DContainer.objects.filter(rockon=rockon): if (DPort.objects.filter( container=co2, containerp=port_map[p]).exists()): # found the container that needs this port. po = DPort.objects.get(container=co2, containerp=port_map[p]) po.hostp = p po.save() break for c in cc_map.keys(): if (not DCustomConfig.objects.filter(rockon=rockon, key=c).exists()): e_msg = ('Invalid custom config key(%s)' % c) handle_exception(Exception(e_msg), request) cco = DCustomConfig.objects.get(rockon=rockon, key=c) cco.val = cc_map[c] cco.save() for e in env_map.keys(): if (not DContainerEnv.objects.filter(container=co, key=e).exists()): e_msg = ('Invalid environment variabled(%s)' % e) handle_exception(Exception(e_msg), request) ceo = DContainerEnv.objects.get(container=co, key=e) ceo.val = env_map[e] ceo.save() install. async (rockon.id) rockon.state = 'pending_install' rockon.save() elif (command == 'uninstall'): self._pending_check(request) if (rockon.state != 'installed'): e_msg = ('Rock-on(%s) is not currently installed. Cannot ' 'uninstall it' % rockon.name) handle_exception(Exception(e_msg), request) if (rockon.status == 'started' or rockon.status == 'pending_start'): e_msg = ('Rock-on(%s) must be stopped before it can ' 'be uninstalled. Stop it and try again' % rockon.name) handle_exception(Exception(e_msg), request) uninstall. async (rockon.id) rockon.state = 'pending_uninstall' rockon.save() for co in DContainer.objects.filter(rockon=rockon): DVolume.objects.filter(container=co, uservol=True).delete() elif (command == 'update'): self._pending_check(request) if (rockon.state != 'installed'): e_msg = ('Rock-on(%s) is not currently installed. Cannot ' 'update it' % rockon.name) handle_exception(Exception(e_msg), request) if (rockon.status == 'started' or rockon.status == 'pending_start'): e_msg = ('Rock-on(%s) must be stopped before it can ' 'be updated. Stop it and try again' % rockon.name) handle_exception(Exception(e_msg), request) share_map = request.data.get('shares') for co in DContainer.objects.filter(rockon=rockon): for s in share_map.keys(): sname = share_map[s] if (not Share.objects.filter(name=sname).exists()): e_msg = ('Invalid Share(%s).' % sname) handle_exception(Exception(e_msg), request) so = Share.objects.get(name=sname) if (DVolume.objects.filter(container=co, share=so).exists()): e_msg = ('Share(%s) is already assigned to ' 'this Rock-on' % sname) handle_exception(Exception(e_msg), request) if (DVolume.objects.filter(container=co, dest_dir=s).exists()): e_msg = ('Directory(%s) is already mapped for ' 'this Rock-on' % s) handle_exception(Exception(e_msg), request) if (not s.startswith('/')): e_msg = ('Invalid Directory(%s). Must provide an ' 'absolute path. Eg: /data/media' % s) handle_exception(Exception(e_msg), request) do = DVolume(container=co, share=so, uservol=True, dest_dir=s) do.save() rockon.state = 'pending_update' rockon.save() update. async (rockon.id) elif (command == 'stop'): stop. async (rockon.id) rockon.status = 'pending_stop' rockon.save() elif (command == 'start'): start. async (rockon.id) rockon.status = 'pending_start' rockon.save() elif (command == 'state_update'): state = request.data.get('new_state') rockon.state = state rockon.save() elif (command == 'status_update'): status = request.data.get('new_status') rockon.status = status rockon.save() return Response(RockOnSerializer(rockon).data)
def post(self, request, rid, command): with self._handle_exception(request): if not docker_status(): e_msg = "Docker service is not running. Start it and try again." handle_exception(Exception(e_msg), request) try: rockon = RockOn.objects.get(id=rid) except: e_msg = "Rock-on ({}) does not exist.".format(rid) handle_exception(Exception(e_msg), request) try: dname = "ztask-daemon" e_msg = "ztask daemon is not running and could not be started." o, e, rc = superctl(dname, "status") if rc == 1: superctl(dname, "restart") time.sleep(5) except Exception as e: logger.exception(e) handle_exception(Exception(e_msg), request) finally: if rc == 1: o, e, rc = superctl(dname, "status") if rc == 1: handle_exception(Exception(e_msg), request) if command == "install": self._pending_check(request) share_map = request.data.get("shares", {}) port_map = request.data.get("ports", {}) dev_map = request.data.get("devices", {}) cc_map = request.data.get("cc", {}) env_map = request.data.get("environment", {}) containers = DContainer.objects.filter(rockon=rockon) for co in containers: for sname in share_map.keys(): dest_dir = share_map[sname] if not Share.objects.filter(name=sname).exists(): e_msg = "Invalid share ({}).".format(sname) handle_exception(Exception(e_msg), request) if DVolume.objects.filter(container=co, dest_dir=dest_dir).exists(): so = Share.objects.get(name=sname) vo = DVolume.objects.get(container=co, dest_dir=dest_dir) vo.share = so vo.save() # {'host_port' : 'container_port', ... } for p in port_map.keys(): if DPort.objects.filter(hostp=p).exists(): dup_po = DPort.objects.get(hostp=p) if dup_po.container.rockon.id != rockon.id: if dup_po.container.rockon.state in ( "installed", "pending_install", ): # cannot claim from a rock-on that's # installed. conf_ro = dup_po.container.rockon.name e_msg = ( "Port ({}) belongs to another " "rock-on ({}). Choose a different " "port. If you must choose the same " "port, uninstall ({}) first and try " "again.").format(p, conf_ro, conf_ro) handle_exception(Exception(e_msg), request) # change the host port to next available. dup_po.hostp = self._next_available_default_hostp( dup_po.hostp) # noqa E501 dup_po.save() for co2 in DContainer.objects.filter(rockon=rockon): if DPort.objects.filter( container=co2, containerp=port_map[p]).exists(): # found the container that needs this port. po = DPort.objects.get(container=co2, containerp=port_map[p]) po.hostp = p po.save() break for d in dev_map.keys(): if not DContainerDevice.objects.filter(container=co, dev=d).exists(): e_msg = ("Invalid device variable ({}).").format(d) handle_exception(Exception(e_msg), request) cdo = DContainerDevice.objects.get(container=co, dev=d) cdo.val = dev_map[d] cdo.save() for c in cc_map.keys(): if not DCustomConfig.objects.filter(rockon=rockon, key=c).exists(): e_msg = "Invalid custom config key ({}).".format(c) handle_exception(Exception(e_msg), request) cco = DCustomConfig.objects.get(rockon=rockon, key=c) cco.val = cc_map[c] cco.save() for e in env_map.keys(): if not DContainerEnv.objects.filter(container=co, key=e).exists(): e_msg = ( "Invalid environment variable ({}).").format(e) handle_exception(Exception(e_msg), request) ceo = DContainerEnv.objects.get(container=co, key=e) ceo.val = env_map[e] ceo.save() install. async (rockon.id) rockon.state = "pending_install" rockon.save() elif command == "uninstall": self._pending_check(request) if rockon.state != "installed": e_msg = ("Rock-on ({}) is not currently installed. Cannot " "uninstall it.").format(rockon.name) handle_exception(Exception(e_msg), request) if rockon.status == "started" or rockon.status == "pending_start": e_msg = ("Rock-on ({}) must be stopped before it can " "be uninstalled. Stop it and " "try again.").format(rockon.name) handle_exception(Exception(e_msg), request) uninstall. async (rockon.id) rockon.state = "pending_uninstall" rockon.save() for co in DContainer.objects.filter(rockon=rockon): DVolume.objects.filter(container=co, uservol=True).delete() DContainerLabel.objects.filter(container=co).delete() DContainerNetwork.objects.filter(container=co).delete() for lo in DContainerLink.objects.filter(destination=co): dnet_remove(network=lo.name) # Reset all ports to a published state (if any) for po in DPort.objects.filter(container=co): po.publish = True po.save() elif command == "update": self._pending_check(request) if rockon.state != "installed": e_msg = ( "Rock-on ({}) is not currently installed. Cannot update it." ).format(rockon.name) handle_exception(Exception(e_msg), request) if rockon.status == "started" or rockon.status == "pending_start": e_msg = ("Rock-on ({}) must be stopped before it can " "be updated. Stop it and " "try again.").format(rockon.name) handle_exception(Exception(e_msg), request) share_map = request.data.get("shares") label_map = request.data.get("labels") ports_publish = request.data.get("edit_ports") cnets_map = request.data.get("cnets") update_mode = request.data.get("update_mode") live = False if request.data.get("update_mode") == "live": live = True if bool(share_map): for co in DContainer.objects.filter(rockon=rockon): for s in share_map.keys(): sname = share_map[s] if not Share.objects.filter(name=sname).exists(): e_msg = "Invalid share ({}).".format(sname) handle_exception(Exception(e_msg), request) so = Share.objects.get(name=sname) if DVolume.objects.filter(container=co, share=so).exists(): e_msg = ( "Share ({}) is already assigned to this rock-on." ).format(sname) handle_exception(Exception(e_msg), request) if DVolume.objects.filter(container=co, dest_dir=s).exists(): e_msg = ( "Directory ({}) is already mapped for " "this rock-on.").format(s) handle_exception(Exception(e_msg), request) if not s.startswith("/"): e_msg = ( "Invalid directory ({}). Must provide an " "absolute path. Eg: " "(/data/media).").format(s) handle_exception(Exception(e_msg), request) do = DVolume(container=co, share=so, uservol=True, dest_dir=s) do.save() if bool(label_map): for co in DContainer.objects.filter(rockon=rockon): for c in label_map.keys(): cname = label_map[c] coname = co.name if cname != coname: continue lo = DContainerLabel(container=co, key=cname, val=c) lo.save() if (update_mode == "normal") and bool(ports_publish): for p in ports_publish.keys(): po = DPort.objects.get(id=p) pub = ports_publish[p] po.publish = True if pub == "unchecked": po.publish = False po.save() if bool(update_mode): # Reset all existing rocknets for co in DContainer.objects.filter(rockon=rockon): for cno in DContainerNetwork.objects.filter( container=co.id): dnet_disconnect(co.name, cno.connection.docker_name) DContainerNetwork.objects.filter(container=co).delete() # Create new one(s) if bool(cnets_map): for c in cnets_map.keys(): # Create new entries for updated rocknets settings for net in cnets_map[c]: if not BridgeConnection.objects.filter( docker_name=net).exists(): dnet_create(network=net) self._refresh_connections() brco = BridgeConnection.objects.get( docker_name=net) co = DContainer.objects.get(rockon=rockon, name=c) cno = DContainerNetwork(container=co, connection=brco) cno.save() rockon.state = "pending_update" rockon.save() update. async (rockon.id, live=live) elif command == "stop": stop. async (rockon.id) rockon.status = "pending_stop" rockon.save() elif command == "start": start. async (rockon.id) rockon.status = "pending_start" rockon.save() elif command == "state_update": state = request.data.get("new_state") rockon.state = state rockon.save() elif command == "status_update": status = request.data.get("new_status") rockon.status = status rockon.save() return Response(RockOnSerializer(rockon).data)
def post(self, request, command=None): with self._handle_exception(request): if (not docker_status()): e_msg = ('Rock-on service is not running. Start it and try ' 'again') handle_exception(Exception(e_msg), request) if (command == 'update'): rockons = self._get_available(request) for r in rockons.keys(): name = r ro = None if (RockOn.objects.filter(name=name).exists()): ro = RockOn.objects.get(name=name) if (ro.state != 'available'): #don't update metadata if it's installed or in some pending state. continue ro.description = rockons[r]['description'] else: ro = RockOn(name=name, description=rockons[r]['description'], version='1.0', state='available', status='stopped') ro.save() containers = rockons[r]['containers'] for c in containers.keys(): io = None iname = containers[c]['image'] if (DImage.objects.filter(name=iname).exists()): io = DImage.objects.get(name=iname) else: io = DImage(name=iname, tag='latest', repo='foo') io.save() co = None if (DContainer.objects.filter(name=c).exists()): co = DContainer.objects.get(name=c) co.dimage = io co.rockon = ro else: co = DContainer(rockon=ro, dimage=io, name=c) co.save() if ('ports' in containers[c]): ports = containers[c]['ports'] for p in ports.keys(): po = None if (DPort.objects.filter(hostp=p).exists()): po = DPort.objects.get(hostp=p) po.container = co elif (DPort.objects.filter(containerp=p, container=co).exists()): po = DPort.objects.get(containerp=p, container=co) po.hostp = p else: po = DPort(hostp=p, containerp=p, container=co) if (ports[p] == 'ui'): po.uiport = True else: po.protocol = ports[p] po.save() if ('volumes' in containers[c]): volumes = containers[c]['volumes'] for v in volumes: if (not DVolume.objects.filter( dest_dir=v, container=co).exists()): vo = DVolume(container=co, dest_dir=v) vo.save() for vo in DVolume.objects.filter(container=co): if (vo.dest_dir not in volumes): vo.delete() if ('opts' in containers[c]): options = containers[c]['opts'] for o in options.keys(): if (not ContainerOption.objects.filter( container=co, name=options[o]).exists()): oo = ContainerOption(container=co, name=o, val=options[o]) oo.save() if ('custom_config' in rockons[r]): cc_d = rockons[r]['custom_config'] for k in cc_d: cco, created = DCustomConfig.objects.get_or_create( rockon=ro, key=k, defaults={'description': cc_d[k]}) if (not created): cco.description = cc_d[k] if (not created and k == 'iprange' and ro.name == 'Plex'): from storageadmin.models import NetworkInterface try: ni = NetworkInterface.objects.filter(itype='management')[0] cco.val = ('%s/255.255.255.0' % ni.ipaddr) except: pass cco.save() if ('app_link' in rockons[r]): app_link = rockons[r]['app_link'] if (ro.state != 'installed'): ro.link = app_link if ('website' in rockons[r]): ro.website = rockons[r]['website'] ro.save() return Response()
sname = share_map[s] if (not Share.objects.filter(name=sname).exists()): e_msg = ('Invalid Share(%s).' % sname) handle_exception(Exception(e_msg), request) so = Share.objects.get(name=sname) if (DVolume.objects.filter(container=co, share=so).exists()): e_msg = ('Share(%s) is already assigned to this Rock-on' % sname) handle_exception(Exception(e_msg), request) if (DVolume.objects.filter(container=co, dest_dir=s).exists()): e_msg = ('Directory(%s) is already mapped for this Rock-on' % s) handle_exception(Exception(e_msg), request) if (not s.startswith('/')): e_msg = ('Invalid Directory(%s). Must provide an ' 'absolute path. Eg: /data/media' % s) handle_exception(Exception(e_msg), request) do = DVolume(container=co, share=so, uservol=True, dest_dir=s) do.save() rockon.state = 'pending_update' rockon.save() update.async(rockon.id) elif (command == 'stop'): stop.async(rockon.id) rockon.status = 'pending_stop' rockon.save() elif (command == 'start'): start.async(rockon.id) rockon.status = 'pending_start' rockon.save() elif (command == 'state_update'): state = request.data.get('new_state') rockon.state = state
def post(self, request, rid, command): with self._handle_exception(request): if (not docker_status()): e_msg = ('Docker service is not running. Start it and try ' 'again.') handle_exception(Exception(e_msg), request) try: rockon = RockOn.objects.get(id=rid) except: e_msg = ('Rock-on(%d) does not exist' % rid) handle_exception(Exception(e_msg), request) try: dname = 'ztask-daemon' e_msg = ('ztask daemon is not running and could not be ' 'started') o, e, rc = superctl(dname, 'status') if (rc == 1): superctl(dname, 'restart') time.sleep(5) except Exception as e: logger.exception(e) handle_exception(Exception(e_msg), request) finally: if (rc == 1): o, e, rc = superctl(dname, 'status') if (rc == 1): handle_exception(Exception(e_msg), request) if (command == 'install'): self._pending_check(request) share_map = request.data.get('shares', {}) port_map = request.data.get('ports', {}) cc_map = request.data.get('cc', {}) env_map = request.data.get('environment', {}) containers = DContainer.objects.filter(rockon=rockon) for co in containers: for sname in share_map.keys(): dest_dir = share_map[sname] if (not Share.objects.filter(name=sname).exists()): e_msg = ('Invalid Share(%s).' % sname) handle_exception(Exception(e_msg), request) if (DVolume.objects.filter( container=co, dest_dir=dest_dir).exists()): so = Share.objects.get(name=sname) vo = DVolume.objects.get(container=co, dest_dir=dest_dir) vo.share = so vo.save() # {'host_port' : 'container_port', ... } for p in port_map.keys(): if (DPort.objects.filter(hostp=p).exists()): dup_po = DPort.objects.get(hostp=p) if (dup_po.container.rockon.id != rockon.id): if (dup_po.container.rockon.state in ('installed', 'pending_install')): # cannot claim from a rock-on that's # installed. conf_ro = dup_po.container.rockon.name e_msg = ( 'Port(%s) belongs to another ' 'Rock-n(%s). Choose a different ' 'port. If you must choose the same ' 'port, uninstall %s first and try ' 'again.' % (p, conf_ro, conf_ro)) handle_exception(Exception(e_msg), request) # change the host port to next available. dup_po.hostp = self._next_available_default_hostp(dup_po.hostp) # noqa E501 dup_po.save() for co2 in DContainer.objects.filter(rockon=rockon): if (DPort.objects.filter( container=co2, containerp=port_map[p]).exists()): # found the container that needs this port. po = DPort.objects.get(container=co2, containerp=port_map[p]) po.hostp = p po.save() break for c in cc_map.keys(): if (not DCustomConfig.objects.filter( rockon=rockon, key=c).exists()): e_msg = ('Invalid custom config key(%s)' % c) handle_exception(Exception(e_msg), request) cco = DCustomConfig.objects.get(rockon=rockon, key=c) cco.val = cc_map[c] cco.save() for e in env_map.keys(): if (not DContainerEnv.objects.filter( container=co, key=e).exists()): e_msg = ('Invalid environment variabled(%s)' % e) handle_exception(Exception(e_msg), request) ceo = DContainerEnv.objects.get(container=co, key=e) ceo.val = env_map[e] ceo.save() install.async(rockon.id) rockon.state = 'pending_install' rockon.save() elif (command == 'uninstall'): self._pending_check(request) if (rockon.state != 'installed'): e_msg = ('Rock-on(%s) is not currently installed. Cannot ' 'uninstall it' % rockon.name) handle_exception(Exception(e_msg), request) if (rockon.status == 'started' or rockon.status == 'pending_start'): e_msg = ('Rock-on(%s) must be stopped before it can ' 'be uninstalled. Stop it and try again' % rockon.name) handle_exception(Exception(e_msg), request) uninstall.async(rockon.id) rockon.state = 'pending_uninstall' rockon.save() for co in DContainer.objects.filter(rockon=rockon): DVolume.objects.filter(container=co, uservol=True).delete() elif (command == 'update'): self._pending_check(request) if (rockon.state != 'installed'): e_msg = ('Rock-on(%s) is not currently installed. Cannot ' 'update it' % rockon.name) handle_exception(Exception(e_msg), request) if (rockon.status == 'started' or rockon.status == 'pending_start'): e_msg = ('Rock-on(%s) must be stopped before it can ' 'be updated. Stop it and try again' % rockon.name) handle_exception(Exception(e_msg), request) share_map = request.data.get('shares') for co in DContainer.objects.filter(rockon=rockon): for s in share_map.keys(): sname = share_map[s] if (not Share.objects.filter(name=sname).exists()): e_msg = ('Invalid Share(%s).' % sname) handle_exception(Exception(e_msg), request) so = Share.objects.get(name=sname) if (DVolume.objects.filter( container=co, share=so).exists()): e_msg = ('Share(%s) is already assigned to ' 'this Rock-on' % sname) handle_exception(Exception(e_msg), request) if (DVolume.objects.filter( container=co, dest_dir=s).exists()): e_msg = ('Directory(%s) is already mapped for ' 'this Rock-on' % s) handle_exception(Exception(e_msg), request) if (not s.startswith('/')): e_msg = ('Invalid Directory(%s). Must provide an ' 'absolute path. Eg: /data/media' % s) handle_exception(Exception(e_msg), request) do = DVolume(container=co, share=so, uservol=True, dest_dir=s) do.save() rockon.state = 'pending_update' rockon.save() update.async(rockon.id) elif (command == 'stop'): stop.async(rockon.id) rockon.status = 'pending_stop' rockon.save() elif (command == 'start'): start.async(rockon.id) rockon.status = 'pending_start' rockon.save() elif (command == 'state_update'): state = request.data.get('new_state') rockon.state = state rockon.save() elif (command == 'status_update'): status = request.data.get('new_status') rockon.status = status rockon.save() return Response(RockOnSerializer(rockon).data)