def __init__(self, job, *args, **kwargs): self.job = job self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs['region']) self.oss_api = OssAPI(conf=self.configs['oss']['ali_shanghai']) self.locker = TaskLocker(conf=self.configs['etcd']) self.user_cs_client = UserConsoleAPI(conf=self.configs['userconsole']) self.api = ACPAPI(conf=self.configs['region']) self.region_client = RegionBackAPI() self.slug_configs = self.configs["publish"]["slug"] self.is_region_slug = self.slug_configs.get('all_region_ftp') self.is_oss_ftp = self.slug_configs.get('oss_ftp') # 用户文件存储路径 self.SRV_SLUG_BASE_DIR = self.slug_configs.get( 'slug_path') + '{tenantId}/slug/{serviceId}/{deployVersion}.tgz' # 数据中心slug存储路径 self.SLUG_PATH = self.slug_configs.get( 'curr_region_dir') + '{serviceKey}/{appVersion}.tgz' self.CURR_REGION_PATH = self.slug_configs.get( 'curr_region_path') + self.SLUG_PATH # 区域中心slug的ftp配置 self.ALL_REGION_FTP_HOST = self.slug_configs.get('all_region_ftp_host') self.ALL_REGION_FTP_PORT = self.slug_configs.get('all_region_ftp_port') self.ALL_REGION_FTP_USERNAME = self.slug_configs.get( 'all_region_username') self.ALL_REGION_FTP_PASSWORD = self.slug_configs.get( 'all_region_password') self.ALL_REGION_FTP_NAMESPACE = self.slug_configs.get( 'all_region_namespace') self.ALL_REGION_FTP_PATH = self.ALL_REGION_FTP_NAMESPACE + '{serviceKey}/{appVersion}.tgz' # oss存储路径 CLOUD_ASSISTANT = self.configs.get('CLOUD_ASSISTANT') self.OSS_BUCKET = self.slug_configs.get('oss_bucket', "") self.OSS_OBJECT_NAME = CLOUD_ASSISTANT + '/{serviceKey}/{appVersion}.tgz' logger.debug("mq_work.app_slug", 'init app slug')
def __init__(self, job, *args, **kwargs): self.job = job self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs['region']) image_config = self.configs["publish"]["image"] self.region_client = RegionBackAPI() self.region_registry = RegistryAPI( host=image_config.get('curr_registry')) # self.region_registry.set_log_topic('mq_work.image_manual') self.oss_registry = RegistryAPI(host=image_config.get('all_registry')) self.oss_registry.set_log_topic('mq_work.image_manual') self.locker = TaskLocker(conf=self.configs['etcd']) self.api = ACPAPI(conf=self.configs['region']) self.namespace = image_config.get('oss_namespace') self.user_cs_client = UserConsoleAPI(conf=self.configs['userconsole'])
def __init__(self, job, *args, **kwargs): self.job = job self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs["region"]) self.region_client = RegionBackAPI() self.api = ACPAPI(conf=self.configs['region']) image_config = self.configs["publish"]["image"] self.region_registry = RegistryAPI( host=image_config.get('curr_registry')) self.oss_registry = RegistryAPI(host=image_config.get('all_registry')) self.region_registry.set_log_topic('mq_work.app_image') self.oss_registry.set_log_topic('mq_work.app_image') self.locker = TaskLocker(conf=self.configs['etcd']) self.namespace = image_config.get('oss_namespace') self.user_cs_client = UserConsoleAPI(conf=self.configs["userconsole"]) self.hubclient = HubUtils(image_config) # 是否配置oss.goodrain.me self.is_region_image = image_config.get('all_region_image') self.is_oss_image = image_config.get('oss_image')
def __init__(self, task, *args, **kwargs): self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs['region']) self.api = ACPAPI(conf=self.configs['region']) self.user_cs_client = UserConsoleAPI(conf=self.configs['userconsole']) self.repo_url = task['repo_url'] self.region_client = RegionBackAPI() self.tenant_id = task['tenant_id'] self.service_id = task['service_id'] self.tenant_name = task['tenant_name'] self.service_alias = task['service_alias'] self.deploy_version = task['deploy_version'] self.action = task['action'] if 'event_id' in task: self.event_id = task["event_id"] self.log = EventLog().bind(event_id=self.event_id) else: self.event_id = "" self.log = EventLog().bind(event_id=self.event_id) self.operator = task['operator'] self.build_envs = task.get('envs', {}) self.expire = task.get('expire', 60) self.start_time = int(time.time()) # self.source_dir = '/tmp/goodrain_web' self.source_dir = SOURCE_DIR.format(tenantId=self.tenant_id, serviceId=self.service_id) self.cache_dir = CACHE_DIR.format(tenantId=self.tenant_id, serviceId=self.service_id) self.tgz_dir = TGZ_DIR.format(tenantId=self.tenant_id, serviceId=self.service_id) self.build_log_dir = BUILD_LOG_DIR.format(tenantId=self.tenant_id, serviceId=self.service_id) self.build_cmd = 'plugins/scripts/build.pl'
class ImageManual(): def __init__(self, job, *args, **kwargs): self.job = job self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs['region']) image_config = self.configs["publish"]["image"] self.region_client = RegionBackAPI() self.region_registry = RegistryAPI( host=image_config.get('curr_registry')) # self.region_registry.set_log_topic('mq_work.image_manual') self.oss_registry = RegistryAPI(host=image_config.get('all_registry')) self.oss_registry.set_log_topic('mq_work.image_manual') self.locker = TaskLocker(conf=self.configs['etcd']) self.api = ACPAPI(conf=self.configs['region']) self.namespace = image_config.get('oss_namespace') self.user_cs_client = UserConsoleAPI(conf=self.configs['userconsole']) def do_work(self): try: task = json.loads(self.job.body) self.task = task if "event_id" in self.task: self.event_id = task["event_id"] self.log = EventLog().bind(event_id=self.event_id, step="image_manual") else: self.event_id = "" self.log = EventLog().bind(event_id="", step="image_manual") logger.info("mq_work.image_manual", "new image_manual task: {}".format(task)) if task['action'] == 'create_new_version': self.log.info("开始升级应用。") self.create_new_version() elif task['action'] == 'download_and_deploy': self.log.info("开始下载镜像并部署应用。") self.download_and_deploy() elif task['action'] == 'delete_old_version': self.log.info("开始删除旧版本。") self.delete_old_version() except Exception as e: if self.log: self.log.error("从自定义镜像部署应用失败。{}".format(e.message), step="callback", status="failure") logger.exception('mq_work.image_manual', e) def create_new_version(self): logger.debug("mq_work.image_manual", "now create new version and upload image") def delete_old_version(self): logger.debug("mq_work.image_manual", "now delete old version") def download_and_deploy(self): image = self.task['image'] # namespace = self.task['namespace'] tenant_name = self.task['tenant_name'] service_alias = self.task['service_alias'] event_id = self.task['event_id'] service_alias = self.task.get("service_alias", None) has_download = False inner_image = self.oss_registry.rename_image(image) inner_image = "{0}_{1}".format(inner_image, service_alias) local_image = self.region_registry.rename_image(image) local_image = "{0}_{1}".format(local_image, service_alias) # 直接下载docker image try: self.log.info("开始下载镜像:{0}".format(image)) pull_result = self._pull(image) if pull_result: # image_id = self.get_image_property(image, 'Id') self._tag(image, local_image) self.log.info("修改镜像名为:{0}".format(local_image)) ok = self._push(local_image) if not ok: self.log.error("上传镜像发生错误,重试失败,退出。", step="callback", status="failure") return self.log.info("镜像推送到本地仓库完成。") # self._tag(image, inner_image) # self._push(inner_image) has_download = True else: self.log.error("下载镜像发生错误。", step="callback", status="failure") logger.error("mq_work.image_manual", "download image failed! image:{}".format(image)) except Exception as e: self.log.error("镜像操作发生错误。{0}".format(e.__str__()), step="callback", status="failure") logger.exception("mq_work.image_manual", e) version_status = { "final_status": "failure", } if has_download: self.log.info("应用同步完成。", step="app-image", status="success") version_body = { "type": 'image', "path": local_image, "event_id": self.event_id } version_status['final_status'] = "success" try: self.region_client.update_version_region( json.dumps(version_body)) self.region_client.update_version_event( self.event_id, json.dumps(version_status)) except Exception as e: pass try: self.api.update_iamge(tenant_name, service_alias, local_image) self.log.info("应用信息更新完成,开始启动应用。", step="app-image", status="success") self.api.start_service(tenant_name, service_alias, event_id) except Exception as e: logger.exception(e) self.log.error("应用自动启动失败。请手动启动", step="callback", status="failure") else: try: self.region_client.update_version_event( self.event_id, json.dumps(version_status)) except Exception as e: pass self.log.error("应用同步失败。", step="callback", status="failure") def queryServiceStatus(self, service_id): try: res, body = self.region_api.is_service_running(service_id) logger.info( 'mq_work.image_manual', "service_id=" + service_id + ";body=" + json.dumps(body)) status = body.get(service_id, "closed") if status == "running": self.log.debug("依赖的应用状态已经为运行中。", step="worker") return True except: pass self.log.debug("依赖的应用状态不是运行中,本应用稍后启动。", step="worker") return False def get_image_property(self, image, name): query_format = '{{.%s}}' % name try: output = shell.call("{2} inspect -f '{0}' {1}".format( query_format, image, DOCKER_BIN)) if output == '<no value>': return None else: return output[0].rstrip('\n') except shell.ExecException, e: logger.exception("mq_work.image_manual", e) return None
class AppSlug(): def __init__(self, job, *args, **kwargs): self.job = job self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs['region']) self.oss_api = OssAPI(conf=self.configs['oss']['ali_shanghai']) self.locker = TaskLocker(conf=self.configs['etcd']) self.user_cs_client = UserConsoleAPI(conf=self.configs['userconsole']) self.api = ACPAPI(conf=self.configs['region']) self.region_client = RegionBackAPI() self.slug_configs = self.configs["publish"]["slug"] self.is_region_slug = self.slug_configs.get('all_region_ftp') self.is_oss_ftp = self.slug_configs.get('oss_ftp') # 用户文件存储路径 self.SRV_SLUG_BASE_DIR = self.slug_configs.get( 'slug_path') + '{tenantId}/slug/{serviceId}/{deployVersion}.tgz' # 数据中心slug存储路径 self.SLUG_PATH = self.slug_configs.get( 'curr_region_dir') + '{serviceKey}/{appVersion}.tgz' self.CURR_REGION_PATH = self.slug_configs.get( 'curr_region_path') + self.SLUG_PATH # 区域中心slug的ftp配置 self.ALL_REGION_FTP_HOST = self.slug_configs.get('all_region_ftp_host') self.ALL_REGION_FTP_PORT = self.slug_configs.get('all_region_ftp_port') self.ALL_REGION_FTP_USERNAME = self.slug_configs.get( 'all_region_username') self.ALL_REGION_FTP_PASSWORD = self.slug_configs.get( 'all_region_password') self.ALL_REGION_FTP_NAMESPACE = self.slug_configs.get( 'all_region_namespace') self.ALL_REGION_FTP_PATH = self.ALL_REGION_FTP_NAMESPACE + '{serviceKey}/{appVersion}.tgz' # oss存储路径 CLOUD_ASSISTANT = self.configs.get('CLOUD_ASSISTANT') self.OSS_BUCKET = self.slug_configs.get('oss_bucket', "") self.OSS_OBJECT_NAME = CLOUD_ASSISTANT + '/{serviceKey}/{appVersion}.tgz' logger.debug("mq_work.app_slug", 'init app slug') def do_work(self): try: logger.debug("mq_work.app_slug", 'get task....{}'.format(self.job.body)) task = json.loads(self.job.body) self.task = task if "event_id" in self.task: self.event_id = task["event_id"] self.log = EventLog().bind( event_id=self.event_id, step="image_manual") else: self.event_id = "" self.log = EventLog().bind(event_id="", step="image_manual") if task['action'] == 'create_new_version': self.log.info("开始分享新版本应用。") self.create_new_version() elif task['action'] == 'download_and_deploy': self.log.info("开始同步应用。") self.download_and_deploy() elif task['action'] == 'delete_old_version': self.log.info("开始删除旧版本应用。") self.delete_old_version() except Exception as e: logger.exception('mq_work.app_slug', e) def _upload_ftp(self, service_key, app_version, md5file): """ 上传文件到ftp """ utils = FTPUtils( host=self.ALL_REGION_FTP_HOST, username=self.ALL_REGION_FTP_USERNAME, password=self.ALL_REGION_FTP_PASSWORD, namespace=self.ALL_REGION_FTP_NAMESPACE, port=self.ALL_REGION_FTP_PORT) # 检查service_key对应的文件是否存在,不存在生成 service_dir = self.ALL_REGION_FTP_NAMESPACE + service_key logger.debug("mq_work.app_slug", 'slug task is {}'.format(self.task)) logger.debug("mq_work.app_slug", '*******upload dir is {}'.format(service_dir)) utils.check_dir(service_dir) # 上传文件 curr_region_slug = self.CURR_REGION_PATH.format( serviceKey=service_key, appVersion=app_version) logger.debug("mq_work.app_slug", '*******upload file path is {}'.format(curr_region_slug)) utils.upload(service_dir, curr_region_slug) # 上传md5文件 if md5file: utils.upload(service_dir, md5file) return True def _create_md5(self, md5string, dest_slug_file): try: md5file = dest_slug_file + ".md5" f = open(md5file, "w") f.write(md5string) f.close() return md5file except Exception as e: logger.error("mq_work.app_slug", "sum file md5 filed!") logger.exception("mq_work.app_slug", e) return None def _check_md5(self, md5string, md5file): try: f = open(md5file) new_md5 = f.readline() return md5string == new_md5 except Exception as e: logger.error("mq_work.app_slug", "check md5 filed!") logger.exception("mq_work.app_slug", e) return False def create_new_version(self): service_key = self.task['service_key'] app_version = self.task['app_version'] service_id = self.task['service_id'] deploy_version = self.task['deploy_version'] tenant_id = self.task['tenant_id'] dest = self.task['dest'] share_id = self.task.get('share_id', None) # 检查数据中心下路径是否存在 source_slug_file = self.SRV_SLUG_BASE_DIR.format( tenantId=tenant_id, serviceId=service_id, deployVersion=deploy_version) self.log.debug("数据中心文件路径{0}".format(source_slug_file)) # 当前数据中心文件名称 dest_slug_file = self.CURR_REGION_PATH.format( serviceKey=service_key, appVersion=app_version) self.log.debug('当前数据中心文件名称'.format(dest_slug_file)) # 检查目录是否存在 curr_region_dir = os.path.dirname(dest_slug_file) if not os.path.exists(curr_region_dir): os.makedirs(curr_region_dir) # 复制文件 self.log.debug( "开始复制文件 file {0} to {1}".format(source_slug_file, dest_slug_file)) shutil.copyfile(source_slug_file, dest_slug_file) # 计算md5 md5string = get_md5(source_slug_file) # 生成md5file md5file = self._create_md5(md5string, dest_slug_file) if md5file is None: self.log.error("md5文件没有生成。") # 区域中心对象存储,使用ftp slug = self.SLUG_PATH.format( serviceKey=service_key, appVersion=app_version) if dest == "yb": data = { 'service_key': service_key, 'app_version': app_version, 'slug': slug, 'image': "", 'dest_yb': True, 'dest_ys': False, } if share_id is not None: data['share_id'] = share_id try: self.region_client.service_publish_new_region(data) except Exception as e: self.region_client.service_publish_failure_region(data) self.log.error( "云帮应用本地发布失败,保存publish 失败。{0}".format(e.message), step="callback", status="failure") pass if self.is_region_slug: try: self.log.info("开始上传应用到本地云帮") self._upload_ftp(service_key, app_version, md5file) logger.debug("mq_work.app_slug", "*******ftp upload success!") # self.update_publish_event(event_id=event_id, status='end', desc=u"云帮应用本地发布完毕") self.user_cs_client.service_publish_success( json.dumps(data)) try: self.region_client.service_publish_success_region(data) except Exception as e: self.region_client.service_publish_failure_region(data) logger.exception(e) pass self.log.info("云帮应用本地发布完毕", step="last", status="success") except Exception as e: logger.error("mq_work.app_slug", "*******ftp upload failed") logger.exception("mq_work.app_slug", e) self.region_client.service_publish_failure_region(data) self.log.info( "云帮应用本地发布失败。{}".format(e.message), step="callback", status="failure") else: self.user_cs_client.service_publish_success(json.dumps(data)) try: self.region_client.service_publish_success_region(data) except Exception as e: self.region_client.service_publish_failure_region(data) logger.exception(e) pass self.log.info("云帮应用本地发布完毕", step="last", status="success") elif dest == "ys": data = { 'service_key': service_key, 'app_version': app_version, 'slug': slug, 'image': "", 'dest_ys': True, 'dest_yb': False } if share_id is not None: data['share_id'] = share_id try: self.region_client.service_publish_new_region(data) except Exception as e: self.region_client.service_publish_failure_region(data) self.log.error( "云帮应用本地发布失败,保存publish 失败。{0}".format(e.message), step="callback", status="failure") pass if self.is_oss_ftp: try: self.log.info("开始上传应用到云市") self._upload_ftp(service_key, app_version, md5file) logger.debug("mq_work.app_slug", "*******ftp upload success!") self.log.info("云市应用发布完毕", step="last", status="success") self.user_cs_client.service_publish_success( json.dumps(data)) try: self.region_client.service_publish_success_region(data) except Exception as e: logger.exception(e) self.region_client.service_publish_failure_region(data) pass except Exception as e: logger.error("mq_work.app_slug", "*******ftp upload failed, {0}".format(e)) self.region_client.service_publish_failure_region(data) self.log.error( "云市应用发布失败.", status="failure", step="callback") else: self.user_cs_client.service_publish_success(json.dumps(data)) try: self.region_client.service_publish_success_region(data) except Exception as e: logger.exception(e) self.region_client.service_publish_failure_region(data) pass self.log.info("云市应用发布完毕", step="last", status="success") def _download_ftp(self, service_key, app_version, namespace, is_md5=False): """ 云帮ftp下载文件 """ utils = FTPUtils( host=self.ALL_REGION_FTP_HOST, username=self.ALL_REGION_FTP_USERNAME, password=self.ALL_REGION_FTP_PASSWORD, namespace=self.ALL_REGION_FTP_NAMESPACE, port=self.ALL_REGION_FTP_PORT) logger.info("mq_work.app_slug", "*******[download]download file from ftp") # 检查service_key对应的文件是否存在,不存在生成 remote_file = self.ALL_REGION_FTP_PATH.format( serviceKey=service_key, appVersion=app_version) if is_md5: remote_file += ".md5" if not namespace: logger.info("mq_work.app_slug", "*******[download]namespace is null") logger.error("mq_work.app_slug", "*******[download]namespace is null") else: logger.info("mq_work.app_slug", "*******[download]namespace is {}".format(namespace)) remote_file = "../" + namespace + "/" + remote_file logger.info("mq_work.app_slug", "*******[download]remote file is {}".format(remote_file)) curr_region_slug = self.CURR_REGION_PATH.format( serviceKey=service_key, appVersion=app_version) if is_md5: curr_region_slug += ".md5" logger.info( "mq_work.app_slug", "*******[download]curr_region_slug is {}".format(curr_region_slug)) return utils.download(remote_file, curr_region_slug) def _download_ftp_market(self, service_key, app_version, namespace, is_md5=False): """ 云市ftp下载文件 """ utils = FTPUtils( host=self.ALL_REGION_FTP_HOST, username=self.ALL_REGION_FTP_USERNAME, password=self.ALL_REGION_FTP_PASSWORD, namespace=self.ALL_REGION_FTP_NAMESPACE, port=self.ALL_REGION_FTP_PORT) logger.info("mq_work.app_slug", "*******[download]download file from ftp") # 检查service_key对应的文件是否存在,不存在生成 remote_file = self.ALL_REGION_FTP_PATH.format( serviceKey=service_key, appVersion=app_version) if is_md5: remote_file += ".md5" if not namespace: logger.info("mq_work.app_slug", "*******[download]namespace is null") logger.error("mq_work.app_slug", "*******[download]namespace is null") else: logger.info("mq_work.app_slug", "*******[download]namespace is {}".format(namespace)) remote_file = "../" + namespace + "/" + remote_file logger.info("mq_work.app_slug", "*******[download]remote file is {}".format(remote_file)) curr_region_slug = self.CURR_REGION_PATH.format( serviceKey=service_key, appVersion=app_version) if is_md5: curr_region_slug += ".md5" logger.info( "mq_work.app_slug", "*******[download]curr_region_slug is {}".format(curr_region_slug)) return utils.download(remote_file, curr_region_slug) def download_and_deploy(self): """ 下载slug包 """ def start_service(service_id, deploy_version, operator): # body = { # "deploy_version": deploy_version, # "operator": operator, # "event_id": self.event_id # } body = { "deploy_version": deploy_version, "event_id": self.event_id } try: # logger.info("mq_work.app_slug", "start service {}:{}".format(service_id, deploy_version)) self.log.info("开始调用api启动应用。") self.api.upgrade_service(self.tenant_name, self.service_alias, json.dumps(body)) # self.region_api.start_service(service_id, json.dumps(body)) except self.region_api.CallApiError, e: self.log.info( "开始调用api启动应用失败。{}".format(e.message), step="callback", status="failure") logger.exception("mq_work.app_slug", e) service_key = self.task['app_key'] namespace = self.task['namespace'] app_version = self.task['app_version'] tenant_name = self.task['tenant_name'] service_alias = self.task['service_alias'] event_id = self.task['event_id'] # 检查数据中心的是否存在slug包 dest_slug_file = self.CURR_REGION_PATH.format( serviceKey=service_key, appVersion=app_version) logger.info("mq_work.app_slug", "dest_slug_file:{}".format(dest_slug_file)) ftp_ok = False try: # 检查当前服务器是否有slug文件 if os.path.exists(dest_slug_file): self.log.debug("当前服务器存在本应用。本机同步开始") md5string = get_md5(dest_slug_file) # 检查云帮ftp是否打开, 下载md5进行校验 md5_ok = False if self.is_region_slug: self.log.debug("文件MD5校验开始。") try: md5_ok = self._download_ftp(service_key, app_version, namespace, True) self.log.info("MD5校验完成。") except Exception as e: logger.info( "mq_work.app_slug", "download md5 file from cloudassistant ftp failed!" ) self.log.error( "MD5校验失败。{}".format(e.message), step="callback", status="failure") logger.exception("mq_work.app_slug", e) # md5未下载并且云市ftp开启 if not md5_ok and self.is_oss_ftp: self.log.info("MD5校验不通过。开始从云市同步新版本。") try: md5_ok = self._download_ftp_market( service_key, app_version, namespace, True) except Exception as e: self.log.info( "从云市同步新版本发生异常。{}".format(e.message), step="callback", status="failure") logger.exception("mq_work.app_slug", e) if md5_ok: md5file = dest_slug_file + ".md5" same_file = self._check_md5(md5string, md5file) if same_file: logger.debug("mq_work.app_slug", "md5 check same.") ftp_ok = True else: logger.debug( "mq_work.app_slug", "file md5 is changed, now delete old file") os.remove(dest_slug_file) else: logger.debug("mq_work.app_slug", "md5file download failed, now delete slug") os.remove(dest_slug_file) # 检查当前服务器是否有slug文件 if not os.path.exists(dest_slug_file): curr_region_dir = os.path.dirname(dest_slug_file) if not os.path.exists(curr_region_dir): os.makedirs(curr_region_dir) logger.debug("mq_work.app_slug", "now check ftp:".format(self.is_region_slug)) # 云帮ftp开关是否打开 if self.is_region_slug: logger.debug('mq_work.app_slug', 'now check file on ftp!') try: ftp_ok = self._download_ftp(service_key, app_version, namespace) except Exception as e: logger.info("mq_work.app_slug", "download object failed") logger.exception("mq_work.app_slug", e) logger.debug( "mq_work.app_slug", "*******[ftp download slug]result:==={}".format( ftp_ok)) # 判断是否需要从云市上下载,未下载并且云市ftp开启 if not ftp_ok and self.is_oss_ftp: logger.info( "mq_work.app_slug", "now download from hub ftp:{}".format(dest_slug_file)) ftp_ok = self._download_ftp_market(service_key, app_version, namespace) logger.debug( "mq_work.app_slug", "*******[ftp download slug]result:==={}".format( ftp_ok)) else: ftp_ok = True except Exception as e: logger.exception("mq_work.app_slug", e) version_status = { "final_status":"failure", } if ftp_ok: self.log.info("应用同步完成,开始启动应用。", step="app-image", status="success") version_body = { "type": 'slug', "path": dest_slug_file, "event_id": self.event_id } version_status = { "final_status":"success", } try: self.region_client.update_version_region(json.dumps(version_body)) self.region_client.update_version_event(self.event_id,json.dumps(version_status)) except Exception as e: pass try: body = { "deploy_version": self.task['deploy_version'], "event_id": self.event_id } # self.api.start_service(tenant_name, service_alias, event_id) self.api.upgrade_service(self.task['tenant_name'], self.task['service_alias'], json.dumps(body)) except Exception as e: logger.exception(e) self.log.error( "应用自动启动失败。请手动启动", step="callback", status="failure") else: self.log.error("应用同步失败。", step="callback", status="failure") try: self.region_client.update_version_event(self.event_id,json.dumps(version_status)) except Exception as e: self.log.error("更新version信息失败", step="app-slug") pass
class ImageManual(): def __init__(self, job, *args, **kwargs): self.job = job self.configs = kwargs.get("config") self.region_api = RegionAPI(conf=self.configs['region']) image_config = self.configs["publish"]["image"] self.region_client = RegionBackAPI() self.region_registry = RegistryAPI( host=image_config.get('curr_registry')) # self.region_registry.set_log_topic('mq_work.image_manual') self.oss_registry = RegistryAPI(host=image_config.get('all_registry')) self.oss_registry.set_log_topic('mq_work.image_manual') self.locker = TaskLocker(conf=self.configs['etcd']) self.api = ACPAPI(conf=self.configs['region']) self.namespace = image_config.get('oss_namespace') self.user_cs_client = UserConsoleAPI(conf=self.configs['userconsole']) def do_work(self): try: task = json.loads(self.job.body) self.task = task if "event_id" in self.task: self.event_id = task["event_id"] self.log = EventLog().bind( event_id=self.event_id, step="image_manual") else: self.event_id = "" self.log = EventLog().bind(event_id="", step="image_manual") logger.info("mq_work.image_manual", "new image_manual task: {}".format(task)) if task['action'] == 'create_new_version': self.log.info("开始升级应用。") self.create_new_version() elif task['action'] == 'download_and_deploy': self.log.info("开始下载镜像并部署应用。") self.download_and_deploy() elif task['action'] == 'delete_old_version': self.log.info("开始删除旧版本。") self.delete_old_version() except Exception as e: if self.log: self.log.error( "从自定义镜像部署应用失败。{}".format(e.message), step="callback", status="failure") logger.exception('mq_work.image_manual', e) def create_new_version(self): logger.debug("mq_work.image_manual", "now create new version and upload image") def delete_old_version(self): logger.debug("mq_work.image_manual", "now delete old version") def download_and_deploy(self): image = self.task['image'] # namespace = self.task['namespace'] tenant_name = self.task['tenant_name'] service_alias = self.task['service_alias'] event_id = self.task['event_id'] service_alias = self.task.get("service_alias", None) has_download = False inner_image = self.oss_registry.rename_image(image) inner_image = "{0}_{1}".format(inner_image, service_alias) local_image = self.region_registry.rename_image(image) local_image = "{0}_{1}".format(local_image, service_alias) # 直接下载docker image try: self.log.info("开始下载镜像:{0}".format(image)) pull_result = self._pull(image) if pull_result: # image_id = self.get_image_property(image, 'Id') self._tag(image, local_image) self.log.info("修改镜像名为:{0}".format(local_image)) ok = self._push(local_image) if not ok: self.log.error( "上传镜像发生错误,重试失败,退出。", step="callback", status="failure") return self.log.info("镜像推送到本地仓库完成。") # self._tag(image, inner_image) # self._push(inner_image) has_download = True else: self.log.error("下载镜像发生错误。", step="callback", status="failure") logger.error("mq_work.image_manual", "download image failed! image:{}".format(image)) except Exception as e: self.log.error( "镜像操作发生错误。{0}".format(e.__str__()), step="callback", status="failure") logger.exception("mq_work.image_manual", e) version_status = { "final_status":"failure", } if has_download: self.log.info("应用同步完成。", step="app-image", status="success") version_body = { "type": 'image', "path": local_image, "event_id": self.event_id } body = { "deploy_version": self.task['deploy_version'], "event_id": self.event_id, } version_status['final_status'] = "success" try: self.region_client.update_version_region(json.dumps(version_body)) self.region_client.update_version_event(self.event_id,json.dumps(version_status)) except Exception as e: pass try: self.api.update_iamge(tenant_name, service_alias, local_image) version = self.task['deploy_version'] self.log.info("应用信息更新完成,开始启动应用。", step="app-image", status="success") self.api.upgrade_service(self.task['tenant_name'], self.task['service_alias'], json.dumps(body)) # self.api.start_service(tenant_name, service_alias, event_id) except Exception as e: logger.exception(e) self.log.error( "应用自动启动失败。请手动启动", step="callback", status="failure") else: try: self.region_client.update_version_event(self.event_id,json.dumps(version_status)) except Exception as e: pass self.log.error("应用同步失败。", step="callback", status="failure") def queryServiceStatus(self, service_id): try: res, body = self.region_api.is_service_running(service_id) logger.info( 'mq_work.image_manual', "service_id=" + service_id + ";body=" + json.dumps(body)) status = body.get(service_id, "closed") if status == "running": self.log.debug("依赖的应用状态已经为运行中。", step="worker") return True except: pass self.log.debug("依赖的应用状态不是运行中,本应用稍后启动。", step="worker") return False def get_image_property(self, image, name): query_format = '{{.%s}}' % name try: output = shell.call("{2} inspect -f '{0}' {1}".format( query_format, image, DOCKER_BIN)) if output == '<no value>': return None else: return output[0].rstrip('\n') except shell.ExecException, e: logger.exception("mq_work.image_manual", e) return None