def _create_update_meta(self, name, r_d): #Update our application state with any changes from hosted app #profiles(app.json files). Some attributes cannot be updated #if the Rock-on is currently installed. These will be logged and #ignored. ro_defaults = { 'description': r_d['description'], 'website': r_d['website'], 'version': r_d['version'], 'state': 'available', 'status': 'stopped' } ro, created = RockOn.objects.get_or_create(name=name, defaults=ro_defaults) if (not created): ro.description = ro_defaults['description'] ro.website = ro_defaults['website'] ro.version = ro_defaults['version'] if ('ui' in r_d): ui_d = r_d['ui'] ro.link = ui_d['slug'] if ('https' in ui_d): ro.https = ui_d['https'] if ('icon' in r_d): ro.icon = r_d['icon'] if ('volume_add_support' in r_d): ro.volume_add_support = r_d['volume_add_support'] if ('more_info' in r_d): ro.more_info = r_d['more_info'] ro.save() containers = r_d['containers'] cur_containers = [ co.name for co in DContainer.objects.filter(rockon=ro) ] if (len(set(containers.keys()) ^ set(cur_containers)) != 0): if (ro.state != 'available'): e_msg = ('Cannot add/remove container definitions for %s as ' 'it is not in available state. Uninstall the ' 'Rock-on first and try again.' % ro.name) handle_exception(Exception(e_msg), self.request) #rock-on is in available state. we can safely wipe metadata #and start fresh. DContainer.objects.filter(rockon=ro).delete() for c in containers: c_d = containers[c] co = None if (DContainer.objects.filter(name=c).exists()): co = DContainer.objects.get(name=c) if (co.rockon.id != ro.id): e_msg = ('Duplicate container(%s) definition detected. ' 'It belongs to another Rock-on(%s). Uninstall ' 'one of them and try again.' % (co.name, co.rockon.name)) handle_exception(Exception(e_msg), self.request) if (co.dimage.name != c_d['image']): if (ro.state != 'available'): e_msg = ('Cannot change image of the container(%s) ' 'as it belongs to an installed Rock-on(%s). ' 'Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) co.dimage.delete() if (co is None): co = DContainer(name=c, rockon=ro) defaults = { 'tag': c_d.get('tag', 'latest'), 'repo': 'na', } io, created = DImage.objects.get_or_create(name=c_d['image'], defaults=defaults) co.dimage = io co.launch_order = c_d['launch_order'] if ('uid' in c_d): co.uid = int(c_d['uid']) co.save() ports = containers[c].get('ports', {}) cur_ports = [ po.containerp for po in DPort.objects.filter(container=co) ] if (len(set(map(int, ports.keys())) ^ set(cur_ports)) != 0): if (ro.state != 'available'): e_msg = ('Cannot add/remove port definitions of the ' 'container(%s) as it belongs to an installed ' 'Rock-on(%s). Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) DPort.objects.filter(container=co).delete() for p in ports: p_d = ports[p] if ('protocol' not in p_d): p_d['protocol'] = None p = int(p) po = None if (DPort.objects.filter(containerp=p, container=co).exists()): po = DPort.objects.get(containerp=p, container=co) if (po.hostp_default != p_d['host_default']): po.hostp_default = self._next_available_default_hostp( p_d['host_default']) po.description = p_d['description'] po.protocol = p_d['protocol'] po.label = p_d['label'] else: #let's find next available default if default is already taken def_hostp = self._next_available_default_hostp( p_d['host_default']) po = DPort(description=p_d['description'], hostp=def_hostp, containerp=p, hostp_default=def_hostp, container=co, protocol=p_d['protocol'], label=p_d['label']) if ('ui' in p_d): po.uiport = p_d['ui'] if (po.uiport): ro.ui = True ro.save() po.save() v_d = c_d.get('volumes', {}) cur_vols = [ vo.dest_dir for vo in DVolume.objects.filter(container=co) ] if (len(set(v_d.keys()) ^ set(cur_vols)) != 0): if (ro.state != 'available'): e_msg = ('Cannot add/remove volume definitions of the ' 'container(%s) as it belongs to an installed ' 'Rock-on(%s). Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) DVolume.objects.filter(container=co).delete() for v in v_d: cv_d = v_d[v] vo_defaults = { 'description': cv_d['description'], 'label': cv_d['label'] } vo, created = DVolume.objects.get_or_create( dest_dir=v, container=co, defaults=vo_defaults) if (not created): vo.description = vo_defaults['description'] vo.label = vo_defaults['label'] if ('min_size' in cv_d): vo.min_size = cv_d['min_size'] vo.save() self._update_env(co, c_d) options = containers[c].get('opts', []) id_l = [] for o in options: #there are no unique constraints on this model, so we need this bandaid. if (ContainerOption.objects.filter( container=co, name=o[0], val=o[1]).count() > 1): ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).delete() oo, created = ContainerOption.objects.get_or_create( container=co, name=o[0], val=o[1]) id_l.append(oo.id) for oo in ContainerOption.objects.filter(container=co): if (oo.id not in id_l): oo.delete() l_d = r_d.get('container_links', {}) for cname in l_d: ll = l_d[cname] lsources = [l['source_container'] for l in ll] co = DContainer.objects.get(rockon=ro, name=cname) for clo in co.destination_container.all(): if (clo.name not in lsources): clo.delete() for cl_d in ll: sco = DContainer.objects.get(rockon=ro, name=cl_d['source_container']) clo, created = DContainerLink.objects.get_or_create( source=sco, destination=co) clo.name = cl_d['name'] clo.save() self._update_cc(ro, r_d)
def _create_update_meta(self, name, r_d): #Update our application state with any changes from hosted app #profiles(app.json files). Some attributes cannot be updated #if the Rock-on is currently installed. These will be logged and #ignored. ro_defaults = {'description': r_d['description'], 'website': r_d['website'], 'version': r_d['version'], 'state': 'available', 'status': 'stopped'} ro, created = RockOn.objects.get_or_create(name=name, defaults=ro_defaults) if (not created): ro.description = ro_defaults['description'] ro.website = ro_defaults['website'] ro.version = ro_defaults['version'] if ('ui' in r_d): ui_d = r_d['ui'] ro.link = ui_d['slug'] if ('https' in ui_d): ro.https = ui_d['https'] if ('icon' in r_d): ro.icon = r_d['icon'] if ('volume_add_support' in r_d): ro.volume_add_support = r_d['volume_add_support'] if ('more_info' in r_d): ro.more_info = r_d['more_info'] ro.save() containers = r_d['containers'] cur_containers = [co.name for co in DContainer.objects.filter(rockon=ro)] if (len(set(containers.keys()) ^ set(cur_containers)) != 0): if (ro.state != 'available'): e_msg = ('Cannot add/remove container definitions for %s as ' 'it is not in available state. Uninstall the ' 'Rock-on first and try again.' % ro.name) handle_exception(Exception(e_msg), self.request) #rock-on is in available state. we can safely wipe metadata #and start fresh. DContainer.objects.filter(rockon=ro).delete() for c in containers: c_d = containers[c] co = None if (DContainer.objects.filter(name=c).exists()): co = DContainer.objects.get(name=c) if (co.rockon.id != ro.id): e_msg = ('Duplicate container(%s) definition detected. ' 'It belongs to another Rock-on(%s). Uninstall ' 'one of them and try again.' % (co.name, co.rockon.name)) handle_exception(Exception(e_msg), self.request) if (co.dimage.name != c_d['image']): if (ro.state != 'available'): e_msg = ('Cannot change image of the container(%s) ' 'as it belongs to an installed Rock-on(%s). ' 'Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) co.dimage.delete() if (co is None): co = DContainer(name=c, rockon=ro) defaults = {'tag': c_d.get('tag', 'latest'), 'repo': 'na',} io, created = DImage.objects.get_or_create(name=c_d['image'], defaults=defaults) co.dimage = io co.launch_order = c_d['launch_order'] if ('uid' in c_d): co.uid = int(c_d['uid']) co.save() ports = containers[c].get('ports', {}) cur_ports = [po.containerp for po in DPort.objects.filter(container=co)] if (len(set(map(int, ports.keys())) ^ set(cur_ports)) != 0): if (ro.state != 'available'): e_msg = ('Cannot add/remove port definitions of the ' 'container(%s) as it belongs to an installed ' 'Rock-on(%s). Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) DPort.objects.filter(container=co).delete() for p in ports: p_d = ports[p] if ('protocol' not in p_d): p_d['protocol'] = None p = int(p) po = None if (DPort.objects.filter(containerp=p, container=co).exists()): po = DPort.objects.get(containerp=p, container=co) if (po.hostp_default != p_d['host_default']): po.hostp_default = self._next_available_default_hostp(p_d['host_default']) po.description = p_d['description'] po.protocol = p_d['protocol'] po.label = p_d['label'] else: #let's find next available default if default is already taken def_hostp = self._next_available_default_hostp(p_d['host_default']) po = DPort(description=p_d['description'], hostp=def_hostp, containerp=p, hostp_default=def_hostp, container=co, protocol=p_d['protocol'], label=p_d['label']) if ('ui' in p_d): po.uiport = p_d['ui'] if (po.uiport): ro.ui = True ro.save() po.save() v_d = c_d.get('volumes', {}) cur_vols = [vo.dest_dir for vo in DVolume.objects.filter(container=co)] if (len(set(v_d.keys()) ^ set(cur_vols)) != 0): if (ro.state != 'available'): e_msg = ('Cannot add/remove volume definitions of the ' 'container(%s) as it belongs to an installed ' 'Rock-on(%s). Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) DVolume.objects.filter(container=co).delete() for v in v_d: cv_d = v_d[v] vo_defaults = {'description': cv_d['description'], 'label': cv_d['label']} vo, created = DVolume.objects.get_or_create(dest_dir=v, container=co, defaults=vo_defaults) if (not created): vo.description = vo_defaults['description'] vo.label = vo_defaults['label'] if ('min_size' in cv_d): vo.min_size = cv_d['min_size'] vo.save() self._update_env(co, c_d) options = containers[c].get('opts', []) id_l = [] for o in options: #there are no unique constraints on this model, so we need this bandaid. if (ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).count() > 1): ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).delete() oo, created = ContainerOption.objects.get_or_create(container=co, name=o[0], val=o[1]) id_l.append(oo.id) for oo in ContainerOption.objects.filter(container=co): if (oo.id not in id_l): oo.delete() l_d = r_d.get('container_links', {}) for cname in l_d: ll = l_d[cname] lsources = [l['source_container'] for l in ll] co = DContainer.objects.get(rockon=ro, name=cname) for clo in co.destination_container.all(): if (clo.name not in lsources): clo.delete() for cl_d in ll: sco = DContainer.objects.get(rockon=ro, name=cl_d['source_container']) clo, created = DContainerLink.objects.get_or_create(source=sco, destination=co) clo.name = cl_d['name'] clo.save() self._update_cc(ro, r_d)
def _create_update_meta(self, name, r_d): # Update our application state with any changes from hosted app # profiles(app.json files). Some attributes cannot be updated if the # Rock-on is currently installed. These will be logged and ignored. ro_defaults = {'description': r_d['description'], 'website': r_d['website'], 'version': r_d['version'], 'state': 'available', 'status': 'stopped'} ro, created = RockOn.objects.get_or_create(name=name, defaults=ro_defaults) if (not created): ro.description = ro_defaults['description'] ro.website = ro_defaults['website'] ro.version = ro_defaults['version'] if ('ui' in r_d): ui_d = r_d['ui'] ro.link = ui_d['slug'] if ('https' in ui_d): ro.https = ui_d['https'] if ('icon' in r_d): ro.icon = r_d['icon'] if ('volume_add_support' in r_d): ro.volume_add_support = r_d['volume_add_support'] if ('more_info' in r_d): ro.more_info = r_d['more_info'] ro.save() containers = r_d['containers'] cur_containers = [co.name for co in DContainer.objects.filter(rockon=ro)] if (len(set(containers.keys()) ^ set(cur_containers)) != 0): if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot add/remove container definitions for {} as ' 'it is not in available state. Uninstall the ' 'Rock-on first and try again.').format(ro.name) handle_exception(Exception(e_msg), self.request) # rock-on is in available state. we can safely wipe metadata # and start fresh. DContainer.objects.filter(rockon=ro).delete() for c in containers: c_d = containers[c] co = None if (DContainer.objects.filter(name=c).exists()): co = DContainer.objects.get(name=c) if (co.rockon.id != ro.id): e_msg = ('Duplicate container ({}) definition detected. ' 'It belongs to another Rock-on ({}). Uninstall ' 'one of them and ' 'try again.').format(co.name, co.rockon.name) handle_exception(Exception(e_msg), self.request) if (co.dimage.name != c_d['image']): if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot change image of the container ({}) ' 'as it belongs to an installed Rock-on ({}). ' 'Uninstall it first and ' 'try again.').format(co.name, ro.name) handle_exception(Exception(e_msg), self.request) co.dimage.delete() if (co is None): co = DContainer(name=c, rockon=ro) defaults = {'tag': c_d.get('tag', 'latest'), 'repo': 'na', } io, created = DImage.objects.get_or_create(name=c_d['image'], defaults=defaults) co.dimage = io co.launch_order = c_d['launch_order'] if ('uid' in c_d): co.uid = int(c_d['uid']) co.save() ports = containers[c].get('ports', {}) cur_ports = [po.containerp for po in DPort.objects.filter(container=co)] if (len(set(map(int, ports.keys())) ^ set(cur_ports)) != 0): if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot add/remove port definitions of the ' 'container ({}) as it belongs to an installed ' 'Rock-on ({}). Uninstall it first and ' 'try again.').format(co.name, ro.name) handle_exception(Exception(e_msg), self.request) DPort.objects.filter(container=co).delete() for p in ports: p_d = ports[p] if ('protocol' not in p_d): p_d['protocol'] = None p = int(p) po = None if (DPort.objects.filter(containerp=p, container=co).exists()): po = DPort.objects.get(containerp=p, container=co) if (po.hostp_default != p_d['host_default']): po.hostp_default = self._next_available_default_hostp( p_d['host_default']) po.description = p_d['description'] po.protocol = p_d['protocol'] po.label = p_d['label'] else: # let's find next available default if default is already # taken def_hostp = self._next_available_default_hostp(p_d['host_default']) # noqa E501 po = DPort(description=p_d['description'], hostp=def_hostp, containerp=p, hostp_default=def_hostp, container=co, protocol=p_d['protocol'], label=p_d['label']) if ('ui' in p_d): po.uiport = p_d['ui'] if (po.uiport): ro.ui = True ro.save() po.save() v_d = c_d.get('volumes', {}) cur_vols = [vo.dest_dir for vo in DVolume.objects.filter(container=co)] # cur_vols can have entries not in the config for Shares mapped # post install. If we have more volumes defined in the rock-on # definition than we have previously seen for this rockon, ie # volumes added in newer definition, then remove our existing # volumes record. if (len(set(v_d.keys()) - set(cur_vols)) != 0): # but only if the current state is 'available' (to install) or # 'install failed', otherwise raise warning about changing an # installed rock-ons. if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot add/remove volume definitions of the ' 'container ({}) as it belongs to an installed ' 'Rock-on ({}). Uninstall it first and ' 'try again.').format(co.name, ro.name) handle_exception(Exception(e_msg), self.request) # Delete all volume entries for this container so that they # might be created a fresh. DVolume.objects.filter(container=co).delete() # If the existing rock-on db entry indicates this container is not # installed ie state available or install_failed then check if we # need to remove any now deprecated volume entries. # Ie updated config that has removed a previously seen volume. if (ro.state in ('available', 'install_failed')): if (len(set(cur_vols) - set(v_d.keys())) > 0): # we have some current volumes in db that are no longer in # our updated rock-on definition so remove all volumes for # this rock-on so they might be updated whole sale. # Delete all volume entries for this container so that they # might be created a fresh. DVolume.objects.filter(container=co).delete() # Cycle through all volumes in the rock-on json definition and # update or create the appropriate db volumes entry. for v in v_d: cv_d = v_d[v] vo_defaults = {'description': cv_d['description'], 'label': cv_d['label']} vo, created = DVolume.objects.get_or_create( dest_dir=v, container=co, defaults=vo_defaults) # If this db entry previously existed then update it's # description and label to that found in our rock-on json # This ensures changes made in repo json to the description and # label's get updated in the local db. if (not created): vo.description = vo_defaults['description'] vo.label = vo_defaults['label'] if ('min_size' in cv_d): vo.min_size = cv_d['min_size'] vo.save() self._update_env(co, c_d) options = containers[c].get('opts', []) id_l = [] for o in options: # there are no unique constraints on this model, so we need # this bandaid. if (ContainerOption.objects.filter( container=co, name=o[0], val=o[1]).count() > 1): ContainerOption.objects.filter( container=co, name=o[0], val=o[1]).delete() oo, created = ContainerOption.objects.get_or_create( container=co, name=o[0], val=o[1]) id_l.append(oo.id) for oo in ContainerOption.objects.filter(container=co): if (oo.id not in id_l): oo.delete() l_d = r_d.get('container_links', {}) for cname in l_d: ll = l_d[cname] lsources = [l['source_container'] for l in ll] co = DContainer.objects.get(rockon=ro, name=cname) for clo in co.destination_container.all(): if (clo.name not in lsources): clo.delete() for cl_d in ll: sco = DContainer.objects.get(rockon=ro, name=cl_d['source_container']) clo, created = DContainerLink.objects.get_or_create( source=sco, destination=co) clo.name = cl_d['name'] clo.save() self._update_cc(ro, r_d)
def _create_update_meta(self, name, r_d): # Update our application state with any changes from hosted app # profiles(app.json files). Some attributes cannot be updated if the # Rock-on is currently installed. These will be logged and ignored. ro_defaults = { "description": r_d["description"], "website": r_d["website"], "version": r_d["version"], "state": "available", "status": "stopped", } ro, created = RockOn.objects.get_or_create(name=name, defaults=ro_defaults) if not created: ro.description = ro_defaults["description"] ro.website = ro_defaults["website"] ro.version = ro_defaults["version"] if "ui" in r_d: ui_d = r_d["ui"] ro.link = ui_d["slug"] if "https" in ui_d: ro.https = ui_d["https"] if "icon" in r_d: ro.icon = r_d["icon"] if "volume_add_support" in r_d: ro.volume_add_support = r_d["volume_add_support"] if "more_info" in r_d: ro.more_info = r_d["more_info"] ro.save() containers = r_d["containers"] cur_containers = [ co.name for co in DContainer.objects.filter(rockon=ro) ] if len(set(containers.keys()) ^ set(cur_containers)) != 0: if ro.state not in ("available", "install_failed"): e_msg = ("Cannot add/remove container definitions for {} as " "it is not in available state. Uninstall the " "Rock-on first and try again.").format(ro.name) handle_exception(Exception(e_msg), self.request) # rock-on is in available state. we can safely wipe metadata # and start fresh. DContainer.objects.filter(rockon=ro).delete() for c in containers: c_d = containers[c] co = None if DContainer.objects.filter(name=c).exists(): co = DContainer.objects.get(name=c) if co.rockon.id != ro.id: e_msg = ("Duplicate container ({}) definition detected. " "It belongs to another Rock-on ({}). Uninstall " "one of them and " "try again.").format(co.name, co.rockon.name) handle_exception(Exception(e_msg), self.request) if co.dimage.name != c_d["image"]: if ro.state not in ("available", "install_failed"): e_msg = ("Cannot change image of the container ({}) " "as it belongs to an installed Rock-on ({}). " "Uninstall it first and " "try again.").format(co.name, ro.name) handle_exception(Exception(e_msg), self.request) co.dimage.delete() if co is None: co = DContainer(name=c, rockon=ro) defaults = { "repo": "na", } io, created = DImage.objects.get_or_create(name=c_d["image"], tag=c_d.get( "tag", "latest"), defaults=defaults) co.dimage = io co.launch_order = c_d["launch_order"] if "uid" in c_d: co.uid = int(c_d["uid"]) co.save() ports = containers[c].get("ports", {}) cur_ports = [ po.containerp for po in DPort.objects.filter(container=co) ] if len(set(map(int, ports.keys())) ^ set(cur_ports)) != 0: if ro.state not in ("available", "install_failed"): e_msg = ("Cannot add/remove port definitions of the " "container ({}) as it belongs to an installed " "Rock-on ({}). Uninstall it first and " "try again.").format(co.name, ro.name) handle_exception(Exception(e_msg), self.request) DPort.objects.filter(container=co).delete() for p in ports: p_d = ports[p] if "protocol" not in p_d: p_d["protocol"] = None p = int(p) po = None if DPort.objects.filter(containerp=p, container=co).exists(): po = DPort.objects.get(containerp=p, container=co) if po.hostp_default != p_d["host_default"]: po.hostp_default = self._next_available_default_hostp( p_d["host_default"]) po.description = p_d["description"] po.protocol = p_d["protocol"] po.label = p_d["label"] else: # let's find next available default if default is already # taken def_hostp = self._next_available_default_hostp( p_d["host_default"]) # noqa E501 po = DPort( description=p_d["description"], hostp=def_hostp, containerp=p, hostp_default=def_hostp, container=co, protocol=p_d["protocol"], label=p_d["label"], ) if "ui" in p_d: po.uiport = p_d["ui"] if po.uiport: ro.ui = True ro.save() po.save() v_d = c_d.get("volumes", {}) cur_vols = [ vo.dest_dir for vo in DVolume.objects.filter(container=co) ] # cur_vols can have entries not in the config for Shares mapped # post install. If we have more volumes defined in the rock-on # definition than we have previously seen for this rockon, ie # volumes added in newer definition, then remove our existing # volumes record. if len(set(v_d.keys()) - set(cur_vols)) != 0: # but only if the current state is 'available' (to install) or # 'install failed', otherwise raise warning about changing an # installed rock-ons. if ro.state not in ("available", "install_failed"): e_msg = ("Cannot add/remove volume definitions of the " "container ({}) as it belongs to an installed " "Rock-on ({}). Uninstall it first and " "try again.").format(co.name, ro.name) handle_exception(Exception(e_msg), self.request) # Delete all volume entries for this container so that they # might be created a fresh. DVolume.objects.filter(container=co).delete() # If the existing rock-on db entry indicates this container is not # installed ie state available or install_failed then check if we # need to remove any now deprecated volume entries. # Ie updated config that has removed a previously seen volume. if ro.state in ("available", "install_failed"): if len(set(cur_vols) - set(v_d.keys())) > 0: # we have some current volumes in db that are no longer in # our updated rock-on definition so remove all volumes for # this rock-on so they might be updated whole sale. # Delete all volume entries for this container so that they # might be created a fresh. DVolume.objects.filter(container=co).delete() # Cycle through all volumes in the rock-on json definition and # update or create the appropriate db volumes entry. for v in v_d: cv_d = v_d[v] vo_defaults = { "description": cv_d["description"], "label": cv_d["label"], } vo, created = DVolume.objects.get_or_create( dest_dir=v, container=co, defaults=vo_defaults) # If this db entry previously existed then update its # description and label to that found in our rock-on json # This ensures changes made in repo json to the description and # label's get updated in the local db. if not created: vo.description = vo_defaults["description"] vo.label = vo_defaults["label"] if "min_size" in cv_d: vo.min_size = cv_d["min_size"] vo.save() self._update_env(co, c_d) self._update_device(co, c_d) options = containers[c].get("opts", []) id_l = [] for o in options: # there are no unique constraints on this model, so we need # this bandaid. if (ContainerOption.objects.filter( container=co, name=o[0], val=o[1]).count() > 1): ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).delete() oo, created = ContainerOption.objects.get_or_create( container=co, name=o[0], val=o[1]) id_l.append(oo.id) for oo in ContainerOption.objects.filter(container=co): if oo.id not in id_l: oo.delete() cmd_args = containers[c].get("cmd_arguments", []) id_l = [] for ca in cmd_args: # there are no unique constraints on this model, so we need # this bandaid. if (DContainerArgs.objects.filter( container=co, name=ca[0], val=ca[1]).count() > 1): DContainerArgs.objects.filter(container=co, name=ca[0], val=ca[1]).delete() cao, created = DContainerArgs.objects.get_or_create( container=co, name=ca[0], val=ca[1]) id_l.append(cao.id) for cao in DContainerArgs.objects.filter(container=co): if cao.id not in id_l: cao.delete() l_d = r_d.get("container_links", {}) for cname in l_d: ll = l_d[cname] lsources = [l["source_container"] for l in ll] co = DContainer.objects.get(rockon=ro, name=cname) for clo in co.destination_container.all(): if clo.name not in lsources: clo.delete() for cl_d in ll: sco = DContainer.objects.get(rockon=ro, name=cl_d["source_container"]) clo, created = DContainerLink.objects.get_or_create( source=sco, destination=co) clo.name = cl_d["name"] clo.save() self._update_cc(ro, r_d)
def _create_update_meta(self, name, r_d): #Update our application state with any changes from hosted app #profiles(app.json files). Some attributes cannot be updated #if the Rock-on is currently installed. These will be logged and #ignored. ro_defaults = {'description': r_d['description'], 'website': r_d['website'], 'version': r_d['version'], 'state': 'available', 'status': 'stopped'} ro, created = RockOn.objects.get_or_create(name=name, defaults=ro_defaults) if (not created): ro.description = ro_defaults['description'] ro.website = ro_defaults['website'] ro.version = ro_defaults['version'] if ('ui' in r_d): ui_d = r_d['ui'] ro.link = ui_d['slug'] if ('https' in ui_d): ro.https = ui_d['https'] if ('icon' in r_d): ro.icon = r_d['icon'] if ('volume_add_support' in r_d): ro.volume_add_support = r_d['volume_add_support'] if ('more_info' in r_d): ro.more_info = r_d['more_info'] ro.save() containers = r_d['containers'] cur_containers = [co.name for co in DContainer.objects.filter(rockon=ro)] if (len(set(containers.keys()) ^ set(cur_containers)) != 0): if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot add/remove container definitions for %s as ' 'it is not in available state. Uninstall the ' 'Rock-on first and try again.' % ro.name) handle_exception(Exception(e_msg), self.request) #rock-on is in available state. we can safely wipe metadata #and start fresh. DContainer.objects.filter(rockon=ro).delete() for c in containers: c_d = containers[c] co = None if (DContainer.objects.filter(name=c).exists()): co = DContainer.objects.get(name=c) if (co.rockon.id != ro.id): e_msg = ('Duplicate container(%s) definition detected. ' 'It belongs to another Rock-on(%s). Uninstall ' 'one of them and try again.' % (co.name, co.rockon.name)) handle_exception(Exception(e_msg), self.request) if (co.dimage.name != c_d['image']): if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot change image of the container(%s) ' 'as it belongs to an installed Rock-on(%s). ' 'Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) co.dimage.delete() if (co is None): co = DContainer(name=c, rockon=ro) defaults = {'tag': c_d.get('tag', 'latest'), 'repo': 'na',} io, created = DImage.objects.get_or_create(name=c_d['image'], defaults=defaults) co.dimage = io co.launch_order = c_d['launch_order'] if ('uid' in c_d): co.uid = int(c_d['uid']) co.save() ports = containers[c].get('ports', {}) cur_ports = [po.containerp for po in DPort.objects.filter(container=co)] if (len(set(map(int, ports.keys())) ^ set(cur_ports)) != 0): if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot add/remove port definitions of the ' 'container(%s) as it belongs to an installed ' 'Rock-on(%s). Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) DPort.objects.filter(container=co).delete() for p in ports: p_d = ports[p] if ('protocol' not in p_d): p_d['protocol'] = None p = int(p) po = None if (DPort.objects.filter(containerp=p, container=co).exists()): po = DPort.objects.get(containerp=p, container=co) if (po.hostp_default != p_d['host_default']): po.hostp_default = self._next_available_default_hostp(p_d['host_default']) po.description = p_d['description'] po.protocol = p_d['protocol'] po.label = p_d['label'] else: #let's find next available default if default is already taken def_hostp = self._next_available_default_hostp(p_d['host_default']) po = DPort(description=p_d['description'], hostp=def_hostp, containerp=p, hostp_default=def_hostp, container=co, protocol=p_d['protocol'], label=p_d['label']) if ('ui' in p_d): po.uiport = p_d['ui'] if (po.uiport): ro.ui = True ro.save() po.save() v_d = c_d.get('volumes', {}) cur_vols = [vo.dest_dir for vo in DVolume.objects.filter(container=co)] # cur_vols can have entries not in the config for Shares mapped post # install. # If we have more volumes defined in the rock-on definition than # we have previously seen for this rockon, ie volumes added in newer # definition, then remove our existing volumes record. if (len(set(v_d.keys()) - set(cur_vols)) != 0): # but only if the current state is 'available' (to install) or # 'install failed', otherwise raise warning about changing an # installed rock-ons. if (ro.state not in ('available', 'install_failed')): e_msg = ('Cannot add/remove volume definitions of the ' 'container(%s) as it belongs to an installed ' 'Rock-on(%s). Uninstall it first and try again.' % (co.name, ro.name)) handle_exception(Exception(e_msg), self.request) # Delete all volume entries for this container so that they # might be created a fresh. DVolume.objects.filter(container=co).delete() # If the existing rock-on db entry indicates this container is not # installed ie state available or install_failed then check if we # need to remove any now deprecated volume entries. # Ie updated config that has removed a previously seen volume. if (ro.state in ('available', 'install_failed')): if (len(set(cur_vols) - set(v_d.keys())) > 0): # we have some current volumes in db that are no longer in # our updated rock-on definition so remove all volumes for # this rock-on so they might be updated whole sale. # Delete all volume entries for this container so that they # might be created a fresh. DVolume.objects.filter(container=co).delete() # Cycle through all volumes in the rock-on json definition and # update or create the appropriate db volumes entry. for v in v_d: cv_d = v_d[v] vo_defaults = {'description': cv_d['description'], 'label': cv_d['label']} vo, created = DVolume.objects.get_or_create(dest_dir=v, container=co, defaults=vo_defaults) # If this db entry previously existed then update it's # description and label to that found in our rock-on json # This ensures changes made in repo json to the description and # label's get updated in the local db. if (not created): vo.description = vo_defaults['description'] vo.label = vo_defaults['label'] if ('min_size' in cv_d): vo.min_size = cv_d['min_size'] vo.save() self._update_env(co, c_d) options = containers[c].get('opts', []) id_l = [] for o in options: #there are no unique constraints on this model, so we need this bandaid. if (ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).count() > 1): ContainerOption.objects.filter(container=co, name=o[0], val=o[1]).delete() oo, created = ContainerOption.objects.get_or_create(container=co, name=o[0], val=o[1]) id_l.append(oo.id) for oo in ContainerOption.objects.filter(container=co): if (oo.id not in id_l): oo.delete() l_d = r_d.get('container_links', {}) for cname in l_d: ll = l_d[cname] lsources = [l['source_container'] for l in ll] co = DContainer.objects.get(rockon=ro, name=cname) for clo in co.destination_container.all(): if (clo.name not in lsources): clo.delete() for cl_d in ll: sco = DContainer.objects.get(rockon=ro, name=cl_d['source_container']) clo, created = DContainerLink.objects.get_or_create(source=sco, destination=co) clo.name = cl_d['name'] clo.save() self._update_cc(ro, r_d)