Exemplo n.º 1
0
def apt_select():
    """Run apt-select: Ubuntu archive mirror reporting tool"""
    parser = get_args()
    args = parser.parse_args()
    top_number = args.top_number[0]
    ping_only = args.ping_only
    list_only = args.list_only
    choose = args.choose
    min_status = args.min_status[0].replace('-', ' ')

    if not ping_only and (min_status != 'unknown'):
        # Convert status argument to format used by Launchpad
        min_status = min_status[0].upper() + min_status[1:]

    if choose and (not top_number or top_number < 2):
        parser.print_usage()
        exit((
            "error: -c/--choose option requires -t/--top-number NUMBER "
            "where NUMBER is greater than 1."
        ))

    try:
        release = check_output(["lsb_release", "-ics"])
    except OSError:
        not_ubuntu()
    else:
        release = [s.strip() for s in release.decode('utf-8').split()]

    if release[0] == 'Debian':
        exit("Debian is not currently supported")
    elif release[0] != 'Ubuntu':
        not_ubuntu()

    directory = '/etc/apt/'
    apt_file = 'sources.list'
    sources_path = directory + apt_file
    if not path.isfile(sources_path):
        exit("%s must exist as file" % sources_path)

    mirrors_loc = "mirrors.ubuntu.com"
    mirrors_url = "http://%s/mirrors.txt" % mirrors_loc
    stderr.write("Getting list of mirrors...")
    try:
        mirrors_list = get_html(mirrors_url)
    except HTMLGetError as err:
        exit("Error getting list from %s:\n\t%s" % (mirrors_list, err))
    stderr.write("done.\n")
    mirrors_list = mirrors_list.splitlines()

    codename = release[1][0].upper() + release[1][1:]
    hardware = check_output(["uname", "-m"]).strip().decode('utf-8')
    if hardware == 'x86_64':
        hardware = 'amd64'
    else:
        hardware = 'i386'

    archives = Mirrors(mirrors_list, ping_only, min_status)
    archives.get_rtts()
    if archives.got["ping"] < top_number:
        top_number = archives.got["ping"]

    if top_number == 0:
        exit("Cannot connect to any mirrors in %s\n." % mirrors_list)

    if not ping_only:
        archives.get_launchpad_urls()
        if not archives.abort_launch:
            # Mirrors needs a limit to stop launching threads
            archives.status_num = top_number
            stderr.write("Looking up %d status(es)\n" % top_number)
            archives.lookup_statuses(min_status, codename, hardware)

        if top_number > 1:
            stderr.write('\n')

    repo_name = ""
    found = False
    skip_gen_msg = "Skipping file generation."
    with open(sources_path, 'r') as sources_file:
        lines = sources_file.readlines()
        repos = []
        required_repo = "main"
        for line in lines:
            fields = line.split()
            if confirm_mirror(fields):
                if (not found and
                        (release[1] in fields[2]) and
                        (fields[3] == required_repo)):
                    repos += [fields[1]]
                    found = True
                    continue
                elif fields[2] == '%s-security' % (release[1]):
                    repos += [fields[1]]
                    break

        if not repos:
            stderr.write((
                "Error finding current %s repository in %s\n%s\n" %
                (required_repo, sources_path, skip_gen_msg)
            ))
        else:
            repo_name = repos[0]

    rank = 0
    current_key = -1
    if ping_only:
        archives.top_list = archives.ranked[:top_number+1]

    for url in archives.top_list:
        info = archives.urls[url]
        host = info["Host"]
        if url == repo_name:
            host += " (current)"
            current_key = rank

        if not ping_only and not archives.abort_launch:
            if "Status" in info:
                assign_defaults(info, ("Org", "Speed"), "N/A")
                print((
                    "%(rank)d. %(mirror)s\n%(tab)sLatency: %(ms)d ms\n"
                    "%(tab)sOrg:     %(org)s\n%(tab)sStatus:  %(status)s\n"
                    "%(tab)sSpeed:   %(speed)s" % {
                        'tab': '    ',
                        'rank': rank + 1,
                        'mirror': host,
                        'ms': info["Latency"],
                        'org': info["Organisation"],
                        'status': info["Status"],
                        'speed': info["Speed"]
                    }
                ))
        else:
            print("%d. %s: %d ms" % (rank+1, info["Host"], info["Latency"]))

        rank += 1
        if rank == top_number:
            break

    key = 0
    if choose:
        key = ask((
            "Choose a mirror (1 - %d)\n'q' to quit " %
            len(archives.top_list)
        ))
        while True:
            try:
                key = int(key)
            except ValueError:
                if key == 'q':
                    exit()

            if (type(key) is not str) and (key >= 1) and (key <= rank):
                break

            key = ask("Invalid entry ")

        key -= 1

    if list_only:
        exit()

    # Avoid generating duplicate sources.list
    if current_key == key:
        exit((
            "%s is the currently used mirror.\n%s" %
            (archives.urls[repo_name]["Host"], skip_gen_msg)
        ))

    mirror = archives.top_list[key]
    lines = ''.join(lines)
    for repo in repos:
        lines = lines.replace(repo, mirror)

    work_dir = getcwd()
    if work_dir == directory[0:-1]:
        query = (
            "'%(dir)s' is the current directory.\n"
            "Generating a new '%(apt)s' file will "
            "overwrite the current file.\n"
            "You should copy or backup '%(apt)s' before replacing it.\n"
            "Continue?\n[yes|no] " % {
                'dir': directory,
                'apt': apt_file
            }
        )
        yes_or_no(query)

    write_file = work_dir.rstrip('/') + '/' + apt_file
    try:
        with open(write_file, 'w') as sources_file:
            sources_file.write(lines)
    except IOError as err:
        exit("Unable to generate sources.list:\n\t%s\n" % err)
    else:
        print("New config file saved to %s" % write_file)

    exit()
Exemplo n.º 2
0
    def gather(self, debug=False):
        def _stage(text):
            print 'Processing %s' % (text)
        # Local imports to not pull missing dependencies in
        # on non-Gentoo machines.
        from globaluseflags import GlobalUseFlags
        from compileflags import CompileFlags
        from mirrors import Mirrors
        from overlays import Overlays
        from packagestar import PackageMask
        from systemprofile import SystemProfile
        from trivials import Trivials
        from features import Features
        from installedpackages import InstalledPackages

        _stage('global use flags')
        global_use_flags = GlobalUseFlags()

        _stage('compile flags')
        compile_flags = CompileFlags()

        _stage('mirrors')
        mirrors = Mirrors(debug=debug)

        _stage('overlays')
        overlays = Overlays()

        _stage('package.mask entries')
        user_package_mask = PackageMask()

        _stage('features')
        features = Features()

        _stage('trivials')
        trivials = Trivials()

        _stage('installed packages (takes some time)')
        if debug:
            def cb_enter(cpv, i, count):
                print '[% 3d%%] %s' % (i * 100 / count, cpv)
        else:
            def cb_enter(*_):
                pass
        installed_packages = InstalledPackages(debug=debug, cb_enter=cb_enter)

        machine_data = {}
        html_lines = []
        rst_lines = []
        metrics_dict = {}

        html_lines.append('<h1>Gentoo</h1>')
        rst_lines.append('Gentoo')
        rst_lines.append('=================================')
        rst_lines.append('')
        machine_data['protocol'] = '1.2'

        trivials.dump_html(html_lines)
        trivials.dump_rst(rst_lines)
        rst_lines.append('')
        trivials.get_metrics(metrics_dict)

        machine_data['features'] = features.serialize()
        features.dump_html(html_lines)
        features.dump_rst(rst_lines)
        rst_lines.append('')
        features.get_metrics(metrics_dict)

        machine_data['call_flags'] = compile_flags.serialize()
        compile_flags.dump_html(html_lines)
        compile_flags.dump_rst(rst_lines)
        rst_lines.append('')
        compile_flags.get_metrics(metrics_dict)

        machine_data['mirrors'] = mirrors.serialize()
        mirrors.dump_html(html_lines)
        mirrors.dump_rst(rst_lines)
        rst_lines.append('')
        mirrors.get_metrics(metrics_dict)

        machine_data['repos'] = overlays.serialize()
        overlays.dump_html(html_lines)
        overlays.dump_rst(rst_lines)
        rst_lines.append('')
        overlays.get_metrics(metrics_dict)

        machine_data['user_package_mask'] = user_package_mask.serialize()
        user_package_mask.dump_html(html_lines)
        user_package_mask.dump_rst(rst_lines)
        rst_lines.append('')
        user_package_mask.get_metrics(metrics_dict)

        machine_data['global_use_flags'] = global_use_flags.serialize()
        global_use_flags.dump_html(html_lines)
        global_use_flags.dump_rst(rst_lines)
        rst_lines.append('')
        global_use_flags.get_metrics(metrics_dict)

        machine_data['installed_packages'] = installed_packages.serialize()
        installed_packages.dump_html(html_lines)
        installed_packages.dump_rst(rst_lines)
        installed_packages.get_metrics(metrics_dict)

        for container in (trivials, ):
            for k, v in container.serialize().items():
                key = k.lower()
                if key in machine_data:
                    raise Exception('Unintended key collision')
                machine_data[key] = v

        machine_data['privacy_metrics'] = metrics_dict
        self.dump_metrics_html(html_lines, metrics_dict)
        rst_lines.append('')
        self.dump_metrics_rst(rst_lines, metrics_dict)

        excerpt_lines = []
        excerpt_lines.append('ACCEPT_KEYWORDS: ' + ' '.join(trivials.serialize()['accept_keywords']))
        excerpt_lines.append('CXXFLAGS: ' + ' '.join(compile_flags.serialize()['cxxflags']))
        excerpt_lines.append('MAKEOPTS: ' + ' '.join(compile_flags.serialize()['makeopts']))
        excerpt_lines.append('...')

        self._data = machine_data
        self._html = '\n'.join(html_lines)
        self._rst = '\n'.join(rst_lines)
        self._excerpt = '\n'.join(excerpt_lines)
Exemplo n.º 3
0
def apt_select():
    """Run apt-select: Ubuntu archive mirror reporting tool"""
    parser = get_args()
    args = parser.parse_args()
    top_number = args.top_number[0]
    ping_only = args.ping_only
    list_only = args.list_only
    choose = args.choose
    min_status = args.min_status[0].replace('-', ' ')

    if not ping_only and (min_status != 'unknown'):
        # Convert status argument to format used by Launchpad
        min_status = min_status[0].upper() + min_status[1:]

    if choose and (not top_number or top_number < 2):
        parser.print_usage()
        exit(("error: -c/--choose option requires -t/--top-number NUMBER "
              "where NUMBER is greater than 1."))

    try:
        release = check_output(["lsb_release", "-ics"])
    except OSError:
        not_ubuntu()
    else:
        release = [s.strip() for s in release.decode('utf-8').split()]

    if release[0] == 'Debian':
        exit("Debian is not currently supported")
    elif release[0] != 'Ubuntu':
        not_ubuntu()

    directory = '/etc/apt/'
    apt_file = 'sources.list'
    sources_path = directory + apt_file
    if not path.isfile(sources_path):
        exit("%s must exist as file" % sources_path)

    mirrors_loc = "mirrors.ubuntu.com"
    mirrors_url = "http://%s/mirrors.txt" % mirrors_loc
    stderr.write("Getting list of mirrors...")
    try:
        mirrors_list = get_html(mirrors_url)
    except HTMLGetError as err:
        exit("Error getting list from %s:\n\t%s" % (mirrors_list, err))
    stderr.write("done.\n")
    mirrors_list = mirrors_list.splitlines()

    codename = release[1][0].upper() + release[1][1:]
    hardware = check_output(["uname", "-m"]).strip().decode('utf-8')
    if hardware == 'x86_64':
        hardware = 'amd64'
    else:
        hardware = 'i386'

    archives = Mirrors(mirrors_list, ping_only, min_status)
    archives.get_rtts()
    if archives.got["ping"] < top_number:
        top_number = archives.got["ping"]

    if top_number == 0:
        exit("Cannot connect to any mirrors in %s\n." % mirrors_list)

    if not ping_only:
        archives.get_launchpad_urls()
        if not archives.abort_launch:
            # Mirrors needs a limit to stop launching threads
            archives.status_num = top_number
            stderr.write("Looking up %d status(es)\n" % top_number)
            archives.lookup_statuses(min_status, codename, hardware)

        if top_number > 1:
            stderr.write('\n')

    repo_name = ""
    found = False
    skip_gen_msg = "Skipping file generation."
    with open(sources_path, 'r') as sources_file:
        lines = sources_file.readlines()
        repos = []
        required_repo = "main"
        for line in lines:
            fields = line.split()
            if confirm_mirror(fields):
                if (not found and (release[1] in fields[2])
                        and (fields[3] == required_repo)):
                    repos += [fields[1]]
                    found = True
                    continue
                elif fields[2] == '%s-security' % (release[1]):
                    repos += [fields[1]]
                    break

        if not repos:
            stderr.write(("Error finding current %s repository in %s\n%s\n" %
                          (required_repo, sources_path, skip_gen_msg)))
        else:
            repo_name = repos[0]

    rank = 0
    current_key = -1
    if ping_only:
        archives.top_list = archives.ranked[:top_number + 1]

    for url in archives.top_list:
        info = archives.urls[url]
        host = info["Host"]
        if url == repo_name:
            host += " (current)"
            current_key = rank

        if not ping_only and not archives.abort_launch:
            if "Status" in info:
                assign_defaults(info, ("Org", "Speed"), "N/A")
                print(("%(rank)d. %(mirror)s\n%(tab)sLatency: %(ms)d ms\n"
                       "%(tab)sOrg:     %(org)s\n%(tab)sStatus:  %(status)s\n"
                       "%(tab)sSpeed:   %(speed)s" % {
                           'tab': '    ',
                           'rank': rank + 1,
                           'mirror': host,
                           'ms': info["Latency"],
                           'org': info["Organisation"],
                           'status': info["Status"],
                           'speed': info["Speed"]
                       }))
        else:
            print("%d. %s: %d ms" % (rank + 1, info["Host"], info["Latency"]))

        rank += 1
        if rank == top_number:
            break

    key = 0
    if choose:
        key = ask(("Choose a mirror (1 - %d)\n'q' to quit " %
                   len(archives.top_list)))
        while True:
            try:
                key = int(key)
            except ValueError:
                if key == 'q':
                    exit()

            if (type(key) is not str) and (key >= 1) and (key <= rank):
                break

            key = ask("Invalid entry ")

        key -= 1

    if list_only:
        exit()

    # Avoid generating duplicate sources.list
    if current_key == key:
        exit(("%s is the currently used mirror.\n%s" %
              (archives.urls[repo_name]["Host"], skip_gen_msg)))

    mirror = archives.top_list[key]
    lines = ''.join(lines)
    for repo in repos:
        lines = lines.replace(repo, mirror)

    work_dir = getcwd()
    if work_dir == directory[0:-1]:
        query = ("'%(dir)s' is the current directory.\n"
                 "Generating a new '%(apt)s' file will "
                 "overwrite the current file.\n"
                 "You should copy or backup '%(apt)s' before replacing it.\n"
                 "Continue?\n[yes|no] " % {
                     'dir': directory,
                     'apt': apt_file
                 })
        yes_or_no(query)

    write_file = work_dir.rstrip('/') + '/' + apt_file
    try:
        with open(write_file, 'w') as sources_file:
            sources_file.write(lines)
    except IOError as err:
        exit("Unable to generate sources.list:\n\t%s\n" % err)
    else:
        print("New config file saved to %s" % write_file)

    exit()