Beispiel #1
0
def dst_dir_report(jobs, dstdirs, width, prefix=''):
    tab = tt.Texttable()
    dir2oldphase = manager.dstdirs_to_furthest_phase(jobs)
    dir2newphase = manager.dstdirs_to_youngest_phase(jobs)
    headings = ['dst', 'plots', 'GBfree', 'inbnd phases', 'pri']
    tab.header(headings)
    tab.set_cols_dtype('t' * len(headings))

    for d in sorted(dstdirs):
        # TODO: This logic is replicated in archive.py's priority computation,
        # maybe by moving more of the logic in to directory.py
        eldest_ph = dir2oldphase.get(d, (0, 0))
        phases = job.job_phases_for_dstdir(d, jobs)

        dir_plots = plot_util.list_k32_plots(d)
        gb_free = int(plot_util.df_b(d) / plot_util.GB)
        n_plots = len(dir_plots)
        priority = archive.compute_priority(eldest_ph, gb_free, n_plots)
        row = [
            abbr_path(d, prefix), n_plots, gb_free,
            phases_str(phases, 5), priority
        ]
        tab.add_row(row)
    tab.set_max_width(width)
    tab.set_deco(tt.Texttable.BORDER | tt.Texttable.HEADER)
    tab.set_deco(0)  # No borders
    return tab.draw()
Beispiel #2
0
def archive(dir_cfg, all_jobs):
    '''Configure one archive job.  Needs to know all jobs so it can avoid IO
    contention on the plotting dstdir drives.  Returns either (False, <reason>) 
    if we should not execute an archive job or (True, <cmd>) with the archive
    command if we should.'''

    dstdirs = dir_cfg['dst']
    arch_cfg = dir_cfg['archive']

    dir2ph = manager.dstdirs_to_furthest_phase(all_jobs)
    best_priority = -100000000
    chosen_plot = None

    for d in dstdirs:
        ph = dir2ph.get(d, (0, 0))
        dir_plots = plot_util.list_k32_plots(d)
        gb_free = plot_util.df_b(d) / plot_util.GB
        n_plots = len(dir_plots)
        priority = compute_priority(ph, gb_free, n_plots)
        if priority >= best_priority and dir_plots:
            best_priority = priority
            chosen_plot = dir_plots[0]

    if not chosen_plot:
        return (False, 'No plots found')

    # TODO: sanity check that archive machine is available
    # TODO: filter drives mounted RO

    #
    # Pick first archive dir with sufficient space
    #
    archdir_freebytes = get_archdir_freebytes(arch_cfg)
    if not archdir_freebytes:
        return (False, 'No free archive dirs found.')

    archdir = ''
    for (d, space) in sorted(archdir_freebytes.items()):
        # TODO: make buffer configurable
        if space > 1.2 * plot_util.get_k32_plotsize():  # Leave a little buffer
            archdir = d
            freespace = space
            break

    if not archdir:
        return (False, 'No archive directories found with enough free space')

    msg = 'Found %s with ~%d GB free' % (archdir, freespace / plot_util.GB)

    bwlimit = arch_cfg['rsyncd_bwlimit']
    throttle_arg = ('--bwlimit=%d' % bwlimit) if bwlimit else ''
    cmd = ('rsync %s --remove-source-files -P %s %s' %
           (throttle_arg, chosen_plot, rsync_dest(arch_cfg, archdir)))

    return (True, cmd)
Beispiel #3
0
    def test_dstdirs_to_furthest_phase(self):
        all_jobs = [
            self.job_w_dstdir_phase('/plots1', (1, 5)),
            self.job_w_dstdir_phase('/plots2', (1, 1)),
            self.job_w_dstdir_phase('/plots2', (3, 1)),
            self.job_w_dstdir_phase('/plots2', (2, 1)),
            self.job_w_dstdir_phase('/plots3', (4, 1))
        ]

        self.assertEqual(
            {
                '/plots1': (1, 5),
                '/plots2': (3, 1),
                '/plots3': (4, 1)
            }, manager.dstdirs_to_furthest_phase(all_jobs))
Beispiel #4
0
        # Start running archival
        elif args.cmd == 'archive':
            print('...starting archive loop')
            firstit = True
            while True:
                if not firstit:
                    print('Sleeping 60s until next iteration...')
                    time.sleep(60)
                    jobs = Job.get_running_jobs(dir_cfg['log'])
                firstit = False
                archive.archive(dir_cfg, jobs)

        # Debugging: show the destination drive usage schedule
        elif args.cmd == 'dsched':
            dstdirs = dir_cfg['dst']
            for (d, ph) in manager.dstdirs_to_furthest_phase(jobs).items():
                print('  %s : %s' % (d, str(ph)))

        #
        # Job control commands
        #
        elif args.cmd in ['details', 'files', 'kill', 'suspend', 'resume']:
            print(args)

            selected = []

            # TODO: clean up treatment of wildcard
            if args.idprefix[0] == 'all':
                selected = jobs
            else:
                # TODO: allow multiple idprefixes, not just take the first