Esempio n. 1
0
    async def execute_run(self, project: Project, flow_id: str, context: Context):

        env = await context.get('env', YouwolEnvironment)

        await context.info(text="create 'cdn.zip' in project")
        files = await self.packaged_files(project, flow_id, context)
        zip_path = project.path / 'cdn.zip'
        await create_cdn_zip(zip_path=zip_path, project=project, flow_id=flow_id, files=files, context=context)

        local_gtw = LocalClients.get_assets_gateway_client(env=env)
        local_treedb = LocalClients.get_treedb_client(env=env)
        asset_id = encode_id(project.id)
        try:
            item = await local_treedb.get_item(item_id=asset_id)
            folder_id = item['folderId']
        except HTTPException as e:
            if e.status_code == 404:
                await context.info("The package has not been published yet, start creation")
                drive: DefaultDriveResponse = await env.get_default_drive(context=context)
                folder_id = drive.downloadFolderId
            else:
                raise e

        data = {'file': zip_path.read_bytes(), 'content_encoding': 'identity'}
        resp = await local_gtw.put_asset_with_raw(kind='package', folder_id=folder_id, data=data, timeout=600)
        await context.info(text="Asset posted in assets_gtw", data=resp)
        local_cdn = LocalClients.get_cdn_client(env=env)
        resp = await local_cdn.get_package(library_name=project.name, version=project.version, metadata=True)
        await context.info(text="Package retrieved from local cdn", data=resp)
        resp['src_files_fingerprint'] = files_check_sum(files)
        base_path = env.pathsBook.artifacts_flow(project_name=project.name, flow_id=flow_id)
        resp['src_base_path'] = str(base_path)
        resp['src_files'] = [str(f.relative_to(base_path)) for f in files]
        return resp
Esempio n. 2
0
    async def get_status(self, project: Project, flow_id: str, last_manifest: Optional[Manifest], context: Context) \
            -> PipelineStepStatus:

        if last_manifest and not last_manifest.succeeded:
            return PipelineStepStatus.KO

        env = await context.get('env', YouwolEnvironment)
        local_cdn = LocalClients.get_cdn_client(env=env)
        remote_gtw = await RemoteClients.get_assets_gateway_client(context=context)

        local_info, remote_info = await asyncio.gather(
            local_cdn.get_package(library_name=project.name, version=project.version, metadata=True),
            remote_gtw.cdn_get_package(library_name=project.name, version=project.version, metadata=True),
            return_exceptions=True
            )
        if isinstance(remote_info, HTTPException) and remote_info.status_code == 404:
            return PipelineStepStatus.none

        if isinstance(local_info, HTTPException) and local_info.status_code == 404:
            return PipelineStepStatus.outdated

        if isinstance(remote_info, Exception) or isinstance(local_info, Exception):
            raise remote_info if isinstance(remote_info, Exception) else local_info

        local_info = cast(Mapping, local_info)
        remote_info = cast(Mapping, remote_info)
        local_fp, remote_fp = local_info['fingerprint'],  remote_info['fingerprint']
        if local_fp == remote_fp:
            return PipelineStepStatus.OK

        return PipelineStepStatus.outdated
Esempio n. 3
0
    async def execute_run(self, project: Project, flow_id: str, context: Context):

        env = await context.get('env', YouwolEnvironment)
        await upload_asset(body={'assetId': encode_id(project.id)}, context=context)
        # # No ideal solution to get back the fingerprint here:
        # # (i) this one is brittle if the source code of the CDN is not the same between local vs remote
        local_cdn = LocalClients.get_cdn_client(env=env)
        resp = await local_cdn.get_package(library_name=project.name, version=project.version, metadata=True)
        # # (ii) this one is brittle in terms of eventual consistency
        # # resp = await remote_gtw.cdn_get_package(library_name=project.name, version=project.version, metadata=True)
        return resp
Esempio n. 4
0
 async def is_local_up_to_date(self):
     env = await self.context.get('env', YouwolEnvironment)
     local_assets: AssetsClient = LocalClients.get_assets_client(env=env)
     try:
         await local_assets.get(asset_id=self.asset_id)
         return True
     except HTTPException as e:
         if e.status_code == 404:
             return False
         else:
             raise e
Esempio n. 5
0
 async def is_local_up_to_date(self):
     env = await self.context.get('env', YouwolEnvironment)
     local_cdn: CdnClient = LocalClients.get_cdn_client(env=env)
     try:
         await local_cdn.get_package(library_name=self.package_name,
                                     version=self.version,
                                     metadata=True)
         return True
     except HTTPException as e:
         if e.status_code == 404:
             return False
         raise e
Esempio n. 6
0
    async def is_local_up_to_date(self):

        env = await self.context.get('env', YouwolEnvironment)
        local_flux: FluxClient = LocalClients.get_flux_client(env=env)
        try:
            await local_flux.get_project(project_id=self.raw_id)
            return True
        except HTTPException as e:
            if e.status_code == 404:
                return False
            else:
                raise e
Esempio n. 7
0
    async def get_status(self,  project: Project, flow_id: str, last_manifest: Optional[Manifest], context: Context) \
            -> PipelineStepStatus:

        env = await context.get('env', YouwolEnvironment)
        local_cdn = LocalClients.get_cdn_client(env=env)
        if not last_manifest:
            return PipelineStepStatus.none

        try:
            local_info = await local_cdn.get_package(library_name=project.name, version=project.version, metadata=True)
        except HTTPException as e:
            if e.status_code == 404:
                return PipelineStepStatus.none
            raise e
        files = await self.packaged_files(project, flow_id, context)
        src_files_fingerprint = files_check_sum(files)
        if last_manifest.fingerprint == local_info['fingerprint'] and \
                last_manifest.cmdOutputs['src_files_fingerprint'] == src_files_fingerprint:
            return PipelineStepStatus.OK

        if last_manifest.fingerprint != local_info['fingerprint']:
            await context.info(
                text="Mismatch between cdn-backend fingerprint and saved manifest's fingerprint",
                data={
                    'cdn-backend fingerprint': local_info['fingerprint'],
                    "saved manifest's fingerprint": last_manifest.fingerprint
                }
            )
        if last_manifest.cmdOutputs['src_files_fingerprint'] != src_files_fingerprint:
            await context.info(
                text="Mismatch between actual src files fingerprint and saved manifest's src_files_fingerprint",
                data={
                    'actual src files fingerprint': src_files_fingerprint,
                    "saved manifest's src_files_fingerprint": last_manifest.cmdOutputs['src_files_fingerprint']
                }
            )

        return PipelineStepStatus.outdated
Esempio n. 8
0
async def create_asset_local(asset_id: str, kind: str,
                             default_owning_folder_id,
                             get_raw_data: Callable[[], Awaitable[T]],
                             to_post_raw_data: Callable[[T], any],
                             context: Context):
    env = await context.get("env", YouwolEnvironment)
    async with context.start(
            action=f"Fetch asset {asset_id} of kind {kind}", ) as ctx:
        local_treedb: TreeDbClient = LocalClients.get_treedb_client(env)
        local_gtw: AssetsGatewayClient = LocalClients.get_assets_gateway_client(
            env)
        remote_gtw = await RemoteClients.get_assets_gateway_client(context)
        remote_treedb = await RemoteClients.get_treedb_client(context)

        raw_data, metadata, tree_items = await asyncio.gather(
            get_raw_data(),
            remote_gtw.get_asset_metadata(asset_id=asset_id),
            remote_gtw.get_tree_items_by_related_id(related_id=asset_id),
            return_exceptions=True)

        if isinstance(raw_data, Exception):
            await ctx.error(f"Can not fetch raw part of the asset")
            raise raw_data

        if isinstance(metadata, Exception):
            await ctx.error(f"Can not fetch asset's metadata")
            raise metadata

        if isinstance(tree_items, Exception):
            await ctx.error(f"Can not fetch tree-db items")
            raise tree_items

        raw_data = cast(Dict, raw_data)
        metadata = cast(Dict, metadata)
        tree_items = cast(Dict, tree_items)

        await ctx.info(text="Raw & meta data retrieved",
                       data={
                           "metadata": metadata,
                           "tree_items": tree_items,
                       })
        owning_location, borrowed_locations = await get_remote_paths(
            remote_treedb=remote_treedb,
            tree_items=ItemsResponse(**tree_items))
        await ctx.info(text="Explorer paths retrieved",
                       data={
                           "owning_location":
                           owning_location.dict() if owning_location else
                           "No owning location in available groups",
                           "borrowed_locations":
                           [p.dict() for p in borrowed_locations]
                       })

        owning_folder_id = await get_local_owning_folder_id(
            owning_location=owning_location,
            local_treedb=local_treedb,
            default_folder_id=default_owning_folder_id)
        await ctx.info(text="Owning folder retrieved",
                       data={"owning_folder_id": owning_folder_id})

        await local_gtw.put_asset_with_raw(kind=kind,
                                           folder_id=owning_folder_id,
                                           data=to_post_raw_data(raw_data))
        await ctx.info(text="Asset raw's data downloaded successfully")

        await sync_borrowed_items(asset_id=asset_id,
                                  borrowed_locations=borrowed_locations,
                                  local_treedb=local_treedb,
                                  local_gtw=local_gtw)
        await ctx.info(text="Borrowed items created successfully")
        # the next line is not fetching images
        await local_gtw.update_asset(asset_id=asset_id, body=metadata)
        await ctx.info(text="Asset metadata uploaded successfully")