docs: def MakeSelfExtractingZip(self, payload_data, output_path):
      """Repack the installer into the payload.
  
      Args:
        payload_data: data payload for zip file
        output_path: filename for the zip output
  
      Raises:
        RuntimeError: if the ClientBuilder.unzipsfx_stub doesn't require admin.
      Returns:
        output_path: filename string of zip output file
      """
      context = self.context + ["Client Context"]
  
      src_zip = zipfile.ZipFile(io.BytesIO(payload_data), mode="r")
      zip_data = io.BytesIO()
      output_zip = zipfile.ZipFile(
          zip_data, mode="w", compression=zipfile.ZIP_DEFLATED)
  
      config_file_name = config.CONFIG.Get(
          "ClientBuilder.config_filename", context=context)
      # Copy the rest of the files from the package to the new zip.
      for template_file in src_zip.namelist():
        if template_file != config_file_name:
          # Avoid writing the config file twice if we're repacking a binary that
          # has already been run through deployment. We write it in the next step,
          # so no need to copy over from the original here.
          CopyFileInZip(src_zip, template_file, output_zip)
  
      client_config_content = self.GetClientConfig(context)
  
      output_zip.writestr(
          config_file_name,
          client_config_content.encode("utf-8"),
          compress_type=zipfile.ZIP_STORED)
  
      # The zip file comment is used by the self extractor to run the installation
      # script. Comment has to be `bytes` object because `zipfile` module is not
      # smart enough to properly handle `unicode` objects. We use the `encode`
      # method instead of `SmartStr` because we expect this option to be an
      # `unicode` object and in case it is not, we want it to blow up.
      output_zip.comment = b"$AUTORUN$>%s" % config.CONFIG.Get(
          "ClientBuilder.autorun_command_line", context=context).encode("utf-8")
  
      output_zip.close()
  
      utils.EnsureDirExists(os.path.dirname(output_path))
      with open(output_path, "wb") as fd:
        # First write the installer stub
        stub_data = io.BytesIO()
        unzipsfx_stub = config.CONFIG.Get(
            "ClientBuilder.unzipsfx_stub", context=context)
        stub_raw = open(unzipsfx_stub, "rb").read()
  
        # Check stub has been compiled with the requireAdministrator manifest.
        if b"level=\"requireAdministrator" not in stub_raw:
          raise RuntimeError("Bad unzip binary in use. Not compiled with the"
                             "requireAdministrator manifest option.")
  
        stub_data.write(stub_raw)
  
        # If in verbose mode, modify the unzip bins PE header to run in console
        # mode for easier debugging.
        SetPeSubsystem(
            stub_data,
            console=config.CONFIG.Get("ClientBuilder.console", context=context))
  
        # Now patch up the .rsrc section to contain the payload.
        end_of_file = zip_data.tell() + stub_data.tell()
  
        # This is the IMAGE_SECTION_HEADER.Name which is also the start of
        # IMAGE_SECTION_HEADER.
        offset_to_rsrc = stub_data.getvalue().find(b".rsrc")
  
        # IMAGE_SECTION_HEADER.PointerToRawData is a 32 bit int.
        stub_data.seek(offset_to_rsrc + 20)
        start_of_rsrc_section = struct.unpack("<I", stub_data.read(4))[0]
  
        # Adjust IMAGE_SECTION_HEADER.SizeOfRawData to span from the old start to
        # the end of file.
        stub_data.seek(offset_to_rsrc + 16)
        stub_data.write(struct.pack("<I", end_of_file - start_of_rsrc_section))
  
        # Concatenate stub and zip file.
        out_data = io.BytesIO()
        out_data.write(stub_data.getvalue())
        out_data.write(zip_data.getvalue())
  
        # Then write the actual output file.
        fd.write(out_data.getvalue())
  
      if self.signer:
        self.signer.SignFile(output_path)
  
      logging.info("Deployable binary generated at %s", output_path)
  
      return output_path