def get_latest_image_for_app(app_name, progress_cb=None): app_info = get_app_info(app_name) image_name = app_name if ('image-base-name' in app_info): image_name = app_info['image-base-name'] image_regexp = get_regexp_for_image_name(image_name) latest_image = { 'imagePushedAt': datetime(1970, 1, 1).astimezone() } ecr_client = DockerRepositoryManager.get_ecr_client() list_resp = ecr_client.describe_images( registryId=REGISTRY_ID, repositoryName=image_name, maxResults=1000 ) while True: for cur_image in list_resp['imageDetails']: if 'imageTags' not in cur_image or not any(image_regexp.match(tag) for tag in cur_image['imageTags']): continue if (latest_image['imagePushedAt'] - cur_image['imagePushedAt']).total_seconds() < 0: latest_image = cur_image next_token = list_resp.get('nextToken', None) if next_token is None: break list_resp = ecr_client.describe_images( registryId=REGISTRY_ID, repositoryName=image_name, maxResults=1000, nextToken=next_token ) if progress_cb: progress_cb(f"*{app_name}* latest image in AWS ECR Repository (might not be deployed!):\n`{latest_image['imageTags'][0]}`\npushed to registry on: `{latest_image['imagePushedAt'].strftime('%d-%b-%Y (%H:%M:%S.%f)')}`") return latest_image
def run(self): """读取一个目录,遍历下面的app文件夹,每个app启动一到两条线程对此提供服 务,一条用来发推送,一条用来收feedback """ self.rds.set('ENHANCE_THREAD', 0) apps = utils.get_apps(self.app_dir) self.app_info = {} # 文件夹下面会有production,develop两个子目录,分别放不同的Key及Cert for app in apps: if app.startswith('.'): continue log.debug('getting ready for app : %s' % app) app_info = utils.get_app_info(self.app_dir, app) self.app_info[app] = app_info self.start_worker(app) start_webserver(self) self.watch_app() log.debug('just wait here,there are %d threads ' % len(self.notifiers)) while True: time.sleep(10)
def update_image(app, progress_cb, dry_run=False): app_info = get_app_info(app) kube_client_api = KubeClientApiInstance.get_client_api(app_info) image_to_update = DockerRepositoryManager.get_latest_image_for_app(app) image_tag = image_to_update['imageTags'][0] running_image = KubeApi.get_app_image(app) if running_image is None: progress_cb( f"failed to *{app}* status from deployment: {app_info['deployment']}" ) return if running_image == image_tag: if progress_cb: progress_cb( f'*{app}* running latest image:\n`{running_image}`\nnothing to deploy.' ) return if dry_run: if progress_cb: progress_cb( f"*{app}* Needs to be updated. Currently running:\n `{running_image}`\n" f"and should update to latest image:\n`{image_tag}`\n" f"pushed to registry on: `{image_to_update['imagePushedAt'].strftime('%d-%b-%Y (%H:%M:%S.%f)')}`" ) return if progress_cb: progress_cb( f"Updating *{app}* deployment with image:\n" f"`{image_tag}`\n" f"pushed to registry on: `{image_to_update['imagePushedAt'].strftime('%d-%b-%Y (%H:%M:%S.%f)')}`" f"\nplease wait...") update_patch_body = KubeApi._create_patch_for_deployment( image_to_update, app_info, app) if update_patch_body is None: if progress_cb: progress_cb( f"Failed to generate an update patch for {image_to_update}, could not find a valid tag name for image" ) return try: api_response = kube_client_api.patch_namespaced_deployment( name=app_info['deployment'], namespace=app_info['namespace'], body=update_patch_body, pretty=True) except ApiException as e: if progress_cb: progress_cb(f'failed to read deployment: {e}') if progress_cb: progress_cb(f'{app} updated successfully.')
def start_worker(self, app): log.debug('start an app : %s' % app) app_info = utils.get_app_info(self.app_dir, app) if 'production' in app_info: self.start_worker_thread(app, False, app_info['production']['cer_file'], app_info['production']['key_file']) if 'develop' in app_info: self.start_worker_thread(app, True, app_info['develop']['cer_file'], app_info['develop']['key_file'])
def get_app_image(app, progress_cb=None): app_info = get_app_info(app) kube_client_api = KubeClientApiInstance.get_client_api(app_info) try: api_response = kube_client_api.read_namespaced_deployment( name=app_info.get('deployment'), namespace=app_info.get('namespace'), pretty=True) print(api_response) running_image = api_response.spec.template.spec.containers[ 0].image.split(':')[1] if progress_cb: progress_cb( f'app *{app}* is currently running image\n`{running_image}`' ) return running_image except ApiException as e: if progress_cb: progress_cb(f'failed to read deployment: {e}') return None
def init_app() -> Starlette: app = FastAPI() # 每个app创建特有路由 for app_info in INJECTION_APPS: router = APIRouter() for api_name, params in get_app_info(parse_path=PRASE_PATH, frida_js_path=app_info["absolute_path"]).items(): params_dict = dict(zip(params, function_params_hints[api_name])) if ( api_name in function_params_hints) else dict.fromkeys(params, "bb") model_name = f"{api_name}Model" Model = create_model(model_name, **params_dict) new_api_name = name_transform(api_name) func = generate_function( new_api_name, app_info["script"], model_name, Model ) router.add_api_route(f"/{new_api_name}", func, methods=["POST"]) app.include_router( router, prefix=f"/{app_info['path']}", tags=[app_info["name"]] ) def custom_openapi(): if app.openapi_schema: return app.openapi_schema openapi_schema = get_openapi( title="Arida框架", version="0.0.1", description="基于FastAPI实现的Frida-RPC工具 https://github.com/lateautumn4lin/arida", routes=app.routes, ) openapi_schema["info"]["x-logo"] = { "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png" } app.openapi_schema = openapi_schema return app.openapi_schema app.openapi = custom_openapi return app