def AddMetadata()

in perfkitbenchmarker/publisher.py [0:0]


  def AddMetadata(self, metadata: dict[str, Any], benchmark_spec):
    new_metadata = {}
    new_metadata['perfkitbenchmarker_version'] = version.VERSION
    if FLAGS.simulate_maintenance:
      new_metadata['simulate_maintenance'] = True
    if FLAGS.hostname_metadata:
      new_metadata['hostnames'] = ','.join(
          [vm.hostname for vm in benchmark_spec.vms]
      )
    if benchmark_spec.container_cluster:
      cluster = benchmark_spec.container_cluster
      for k, v in cluster.GetResourceMetadata().items():
        new_metadata['container_cluster_' + k] = v

    if benchmark_spec.relational_db:
      db = benchmark_spec.relational_db
      for k, v in db.GetResourceMetadata().items():
        # TODO(user): Rename to relational_db.
        new_metadata['managed_relational_db_' + k] = v

    if benchmark_spec.pinecone:
      pinecone = benchmark_spec.pinecone
      for k, v in pinecone.GetResourceMetadata().items():
        new_metadata['pinecone_' + k] = v

    if benchmark_spec.memory_store:
      memory_store = benchmark_spec.memory_store
      for k, v in memory_store.GetResourceMetadata().items():
        new_metadata[k] = v

    for name, tpu in benchmark_spec.tpu_groups.items():
      for k, v in tpu.GetResourceMetadata().items():
        new_metadata['tpu_' + k] = v

    for name, vms in benchmark_spec.vm_groups.items():
      if len(vms) == 0:
        continue

      # Get a representative VM so that we can publish the cloud, zone,
      # machine type, and image.
      vm = vms[-1]
      name_prefix = '' if name == 'default' else name + '_'
      for k, v in vm.GetResourceMetadata().items():
        if k not in _VM_METADATA_TO_LIST_PLURAL:
          new_metadata[name_prefix + k] = v
      new_metadata[name_prefix + 'vm_count'] = len(vms)
      for k, v in vm.GetOSResourceMetadata().items():
        new_metadata[name_prefix + k] = v

      if vm.scratch_disks:
        data_disk = vm.scratch_disks[0]
        new_metadata[name_prefix + 'data_disk_count'] = len(vm.scratch_disks)
        for key, value in data_disk.GetResourceMetadata().items():
          new_metadata[name_prefix + 'data_disk_0_%s' % (key,)] = value

    # Get some new_metadata from all VMs:
    # Here having a lack of a prefix indicate the union of all groups, where it
    # signaled the default vm group above.
    vm_groups_and_all = benchmark_spec.vm_groups | {None: benchmark_spec.vms}
    for group_name, vms in vm_groups_and_all.items():
      name_prefix = group_name + '_' if group_name else ''
      # since id and name are generic new_metadata prefix vm, so it is clear
      # what the resource is.
      name_prefix += 'vm_'
      for key, key_plural in _VM_METADATA_TO_LIST_PLURAL.items():
        values = []
        for vm in vms:
          if value := vm.GetResourceMetadata().get(key):
            values.append(value)
        if values:
          new_metadata[name_prefix + key_plural] = ','.join(values)

    if FLAGS.set_files:
      new_metadata['set_files'] = ','.join(FLAGS.set_files)
    if FLAGS.sysctl:
      new_metadata['sysctl'] = ','.join(FLAGS.sysctl)

    # Add new values, keeping old ones in conflicts.
    overlapping_keys = set(new_metadata.keys()).intersection(metadata.keys())
    if overlapping_keys and _THROW_ON_METADATA_CONFLICT.value:
      conflicts = []
      for key in overlapping_keys:
        if new_metadata[key] != metadata[key]:
          conflicts.append(f'{key}: {new_metadata[key]} != {metadata[key]}')
      if conflicts:
        raise ValueError(
            'Conflicting keys are already set in metadata & are being '
            'overwritten by default metadata provider. Resolve by using a '
            'different VM group, adding prefixes and/or different names to the '
            'metadata keys, or by setting --throw_on_metadata_conflict=False.'
            'Conflicts, with new value on left and old value on right: %s'
            % conflicts
        )
    metadata = new_metadata | metadata
    # Flatten all user metadata into a single list (since each string in the
    # FLAGS.metadata can actually be several key-value pairs) and then
    # iterate over it.
    parsed_metadata = flag_util.ParseKeyValuePairs(FLAGS.metadata)
    metadata.update(parsed_metadata)
    return metadata