def volume_changes(self, new_volumes): old_volumes = volume_repo.get_service_volumes(self.service.service_id) old_volume_paths = { volume.volume_path: volume for volume in old_volumes } add = [] update = [] for new_volume in new_volumes: old_volume = old_volume_paths.get(new_volume["volume_path"], None) if not old_volume: add.append(new_volume) continue if not new_volume.get("file_content"): continue old_file_content = volume_repo.get_service_config_file( old_volume.ID) if old_file_content.file_content != new_volume["file_content"]: update.append(new_volume) if not add and not update: return None return { "add": add, "upd": update, }
def check_volume_path(self, service, volume_path): volume = volume_repo.get_service_volume_by_path(service.service_id, volume_path) if volume: return 412, u"持久化路径 {0} 已存在".format(volume_path) if service.service_source == AppConstants.SOURCE_CODE: if volume_path == "/app": return 409, u"源码应用不能挂载/app目录" if service.image != "goodrain.me/runner": if not volume_path.startswith("/"): return 400, u"路径需要以/(斜杠)开头" if volume_path in self.SYSDIRS: return 412, u"路径{0}为系统路径".format(volume_path) else: if not is_path_legal(volume_path): return 412, u"请输入符合规范的路径(如:/app/volumes )" all_volumes = volume_repo.get_service_volumes(service.service_id).values("volume_path") for path in list(all_volumes): # volume_path不能重复 if path["volume_path"].startswith(volume_path + "/"): return 412, u"已存在以{0}开头的路径".format(path["volume_path"]) if volume_path.startswith(path["volume_path"] + "/"): return 412, u"已存在以{0}开头的路径".format(volume_path) return 200, u"success"
def check_volume_path(self, service, volume_path, local_path=[]): for path in local_path: if volume_path.startswith(path + "/"): raise ServiceHandleException(msg="path error", msg_show="持久化路径不能再挂载共享路径下") volume = volume_repo.get_service_volume_by_path(service.service_id, volume_path) if volume: raise ServiceHandleException( msg="path already exists", msg_show="持久化路径[{0}]已存在".format(volume_path), status_code=412) if service.service_source == AppConstants.SOURCE_CODE: if volume_path == "/app": raise ServiceHandleException(msg="path error", msg_show="源码组件不能挂载/app目录", status_code=409) if not runner_util.is_runner(service.image): volume_path_win = False if re.match('[a-zA-Z]', volume_path[0]) and volume_path[1] == ':': volume_path_win = True if not volume_path.startswith("/") and not volume_path_win: raise ServiceHandleException(msg="path error", msg_show="路径仅支持linux和windows") if volume_path in self.SYSDIRS: raise ServiceHandleException(msg="path error", msg_show="路径{0}为系统路径".format(volume_path), status_code=412) if volume_path_win and len(volume_path) == 3: raise ServiceHandleException(msg="path error", msg_show="路径不能为系统路径", status_code=412) else: if not is_path_legal(volume_path): raise ServiceHandleException(msg="path error", msg_show="请输入符合规范的路径(如:/tmp/volumes)", status_code=412) all_volumes = volume_repo.get_service_volumes(service.service_id).values("volume_path") for path in list(all_volumes): # volume_path不能重复 if path["volume_path"].startswith(volume_path + "/") or volume_path.startswith(path["volume_path"] + "/"): raise ServiceHandleException( msg="path error", msg_show="已存在以{0}开头的路径".format(path["volume_path"]), status_code=412)
def get_service_volumes(self, tenant, service, is_config_file=False): volumes = [] if is_config_file: volumes = volume_repo.get_service_volumes_about_config_file(service.service_id) else: volumes = volume_repo.get_service_volumes(service.service_id) vos = [] res = None body = None if service.create_status != "complete": for volume in volumes: vo = volume.to_dict() vo["status"] = volume_not_bound vos.append(vo) return vos res, body = region_api.get_service_volumes(service.service_region, tenant.tenant_name, service.service_alias, tenant.enterprise_id) if body and body.list: status = {} for volume in body.list: status[volume["volume_name"]] = volume["status"] for volume in volumes: vo = volume.to_dict() vo_status = status.get(vo["volume_name"], None) vo["status"] = volume_not_bound if vo_status and vo_status == volume_ready: vo["status"] = volume_bound vos.append(vo) else: for volume in volumes: vo = volume.to_dict() vo["status"] = volume_not_bound vos.append(vo) return vos
def dep_volumes_changes(self, new_dep_volumes): def key(sid, mnt_name): logger.debug("sid: {}; mnt_name: {}".format(sid, mnt_name)) return sid + "-" + mnt_name old_dep_volumes = mnt_repo.get_service_mnts(self.service.tenant_id, self.service.service_id) olds = {key(item.dep_service_id, item.mnt_name): item for item in old_dep_volumes} tenant_service_volumes = volume_repo.get_service_volumes(self.service.service_id) local_path = [item.volume_path for item in tenant_service_volumes] add = [] for new_dep_volume in new_dep_volumes: dep_service = app_service.get_service_by_service_key(self.service, new_dep_volume["service_share_uuid"]) logger.debug("dep_service: {}".format(dep_service)) if dep_service is None: continue if olds.get(key(dep_service["service_id"], new_dep_volume["mnt_name"]), None): logger.debug("ignore dep volume: {}; dep volume exist.".format( key(dep_service["service_id"], new_dep_volume["mnt_name"]))) continue code, msg = volume_service.check_volume_path(self.service, new_dep_volume["mnt_dir"], local_path=local_path) if code != 200: logger.warning("service id: {}; path: {}; invalid volume: {1}".format(self.service.service_id, new_dep_volume["mnt_dir"], msg)) new_dep_volume["service_id"] = dep_service["service_id"] add.append(new_dep_volume) if not add: return None return {"add": add}
def delete_region_volumes(self, tenant, service): volumes = volume_repo.get_service_volumes(service.service_id) for volume in volumes: try: res, body = region_api.delete_service_volumes(service.service_region, tenant.tenant_name, service.service_alias, volume.volume_name, tenant.enterprise_id) except Exception as e: logger.exception(e)
def create_region_service(self, tenant, service, user_name, do_deploy=True, dep_sids=None): data = self.__init_create_data(tenant, service, user_name, do_deploy, dep_sids) service_dep_relations = dep_relation_repo.get_service_dependencies(tenant.tenant_id, service.service_id) # 依赖 depend_ids = [{ "dep_order": dep.dep_order, "dep_service_type": dep.dep_service_type, "depend_service_id": dep.dep_service_id, "service_id": dep.service_id, "tenant_id": dep.tenant_id } for dep in service_dep_relations] data["depend_ids"] = depend_ids # 端口 ports = port_repo.get_service_ports(tenant.tenant_id, service.service_id) ports_info = ports.values('container_port', 'mapping_port', 'protocol', 'port_alias', 'is_inner_service', 'is_outer_service') for port_info in ports_info: port_info["is_inner_service"] = False port_info["is_outer_service"] = False if ports_info: data["ports_info"] = list(ports_info) # 环境变量 envs_info = env_var_repo.get_service_env(tenant.tenant_id, service.service_id).values( 'container_port', 'name', 'attr_name', 'attr_value', 'is_change', 'scope') if envs_info: data["envs_info"] = list(envs_info) # 持久化目录 volume_info = volume_repo.get_service_volumes(service.service_id).values( 'ID', 'service_id', 'category', 'volume_name', 'volume_path', 'volume_type') if volume_info: logger.debug('--------volume_info----->{0}'.format(volume_info)) for volume in volume_info: volume_id = volume['ID'] config_file = volume_repo.get_service_config_file(volume_id) if config_file: volume.update({"file_content": config_file.file_content}) logger.debug('--------volume_info22222----->{0}'.format(volume_info)) data["volumes_info"] = list(volume_info) logger.debug(tenant.tenant_name + " start create_service:" + datetime.datetime.now().strftime('%Y%m%d%H%M%S')) # 挂载信息 mnt_info = mnt_repo.get_service_mnts(service.tenant_id, service.service_id) if mnt_info: data["dep_volumes_info"] = [{ "dep_service_id": mnt.dep_service_id, "volume_path": mnt.mnt_dir, "volume_name": mnt.mnt_name } for mnt in mnt_info] # 数据中心创建 region_api.create_service(service.service_region, tenant.tenant_name, data) # 将服务创建状态变更为创建完成 service.create_status = "complete" self.__handle_service_ports(tenant, service, ports) service.save() return service
def get_service_details(self, tenant, service): service_base = service.to_dict() service_labels = service_label_repo.get_service_labels(service.service_id) service_domains = domain_repo.get_service_domains(service.service_id) service_tcpdomains = tcp_domain.get_service_tcpdomains(service.service_id) service_events = event_repo.get_specified_num_events(tenant.tenant_id, service.service_id) service_perms = service_perm_repo.get_service_perms_by_service_pk(service.ID) service_probes = probe_repo.get_service_probe(service.service_id) service_source = service_source_repo.get_service_source(tenant.tenant_id, service.service_id) service_auths = auth_repo.get_service_auth(service.service_id) service_env_vars = env_var_repo.get_service_env(tenant.tenant_id, service.service_id) service_compile_env = compile_env_repo.get_service_compile_env(service.service_id) service_extend_method = extend_repo.get_extend_method_by_service(service) image_service_relation = image_service_relation_repo.get_image_service_relation(tenant.tenant_id, service.service_id) service_mnts = mnt_repo.get_service_mnts(tenant.tenant_id, service.service_id) service_plugin_relation = app_plugin_relation_repo.get_service_plugin_relation_by_service_id(service.service_id) service_plugin_config = service_plugin_config_repo.get_service_plugin_all_config(service.service_id) service_relation = dep_relation_repo.get_service_dependencies(tenant.tenant_id, service.service_id) service_volumes = volume_repo.get_service_volumes(service.service_id) service_config_file = volume_repo.get_service_config_files(service.service_id) service_ports = port_repo.get_service_ports(tenant.tenant_id, service.service_id) app_info = { "service_base": service_base, "service_labels": [label.to_dict() for label in service_labels], "service_domains": [domain.to_dict() for domain in service_domains], "service_tcpdomains": [tcpdomain.to_dict() for tcpdomain in service_tcpdomains], "service_events": [event.to_dict() for event in service_events], "service_perms": [perm.to_dict() for perm in service_perms], "service_probes": [probe.to_dict() for probe in service_probes], "service_source": service_source.to_dict() if service_source else None, "service_auths": [auth.to_dict() for auth in service_auths], "service_env_vars": [env_var.to_dict() for env_var in service_env_vars], "service_compile_env": service_compile_env.to_dict() if service_compile_env else None, "service_extend_method": service_extend_method.to_dict() if service_extend_method else None, "image_service_relation": image_service_relation.to_dict() if image_service_relation else None, "service_mnts": [mnt.to_dict() for mnt in service_mnts], "service_plugin_relation": [plugin_relation.to_dict() for plugin_relation in service_plugin_relation], "service_plugin_config": [config.to_dict() for config in service_plugin_config], "service_relation": [relation.to_dict() for relation in service_relation], "service_volumes": [volume.to_dict() for volume in service_volumes], "service_config_file": [config_file.to_dict() for config_file in service_config_file], "service_ports": [port.to_dict() for port in service_ports] } return app_info
def check_volume_path(self, service, volume_path, local_path=[]): os_type = label_service.get_service_os_name(service) if os_type == "windows": return for path in local_path: if volume_path.startswith(path + "/"): raise ErrVolumePath(msg="path error", msg_show="持久化路径不能再挂载共享路径下") volume = volume_repo.get_service_volume_by_path( service.service_id, volume_path) if volume: raise ErrVolumePath(msg="path already exists", msg_show="持久化路径[{0}]已存在".format(volume_path), status_code=412) if service.service_source == AppConstants.SOURCE_CODE and service.language != ServiceLanguageConstants.DOCKER_FILE: if volume_path == "/app" or volume_path == "/tmp": raise ErrVolumePath(msg="path error", msg_show="源码组件不能挂载/app或/tmp目录", status_code=409) if not volume_path.startswith("/"): raise ErrVolumePath(msg_show="挂载路径需为标准的 Linux 路径") if volume_path in self.SYSDIRS: raise ErrVolumePath(msg_show="路径{0}为系统路径".format(volume_path)) else: if not is_path_legal(volume_path): raise ErrVolumePath(msg_show="请输入符合规范的路径(如:/tmp/volumes)") all_volumes = volume_repo.get_service_volumes( service.service_id).values("volume_path") for path in list(all_volumes): # volume_path不能重复 if path["volume_path"].startswith(volume_path + "/") or volume_path.startswith( path["volume_path"] + "/"): raise ErrVolumePath(msg="path error", msg_show="已存在以{0}开头的路径".format( path["volume_path"]), status_code=412)
def check_volume_path(self, service, volume_path, local_path): if local_path: for path in local_path: # if volume_path.startswith(path): # return 412, u"持久化路径不能和挂载共享路径相同" if volume_path.startswith(path + "/"): return 412, u"持久化路径不能再挂载共享路径下" volume = volume_repo.get_service_volume_by_path( service.service_id, volume_path) if volume: return 412, u"持久化路径 {0} 已存在".format(volume_path) if service.service_source == AppConstants.SOURCE_CODE: if volume_path == "/app": return 409, u"源码应用不能挂载/app目录" if service.image != "goodrain.me/runner": volume_path_win = False if re.match('[a-zA-Z]', volume_path[0]) and volume_path[1] == ':': volume_path_win = True if not volume_path.startswith("/") and not volume_path_win: return 400, u"路径仅支持linux和windows" if volume_path in self.SYSDIRS: return 412, u"路径{0}为系统路径".format(volume_path) if volume_path_win and len(volume_path) == 3: return 412, u"路径不能为系统路径" else: if not is_path_legal(volume_path): return 412, u"请输入符合规范的路径(如:/app/volumes )" all_volumes = volume_repo.get_service_volumes( service.service_id).values("volume_path") for path in list(all_volumes): # volume_path不能重复 if path["volume_path"].startswith(volume_path + "/"): return 412, u"已存在以{0}开头的路径".format(path["volume_path"]) if volume_path.startswith(path["volume_path"] + "/"): return 412, u"已存在以{0}开头的路径".format(volume_path) return 200, u"success"
def get_service_volumes(self, tenant, service): return volume_repo.get_service_volumes(service.service_id)