diff options
-rw-r--r-- | build/all.gyp | 1 | ||||
-rw-r--r-- | chrome/tools/build/win/FILES.cfg | 7 | ||||
-rw-r--r-- | remoting/host/win/parameters.json | 6 | ||||
-rw-r--r-- | remoting/remoting.gyp | 44 | ||||
-rwxr-xr-x | remoting/tools/candle_and_light.py | 78 | ||||
-rwxr-xr-x | remoting/tools/dark_and_candle_and_light.py | 73 | ||||
-rwxr-xr-x | remoting/tools/zip2msi.py | 154 |
7 files changed, 101 insertions, 262 deletions
diff --git a/build/all.gyp b/build/all.gyp index bd09316..611208f 100644 --- a/build/all.gyp +++ b/build/all.gyp @@ -613,7 +613,6 @@ sas_dll_exists == "True"', { 'dependencies': [ '../remoting/remoting.gyp:remoting_host_installation', - '../remoting/remoting.gyp:remoting_host_installation_unittest', ], }], # component != "shared_library" ] diff --git a/chrome/tools/build/win/FILES.cfg b/chrome/tools/build/win/FILES.cfg index 050449a..21d6ed3 100644 --- a/chrome/tools/build/win/FILES.cfg +++ b/chrome/tools/build/win/FILES.cfg @@ -445,6 +445,13 @@ FILES = [ 'direct_archive': 1, }, { + 'filename': 'remoting-me2me-host-win.zip', + 'arch': ['32bit', '64bit'], + 'buildtype': ['dev', 'official'], + 'archive': 'remoting-me2me-host-win.zip', + 'direct_archive': 1, + }, + { 'filename': 'remoting_host_controller.exe', 'arch': ['32bit', '64bit'], 'buildtype': ['official'], 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()) |