summaryrefslogtreecommitdiffstats
path: root/remoting
diff options
context:
space:
mode:
Diffstat (limited to 'remoting')
-rw-r--r--remoting/host/win/parameters.json6
-rw-r--r--remoting/remoting.gyp44
-rwxr-xr-xremoting/tools/candle_and_light.py78
-rwxr-xr-xremoting/tools/dark_and_candle_and_light.py73
-rwxr-xr-xremoting/tools/zip2msi.py154
5 files changed, 94 insertions, 261 deletions
diff --git a/remoting/host/win/parameters.json b/remoting/host/win/parameters.json
index 9a2deda..bd7e1f5 100644
--- a/remoting/host/win/parameters.json
+++ b/remoting/host/win/parameters.json
@@ -11,6 +11,12 @@
"WixUIExtension.dll",
"WixUtilExtension.dll"
],
+ "sign": [
+ "remoting_desktop.exe",
+ "remoting_host_controller.exe",
+ "remoting_me2me_host.exe",
+ "remoting_service.exe"
+ ],
"source": "chromoting.wxs",
"bind_path": "files",
"light": {
diff --git a/remoting/remoting.gyp b/remoting/remoting.gyp
index 3fc9245..a448657 100644
--- a/remoting/remoting.gyp
+++ b/remoting/remoting.gyp
@@ -735,50 +735,6 @@
],
}, # end of target 'remoting_host_installation'
- # The 'remoting_host_installation_unittest' target is used to make sure
- # that the code signing job (running outside of Chromium tree) will be
- # able to unpack and re-assemble the installation successfully.
- #
- # *** If this target fails to compile the code signing job will fail
- # too, breaking the official build. ***
- #
- # N.B. The command lines passed to the WiX tools here should be in sync
- # with the code signing script.
- {
- 'target_name': 'remoting_host_installation_unittest',
- 'type': 'none',
- 'dependencies': [
- 'remoting_host_installation',
- ],
- 'sources': [
- '<(PRODUCT_DIR)/chromoting.msi',
- ],
- 'outputs': [
- '<(INTERMEDIATE_DIR)/chromoting-test.msi',
- ],
- 'rules': [
- {
- 'rule_name': 'dark_and_candle_and_light',
- 'extension': 'msi',
- 'inputs': [
- 'tools/dark_and_candle_and_light.py',
- ],
- 'outputs': [
- '<(INTERMEDIATE_DIR)/chromoting-test.msi',
- ],
- 'msvs_cygwin_shell': 0,
- 'action': [
- 'python',
- 'tools/dark_and_candle_and_light.py',
- '--wix_path', '<(wix_path)',
- '--input', '<(RULE_INPUT_PATH)',
- '--intermediate_dir', '<(INTERMEDIATE_DIR)/installation',
- '--output', '<@(_outputs)',
- ],
- 'message': 'Unpacking and repacking to <@(_outputs)',
- },
- ],
- }, # end of target 'remoting_host_installation_unittest'
{
'target_name': 'remoting_me2me_host_archive',
'type': 'none',
diff --git a/remoting/tools/candle_and_light.py b/remoting/tools/candle_and_light.py
deleted file mode 100755
index 47c618c..0000000
--- a/remoting/tools/candle_and_light.py
+++ /dev/null
@@ -1,78 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Run 'candle' and 'light' to transform .wxs to .msi."""
-
-from optparse import OptionParser
-import os
-import subprocess
-import sys
-
-def run(command):
- popen = subprocess.Popen(
- command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- out, _ = popen.communicate()
- return popen.returncode, out
-
-def main():
- parser = OptionParser()
- parser.add_option('--wix_path', dest='wix_path')
- parser.add_option('--version', dest='version')
- parser.add_option('--controller_clsid', dest='controller_clsid')
- parser.add_option('--product_dir', dest='product_dir')
- parser.add_option('--intermediate_dir', dest='intermediate_dir')
- parser.add_option('--sas_dll_path', dest='sas_dll_path')
- parser.add_option('-d', dest='define_list', action='append')
- parser.add_option('--input', dest='input')
- parser.add_option('--output', dest='output')
- options, args = parser.parse_args()
- if args:
- parser.error("no positional arguments expected")
- parameters = dict(options.__dict__)
-
- parameters['basename'] = os.path.splitext(os.path.basename(options.input))[0]
- parameters['defines'] = '-d' + ' -d'.join(parameters['define_list'])
-
- common = (
- '-nologo '
- '-ext "%(wix_path)s\\WixFirewallExtension.dll" '
- '-ext "%(wix_path)s\\WixUIExtension.dll" '
- '-ext "%(wix_path)s\\WixUtilExtension.dll" '
- '"-dControllerClsid="%(controller_clsid)s"" '
- '-dVersion=%(version)s '
- '"-dFileSource=%(product_dir)s" '
- '-dIconPath=resources/chromoting.ico '
- '"-dSasDllPath=%(sas_dll_path)s/sas.dll" '
- '%(defines)s '
- )
-
- candle_template = ('"%(wix_path)s\\candle" ' +
- common +
- '-out "%(intermediate_dir)s/%(basename)s.wixobj" ' +
- '"%(input)s" ')
- (rc, out) = run(candle_template % parameters)
- if rc:
- for line in out.splitlines():
- print line
- print 'candle.exe returned %d' % rc
- return rc
-
- light_template = ('"%(wix_path)s\\light" ' +
- common +
- '-cultures:en-us ' +
- '-sw1076 ' +
- '-out "%(output)s" ' +
- '"%(intermediate_dir)s/%(basename)s.wixobj" ')
- (rc, out) = run(light_template % parameters)
- if rc:
- for line in out.splitlines():
- print line
- print 'light.exe returned %d' % rc
- return rc
-
- return 0
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/remoting/tools/dark_and_candle_and_light.py b/remoting/tools/dark_and_candle_and_light.py
deleted file mode 100755
index 6859875..0000000
--- a/remoting/tools/dark_and_candle_and_light.py
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/usr/bin/env python
-# Copyright (c) 2012 The Chromium Authors. All rights reserved.
-# Use of this source code is governed by a BSD-style license that can be
-# found in the LICENSE file.
-
-"""Run 'dark', 'candle', and 'light', to confirm that an msi can be unpacked
-repacked successfully."""
-
-from optparse import OptionParser
-import os
-import subprocess
-import sys
-
-def run(command):
- popen = subprocess.Popen(
- command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
- out, _ = popen.communicate()
- return popen.returncode, out
-
-def main():
- parser = OptionParser()
- parser.add_option('--wix_path', dest='wix_path')
- parser.add_option('--input', dest='input')
- parser.add_option('--intermediate_dir', dest='intermediate_dir')
- parser.add_option('--output', dest='output')
- options, args = parser.parse_args()
- if args:
- parser.error("no positional arguments expected")
- parameters = dict(options.__dict__)
-
- parameters['basename'] = os.path.splitext(os.path.basename(options.output))[0]
-
- dark_template = ('"%(wix_path)s\\dark" ' +
- '-nologo ' +
- '"%(input)s" ' +
- '-o "%(intermediate_dir)s/%(basename)s.wxs" ' +
- '-x "%(intermediate_dir)s"')
- (rc, out) = run(dark_template % parameters)
- if rc:
- for line in out.splitlines():
- print line
- print 'dark.exe returned %d' % rc
- return rc
-
- candle_template = ('"%(wix_path)s\\candle" ' +
- '-nologo ' +
- '"%(intermediate_dir)s/%(basename)s.wxs" ' +
- '-o "%(intermediate_dir)s/%(basename)s.wixobj" ' +
- '-ext "%(wix_path)s\\WixFirewallExtension.dll"')
- (rc, out) = run(candle_template % parameters)
- if rc:
- for line in out.splitlines():
- print line
- print 'candle.exe returned %d' % rc
- return rc
-
- light_template = ('"%(wix_path)s\\light" ' +
- '-nologo ' +
- '"%(intermediate_dir)s/%(basename)s.wixobj" ' +
- '-o "%(output)s" ' +
- '-ext "%(wix_path)s\\WixFirewallExtension.dll" ' +
- '-sw1076 ')
- (rc, out) = run(light_template % parameters)
- if rc:
- for line in out.splitlines():
- print line
- print 'candle.exe returned %d' % rc
- return rc
-
- return 0
-
-if __name__ == "__main__":
- sys.exit(main())
diff --git a/remoting/tools/zip2msi.py b/remoting/tools/zip2msi.py
index e474430..bbe8c8a 100755
--- a/remoting/tools/zip2msi.py
+++ b/remoting/tools/zip2msi.py
@@ -3,20 +3,20 @@
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
-"""
- Generates .msi from a .zip archive or an uppacked directory. The structure of
- the input archive or directory should look like this:
+"""Generates .msi from a .zip archive or an unpacked directory.
+
+The structure of the input archive or directory should look like this:
+- archive.zip
+- archive
+- parameters.json
- The name of the archive and the top level directory in the archive must match.
- When an unpacked directory is used as the input "archive.zip/archive" should
- be passed via the command line.
+The name of the archive and the top level directory in the archive must match.
+When an unpacked directory is used as the input "archive.zip/archive" should
+be passed via the command line.
- 'parameters.json' specifies the parameters to be passed to candle/light and
- must have the following structure:
+'parameters.json' specifies the parameters to be passed to candle/light and
+must have the following structure:
{
"defines": { "name": "value" },
@@ -24,14 +24,25 @@
"switches": [ '-nologo' ],
"source": "chromoting.wxs",
"bind_path": "files",
+ "sign": [ ... ],
"candle": { ... },
"light": { ... }
}
- "source" specifies the name of the input .wxs relative to
- "archive.zip/archive".
- "bind_path" specifies the path where to look for binary files referenced by
- .wxs relative to "archive.zip/archive".
+"source" specifies the name of the input .wxs relative to
+ "archive.zip/archive".
+"bind_path" specifies the path where to look for binary files referenced by
+ .wxs relative to "archive.zip/archive".
+
+This script is used for both building Chromoting Host installation during
+Chromuim build and for signing Chromoting Host installation later. There are two
+copies of this script because of that:
+
+ - one in Chromium tree at src/remoting/tools/zip2msi.py.
+ - another one next to the signing scripts.
+
+The copies of the script can be out of sync so make sure that a newer version is
+compatible with the older ones when updating the script.
"""
import copy
@@ -43,28 +54,35 @@ import subprocess
import sys
import zipfile
-def extractZip(source, dest):
- """ Extracts |source| ZIP archive to |dest| folder returning |True| if
- successful."""
+
+def UnpackZip(target, source):
+ """Unpacks |source| archive to |target| directory."""
+ target = os.path.normpath(target)
archive = zipfile.ZipFile(source, 'r')
for f in archive.namelist():
- target = os.path.normpath(os.path.join(dest, f))
+ target_file = os.path.normpath(os.path.join(target, f))
# Sanity check to make sure .zip uses relative paths.
- if os.path.commonprefix([target, dest]) != dest:
+ if os.path.commonprefix([target_file, target]) != target:
print "Failed to unpack '%s': '%s' is not under '%s'" % (
- source, target, dest)
- return False
+ source, target_file, target)
+ return 1
# Create intermediate directories.
- target_dir = os.path.dirname(target)
+ target_dir = os.path.dirname(target_file)
if not os.path.exists(target_dir):
os.makedirs(target_dir)
- archive.extract(f, dest)
- return True
+ archive.extract(f, target)
+ return 0
+
+
+def Merge(left, right):
+ """Merges two values.
+
+ Raises:
+ TypeError: |left| and |right| cannot be merged.
-def merge(left, right):
- """ Merges to values. The result is:
+ Returns:
- if both |left| and |right| are dictionaries, they are merged recursively.
- if both |left| and |right| are lists, the result is a list containing
elements from both lists.
@@ -77,29 +95,30 @@ def merge(left, right):
retval = copy.copy(left)
for key, value in right.iteritems():
if key in retval:
- retval[key] = merge(retval[key], value)
+ retval[key] = Merge(retval[key], value)
else:
retval[key] = value
return retval
else:
- raise TypeError("Error: merging a dictionary and non-dictionary value")
+ raise TypeError('Error: merging a dictionary and non-dictionary value')
elif isinstance(left, list):
if isinstance(right, list):
return left + right
else:
- raise TypeError("Error: merging a list and non-list value")
+ raise TypeError('Error: merging a list and non-list value')
else:
if isinstance(right, dict):
- raise TypeError("Error: merging a dictionary and non-dictionary value")
+ raise TypeError('Error: merging a dictionary and non-dictionary value')
elif isinstance(right, list):
- raise TypeError("Error: merging a dictionary and non-dictionary value")
+ raise TypeError('Error: merging a dictionary and non-dictionary value')
else:
return right
quote_matcher_regex = re.compile(r'\s|"')
quote_replacer_regex = re.compile(r'(\\*)"')
-def quoteArgument(arg):
+
+def QuoteArgument(arg):
"""Escapes a Windows command-line argument.
So that the Win32 CommandLineToArgv function will turn the escaped result back
@@ -128,15 +147,16 @@ def quoteArgument(arg):
else:
return arg
-def generateCommandLine(tool, source, dest, parameters):
+
+def GenerateCommandLine(tool, source, dest, parameters):
"""Generates the command line for |tool|."""
# Merge/apply tool-specific parameters
params = copy.copy(parameters)
if tool in parameters:
- params = merge(params, params[tool])
+ params = Merge(params, params[tool])
wix_path = os.path.normpath(params.get('wix_path', ''))
- switches = [ os.path.join(wix_path, tool), '-nologo' ]
+ switches = [os.path.join(wix_path, tool), '-nologo']
# Append the list of defines and extensions to the command line switches.
for name, value in params.get('defines', {}).iteritems():
@@ -152,13 +172,13 @@ def generateCommandLine(tool, source, dest, parameters):
switches += ('-out', dest, source)
# Generate the actual command line
- #return ' '.join(map(quoteArgument, switches))
+ #return ' '.join(map(QuoteArgument, switches))
return switches
-def run(args):
- """ Constructs a quoted command line from the passed |args| list and runs it.
- Prints the exit code and output of the command if an error occurs."""
- command = ' '.join(map(quoteArgument, args))
+
+def Run(args):
+ """Runs a command interpreting the passed |args| as a command line."""
+ command = ' '.join(map(QuoteArgument, args))
popen = subprocess.Popen(
command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
out, _ = popen.communicate()
@@ -169,68 +189,70 @@ def run(args):
print '%s returned %d' % (args[0], popen.returncode)
return popen.returncode
-def main():
- usage = "Usage: zip2msi [options] <input.zip> <output.msi>"
- parser = OptionParser(usage=usage)
- parser.add_option('--intermediate_dir', dest='intermediate_dir')
- parser.add_option('--wix_path', dest='wix_path')
- options, args = parser.parse_args()
- if len(args) != 2:
- parser.error("two positional arguments expected")
- parameters = dict(options.__dict__)
- parameters['basename'] = os.path.splitext(os.path.basename(args[0]))[0]
- if not options.intermediate_dir:
- parameters['intermediate_dir'] = os.path.normpath('.')
+def GenerateMsi(target, source, parameters):
+ """Generates .msi from the installation files prepared by Chromium build."""
+ parameters['basename'] = os.path.splitext(os.path.basename(source))[0]
# The script can handle both forms of input a directory with unpacked files or
# a ZIP archive with the same files. In the latter case the archive should be
# unpacked to the intermediate directory.
- intermediate_dir = os.path.normpath(parameters['intermediate_dir'])
source_dir = None
- if os.path.isdir(args[0]):
+ if os.path.isdir(source):
# Just use unpacked files from the supplied directory.
- source_dir = args[0]
+ source_dir = source
else:
# Unpack .zip
- if not extractZip(args[0], intermediate_dir):
- return 1
+ rc = UnpackZip(parameters['intermediate_dir'], source)
+ if rc != 0:
+ return rc
source_dir = '%(intermediate_dir)s\\%(basename)s' % parameters
# Read parameters from 'parameters.json'.
f = open(os.path.join(source_dir, 'parameters.json'))
- parameters = merge(parameters, json.load(f))
+ parameters = Merge(json.load(f), parameters)
f.close()
if 'source' not in parameters:
- print "The source .wxs is not specified"
+ print 'The source .wxs is not specified'
return 1
if 'bind_path' not in parameters:
- print "The binding path is not specified"
+ print 'The binding path is not specified'
return 1
- dest = args[1]
- source = os.path.join(source_dir, parameters['source'])
+ wxs = os.path.join(source_dir, parameters['source'])
# Add the binding path to the light-specific parameters.
bind_path = os.path.join(source_dir, parameters['bind_path'])
- parameters = merge(parameters, {'light': {'switches': ['-b', bind_path]}})
+ parameters = Merge(parameters, {'light': {'switches': ['-b', bind_path]}})
# Run candle and light to generate the installation.
wixobj = '%(intermediate_dir)s\\%(basename)s.wixobj' % parameters
- args = generateCommandLine('candle', source, wixobj, parameters)
- rc = run(args)
+ args = GenerateCommandLine('candle', wxs, wixobj, parameters)
+ rc = Run(args)
if rc:
return rc
- args = generateCommandLine('light', wixobj, dest, parameters)
- rc = run(args)
+ args = GenerateCommandLine('light', wixobj, target, parameters)
+ rc = Run(args)
if rc:
return rc
return 0
-if __name__ == "__main__":
+
+def main():
+ usage = 'Usage: zip2msi [options] <input.zip> <output.msi>'
+ parser = OptionParser(usage=usage)
+ parser.add_option('--intermediate_dir', dest='intermediate_dir', default='.')
+ parser.add_option('--wix_path', dest='wix_path', default='.')
+ options, args = parser.parse_args()
+ if len(args) != 2:
+ parser.error('two positional arguments expected')
+
+ return GenerateMsi(args[1], args[0], dict(options.__dict__))
+
+if __name__ == '__main__':
sys.exit(main())