2012-04-18 03:21:41 +04:00
|
|
|
# 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/.
|
|
|
|
|
2012-05-01 22:42:35 +04:00
|
|
|
import argparse
|
2012-04-18 03:39:13 +04:00
|
|
|
import ConfigParser
|
2012-04-13 03:50:29 +04:00
|
|
|
import inspect
|
2012-05-02 00:29:07 +04:00
|
|
|
import os
|
2012-04-13 03:50:29 +04:00
|
|
|
import platform
|
2012-04-18 03:39:13 +04:00
|
|
|
import StringIO
|
2012-05-01 22:42:35 +04:00
|
|
|
import subprocess
|
2012-04-03 03:52:35 +04:00
|
|
|
import sys
|
2012-04-13 03:50:29 +04:00
|
|
|
import traceback
|
2012-04-03 03:52:35 +04:00
|
|
|
|
2012-05-08 03:32:11 +04:00
|
|
|
# Network configurations we have available. Map internal/parameter name
|
|
|
|
# to descriptive name
|
|
|
|
netconfigs = {
|
|
|
|
'broadband':'Modern Wired Broadband (Cable/ADSL)',
|
|
|
|
'umts':'Modern Cellular (UMTS)',
|
|
|
|
'gsm':'Legacy Cellular (GSM/EDGE)',
|
|
|
|
}
|
|
|
|
|
2012-04-17 23:00:27 +04:00
|
|
|
# General information common to all stoneridge programs
|
2012-04-17 23:25:30 +04:00
|
|
|
os_name = None
|
|
|
|
os_version = None
|
2012-04-17 23:00:27 +04:00
|
|
|
download_platform = None
|
|
|
|
download_suffix = None
|
2012-05-08 03:32:11 +04:00
|
|
|
current_netconfig = None
|
2012-04-17 21:27:18 +04:00
|
|
|
|
2012-04-17 23:00:27 +04:00
|
|
|
# Paths that multiple programs need to know about
|
|
|
|
installroot = None
|
|
|
|
workdir = None
|
2012-04-18 03:21:41 +04:00
|
|
|
downloaddir = None
|
2012-04-17 23:00:27 +04:00
|
|
|
bindir = None
|
|
|
|
testroot = None
|
|
|
|
outdir = None
|
2012-04-18 03:21:41 +04:00
|
|
|
archivedir = None
|
|
|
|
logdir = None
|
2012-05-04 02:25:10 +04:00
|
|
|
xpcoutdir = None
|
2012-04-13 03:50:29 +04:00
|
|
|
|
2012-05-01 22:42:35 +04:00
|
|
|
# Misc configuration
|
|
|
|
_debug_enabled = True # Use False for production
|
2012-05-02 01:14:10 +04:00
|
|
|
_xpcshell_tmp_dir = None
|
2012-05-10 07:51:09 +04:00
|
|
|
_conffile = None
|
|
|
|
_cp = None
|
2012-05-01 22:42:35 +04:00
|
|
|
|
2012-04-13 03:50:29 +04:00
|
|
|
def main(_main):
|
|
|
|
"""Mark a function as the main function to run when run as a script.
|
|
|
|
If that function throws an exception, we'll print the traceback to
|
|
|
|
stderr and exit.
|
|
|
|
"""
|
|
|
|
parent = inspect.stack()[1][0]
|
|
|
|
name = parent.f_locals.get('__name__', None)
|
|
|
|
if name == '__main__':
|
2012-04-18 03:39:13 +04:00
|
|
|
rval = 0
|
2012-04-13 03:50:29 +04:00
|
|
|
try:
|
2012-05-01 22:42:35 +04:00
|
|
|
_main()
|
2012-04-13 03:50:29 +04:00
|
|
|
except Exception, e:
|
2012-05-01 22:42:35 +04:00
|
|
|
traceback.print_exception(type(e), e, sys.exc_info()[2], None,
|
|
|
|
sys.stderr)
|
2012-04-13 03:50:29 +04:00
|
|
|
sys.exit(1)
|
2012-04-18 03:39:13 +04:00
|
|
|
sys.exit(rval)
|
2012-04-13 03:50:29 +04:00
|
|
|
return _main
|
2012-04-17 23:00:27 +04:00
|
|
|
|
2012-05-01 22:42:35 +04:00
|
|
|
def debug(msg):
|
|
|
|
if _debug_enabled:
|
|
|
|
sys.stderr.write(msg)
|
|
|
|
|
2012-05-10 07:51:09 +04:00
|
|
|
def get_config(section, option):
|
|
|
|
"""Read a config entry from the stoneridge.ini file
|
2012-04-18 03:21:41 +04:00
|
|
|
"""
|
2012-05-10 07:51:09 +04:00
|
|
|
global _cp
|
|
|
|
|
|
|
|
if _cp is None:
|
|
|
|
_cp = ConfigParser.SafeConfigParser()
|
2012-05-10 21:36:54 +04:00
|
|
|
_cp.read([_conffile])
|
2012-04-18 03:39:13 +04:00
|
|
|
|
|
|
|
try:
|
2012-05-10 21:36:54 +04:00
|
|
|
return _cp.get(section, option)
|
2012-04-18 03:39:13 +04:00
|
|
|
except (ConfigParser.NoSectionError, ConfigParser.NoOptionError), e:
|
2012-05-10 07:51:09 +04:00
|
|
|
return None
|
|
|
|
|
|
|
|
def update(cfile=None):
|
|
|
|
"""Update the stone ridge installation from the latest source
|
|
|
|
"""
|
|
|
|
global _conffile
|
|
|
|
global _cp
|
|
|
|
|
|
|
|
oldcfile = None
|
|
|
|
oldcp = None
|
|
|
|
|
|
|
|
if cfile is not None:
|
|
|
|
oldcfile, _conffile = _conffile, cfile
|
|
|
|
oldcp, _cp = _cp, None
|
|
|
|
|
|
|
|
scheme = get_config('update', 'scheme')
|
|
|
|
if scheme is None:
|
2012-04-18 03:39:13 +04:00
|
|
|
return
|
|
|
|
|
2012-05-10 07:51:09 +04:00
|
|
|
url = get_config('update', 'url')
|
|
|
|
|
|
|
|
if cfile is not None:
|
|
|
|
_conffile = oldcfile
|
|
|
|
_cp = oldcp
|
2012-04-18 03:39:13 +04:00
|
|
|
|
|
|
|
if scheme == 'hg':
|
|
|
|
args = ['hg', 'pull', '-u']
|
|
|
|
elif scheme == 'git':
|
|
|
|
args = ['git', 'pull']
|
|
|
|
else:
|
|
|
|
return
|
|
|
|
|
|
|
|
if url:
|
|
|
|
args.append(url)
|
|
|
|
|
|
|
|
outbuf = StringIO.StringIO()
|
|
|
|
if subprocess.call(args, stdout=outbuf, stderr=subprocess.STDOUT):
|
|
|
|
sys.stderr.write('Error updating Stone Ridge\n')
|
|
|
|
sys.stderr.write(outbuf.getvalue())
|
|
|
|
outbuf.close()
|
2012-04-18 03:21:41 +04:00
|
|
|
|
2012-04-24 00:04:50 +04:00
|
|
|
def run_xpcshell(args, stdout=subprocess.PIPE):
|
|
|
|
"""Run xpcshell with the appropriate args
|
|
|
|
"""
|
|
|
|
xpcargs = [xpcshell] + args
|
|
|
|
proc = subprocess.Popen(xpcargs, stdout=stdout,
|
|
|
|
stderr=subprocess.STDOUT, cwd=bindir)
|
|
|
|
res = proc.wait()
|
|
|
|
return (res, proc.stdout)
|
|
|
|
|
2012-05-04 02:25:10 +04:00
|
|
|
def _get_xpcshell_tmp():
|
2012-04-24 00:04:50 +04:00
|
|
|
"""Determine the temporary directory as xpcshell thinks of it
|
|
|
|
"""
|
2012-05-10 08:04:31 +04:00
|
|
|
global _xpcshell_tmp_dir
|
|
|
|
|
2012-05-02 01:14:10 +04:00
|
|
|
if _xpcshell_tmp_dir is None:
|
|
|
|
# TODO - make sure this works on windows to create a file in python
|
|
|
|
_, stdout = run_xpcshell(['-e',
|
|
|
|
'dump("SR-TMP-DIR:" + '
|
|
|
|
' Components.classes["@mozilla.org/file/directory_service;1"]'
|
|
|
|
' .getService(Components.interfaces.nsIProperties)'
|
|
|
|
' .get("TmpD", Components.interfaces.nsILocalFile)'
|
|
|
|
' .path + "\n");'
|
|
|
|
'quit(0);'])
|
2012-05-04 02:25:10 +04:00
|
|
|
|
2012-05-02 01:14:10 +04:00
|
|
|
for line in stdout:
|
|
|
|
if line.startswith('SR-TMP-DIR:'):
|
|
|
|
_xpcshell_tmp_dir = line.strip().split(':', 1)[1]
|
|
|
|
|
|
|
|
return _xpcshell_tmp_dir
|
2012-04-24 00:04:50 +04:00
|
|
|
|
|
|
|
def get_xpcshell_bin():
|
|
|
|
"""Return the name of the xpcshell binary
|
|
|
|
"""
|
|
|
|
if os_name == 'windows':
|
|
|
|
return 'xpcshell.exe'
|
2012-05-01 22:42:35 +04:00
|
|
|
return 'xpcshell'
|
2012-04-24 00:04:50 +04:00
|
|
|
|
2012-05-02 00:29:07 +04:00
|
|
|
def _determine_os_name():
|
2012-04-20 21:50:18 +04:00
|
|
|
"""Determine the os from platform.system
|
|
|
|
"""
|
|
|
|
global os_name
|
|
|
|
os_name = platform.system().lower()
|
|
|
|
if os_name == 'darwin':
|
|
|
|
os_name = 'mac'
|
|
|
|
|
|
|
|
def _determine_os_version():
|
|
|
|
"""Determine the os version
|
|
|
|
"""
|
|
|
|
global os_version
|
|
|
|
if os_name == 'linux':
|
2012-05-02 00:29:07 +04:00
|
|
|
os_version = ' '.join(platform.linux_distribution()[0:2])
|
2012-04-20 21:50:18 +04:00
|
|
|
elif os_name == 'mac':
|
2012-05-02 00:29:07 +04:00
|
|
|
os_version = platform.mac_ver()[0]
|
2012-04-24 00:04:50 +04:00
|
|
|
elif os_name == 'windows':
|
2012-04-20 21:50:18 +04:00
|
|
|
os_version = platform.win32_ver()[1]
|
|
|
|
else:
|
|
|
|
os_version = 'Unknown'
|
|
|
|
|
|
|
|
def _determine_download_platform():
|
|
|
|
"""Determine which platform to download files for
|
|
|
|
"""
|
|
|
|
global download_platform
|
|
|
|
if os_name == 'linux':
|
|
|
|
if platform.machine() == 'x86_64':
|
|
|
|
download_platform = 'linux64'
|
|
|
|
else:
|
2012-05-01 22:42:35 +04:00
|
|
|
download_platform = 'linux32'
|
2012-04-20 21:50:18 +04:00
|
|
|
elif os_name == 'windows':
|
|
|
|
if platform.machine() == 'x86_64':
|
|
|
|
download_platform = 'win64'
|
|
|
|
else:
|
|
|
|
download_platform = 'win32'
|
|
|
|
else:
|
|
|
|
download_platform = os_name
|
|
|
|
|
|
|
|
def _determine_download_suffix():
|
|
|
|
"""Determine the suffix of the firefox archive to download
|
|
|
|
"""
|
|
|
|
global download_suffix
|
|
|
|
if os_name == 'linux':
|
|
|
|
download_suffix = 'tar.bz2'
|
|
|
|
elif os_name == 'mac':
|
|
|
|
download_suffix = 'dmg'
|
|
|
|
else:
|
|
|
|
download_suffix = 'zip'
|
|
|
|
|
|
|
|
def _determine_bindir():
|
|
|
|
"""Determine the location of the firefox binary based on platform
|
|
|
|
"""
|
|
|
|
global bindir
|
|
|
|
if os_name == 'mac':
|
|
|
|
bindir = os.path.join(workdir, 'FirefoxNightly.app', 'Contents',
|
|
|
|
'MacOS')
|
|
|
|
else:
|
|
|
|
bindir = os.path.join(workdir, 'firefox')
|
|
|
|
|
2012-05-04 02:25:10 +04:00
|
|
|
def setup_dirnames(srroot, srwork, srxpcout):
|
2012-04-20 21:50:18 +04:00
|
|
|
"""Determine the directory names and platform information to be used
|
|
|
|
by this run of stone ridge
|
|
|
|
"""
|
|
|
|
global installroot
|
|
|
|
global workdir
|
|
|
|
global downloaddir
|
|
|
|
global testroot
|
|
|
|
global outdir
|
|
|
|
global archivedir
|
|
|
|
global logdir
|
2012-04-24 00:04:50 +04:00
|
|
|
global xpcshell
|
2012-05-04 02:25:10 +04:00
|
|
|
global xpcoutdir
|
2012-04-20 21:50:18 +04:00
|
|
|
|
|
|
|
installroot = os.path.abspath(srroot)
|
|
|
|
workdir = os.path.abspath(srwork)
|
|
|
|
downloaddir = os.path.join(workdir, 'dl')
|
|
|
|
testroot = os.path.join(installroot, 'tests')
|
|
|
|
outdir = os.path.join(workdir, 'out')
|
|
|
|
archivedir = os.path.join(installroot, 'archives')
|
|
|
|
logdir = os.path.join(installroot, 'logs')
|
|
|
|
|
|
|
|
_determine_os_name()
|
|
|
|
_determine_os_version()
|
|
|
|
_determine_download_platform()
|
|
|
|
_determine_download_suffix()
|
|
|
|
_determine_bindir()
|
|
|
|
|
2012-04-24 00:04:50 +04:00
|
|
|
xpcshell = os.path.join(bindir, get_xpcshell_bin())
|
|
|
|
|
2012-05-04 02:25:10 +04:00
|
|
|
try:
|
|
|
|
xpctmp = _get_xpcshell_tmp()
|
|
|
|
xpcoutdir = os.path.join(xpctmp, srxpcout)
|
|
|
|
except OSError:
|
|
|
|
# We only need this after the point where we can run xpcshell, so
|
|
|
|
# don't worry if we can't get it earlier in the process
|
|
|
|
pass
|
|
|
|
|
2012-04-17 23:00:27 +04:00
|
|
|
class ArgumentParser(argparse.ArgumentParser):
|
2012-04-20 21:50:18 +04:00
|
|
|
"""An argument parser for stone ridge programs that handles the arguments
|
|
|
|
required by all of them
|
|
|
|
"""
|
2012-04-17 23:00:27 +04:00
|
|
|
def __init__(self, **kwargs):
|
2012-04-18 03:21:41 +04:00
|
|
|
argparse.ArgumentParser.__init__(self, **kwargs)
|
2012-04-17 23:00:27 +04:00
|
|
|
|
2012-05-08 03:50:04 +04:00
|
|
|
self.add_argument('--config', dest='_sr_config_', required=True,
|
|
|
|
help='Configuration file')
|
2012-05-08 03:32:11 +04:00
|
|
|
self.add_argument('--netconfig', dest='_sr_netconfig_', required=True,
|
|
|
|
help='Network Configuration in use', choices=netconfigs.keys())
|
2012-04-17 23:00:27 +04:00
|
|
|
self.add_argument('--root', dest='_sr_root_', required=True,
|
|
|
|
help='Root of Stone Ridge installation')
|
|
|
|
self.add_argument('--workdir', dest='_sr_work_', required=True,
|
|
|
|
help='Directory to do all the work in')
|
2012-05-04 02:25:10 +04:00
|
|
|
self.add_argument('--xpcout', dest='_sr_xpcout_', default='stoneridge',
|
|
|
|
help='Subdirectory of xpcshell temp to write output to')
|
2012-04-17 23:00:27 +04:00
|
|
|
|
2012-05-02 00:29:07 +04:00
|
|
|
def parse_args(self, **kwargs):
|
2012-05-10 07:51:09 +04:00
|
|
|
global _conffile
|
2012-05-08 03:32:11 +04:00
|
|
|
global current_netconfig
|
|
|
|
|
2012-04-18 03:21:41 +04:00
|
|
|
args = argparse.ArgumentParser.parse_args(self, **kwargs)
|
2012-04-17 23:00:27 +04:00
|
|
|
|
2012-05-10 07:51:09 +04:00
|
|
|
_conffile = args._sr_config_
|
2012-05-08 03:32:11 +04:00
|
|
|
current_netconfig = args._sr_netconfig_
|
|
|
|
|
2012-05-04 02:25:10 +04:00
|
|
|
setup_dirnames(args._sr_root_, args._sr_work_, args._sr_xpcout_)
|
2012-04-17 23:00:27 +04:00
|
|
|
|
|
|
|
return args
|