예제 #1
0
    def test_load_from_cache_caches_each_file_separately(self):
        log1, log2 = self.make_file(), self.make_file()
        config1 = self.make_file(contents=yaml.safe_dump({'logfile': log1}))
        config2 = self.make_file(contents=yaml.safe_dump({'logfile': log2}))

        self.assertEqual(log1, Config.load_from_cache(config1)['logfile'])
        self.assertEqual(log2, Config.load_from_cache(config2)['logfile'])
예제 #2
0
 def test_load_from_cache_reloads_from_cache_not_from_file(self):
     # A config loaded by Config.load_from_cache() is never reloaded.
     filename = self.make_file(name="config.yaml", contents='')
     config_before = Config.load_from_cache(filename)
     os.unlink(filename)
     config_after = Config.load_from_cache(filename)
     self.assertEqual(config_before, config_after)
예제 #3
0
    def test_load_from_cache_caches_immutable_copy(self):
        logfile = self.make_file()
        filename = self.make_file(
            name="config.yaml", contents=yaml.safe_dump({'logfile': logfile}))

        first_load = Config.load_from_cache(filename)
        second_load = Config.load_from_cache(filename)

        self.assertEqual(first_load, second_load)
        self.assertIsNot(first_load, second_load)
        first_load['logfile'] = factory.make_name('otherlog')
        self.assertNotEqual(first_load['logfile'], second_load['logfile'])
        self.assertEqual(logfile, second_load['logfile'])
        self.assertIsNot(first_load['boot'], second_load['boot'])
        first_load['boot']['architectures'] = [factory.make_name('otherarch')]
        self.assertNotEqual(
            first_load['boot']['architectures'],
            second_load['boot']['architectures'])
예제 #4
0
파일: tftp.py 프로젝트: cloudbase/maas
    def get_bcd_load_options(self, params):
        client = self.clients[params['remote']]
        data = client['data']

        loadoptions = '%s;%s;%s' % \
            (Config.load_from_cache()['windows']['remote_path'],
             "%s\\source" % data['release'],
             data['preseed_url'].replace('/', '\\'))
        return (loadoptions, params)
예제 #5
0
    def test_does_not_modify_config(self):
        self.useFixture(ConfigFixture({
            'boot': {
                'architectures': [factory.make_name('arch')],
                'ephemeral': {
                    'images_directory': self.make_dir(),
                    'releases': [factory.make_name('release')],
                },
            },
        }))
        original_boot_config = deepcopy(Config.load_from_cache()['boot'])
        install_legacy_config(self, make_legacy_config())

        make_arg_parser(factory.getRandomString())

        self.assertEqual(
            original_boot_config,
            Config.load_from_cache()['boot'])
예제 #6
0
    def test_does_not_modify_config(self):
        self.useFixture(
            ConfigFixture({
                'boot': {
                    'architectures': [factory.make_name('arch')],
                    'ephemeral': {
                        'images_directory': self.make_dir(),
                        'releases': [factory.make_name('release')],
                    },
                },
            }))
        original_boot_config = deepcopy(Config.load_from_cache()['boot'])
        install_legacy_config(self, make_legacy_config())

        make_arg_parser(factory.getRandomString())

        self.assertEqual(original_boot_config,
                         Config.load_from_cache()['boot'])
예제 #7
0
def report_to_server():
    """For master worker only: report available netboot images."""
    maas_url, api_credentials = get_cached_knowledge()
    if not all([maas_url, api_credentials]):
        return

    images = tftppath.list_boot_images(
        Config.load_from_cache()['tftp']['root'])

    submit(maas_url, api_credentials, images)
예제 #8
0
def report_to_server():
    """For master worker only: report available netboot images."""
    maas_url, api_credentials = get_cached_knowledge()
    if not all([maas_url, api_credentials]):
        return

    images = tftppath.list_boot_images(
        Config.load_from_cache()['tftp']['root'])

    submit(maas_url, api_credentials, images)
예제 #9
0
def make_arg_parser(doc):
    """Create an `argparse.ArgumentParser` for this script.

    :param doc: Description of the script, for help output.
    """
    try:
        config = Config.load_from_cache()
    except IOError as e:
        if e.errno != errno.ENOENT:
            raise
        # Plod on with defaults.  There may be a legacy shell-script config.
        config = Config.get_defaults()
    # Merge legacy settings into our copy of the config.
    merge_legacy_ephemerals_config(config)

    filters = []
    arches = config['boot'].get('architectures')
    if arches is not None:
        filters.append(compose_filter('arch', arches))
    releases = config['boot']['ephemeral'].get('releases')
    if releases is not None:
        filters.append(compose_filter('release', releases))
    images_directory = config['boot']['ephemeral'].get('images_directory')

    parser = ArgumentParser(description=doc)
    parser.add_argument(
        '--path', action="store", default="streams/v1/index.sjson",
        help="Path to simplestreams index file, relative to mirror URL")
    parser.add_argument(
        '--url', action='store', default=RELEASES_URL,
        help="Simplestreams mirror URL (may use 'file://' for local mirror)")
    parser.add_argument(
        '--output', action='store', default=images_directory,
        help="Directory where boot images should be stored")
    parser.add_argument(
        '--max', action='store', default=1,
        help="Store downloads for only the MAX most recent images.")
    parser.add_argument(
        '--keyring', action='store', default=DEFAULT_KEYRING,
        help="gpg keyring for verifying boot image metadata")
    parser.add_argument(
        '--delete', action='store_true', default=False,
        help="Delete local copies of images when no longer available")
    parser.add_argument(
        '--products', action='store', default=PRODUCTS_REGEX,
        help="Regular expression matching products to import, "
             "e.g. com.ubuntu.maas.daily:ephemerals:.* for daily")
    parser.add_argument(
        'filters', nargs='*', default=filters,
        help="Simplestreams filters for image metadata to download, "
             "e.g. arch=i386 release=precise")
    return parser
예제 #10
0
def get_ephemeral_name(release, arch):
    """Return the name of the most recent ephemeral image.

    That information is read from the config file named 'info' in the
    ephemeral directory e.g:
    /var/lib/maas/ephemeral/precise/ephemeral/i386/20120424/info
    """
    config = Config.load_from_cache()
    root = os.path.join(config["boot"]["ephemeral"]["images_directory"],
                        release, 'ephemeral', arch)
    try:
        filename = os.path.join(get_last_directory(root), 'info')
    except OSError:
        raise EphemeralImagesDirectoryNotFound(
            "The directory containing the ephemeral images/info is missing "
            "(%r).  Make sure to run the script "
            "'maas-import-pxe-files'." % root)
    name = parse_key_value_file(filename, separator="=")['name']
    return name
예제 #11
0
def get_ephemeral_name(release, arch):
    """Return the name of the most recent ephemeral image.

    That information is read from the config file named 'info' in the
    ephemeral directory e.g:
    /var/lib/maas/ephemeral/precise/ephemeral/i386/20120424/info
    """
    config = Config.load_from_cache()
    root = os.path.join(
        config["boot"]["ephemeral"]["images_directory"],
        release, 'ephemeral', arch)
    try:
        filename = os.path.join(get_last_directory(root), 'info')
    except OSError:
        raise EphemeralImagesDirectoryNotFound(
            "The directory containing the ephemeral images/info is missing "
            "(%r).  Make sure to run the script "
            "'maas-import-pxe-files'." % root)
    name = parse_key_value_file(filename, separator="=")['name']
    return name
예제 #12
0
def install_image(image_dir, arch, subarch, release, purpose, config_file=None,
                  alternate_purpose=None):
    """Install a PXE boot image.

    This is the function-call equivalent to a command-line invocation calling
    `add_arguments` and `run`.
    """
    config = Config.load_from_cache(config_file)
    tftproot = config["tftp"]["root"]
    destination = make_destination(tftproot, arch, subarch, release, purpose)
    if not are_identical_dirs(destination, image_dir):
        # Image has changed.  Move the new version into place.
        install_dir(image_dir, destination)

    if alternate_purpose is not None:
        # Symlink the new image directory under the alternate purpose name.
        alternate_destination = make_destination(
            tftproot, arch, subarch, release, alternate_purpose)
        install_symlink(destination, alternate_destination)

    rmtree(image_dir, ignore_errors=True)
예제 #13
0
파일: tftp.py 프로젝트: cloudbase/maas
 def return_binary_path(data):
     r = params['remote']
     self.clients[r] = {}
     self.clients[r]['data'] = data
     self.clients[r]['is_windows'] = False
     log.msg(">>>>>NODE DETAILS%r" % data)
     release = data.get('release')
     if data.get('purpose') == 'local':
         raise FileNotFound("pxelinux.0")
     if release.startswith('win'):
         self.clients[r]['is_windows'] = True
         path = "pxeboot.0"
         self.base = FilePath(
             '/var/lib/maas/tftp/%s/%s/%s/install/' %
             (data['arch'], data['subarch'], data['release']))
         self.clients[r]['base'] = self.base
     else:
         self.is_windows = False
         self.base = FilePath(Config.load_from_cache()['tftp']['root'])
         self.clients[r]['base'] = self.base
         path = "pxelinux.0"
     return path.encode('utf-8')
예제 #14
0
 def test_load_from_cache_uses_defaults(self):
     filename = self.make_file(name='config.yaml', contents='')
     self.assertEqual(
         Config.get_defaults(),
         Config.load_from_cache(filename))
예제 #15
0
 def test_load_from_cache_loads_config(self):
     logfile = self.make_file()
     filename = self.make_file(
         name="config.yaml", contents=yaml.safe_dump({'logfile': logfile}))
     loaded_config = Config.load_from_cache(filename)
     self.assertEqual(logfile, loaded_config['logfile'])