def download_image_descriptions( path, keyring=None, user_agent=None, validate_products=True): """Download image metadata from upstream Simplestreams repo. :param path: The path to a Simplestreams repo. :param keyring: Optional keyring for verifying the repo's signatures. :param user_agent: Optional user agent string for downloading the image descriptions. :return: A `BootImageMapping` describing available boot resources. """ maaslog.info("Downloading image descriptions from %s", path) mirror, rpath = path_from_mirror_url(path, None) policy = get_signing_policy(rpath, keyring) if user_agent is None: reader = UrlMirrorReader(mirror, policy=policy) else: try: reader = UrlMirrorReader( mirror, policy=policy, user_agent=user_agent) except TypeError: # UrlMirrorReader doesn't support the user_agent argument. # simplestream >=bzr429 is required for this feature. reader = UrlMirrorReader(mirror, policy=policy) boot_images_dict = BootImageMapping() dumper = RepoDumper(boot_images_dict, validate_products=validate_products) dumper.sync(reader, rpath) return boot_images_dict
def download_boot_resources(path, store, snapshot_path, product_mapping, keyring_file=None): """Download boot resources for one simplestreams source. :param path: The Simplestreams URL for this source. :param store: A simplestreams `ObjectStore` where downloaded resources should be stored. :param snapshot_path: Filesystem path to a snapshot of current upstream boot resources. :param product_mapping: A `ProductMapping` describing the resources to be downloaded. :param keyring_file: Optional path to a keyring file for verifying signatures. """ maaslog.info("Downloading boot resources from %s", path) writer = RepoWriter(snapshot_path, store, product_mapping) (mirror, rpath) = path_from_mirror_url(path, None) policy = get_signing_policy(rpath, keyring_file) reader = UrlMirrorReader(mirror, policy=policy) writer.sync(reader, rpath)
def import_images(sources): """Import images. Callable from the command line. :param config: An iterable of dicts representing the sources from which boot images will be downloaded. """ if len(sources) == 0: msg = "Can't import: region did not provide a source." try_send_rack_event(EVENT_TYPES.RACK_IMPORT_WARNING, msg) maaslog.warning(msg) return False msg = "Starting rack boot image import" maaslog.info(msg) try_send_rack_event(EVENT_TYPES.RACK_IMPORT_INFO, msg) with ClusterConfiguration.open() as config: storage = FilePath(config.tftp_root).parent().path with tempdir("keyrings") as keyrings_path: # XXX: Band-aid to ensure that the keyring_data is bytes. Future task: # try to figure out why this sometimes happens. for source in sources: if "keyring_data" in source and not isinstance( source["keyring_data"], bytes): source["keyring_data"] = source["keyring_data"].encode("utf-8") # We download the keyrings now because we need them for both # download_all_image_descriptions() and # download_all_boot_resources() later. sources = write_all_keyrings(keyrings_path, sources) # The region produces a SimpleStream which is similar, but not # identical to the actual SimpleStream. These differences cause # validation to fail. So grab everything from the region and trust it # did proper filtering before the rack. image_descriptions = download_all_image_descriptions( sources, validate_products=False) if image_descriptions.is_empty(): msg = ("Finished importing boot images, the region does not have " "any boot images available.") try_send_rack_event(EVENT_TYPES.RACK_IMPORT_WARNING, msg) maaslog.warning(msg) return False meta_file_content = image_descriptions.dump_json() if meta_contains(storage, meta_file_content): maaslog.info("Finished importing boot images, the region does not " "have any new images.") try_send_rack_event(EVENT_TYPES.RACK_IMPORT_INFO, msg) maaslog.info(msg) return False product_mapping = map_products(image_descriptions) try: snapshot_path = download_all_boot_resources( sources, storage, product_mapping) except Exception as e: try_send_rack_event( EVENT_TYPES.RACK_IMPORT_ERROR, "Unable to import boot images: %s" % e, ) maaslog.error( "Unable to import boot images; cleaning up failed snapshot " "and cache.") # Cleanup snapshots and cache since download failed. cleanup_snapshots_and_cache(storage) raise maaslog.info("Writing boot image metadata.") write_snapshot_metadata(snapshot_path, meta_file_content) maaslog.info("Linking boot images snapshot %s" % snapshot_path) link_bootloaders(snapshot_path) # If we got here, all went well. This is now truly the "current" snapshot. update_current_symlink(storage, snapshot_path) # Now cleanup the old snapshots and cache. maaslog.info("Cleaning up old snapshots and cache.") cleanup_snapshots_and_cache(storage) # Import is now finished. msg = "Finished importing boot images." maaslog.info(msg) try_send_rack_event(EVENT_TYPES.RACK_IMPORT_INFO, msg) return True
def update_iscsi_targets(snapshot_path): maaslog.info("Updating boot image iSCSI targets.") update_targets_conf(snapshot_path)