python/mozboot/bin/bootstrap.py

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/python/mozboot/bin/bootstrap.py	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,152 @@
     1.4 +#!/usr/bin/env python
     1.5 +# This Source Code Form is subject to the terms of the Mozilla Public
     1.6 +# License, v. 2.0. If a copy of the MPL was not distributed with this file,
     1.7 +# You can obtain one at http://mozilla.org/MPL/2.0/.
     1.8 +
     1.9 +# This script provides one-line bootstrap support to configure systems to build
    1.10 +# the tree.
    1.11 +#
    1.12 +# The role of this script is to load the Python modules containing actual
    1.13 +# bootstrap support. It does this through various means, including fetching
    1.14 +# content from the upstream source repository.
    1.15 +
    1.16 +# If we add unicode_literals, optparse breaks on Python 2.6.1 (which is needed
    1.17 +# to support OS X 10.6).
    1.18 +from __future__ import print_function
    1.19 +
    1.20 +import os
    1.21 +import shutil
    1.22 +import sys
    1.23 +import tempfile
    1.24 +try:
    1.25 +    from urllib2 import urlopen
    1.26 +except ImportError:
    1.27 +    from urllib.request import urlopen
    1.28 +
    1.29 +from optparse import OptionParser
    1.30 +
    1.31 +# The next two variables define where in the repository the Python files
    1.32 +# reside. This is used to remotely download file content when it isn't
    1.33 +# available locally.
    1.34 +REPOSITORY_PATH_PREFIX = 'python/mozboot'
    1.35 +
    1.36 +REPOSITORY_PATHS = [
    1.37 +    'mozboot/__init__.py',
    1.38 +    'mozboot/base.py',
    1.39 +    'mozboot/bootstrap.py',
    1.40 +    'mozboot/centos.py',
    1.41 +    'mozboot/debian.py',
    1.42 +    'mozboot/fedora.py',
    1.43 +    'mozboot/freebsd.py',
    1.44 +    'mozboot/gentoo.py',
    1.45 +    'mozboot/openbsd.py',
    1.46 +    'mozboot/osx.py',
    1.47 +    'mozboot/ubuntu.py',
    1.48 +]
    1.49 +
    1.50 +TEMPDIR = None
    1.51 +
    1.52 +def setup_proxy():
    1.53 +    # Some Linux environments define ALL_PROXY, which is a SOCKS proxy
    1.54 +    # intended for all protocols. Python doesn't currently automatically
    1.55 +    # detect this like it does for http_proxy and https_proxy.
    1.56 +    if 'ALL_PROXY' in os.environ and 'https_proxy' not in os.environ:
    1.57 +        os.environ['https_proxy'] = os.environ['ALL_PROXY']
    1.58 +    if 'ALL_PROXY' in os.environ and 'http_proxy' not in os.environ:
    1.59 +        os.environ['http_proxy'] = os.environ['ALL_PROXY']
    1.60 +
    1.61 +def fetch_files(repo_url, repo_type):
    1.62 +    setup_proxy()
    1.63 +    repo_url = repo_url.rstrip('/')
    1.64 +
    1.65 +    files = {}
    1.66 +
    1.67 +    if repo_type == 'hgweb':
    1.68 +        for path in REPOSITORY_PATHS:
    1.69 +            url = repo_url + '/raw-file/default/python/mozboot/' + path
    1.70 +
    1.71 +            req = urlopen(url=url, timeout=30)
    1.72 +            files[path] = req.read()
    1.73 +    else:
    1.74 +        raise NotImplementedError('Not sure how to handle repo type.', repo_type)
    1.75 +
    1.76 +    return files
    1.77 +
    1.78 +def ensure_environment(repo_url=None, repo_type=None):
    1.79 +    """Ensure we can load the Python modules necessary to perform bootstrap."""
    1.80 +
    1.81 +    try:
    1.82 +        from mozboot.bootstrap import Bootstrapper
    1.83 +        return Bootstrapper
    1.84 +    except ImportError:
    1.85 +        # The first fallback is to assume we are running from a tree checkout
    1.86 +        # and have the files in a sibling directory.
    1.87 +        pardir = os.path.join(os.path.dirname(__file__), os.path.pardir)
    1.88 +        include = os.path.normpath(pardir)
    1.89 +
    1.90 +        sys.path.append(include)
    1.91 +        try:
    1.92 +            from mozboot.bootstrap import Bootstrapper
    1.93 +            return Bootstrapper
    1.94 +        except ImportError:
    1.95 +            sys.path.pop()
    1.96 +
    1.97 +            # The next fallback is to download the files from the source
    1.98 +            # repository.
    1.99 +            files = fetch_files(repo_url, repo_type)
   1.100 +
   1.101 +            # Install them into a temporary location. They will be deleted
   1.102 +            # after this script has finished executing.
   1.103 +            global TEMPDIR
   1.104 +            TEMPDIR = tempfile.mkdtemp()
   1.105 +
   1.106 +            for relpath in files.keys():
   1.107 +                destpath = os.path.join(TEMPDIR, relpath)
   1.108 +                destdir = os.path.dirname(destpath)
   1.109 +
   1.110 +                if not os.path.exists(destdir):
   1.111 +                    os.makedirs(destdir)
   1.112 +
   1.113 +                with open(destpath, 'wb') as fh:
   1.114 +                    fh.write(files[relpath])
   1.115 +
   1.116 +            # This should always work.
   1.117 +            sys.path.append(TEMPDIR)
   1.118 +            from mozboot.bootstrap import Bootstrapper
   1.119 +            return Bootstrapper
   1.120 +
   1.121 +def main(args):
   1.122 +    parser = OptionParser()
   1.123 +    parser.add_option('-r', '--repo-url', dest='repo_url',
   1.124 +        default='https://hg.mozilla.org/mozilla-central/',
   1.125 +        help='Base URL of source control repository where bootstrap files can '
   1.126 +             'be downloaded.')
   1.127 +
   1.128 +    parser.add_option('--repo-type', dest='repo_type',
   1.129 +        default='hgweb',
   1.130 +        help='The type of the repository. This defines how we fetch file '
   1.131 +             'content. Like --repo, you should not need to set this.')
   1.132 +
   1.133 +    options, leftover = parser.parse_args(args)
   1.134 +
   1.135 +    try:
   1.136 +        try:
   1.137 +            cls = ensure_environment(options.repo_url, options.repo_type)
   1.138 +        except Exception as e:
   1.139 +            print('Could not load the bootstrap Python environment.\n')
   1.140 +            print('This should never happen. Consider filing a bug.\n')
   1.141 +            print('\n')
   1.142 +            print(e)
   1.143 +            return 1
   1.144 +
   1.145 +        dasboot = cls()
   1.146 +        dasboot.bootstrap()
   1.147 +
   1.148 +        return 0
   1.149 +    finally:
   1.150 +        if TEMPDIR is not None:
   1.151 +            shutil.rmtree(TEMPDIR)
   1.152 +
   1.153 +
   1.154 +if __name__ == '__main__':
   1.155 +    sys.exit(main(sys.argv))

mercurial