sysrepo icon indicating copy to clipboard operation
sysrepo copied to clipboard

Rules for emitting changes to subtrees?

Open gotthardp opened this issue 2 years ago • 6 comments

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.

gotthardp avatar Sep 29 '23 09:09 gotthardp

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()

gotthardp avatar Sep 29 '23 09:09 gotthardp

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).

michalvasko avatar Sep 29 '23 12:09 michalvasko

/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.

jktjkt avatar Sep 29 '23 12:09 jktjkt

Thank you. Just to confirm: the empty non-presence containers are then hidden when exporting data, just like default values are not shown. Right?

gotthardp avatar Sep 29 '23 13:09 gotthardp

Yes, but you can use printing flags to see them if you want.

michalvasko avatar Sep 29 '23 13:09 michalvasko

Unless you use the LYD_PRINT_KEEPEMPTYCONT, then yeah, empty non-presence containers are not printed AFAICT.

jktjkt avatar Sep 29 '23 14:09 jktjkt