Call repacker in a subprocess.

def RepackTemplates(self,
                      repack_configs,
                      templates,
                      output_dir,
                      config=None,
                      sign=False,
                      signed_template=False):
    """Call repacker in a subprocess."""
    pool = multiprocessing.Pool(processes=10)
    results = []
    bulk_sign_installers = False
    for repack_config in repack_configs:
      for template in templates:
        repack_args = ["grr_client_build"]
        if config:
          repack_args.extend(["--config", config])

        repack_args.extend([
            "--secondary_configs", repack_config, "repack", "--template",
            template, "--output_dir",
            self.GetOutputDir(output_dir, repack_config)
        ])

        # We only sign exes and rpms at the moment. The others will raise if we
        # try to ask for signing.
        passwd = None

        if sign:
          if template.endswith(".exe.zip"):
            # This is for osslsigncode only.
            if platform.system() != "Windows":
              passwd = self.GetWindowsPassphrase()
              repack_args.append("--sign")
            else:
              bulk_sign_installers = True
            if signed_template:
              repack_args.append("--signed_template")
          elif template.endswith(".rpm.zip"):
            bulk_sign_installers = True

        print("Calling %s" % " ".join(repack_args))
        results.append(
            pool.apply_async(SpawnProcess, (repack_args,), dict(passwd=passwd)))

        # Also build debug if it's windows.
        if template.endswith(".exe.zip"):
          debug_args = []
          debug_args.extend(repack_args)
          debug_args.append("--debug_build")
          print("Calling %s" % " ".join(debug_args))
          results.append(
              pool.apply_async(SpawnProcess, (debug_args,),
                               dict(passwd=passwd)))

    try:
      pool.close()
      # Workaround to handle keyboard kills
      # http://stackoverflow.com/questions/1408356/keyboard-interrupts-with-pythons-multiprocessing-pool
      # get will raise if the child raises.
      for result_obj in results:
        result_obj.get(9999)
      pool.join()
    except KeyboardInterrupt:
      print("parent received control-c")
      pool.terminate()
    except ErrorDuringRepacking:
      pool.terminate()
      raise

    if bulk_sign_installers:
      to_sign = {}
      for root, _, files in os.walk(output_dir):
        for f in files:
          if f.endswith(".exe"):
            to_sign.setdefault("windows", []).append(os.path.join(root, f))
          elif f.endswith(".rpm"):
            to_sign.setdefault("rpm", []).append(os.path.join(root, f))
      if to_sign.get("windows"):
        signer = repacking.TemplateRepacker().GetSigner([
            "ClientBuilder Context",
            "Platform:%s" % platform.system(), "Target:Windows"
        ])
        signer.SignFiles(to_sign.get("windows"))
      if to_sign.get("rpm"):
        signer = repacking.TemplateRepacker().GetSigner([
            "ClientBuilder Context",
            "Platform:%s" % platform.system(), "Target:Linux", "Target:LinuxRpm"
        ])
        signer.AddSignatureToRPMs(to_sign.get("rpm"))