コード例 #1
0
    def test_prober_jumbo_pallets(self, test_file):
        ''' test that find_pallets can identify jumbo pallets '''
        paldir = tempfile.TemporaryDirectory()

        *pallet_data, expected_probe, filemap = PALLET_DATA[0]
        for input_file, dest in filemap.items():
            pathlib.Path(f'{paldir.name}/pallet1/{dest}').parent.mkdir(
                parents=True, exist_ok=True)
            shutil.copyfile(test_file(f'pallet_artifacts/{input_file}'),
                            f'{paldir.name}/pallet1/{dest}')
        p1 = pal.PalletInfo(*pallet_data, f'{paldir.name}/pallet1',
                            expected_probe)

        *pallet_data, expected_probe, filemap = PALLET_DATA[1]
        for input_file, dest in filemap.items():
            pathlib.Path(f'{paldir.name}/pallet2/{dest}').parent.mkdir(
                parents=True, exist_ok=True)
            shutil.copyfile(test_file(f'pallet_artifacts/{input_file}'),
                            f'{paldir.name}/pallet2/{dest}')
        p2 = pal.PalletInfo(*pallet_data, f'{paldir.name}/pallet2',
                            expected_probe)

        prober = pal.Prober()
        pal_map = prober.find_pallets(paldir.name)
        assert sorted(*pal_map.values()) == sorted([p1, p2])
コード例 #2
0
    def test_prober_multi_args(self, test_file):
        ''' test that find_pallets can accept multiple paths and return multiple pallets '''
        paldirs = []
        palinfos = []

        *pallet_data, expected_probe, filemap = PALLET_DATA[0]
        paldir = tempfile.TemporaryDirectory()
        for input_file, dest in filemap.items():
            pathlib.Path(f'{paldir.name}/{dest}').parent.mkdir(parents=True,
                                                               exist_ok=True)
            shutil.copyfile(test_file(f'pallet_artifacts/{input_file}'),
                            f'{paldir.name}/{dest}')
        paldirs.append(paldir.name)
        palinfos.append(
            [pal.PalletInfo(*pallet_data, paldir.name, expected_probe)])

        *pallet_data, expected_probe, filemap = PALLET_DATA[1]
        paldir2 = tempfile.TemporaryDirectory()
        for input_file, dest in filemap.items():
            pathlib.Path(f'{paldir2.name}/{dest}').parent.mkdir(parents=True,
                                                                exist_ok=True)
            shutil.copyfile(test_file(f'pallet_artifacts/{input_file}'),
                            f'{paldir2.name}/{dest}')
        paldirs.append(paldir2.name)
        palinfos.append(
            [pal.PalletInfo(*pallet_data, paldir2.name, expected_probe)])

        prober = pal.Prober()
        pal_map = prober.find_pallets(*paldirs)
        assert sorted(pal_map.values()) == sorted(palinfos)
コード例 #3
0
    def test_prober(self, test_file, name, version, release, arch,
                    distro_family, expected_probe, filemap):
        ''' test that the sample PALLET_DATA is identified correctly. '''

        prober = pal.Prober()

        with tempfile.TemporaryDirectory() as paldir:
            for input_file, dest in filemap.items():
                pathlib.Path(f'{paldir}/{dest}').parent.mkdir(parents=True,
                                                              exist_ok=True)
                shutil.copyfile(test_file(f'pallet_artifacts/{input_file}'),
                                f'{paldir}/{dest}')
            pal_map = prober.find_pallets(paldir)
            assert pal_map[paldir] == [
                pal.PalletInfo(name, version, release, arch, distro_family,
                               paldir, expected_probe)
            ]
コード例 #4
0
 def test_find_no_pallets(self):
     with tempfile.TemporaryDirectory() as paldir:
         prober = pal.Prober()
         pal_map = prober.find_pallets(paldir)
         assert pal_map[paldir] == []
コード例 #5
0
 def test_collect_probes(self):
     ''' test that instantiating Prober finds at least the probes that stacki ships '''
     prober = pal.Prober()
     assert len(prober.probes) >= 5
コード例 #6
0
ファイル: __init__.py プロジェクト: wwfeng990/stacki
    def run(self, params, args):
        clean, stacki_pallet_dir, updatedb, self.username, self.password = self.fillParams(
            [
                ('clean', False),
                ('dir', '/export/stack/pallets'),
                ('updatedb', True),
                ('username', None),
                ('password', None),
            ])

        # need to provide either both or none
        if self.username or self.password and not all(
            (self.username, self.password)):
            raise UsageError(self,
                             'must supply a password along with the username')

        clean = self.str2bool(clean)
        updatedb = self.str2bool(updatedb)

        # create a contextmanager that we can append cleanup jobs to
        # add its closing to run atexit, so we know it will run
        self.deferred = ExitStack()
        atexit.register(self.deferred.close)

        # special case: no args were specified - check if a pallet is mounted at /mnt/cdrom
        if not args:
            mount_point = '/mnt/cdrom'
            result = self._exec(f'mount | grep {mount_point}', shell=True)
            if result.returncode != 0:
                raise CommandError(
                    self, 'no pallets specified and /mnt/cdrom is unmounted')
            args.append(mount_point)

        # resolve args and check for existence
        bad_args = []
        for i, arg in enumerate(list(args)):
            # TODO: is this a problem?
            if arg.startswith(('https://', 'http://', 'ftp://')):
                args[i] = arg
                continue

            p = pathlib.Path(arg)
            if not p.exists():
                bad_args.append(arg)
            else:
                args[i] = str(p.resolve())

        if bad_args:
            msg = 'The following arguments appear to be local paths that do not exist: '
            raise CommandError(self, msg + ', '.join(bad_args))

        # most plugins will need a temporary directory, so allocate them here so we do cleanup
        # 'canonical_arg' is the arg provided by the user, but cleaned to be explicit (relative
        # paths resolved, etc)
        # 'exploded_path' is the directory where we will start searching for pallets
        # 'matched_pallets' is a list of pallet_info objects found at that path.
        pallet_args = {}
        for arg in args:
            tmpdir = tempfile.mkdtemp()
            self.deferred.callback(shutil.rmtree, tmpdir)
            pallet_args[arg] = {
                'canonical_arg': arg,
                'exploded_path': tmpdir,
                'matched_pallets': [],
            }

        self.runPlugins(pallet_args)

        prober = probepal.Prober()
        pallet_infos = prober.find_pallets(
            *[pallet_args[path]['exploded_path'] for path in pallet_args])

        # pallet_infos returns a dict {path: [pallet1, ...]}
        # note the list - an exploded_path can point to a jumbo pallet

        for path, pals in pallet_infos.items():
            for arg in pallet_args:
                if pallet_args[arg]['exploded_path'] == path:
                    pallet_args[arg]['matched_pallets'] = pals

        # TODO what to do if we match something twice.
        bad_args = [
            arg for arg, info in pallet_args.items()
            if not info['matched_pallets']
        ]
        if bad_args:
            msg = 'The following arguments do not appear to be pallets: '
            raise CommandError(self, msg + ', '.join(bad_args))

        # work off of a copy of pallet args, as we modify it as we go
        for arg, data in pallet_args.copy().items():
            if len(data['matched_pallets']) == 1:
                pallet_args[arg]['exploded_path'] = data['matched_pallets'][
                    0].pallet_root
                continue

            # delete the arg pointing to a jumbo and replace it with N new 'dummy' args
            del pallet_args[arg]
            for pal in data['matched_pallets']:
                fake_arg_name = '-'.join(info_getter(pal))
                pallet_args[fake_arg_name] = data.copy()
                pallet_args[fake_arg_name]['exploded_path'] = pal.pallet_root
                pallet_args[fake_arg_name]['matched_pallets'] = [pal]

        # we want to be able to go tempdir to arg
        # this is because we want `canonical_arg` to be what goes in as the `URL` field in the db
        paths_to_args = {
            data['exploded_path']: data['canonical_arg']
            for data in pallet_args.values()
        }

        # we have everything we need, copy the pallet to the fs, add it to the db, and maybe patch it
        for pallet in flatten(pallet_infos.values()):
            self.copy(stacki_pallet_dir, pallet, clean)
            self.write_pallet_xml(stacki_pallet_dir, pallet)
            if updatedb:
                self.update_db(pallet, paths_to_args[pallet.pallet_root])
            if stacki_pallet_dir == '/export/stack/pallets':
                self.patch_pallet(pallet)

        # Clear the old packages
        self._exec('systemctl start ludicrous-cleaner'.split())