def generate(image, outputdir, platform, searchpath, creds, ipk, appmetadata, yes, nodepwalking, libmatchingmode): """Generate an OCI Bundle for a specified platform """ logger.info(f'Generating new OCI bundle* from {image} for {platform}') outputdir = os.path.abspath(outputdir) # Check if the output dir already exists if os.path.exists(outputdir): if not yes: click.confirm( f"The directory {outputdir} already exists. Are you sure you want to continue? The contents of this directory will be deleted", abort=True) # Delete existing directory shutil.rmtree(outputdir) # Load the config for the platform selected_platform = STBPlatform(platform, searchpath) if not selected_platform.found_config(): logger.error(f"Could not find config for platform {platform}") return # Download the image to a temp directory img_downloader = ImageDownloader() img_path = img_downloader.download_image(image, creds, selected_platform.get_config()) if not img_path: return # Unpack the image with umoci tag = ImageDownloader().get_image_tag(image) img_unpacker = ImageUnpackager() unpack_success = img_unpacker.unpack_image(img_path, tag, outputdir) if not unpack_success: return # Delete the downloaded image now we've unpacked it logger.info(f"Deleting {img_path}") shutil.rmtree(img_path) # Load app metadata app_metadata_file = "" app_metadata_image_path = os.path.join(outputdir, "rootfs", "appmetadata.json") image_metadata_exists = os.path.exists(app_metadata_image_path) if not image_metadata_exists and not appmetadata: # No metadata at all logger.error( f"Cannot find app metadata file in OCI image and none provided to BundleGen" ) return elif not image_metadata_exists and appmetadata: # No metadata in image, but custom file provided if not os.path.exists(appmetadata): logger.error(f'App metadata file {appmetadata} does not exist') return app_metadata_file = appmetadata elif image_metadata_exists and appmetadata: # Got two options for metadata, which one do we want? if click.confirm( "Metadata found in image, but custom metadata provided. Use custom metadata?" ): app_metadata_file = appmetadata else: app_metadata_file = app_metadata_image_path else: app_metadata_file = app_metadata_image_path logger.debug(f"Loading metadata from {app_metadata_file}") # Load the metadata app_metadata_dict = {} with open(app_metadata_file) as metadata: app_metadata_dict = json.load(metadata) # remove app metadata from image rootfs if image_metadata_exists: os.remove(app_metadata_image_path) # Begin processing. Work in the output dir where the img was unpacked to processor = BundleProcessor(selected_platform.get_config(), outputdir, app_metadata_dict, nodepwalking, libmatchingmode) if not processor.check_compatibility(): # Not compatible - delete any work done so far shutil.rmtree(outputdir) return success = processor.begin_processing() if not success: logger.warning("Failed to produce bundle") return # Processing finished, now create a tarball/ipk of the output directory if ipk: # create control file Utils.create_control_file(selected_platform.get_config(), app_metadata_dict) Utils.create_ipk(outputdir, outputdir) logger.success(f"Successfully generated bundle at {outputdir}.ipk") else: Utils.create_tgz(outputdir, outputdir) logger.success(f"Successfully generated bundle at {outputdir}.tar.gz")
def generate(image, outputdir, platform, searchpath, creds, ipk, appmetadata, yes, nodepwalking, libmatchingmode, createmountpoints, appid): """Generate an OCI Bundle for a specified platform """ logger.info(f'Generating new OCI bundle* from {image} for {platform}') outputdir = os.path.abspath(outputdir) # Check if the output dir already exists if os.path.exists(outputdir): if not yes: click.confirm( f"The directory {outputdir} already exists. Are you sure you want to continue? The contents of this directory will be deleted", abort=True) # Delete existing directory shutil.rmtree(outputdir) # Load the config for the platform selected_platform = STBPlatform(platform, searchpath) if not selected_platform.found_config(): logger.error(f"Could not find config for platform {platform}") sys.exit(1) # Download the image to a temp directory img_downloader = ImageDownloader() img_path = img_downloader.download_image( image, creds, selected_platform.get_config()) if not img_path: sys.exit(1) # Unpack the image with umoci tag = ImageDownloader().get_image_tag(image) img_unpacker = ImageUnpackager(src=img_path, dst=outputdir) unpack_success = img_unpacker.unpack_image(tag, delete=True) if not unpack_success: sys.exit(1) # Load app metadata metadata_from_image = img_unpacker.get_app_metadata_from_img() appmetadata = os.path.abspath(appmetadata) if appmetadata else None app_metadata_dict = {} if not metadata_from_image and not appmetadata: # No metadata at all logger.error( f"Cannot find app metadata file in OCI image and none provided to BundleGen") sys.exit(1) if not metadata_from_image and appmetadata: # No metadata in image, but custom file provided if not os.path.exists(appmetadata): logger.error(f'App metadata file {appmetadata} does not exist') sys.exit(1) with open(appmetadata) as metadata: logger.debug(f"Loading metadata from {appmetadata}") app_metadata_dict = json.load(metadata) elif metadata_from_image and appmetadata: # Got two options for metadata, which one do we want? if click.confirm("Metadata found in image, but custom metadata provided. Use custom metadata?"): with open(appmetadata) as metadata: logger.debug(f"Loading metadata from {appmetadata}") app_metadata_dict = json.load(metadata) else: app_metadata_dict = metadata_from_image img_unpacker.delete_img_app_metadata() else: # Take metadata from image app_metadata_dict = metadata_from_image img_unpacker.delete_img_app_metadata() if appid: app_metadata_dict['id'] = appid # Begin processing. Work in the output dir where the img was unpacked to processor = BundleProcessor( selected_platform.get_config(), outputdir, app_metadata_dict, nodepwalking, libmatchingmode, createmountpoints) if not processor.check_compatibility(): # Not compatible - delete any work done so far shutil.rmtree(outputdir) sys.exit(2) success = processor.begin_processing() if not success: logger.warning("Failed to produce bundle") sys.exit(3) # Processing finished, now create a tarball/ipk of the output directory if ipk: # create control file Utils.create_control_file( selected_platform.get_config(), app_metadata_dict) Utils.create_ipk(outputdir, outputdir) logger.success(f"Successfully generated bundle at {outputdir}.ipk") else: tarball_settings = processor.platform_cfg.get('tarball') file_ownership_user = tarball_settings.get('fileOwnershipSameAsUser') if tarball_settings else None file_mask = tarball_settings.get('fileMask') if tarball_settings else None container_uid_gid = processor.get_real_uid_gid() uid = container_uid_gid[0] if container_uid_gid[0] and file_ownership_user else None gid = container_uid_gid[1] if container_uid_gid[1] and file_ownership_user else None Utils.create_tgz(outputdir, outputdir, uid, gid, file_mask) logger.success(f"Successfully generated bundle at {outputdir}.tar.gz")