'swift-ring-builder <builder_file> rebalance [options]
Attempts to rebalance the ring by reassigning partitions that haven\'t been
recently reassigned.'

@staticmethod
def rebalance():

    usage = Commands.rebalance.__doc__.strip()
    parser = optparse.OptionParser(usage)
    parser.add_option('-f', '--force', action='store_true', help='Force    a    rebalanced    ring    to    save    even    if    <    1%    of    parts    changed')
    parser.add_option('-s', '--seed', help='seed    to    use    for    rebalance')
    parser.add_option('-d', '--debug', action='store_true', help='print    debug    information')
    (options, args) = parser.parse_args(argv)
    def get_seed(index):
        if options.seed:
            return options.seed
        try:
            return args[index]
        except IndexError:
            pass
    if options.debug:
        logger = logging.getLogger('swift.ring.builder')
        logger.disabled = False
        logger.setLevel(logging.DEBUG)
        handler = logging.StreamHandler(stdout)
        formatter = logging.Formatter('%(levelname)s:    %(message)s')
        handler.setFormatter(formatter)
        logger.addHandler(handler)
    if builder.next_part_power:
        print('Partition    power    increase    in    progress.')
        print('You    need    to    finish    the    increase    first    before    rebalancing.')
        exit(EXIT_WARNING)
    devs_changed = builder.devs_changed
    min_part_seconds_left = builder.min_part_seconds_left
    try:
        last_balance = builder.get_balance()
        (parts, balance, removed_devs) = builder.rebalance(seed=get_seed(3))
    except exceptions.RingBuilderError as e:
        print(('-' * 79))
        print(('An    error    has    occurred    during    ring    validation.    Common\ncauses    of    failure    are    rings    that    are    empty    or    do    not\nhave    enough    devices    to    accommodate    the    replica    count.\nOriginal    exception    message:\n    %s' % (e,)))
        print(('-' * 79))
        exit(EXIT_ERROR)
    if (not (parts or options.force or removed_devs)):
        print('No    partitions    could    be    reassigned.')
        if (min_part_seconds_left > 0):
            print(('The    time    between    rebalances    must    be    at    least    min_part_hours:    %s    hours    (%s    remaining)' % (builder.min_part_hours, timedelta(seconds=builder.min_part_seconds_left))))
        else:
            print('There    is    no    need    to    do    so    at    this    time')
        exit(EXIT_WARNING)
    if ((not options.force) and (not devs_changed) and (abs((last_balance - balance)) < 1) and (not ((last_balance == MAX_BALANCE) and (balance == MAX_BALANCE)))):
        print('Cowardly    refusing    to    save    rebalance    as    it    did    not    change    at    least    1%.')
        exit(EXIT_WARNING)
    try:
        builder.validate()
    except exceptions.RingValidationError as e:
        print(('-' * 79))
        print(('An    error    has    occurred    during    ring    validation.    Common\ncauses    of    failure    are    rings    that    are    empty    or    do    not\nhave    enough    devices    to    accommodate    the    replica    count.\nOriginal    exception    message:\n    %s' % (e,)))
        print(('-' * 79))
        exit(EXIT_ERROR)
    print(('Reassigned    %d    (%.02f%%)    partitions.    Balance    is    now    %.02f.        Dispersion    is    now    %.02f' % (parts, ((100.0 * parts) / builder.parts), balance, builder.dispersion)))
    status = EXIT_SUCCESS
    if (builder.dispersion > 0):
        print(('-' * 79))
        print(('NOTE:    Dispersion    of    %.06f    indicates    some    parts    are    not\n                        optimally    dispersed.\n\n                        You    may    want    to    adjust    some    device    weights,    increase\n                        the    overload    or    review    the    dispersion    report.' % builder.dispersion))
        status = EXIT_WARNING
        print(('-' * 79))
    elif ((balance > 5) and ((balance / 100.0) > builder.overload)):
        print(('-' * 79))
        print(('NOTE:    Balance    of    %.02f    indicates    you    should    push    this    ' % balance))
        print(('                        ring,    wait    at    least    %d    hours,    and    rebalance/repush.' % builder.min_part_hours))
        print(('-' * 79))
        status = EXIT_WARNING
    ts = time()
    builder.get_ring().save(pathjoin(backup_dir, (('%d.' % ts) + basename(ring_file))))
    builder.save(pathjoin(backup_dir, (('%d.' % ts) + basename(builder_file))))
    builder.get_ring().save(ring_file)
    builder.save(builder_file)
    exit(status)
