sysrepo
                                
                                 sysrepo copied to clipboard
                                
                                    sysrepo copied to clipboard
                            
                            
                            
                        Rules for emitting changes to subtrees?
Hello. We observed the following behaviour, which appears to be inconsistent (but we may be missing something):
(1) When subscribed to /ietf-system:system/ntp changes we receive created/deleted events for the ntp subtree itself. For example, when setting ntp/enabled we get
ChangeCreated(/ietf-system:system/ntp: {'enabled': True})
ChangeCreated(/ietf-system:system/ntp/enabled: True)
(2) When subscribed to /ietf-system:system/dns-resolver changes we don't receive created/deleted events for the dns-resolver subtree itself. For example, after adding a first DNS server we only receive the server events, although the dns-resolver container has been create as well:
ChangeCreated(/ietf-system:system/dns-resolver/server[name='a']: {'name': 'a', 'udp-and-tcp': {'address': '1.1.1.1'}}: AFTER '')
ChangeCreated(/ietf-system:system/dns-resolver/server[name='a']/name: 'a')
ChangeCreated(/ietf-system:system/dns-resolver/server[name='a']/udp-and-tcp: {'address': '1.1.1.1'})
ChangeCreated(/ietf-system:system/dns-resolver/server[name='a']/udp-and-tcp/address: '1.1.1.1')
Please-- is it a bug or a feature? I was expecting we receive an event for all created containers, including the dns-resolver.
Just for the record, I did test it using the following sysrepo-python code:
#!/bin/python3
import sysrepo
import signal
def module_change_cb(event, req_id, changes, private_data):
    print("Module changed event: %s (request ID %s)" % (event, req_id))
    print("----- changes -----")
    for c in changes:
        print(repr(c))
    print("----- end of changes -----")
    print()
def main():
    with sysrepo.SysrepoConnection() as conn:
        with conn.start_session() as sess:
            sess.subscribe_module_change("ietf-system", None, module_change_cb)
            signal.sigwait({signal.SIGINT, signal.SIGTERM})
main()
Based on the behavior of non-presence containers, we have implemented them similarly to default values meaning they exist whenever their parent exists or always if they are top-level. So the reason for this behavior is that ntp is a presence container while dns-resolver is not (so it existed before).
/ietf-system:system/ntp is a presence container, which means that its mere presence/absence has a meaning. On the other hand, /ietf-system:system/dns-resolver is just a regular container. Here's what the standard says about non-presence containers:
If a node that exists in the accessible tree has a non-presence container as a child, then the non-presence container also exists in the accessible tree.
In general, in sysrepo you're going to always "see" the regular, non-presence containers since their "presence" or "non presence" is defined by the standard to not have any consequences.
Thank you. Just to confirm: the empty non-presence containers are then hidden when exporting data, just like default values are not shown. Right?
Yes, but you can use printing flags to see them if you want.
Unless you use the LYD_PRINT_KEEPEMPTYCONT, then yeah, empty non-presence containers are not printed AFAICT.