Пример #1
0
 def test_calls_download_boot_resources(self):
     self.patch(download_resources, "datetime", MockDateTime)
     storage_path = self.make_dir()
     snapshot_path = download_resources.compose_snapshot_path(storage_path)
     cache_path = os.path.join(storage_path, "cache")
     file_store = FileStore(cache_path)
     source = {
         "url": "http://example.com",
         "keyring": self.make_file("keyring"),
     }
     product_mapping = ProductMapping()
     fake = self.patch(download_resources, "download_boot_resources")
     download_resources.download_all_boot_resources(
         sources=[source],
         storage_path=storage_path,
         product_mapping=product_mapping,
         store=file_store,
     )
     self.assertThat(
         fake,
         MockCalledWith(
             source["url"],
             file_store,
             snapshot_path,
             product_mapping,
             keyring_file=source["keyring"],
         ),
     )
Пример #2
0
 def test_returns_snapshot_path(self):
     self.patch(download_resources, 'datetime', MockDateTime)
     storage_path = self.make_dir()
     expected_path = os.path.join(
         storage_path,
         'snapshot-%s' % MockDateTime._utcnow.strftime('%Y%m%d-%H%M%S'))
     self.assertEqual(
         expected_path,
         download_resources.download_all_boot_resources(
             sources=[], storage_path=storage_path, product_mapping=None))
Пример #3
0
 def test_calls_download_boot_resources(self):
     self.patch(download_resources, 'datetime', MockDateTime)
     storage_path = self.make_dir()
     snapshot_path = download_resources.compose_snapshot_path(storage_path)
     cache_path = os.path.join(storage_path, 'cache')
     file_store = FileStore(cache_path)
     source = {
         'url': 'http://example.com',
         'keyring': self.make_file("keyring"),
     }
     product_mapping = ProductMapping()
     fake = self.patch(download_resources, 'download_boot_resources')
     download_resources.download_all_boot_resources(
         sources=[source],
         storage_path=storage_path,
         product_mapping=product_mapping,
         store=file_store)
     self.assertThat(
         fake,
         MockCalledWith(source['url'],
                        file_store,
                        snapshot_path,
                        product_mapping,
                        keyring_file=source['keyring']))
Пример #4
0
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