code: def parse_packer_log(packer_log: str) -> Dict[str, str]:
      """Parse the output of packer's -machine-readable format, strange though it may be."""
      out = {}
  
      lines = packer_log.strip().split("\n")
      fields = [line.split(",") for line in lines]
      # We only care about artifact lines with exactly six fields.
      ArtifactLine = collections.namedtuple(
          "ArtifactLine", "time builder linetype index msgtype val"
      )
  
      # We only care about artifact lines with exactly 6 fields.
      artifact_lines = [
          ArtifactLine(*f)
          for f in fields
          if len(f) == 6 and f[2] == "artifact"
      ]
  
      # Get the ami images, which should match lines like this one (line break for readability):
      #   1598642161,amazon-ebs,artifact,0,id,us-east-1:
      #       ami-04894a7352df9fdf9%!(PACKER_COMMA)us-west-2:ami-017627938fe327e4f
      ami_lines = [
          a
          for a in artifact_lines
          if a.builder.startswith("amazon-ebs")
          and a.msgtype == "id"
          and a.val
      ]
      assert (
          len(ami_lines) == 2
      ), f"expected two matching ami ids line but got: {ami_lines}"
  
      for ami_line in ami_lines:
          ami_fields = ami_line.val.split("%!(PACKER_COMMA)")
          for ami_field in ami_fields:
              region, ami = ami_field.split(":")
              name = region.replace("-", "_") + "_agent_ami"
              out[name] = ami
  
      # Get the GCP builder name by matching the build-id from a line like this one:
      #   1598642161,det-environments-06318c7,artifact,0,builder-id,packer.googlecompute
      gcp_builders = [
          a.builder
          for a in artifact_lines
          if a.msgtype == "builder-id"
          and a.val == "packer.googlecompute"
      ]
      # aws gov images do not have matching gcp environment images.
      if len(gcp_builders) == 0:
          return out
      assert (
          len(gcp_builders) == 1
      ), f"expected one gcp builder but got: {gcp_builders}"
      gcp_builder = gcp_builders[0]
  
      # Get the GCP artifact ID by matching a line like this one:
      #    1598642161,det-environments-06318c7,artifact,0,id,det-environments-06318c7
      gcp_ids = [
          a.val
          for a in artifact_lines
          if a.builder == gcp_builder and a.msgtype == "id" and a.val
      ]
      assert (
          len(gcp_ids) == 1
      ), f"expected one matching gcp id line but got: {gcp_ids}"
      out["gcp_env"] = gcp_ids[0]
  
      return out
  
file_path: determined/tools/scripts/update-bumpenvs-yaml.py
imports: import argparse
  import collections
  import itertools
  import os
  import pathlib
  import sys
  from typing import Any, Dict
  import requests
  from ruamel import yaml
label_desc: Use image node_id 3 for calling a global function with example usage: parse_packer_log(packer_log) and returns: out, out