Esempio n. 1
0
    def post(self, request, *args, **kwargs):
        service_id = request.POST.get("service_id", "")
        result = {}
        try:
            imsr = ImageServiceRelation.objects.get(service_id=service_id)
            tenant_id = imsr.tenant_id
            image_url = imsr.image_url
            service_cname = imsr.service_cname
        except Exception as e:
            logger.exception(e)
            result["status"] = "notfound"
            return JsonResponse(result, status=200)

        service_alias = "gr" + service_id[-6:]
        try:

            # 从url中分析出来service_cname 和 version

            version = ""
            if ":" in image_url:
                index = image_url.rindex(":")
                if service_cname is None or service_cname == "":
                    str_tmp = image_url.split(":")
                    service_cname = str_tmp[len(str_tmp) - 2]
                version = image_url[index + 1:]
            else:
                if service_cname is None or service_cname == "":
                    service_cname = image_url
                version = "latest"

            # 端口信息
            port_list = json.loads(request.POST.get("port_list", "[]"))
            # 环境变量信息
            env_list = json.loads(request.POST.get("env_list", "[]"))
            # 持久化目录信息
            volume_list = json.loads(request.POST.get("volume_list", "[]"))
            # 依赖服务id
            depIds = json.loads(request.POST.get("depend_list", "[]"))
            # 挂载其他服务目录
            service_alias_list = json.loads(request.POST.get('mnt_list', '[]'))
            # 服务内存
            image_service_memory = int(
                request.POST.get("service_min_memory", 512))
            # 服务扩展方式
            service_status = request.POST.get("methodval", "stateless")

            # 判断是否持久化路径是否合法
            from www.utils.path_judge import is_path_legal
            for volume_url in volume_list:
                url = volume_url.get("volume_path", None)
                if url:
                    if not is_path_legal(url):
                        result["status"] = "failure"
                        result["msg"] = "路径:{0}不合法".format(url)
                        return JsonResponse(result, status=200)

            image_url2 = request.POST.get("image_url", "")
            logger.debug("image_url2 is {}".format(image_url2))
            if image_url2 != "" and image_url2 != image_url:
                image_url = image_url2
                try:
                    ImageServiceRelation.objects.filter(
                        service_id=service_id).update(image_url=image_url)
                    logger.debug(
                        "update image_url image_url {0} to image_url2 {1}".
                        format(image_url, image_url2))
                except Exception, e:
                    logger.error("update image_url error, {}".format(str(e)))
                    result["status"] = "failure"
                    return JsonResponse(result, status=200)
            logger.debug("image_url is {}".format(image_url))
            #  启动命令
            start_cmd = request.POST.get("start_cmd", "")

            service = ServiceInfo()
            service.service_key = "0000"
            service.desc = ""
            service.category = "app_publish"
            service.image = image_url
            service.cmd = start_cmd
            service.setting = ""
            service.extend_method = "stateless"
            service.env = ","
            service.min_node = 1
            cm = 128
            if image_service_memory != "":
                cm = int(image_service_memory)
                if cm < 128:
                    cm *= 1024
            service.min_memory = cm
            service.min_cpu = baseService.calculate_service_cpu(
                self.response_region, cm)
            service.inner_port = 0
            # version version需要从image_url中分析出来
            service.version = version
            service.namespace = "goodrain"
            service.update_version = 1
            service.volume_mount_path = ""
            service.service_type = "application"
            # service host_path
            service.host_path = "/grdata/tenant/" + self.tenant.tenant_id + "/service/" + service_id
            # calculate resource
            tempService = TenantServiceInfo()
            tempService.min_memory = cm
            tempService.service_region = self.response_region
            tempService.min_node = int(service.min_node)

            diffMemory = cm
            # 判断是否超出资源
            rt_type, flag = tenantUsedResource.predict_next_memory(
                self.tenant, tempService, diffMemory, False)
            if not flag:
                if rt_type == "memory":
                    result["status"] = "over_memory"
                    result["tenant_type"] = self.tenant.pay_type
                else:
                    result["status"] = "over_money"
                return JsonResponse(result, status=200)

            newTenantService = baseService.create_service(
                service_id,
                tenant_id,
                service_alias,
                service_cname,
                service,
                self.user.pk,
                region=self.response_region)
            newTenantService.code_from = "image_manual"
            newTenantService.language = "docker-image"
            newTenantService.save()
            self.service = newTenantService

            sai = attach_info_mamage.create_service_attach_info(
                newTenantService,
                newTenantService.min_memory * newTenantService.min_node, 0)

            monitorhook.serviceMonitor(self.user.nick_name, newTenantService,
                                       'create_service', True)

            self.save_ports_envs_and_volumes(port_list, env_list, volume_list,
                                             newTenantService)
            baseService.create_region_service(newTenantService,
                                              self.tenantName,
                                              self.response_region,
                                              self.user.nick_name,
                                              dep_sids=json.dumps([]))

            baseService.batch_add_dep_volume_v2(self.tenant, self.service,
                                                service_alias_list)

            data = {}
            data[
                "label_values"] = "无状态的应用" if service_status == "stateless" else "有状态的应用"
            data["enterprise_id"] = self.tenant.enterprise_id
            region_api.update_service_state_label(self.response_region,
                                                  self.tenantName,
                                                  self.service.service_alias,
                                                  data)
            self.service.extend_method = service_status
            self.service.save()

            # 发送build请求
            body = {}
            event = self.create_service_event(newTenantService, self.tenant,
                                              "deploy")
            kind = "image"
            body["event_id"] = event.event_id
            body["deploy_version"] = newTenantService.deploy_version
            body["operator"] = self.user.nick_name
            body["action"] = "upgrade"
            body["kind"] = kind

            envs = {}
            buildEnvs = TenantServiceEnvVar.objects.filter(
                service_id=service_id,
                attr_name__in=("COMPILE_ENV", "NO_CACHE", "DEBUG", "PROXY",
                               "SBT_EXTRAS_OPTS"))
            for benv in buildEnvs:
                envs[benv.attr_name] = benv.attr_value
            body["envs"] = envs

            body["enterprise_id"] = self.tenant.enterprise_id
            region_api.build_service(newTenantService.service_region,
                                     self.tenantName,
                                     newTenantService.service_alias, body)

            monitorhook.serviceMonitor(self.user.nick_name, newTenantService,
                                       'init_region_service', True)

            logger.debug(depIds)
            for sid in depIds:
                try:
                    baseService.create_service_dependency(
                        self.tenant, newTenantService, sid,
                        self.response_region)
                except Exception as e:
                    logger.exception(e)

            result["status"] = "success"
            result["service_id"] = service_id
            result["service_alias"] = service_alias

            attach_info_mamage.update_attach_info_by_tenant(
                self.tenant, self.service)
    def post(self, request, *args, **kwargs):
        data = {}
        service_alias_list = []
        init_region = False
        try:
            # 内存大小
            min_memory = int(request.POST.get("service_min_memory", 512))
            if min_memory < 128:
                min_memory *= 1024
            # 端口信息
            port_list = json.loads(request.POST.get("port_list", "[]"))
            # 环境变量信息
            env_list = json.loads(request.POST.get("env_list", "[]"))
            # 持久化目录信息
            volume_list = json.loads(request.POST.get("volume_list", "[]"))
            # 依赖服务id
            depIds = json.loads(request.POST.get("depend_list", "[]"))
            # 挂载其他服务目录
            service_alias_list = json.loads(request.POST.get("mnt_list", "[]"))
            # 服务扩展方式
            service_status = request.POST.get("methodval", "stateless")
            # 将刚开始创建的5000端口删除
            previous_list = map(
                lambda containerPort: containerPort["container_port"],
                port_list)

            from www.utils.path_judge import is_path_legal
            for volume_url in volume_list:
                url = volume_url.get("volume_path", None)
                if url:
                    if not is_path_legal(url):
                        result = {
                            "status": "failure",
                            "msg": "路径:{0}不合法".format(url)
                        }
                        return JsonResponse(result, status=200)

            # 处理用户自定义的port
            if len(previous_list) == 0:
                TenantServicesPort.objects.filter(
                    service_id=self.service.service_id).delete()
            else:
                delete_default_port = True
                for tmp_port in previous_list:
                    if tmp_port == 5000:
                        delete_default_port = False
                        continue
                if delete_default_port:
                    TenantServicesPort.objects.filter(
                        service_id=self.service.service_id,
                        container_port=5000).delete()

            newTenantService = TenantServiceInfo.objects.get(
                tenant_id=self.tenant.tenant_id,
                service_id=self.service.service_id)

            newTenantService.min_memory = min_memory
            cpu = baseService.calculate_service_cpu(self.response_region,
                                                    min_memory)
            newTenantService.min_cpu = cpu

            diffMemory = newTenantService.min_node * newTenantService.min_memory
            rt_type, flag = tenantUsedResource.predict_next_memory(
                self.tenant, newTenantService, diffMemory, False)
            if not flag:
                if rt_type == "memory":
                    data["status"] = "over_memory"
                    data["tenant_type"] = self.tenant.pay_type
                else:
                    data["status"] = "over_money"
                return JsonResponse(data, status=200)

            # newTenantService.expired_time = self.tenant.expired_time
            newTenantService.save()
            self.save_ports_envs_and_volumes(port_list, env_list, volume_list,
                                             newTenantService)

            baseService.create_region_service(newTenantService,
                                              self.tenantName,
                                              self.response_region,
                                              self.user.nick_name)

            # 创建挂载目录
            baseService.batch_add_dep_volume_v2(self.tenant, self.service,
                                                service_alias_list)
            baseService.add_service_default_probe(self.tenant, self.service)

            body = dict()
            body[
                "label_value"] = "StatelessServiceType" if service_status == "stateless" else "StatefulServiceType"
            data["label_key"] = "service-type"
            service_label_list = list()
            service_label_list.append(data)
            body_dict = {"labels": service_label_list}
            region_api.update_service_state_label(self.response_region,
                                                  self.tenantName,
                                                  self.serviceAlias, body_dict)
            newTenantService.extend_method = service_status
            newTenantService.save()

            init_region = True
            logger.debug(depIds)
            if len(depIds) > 0:
                # 检查当前服务是否有GDADAPTER参数
                for sid in depIds:
                    try:
                        baseService.create_service_dependency(
                            self.tenant, self.service, sid,
                            self.response_region)
                    except Exception as e:
                        logger.exception(e)

            data["status"] = "success"

        except Exception as e:
            TenantServiceEnvVar.objects.filter(
                service_id=self.service.service_id).delete()
            TenantServiceVolume.objects.filter(
                service_id=self.service.service_id).delete()
            TenantServiceMountRelation.objects.filter(
                service_id=self.service.service_id).delete()
            if len(service_alias_list) > 0:
                for vol in service_alias_list:
                    baseService.delete_dep_volume_v2(self.tenant, self.service,
                                                     vol['id'])
                    # baseService.cancel_service_mnt(self.tenant, self.service, dep_service_alias, self.service.service_region)
            if init_region:
                region_api.delete_service(self.service.service_region,
                                          self.tenantName,
                                          self.service.service_alias,
                                          self.tenant.enterprise_id)
            logger.exception(e)
            logger.error("AppSettingsView create service error!")
            data["status"] = "failure"
        return JsonResponse(data, status=200)