Search code examples
pythonyamlnested-listspyyamlruamel.yaml

How to compare contents of several memserves in yaml?


I have to check few conditions from the yaml file given below:

provider: sockets
delayed_free_threads: 0
ATL_threads: 0
ATL_queue_size: 1000
ATL_data_size: 1024
Memservers:
  0:
    memory_type: volatile
    fam_path: /dev/shm/vol_path
    rpc_interface: fam5:8793
    libfabric_port: 7500
    if_device: eth0
  1:
    memory_type: volatile
    fam_path: /dev/shm/vol_path
    rpc_interface: fam4:8793
    libfabric_port: 7500
    if_device: eth1
  2:
    memory_type: volatile
    fam_path: /dev/shm/vol_path
    rpc_interface: fam3:8793
    libfabric_port: 7500
    if_device: eth1

Here are the conditions that I want to check: 1.If the rpc_interface is same. 2.If rpc_interface is same, is fam_path same? 3.If rpc_interface is same, is libabric_port same?

Here's the code that i tried:

def compare():
    host_port = {}
    fam_path_list = {}
    libabric_port_list ={}
    file_in = Path(r'C:\Users\User\OneDrive\Desktop\toold\fam_memoryserver_config.yaml')
    yaml = ruamel.yaml.YAML(typ='safe')  
    data = yaml.load(file_in)
    print(data.values())
    for machine, config in data.values():
            if 'rpc_interface' not in config: 
                print(f'machine {machine} has no "rpc_interface"');
                sys.exit(1)
            else:
                host_port.setdefault(con['rpc_interface'], set()).add(machine)
                fam_path_list.setdefault(config['fam_path'], set()).add(machine)
                libabric_port_list.setdefault(config['libfabric_port'], set()).add(machine)
    # check if host_port has any values that have more than one machine
    for hp, machine_nrs in host_port.items():
        if len(machine_nrs) == 1:
            continue
        j=[str(x) for x in machine_nrs]
        print(f'Found {hp} in machines: {", ".join(j)}')
   
    for hp, machine_nrs in fam_path_list.items():
        if len(machine_nrs) == 1:
            continue
        k=[str(x) for x in machine_nrs]
        print(f'Found {hp} in machines: {", ".join(k)}')

    for hp, machine_nrs in libabric_port_list.items():
        if len(machine_nrs) == 1:
           continue
        l=[str(x) for x in machine_nrs]
        print(f'Found {hp} in machines: {", ".join([str(x) for x in machine_nrs])}')

    def removeElements(j, k):
        return ', '.join(map(str, j)) in ', '.join(map(str, k))

    if (removeElements(j, k)==True) :
        print(f'The memory servers {j}, have the same fam_path, hence Validation failed!')
    else:
        print('Only the rpc_interface of the machines are same, hence Validation failed!')
 

    def removeElements(j, l):
        return ', '.join(map(str, j)) in ', '.join(map(str, l))

    if (removeElements(j, l)==True) :
        print(f'The memory servers {j}, have the same libfabric_port, hence Validation failed!')
        
    else:
        print('Only the rpc_interface of the machines are same, hence Validation failed!')

compare()

But the eror I am getting is :

for machine, config in data.values():
ValueError: too many values to unpack (expected 2)

Please let me know how to correct it


Solution

  • Your data is a dict (loaded from the root-level mapping in your YAML). If you iterate over data.values() you only get the values, i.e. sockets, 0, etc. YOu cannot assign that to two variables.

    Since you are testing on rpc_interface you probably want to do:

    for machine, config in data['Memservers'].items():