  def GetOrCreateAnalysisVm(
      self,
      vm_name: str,
      boot_disk_size: int = 10,
      disk_type: str = 'pd-standard',
      cpu_cores: int = 4,
      image_project: str = 'ubuntu-os-cloud',
      image_family: str = 'ubuntu-2204-lts',
      packages: Optional[List[str]] = None,
      zone: Optional[str] = None,
      data_disks: Optional[List[Union['GoogleComputeDisk',
                                      'GoogleRegionComputeDisk']]] = None
  ) -> Tuple['GoogleComputeInstance', bool]:
    """Get or create a new virtual machine for analysis purposes.

    If none of the optional parameters are specified, then by default the
    analysis VM that will be created will run Ubuntu 22.04 LTS. A default
    set of forensic tools is also installed (a custom one may be provided
    using the 'packages' argument).

    Args:
      vm_name: Name of the virtual machine.
      boot_disk_size: boot disk size in base-2 GB. If you specify a sourceImage,
          which is required for boot disks, the default size is the size
          of the sourceImage, else default is 10 GB.
      disk_type: URL of the disk type resource describing
          which disk type to use to create the disk. Default is pd-standard. Use
          pd-ssd to have a SSD disk.
      cpu_cores: Number of CPU cores for the virtual machine.
      image_project: Name of the project where the analysis VM
          image is hosted.
      image_family: Name of the image to use to create the
          analysis VM.
      packages: List of packages to install in the VM.
      zone: Compute zone to start the instance in, default is self.default_zone.
      data_disks: List of disks to attach to the instance, default
          mode is READ_ONLY. If the VM already exists, disks will be attached
          to the existing VM.

    Returns:
      A tuple with a virtual machine object and a boolean indicating
          if the virtual machine was created or re-used.

    Raises:
      ResourceCreationError: If virtual machine cannot be found after creation.
      ValueError: If the requested CPU cores is not available for the
        specified machine type.
    """

    # Re-use instance if it already exists, or create a new one.
    try:
      instance = self.GetInstance(vm_name)

      # Instance exists, attach disks that have not already been attached
      if data_disks:
        disks_to_attach = {disk.name : disk for disk in data_disks}
        attached_disks = instance.ListDisks().keys()
        for attached_disk in attached_disks:
          disks_to_attach.pop(attached_disk, None)
        for disk_to_attach in disks_to_attach.values():
          instance.AttachDisk(disk_to_attach)

      return instance, False
    except errors.ResourceNotFoundError:
      pass
    compute_zone = zone if zone else self.default_zone

    if cpu_cores not in E2_STANDARD_CPU_CORES:
      raise ValueError(
          'Number of requested CPU cores ({0:d}) not available for machine type'
          ' {1:s}'.format(cpu_cores, DEFAULT_MACHINE_TYPE))
    machine_type = '{0:s}-{1:d}'.format(DEFAULT_MACHINE_TYPE, cpu_cores)
    startup_script = utils.ReadStartupScript(utils.FORENSICS_STARTUP_SCRIPT_GCP)

    if packages:
      startup_script = startup_script.replace(
          '${packages[@]}', ' '.join(packages))
    instance = self.CreateInstanceFromArguments(
        vm_name,
        machine_type,
        compute_zone,
        boot_disk_type=disk_type,
        boot_disk_size=boot_disk_size,
        boot_image_project=image_project,
        boot_image_family=image_family,
        data_disks=data_disks,
        metadata={'startup-script': startup_script},
        network_name='default',
        external_ip=True)
    return instance, True
Get or create a new virtual machine for analysis purposes.

If none of the optional parameters are specified, then by default the
analysis VM that will be created will run Ubuntu 22.04 LTS. A default
set of forensic tools is also installed (a custom one may be provided
using the 'packages' argument).

Args:
vm_name: Name of the virtual machine.
boot_disk_size: boot disk size in base-2 GB. If you specify a sourceImage,
which is required for boot disks, the default size is the size
of the sourceImage, else default is 10 GB.
disk_type: URL of the disk type resource describing
which disk type to use to create the disk. Default is pd-standard. Use
pd-ssd to have a SSD disk.
cpu_cores: Number of CPU cores for the virtual machine.
image_project: Name of the project where the analysis VM
image is hosted.
image_family: Name of the image to use to create the
analysis VM.
packages: List of packages to install in the VM.
zone: Compute zone to start the instance in, default is self.default_zone.
data_disks: List of disks to attach to the instance, default
mode is READ_ONLY. If the VM already exists, disks will be attached
to the existing VM.

Returns:
A tuple with a virtual machine object and a boolean indicating
if the virtual machine was created or re-used.

Raises:
ResourceCreationError: If virtual machine cannot be found after creation.
ValueError: If the requested CPU cores is not available for the
specified machine type.
libcloudforensics/providers/gcp/internal/compute.py