code: def open(self):
      # ControlMaster and ControlPath are always set
      command = [
          "ssh",
          "-f",
          "-N",
          "-M",
          "-S",
          self.control_sock_path,
          "-i",
          self.id_rsa_path,
      ]
      for k, v in self.options.items():
          command += ["-o", f"{k}={v}"]
      for port_remote, port_local in self.ports.items():
          command += ["-L", f"{port_local}:localhost:{port_remote}"]
      command += [self.host]
  
      r = subprocess.run(
          command, stdout=subprocess.PIPE, stderr=subprocess.PIPE
      )
      if r.returncode == 0:
          return
      logger.debug("SSH tunnel failed: %s", r.stderr)
      raise get_ssh_error(r.stderr)
  
file_path: dstack/src/dstack/_internal/core/services/ssh/tunnel.py
imports: import os
  import subprocess
  import tempfile
  from typing import Dict, Optional
  from dstack._internal.core.services.ssh import get_ssh_error
  from dstack._internal.utils.logging import get_logger
  from dstack._internal.utils.path import PathLike
label_desc: Use image node_id 2 for calling the SSHTunnel obj's underlying member method code with example usage: obj.open() without return types