Bug 774112 - Part 1: Skeleton for one-line system bootstrapping; r=jhammel

This commit is contained in:
Gregory Szorc 2012-09-11 16:27:20 -07:00
parent abc5b5999b
commit 31798d11c9
8 changed files with 255 additions and 0 deletions

19
python/mozboot/README.rst Normal file
View File

@ -0,0 +1,19 @@
mozboot - Bootstrap your system to build Mozilla projects
=========================================================
This package contains code used for bootstrapping a system to build
mozilla-central.
This code is not part of the build system per se. Instead, it is related
to everything up to invoking the actual build system.
If you have a copy of the source tree, you run:
python bin/bootstrap.py
If you don't have a copy of the source tree, you can run:
curl https://hg.mozilla.org/mozilla-central/raw-file/default/python/mozboot/bin/bootstrap.py | python -
The bootstrap script will download everything it needs from hg.mozilla.org
automatically!

131
python/mozboot/bin/bootstrap.py Executable file
View File

@ -0,0 +1,131 @@
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
# This script provides one-line bootstrap support to configure systems to build
# the tree.
#
# The role of this script is to load the Python modules containing actual
# bootstrap support. It does this through various means, including fetching
# content from the upstream source repository.
from __future__ import print_function, unicode_literals
import os
import shutil
import sys
import tempfile
import urllib2
from optparse import OptionParser
# The next two variables define where in the repository the Python files
# reside. This is used to remotely download file content when it isn't
# available locally.
REPOSITORY_PATH_PREFIX = 'python/mozboot'
REPOSITORY_PATHS = [
'mozboot/__init__.py',
'mozboot/base.py',
'mozboot/bootstrap.py',
'mozboot/osx.py',
'mozboot/ubuntu.py',
]
TEMPDIR = None
def fetch_files(repo_url, repo_type):
repo_url = repo_url.rstrip('/')
files = {}
if repo_type == 'hgweb':
for path in REPOSITORY_PATHS:
url = repo_url + '/raw-file/default/python/mozboot/' + path
req = urllib2.urlopen(url=url, timeout=30)
files[path] = req.read()
else:
raise NotImplementedError('Not sure how to handle repo type.', repo_type)
return files
def ensure_environment(repo_url=None, repo_type=None):
"""Ensure we can load the Python modules necessary to perform bootstrap."""
try:
from mozboot.bootstrap import Bootstrapper
return Bootstrapper
except ImportError:
# The first fallback is to assume we are running from a tree checkout
# and have the files in a sibling directory.
pardir = os.path.join(os.path.dirname(__file__), os.path.pardir)
include = os.path.normpath(pardir)
sys.path.append(include)
try:
from mozboot.bootstrap import Bootstrapper
return Bootstrapper
except ImportError:
sys.path.pop()
# The next fallback is to download the files from the source
# repository.
files = fetch_files(repo_url, repo_type)
# Install them into a temporary location. They will be deleted
# after this script has finished executing.
global TEMPDIR
TEMPDIR = tempfile.mkdtemp()
for relpath in files.keys():
destpath = os.path.join(TEMPDIR, relpath)
destdir = os.path.dirname(destpath)
if not os.path.exists(destdir):
os.makedirs(destdir)
with open(destpath, 'wb') as fh:
fh.write(files[relpath])
# This should always work.
sys.path.append(TEMPDIR)
from mozboot.bootstrap import Bootstrapper
return Bootstrapper
def main(args):
parser = OptionParser()
parser.add_option('-r', '--repo-url', dest='repo_url',
default='https://hg.mozilla.org/mozilla-central/',
help='Base URL of source control repository where bootstrap files can '
'be downloaded.')
parser.add_option('--repo-type', dest='repo_type',
default='hgweb',
help='The type of the repository. This defines how we fetch file '
'content. Like --repo, you should not need to set this.')
options, leftover = parser.parse_args(args)
try:
try:
cls = ensure_environment(options.repo_url, options.repo_type)
except Exception as e:
print('Could not load the bootstrap Python environment.\n')
print('This should never happen. Consider filing a bug.\n')
print('\n')
print(e)
return 1
dasboot = cls()
dasboot.bootstrap()
return 0
finally:
if TEMPDIR is not None:
shutil.rmtree(TEMPDIR)
if __name__ == '__main__':
sys.exit(main(sys.argv))

View File

View File

@ -0,0 +1,12 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
class BaseBootstrapper(object):
"""Base class for system bootstrappers."""
def __init__(self):
pass
def install_system_packages(self):
raise NotImplemented('%s must implement install_system_packages()' %
__name__)

View File

@ -0,0 +1,45 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
import platform
import sys
from mozboot.osx import OSXBootstrapper
from mozboot.ubuntu import UbuntuBootstrapper
class Bootstrapper(object):
"""Main class that performs system bootstrap."""
def bootstrap(self):
cls = None
args = {}
if sys.platform.startswith('linux'):
distro, version, dist_id = platform.linux_distribution()
if distro == 'Ubuntu':
cls = UbuntuBootstrapper
else:
raise NotImplementedError('Bootstrap support for this Linux '
'distro not yet available.')
args['version'] = version
args['dist_id'] = dist_id
elif sys.platform.startswith('darwin'):
# TODO Support Darwin platforms that aren't OS X.
major, minor, point = map(int, platform.mac_ver()[0].split('.'))
cls = OSXBootstrapper
args['major'] = major
args['minor'] = minor
args['point'] = point
if cls is None:
raise NotImplementedError('Bootstrap support is not yet available '
'for your OS.')
instance = cls(**args)
instance.install_system_packages()

View File

@ -0,0 +1,17 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
from mozboot.base import BaseBootstrapper
class OSXBootstrapper(BaseBootstrapper):
def __init__(self, major, minor, point):
BaseBootstrapper.__init__(self)
if major == 10 and minor < 6:
raise Exception('OS X 10.6 or above is required.')
def install_system_packages(self):
raise NotImplementedError('OS X bootstrap not yet implemented.')

View File

@ -0,0 +1,15 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
from mozboot.base import BaseBootstrapper
class UbuntuBootstrapper(BaseBootstrapper):
def __init__(self, version, dist_id):
BaseBootstrapper.__init__(self)
self.version = version
self.dist_id = dist_id
def install_system_packages(self):
raise NotImplementedError('Bootstrap for Ubuntu not yet implemented.')

16
python/mozboot/setup.py Normal file
View File

@ -0,0 +1,16 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this file,
# You can obtain one at http://mozilla.org/MPL/2.0/.
from distutils.core import setup
VERSION = '0.1'
setup(
name='mozboot',
description='System bootstrap for building Mozilla projects.',
license='MPL 2.0',
packages=['mozboot'],
version=VERSION,
scripts=['bin/bootstrap.py'],
)