ConfD User Community

Confdc error: No must statements with the given argument is found

Hi all,
this is the 1st time I have to make some changes in a yang file :slight_smile:
The “must” statement in file1 below was already in place , I simply removed from the bottom end some of the checks (specifically there was the “gbytes” units included). This is a change that I did not expect to break an otherwise working compilation. The remaining checks make sure the queue-limit’s value is always larger than the queue-min-limit’s value, irrespective of the units involved.

So I have the main yang file along with some annotations in a 2nd file.

file1.yang

container queue-limit {
       ...
       must "(((../../queue-min-limit/units = 'bytes') and " +
           "  (((../units = 'bytes') and (../value >= ../../queue-min-limit//value)) or " +
           "   ((../units = 'kbytes') and ((../value * 1000) >= (../../queue-min-limit/value))) or " +
           "   ((../units = 'mbytes') and ((../value * 1000000) >= (../../queue-min-limit/value))))) or " +
           " ((../../queue-min-limit/units = 'kbytes') and " +
           "  (((../units = 'bytes') and (../value >= (../../queue-min-limit/value * 1000))) or " +
           "   ((../units = 'kbytes') and (../value >= ../../queue-min-limit/value)) or " +
           "   ((../units = 'mbytes') and ((../value * 1000) >= ../../queue-min-limit/value)))) or " +
           " ((../../queue-min-limit/units = 'mbytes') and " +
           "  (((../units = 'bytes') or " +
           "   ((../units = 'kbytes') and (../value >= (../../queue-min-limit/value * 1000))) or " +
           "   ((../units = 'mbytes') and (../value >= ../../queue-min-limit/value))))))" 
       {
          error-message "Static queue limit cannot be configured to a smaller value than the minimum static queue size.";
       }
       ...
}

some tailf:depencies are in the annotations yang file.

file1-ann.yang

tailf:annotate-statement container[name='queue-limit'] {
           ...
           tailf:annotate-statement "must[name=\"" +
              "(((../../queue-min-limit/units = 'bytes') and " +
              "  (((../units = 'bytes') and (../value >= ../../queue-min-limit//value)) or " +
              "   ((../units = 'kbytes') and ((../value * 1000) >= (../../queue-min-limit/value))) or " +
              "   ((../units = 'mbytes') and ((../value * 1000000) >= (../../queue-min-limit/value))))) or " +
              " ((../../queue-min-limit/units = 'kbytes') and " +
              "  (((../units = 'bytes') and (../value >= (../../queue-min-limit/value * 1000))) or " +
              "   ((../units = 'kbytes') and (../value >= ../../queue-min-limit/value)) or " +
              "   ((../units = 'mbytes') and ((../value * 1000) >= ../../queue-min-limit/value)))) or " +
              " ((../../queue-min-limit/units = 'mbytes') and " +
              "  (((../units = 'bytes') or " +
              "   ((../units = 'kbytes') and (../value >= (../../queue-min-limit/value * 1000))) or " +
              "   ((../units = 'mbytes') and (../value >= ../../queue-min-limit/value)))))) " +
              "\"]" 
           {
              tailf:dependency "/something";
              tailf:dependency "/smth-else";
              tailf:dependency "/yet-another";
           }
       ...
}

I try to compile this to using the following command

confdc \
      [........... tailf-common are included here among with other things..........] \
     -c --verbose  -o output/confd_yang/file1.fxs \
     -a file1_ann.yang \
     file1.yang

and the output I get

Generating .fxs file "output/confd_yang/file1.fxs"
Read file file1.yang
Read file file1-ann.yang
file1.yang:1278: warning: The 'must' expression should have a tailf:dependency. If is doesn't, it will be checked for every commit.
file1.yang:1278: warning: The 'must' expression should have a tailf:dependency. If is doesn't, it will be checked for every commit.
file1.yang:1278: warning: The 'must' expression should have a tailf:dependency. If is doesn't, it will be checked for every commit.
file1-ann.yang:469: error: No must statements with the given argument is found.

The annotate-statement seems the same (to me) as the “must” statement it refers to in file1.yang. I checked the lines side by side in a diff editor such as “meld”. So I expected the compilation to succeed. Yet I get the error that you see in the last line.

What am I missing ?

Thank you in advance for your help!

Hi,
You can try refering to the [<position>] of the “must” statement, not [<arg-name>=<arg-value>].
I.e. which “must” statement in the YANG model you are annotating by position number (starting with 1).

For example, if the “must” statement you are annotating is the first “must” statement in the YANG model:

       tailf:annotate-statement "container[name='queue-limit']" {
          tailf:annotate-statement "must[1]" {
            tailf:dependency "/something";
            tailf:dependency "/smth-else";
            tailf:dependency "/yet-another";
          }
        }
1 Like

…although it seems like the only problem you had was that you were using “name” instead of “condition” in the “must” annotation statement.

Note that tailf:annotate statement use the YIN “argument name” for the “keyword”/“statement-name” (e.g. “must”). See table 1 in the YANG 1.1 RFC on the YIN definition.

So this will work:

        tailf:annotate-statement "container[name='queue-limit']" {
          ...
          tailf:annotate-statement "must[condition=\"" +
                                   "(((../../queue-min-limit/units = 'bytes') and " +
                                   "  (((../units = 'bytes') and (../value >= ../../queue-min-limit//value)) or " +
                                   "   ((../units = 'kbytes') and ((../value * 1000) >= (../../queue-min-limit/value))) or " +
                                   "   ((../units = 'mbytes') and ((../value * 1000000) >= (../../queue-min-limit/value))))) or " +
                                   " ((../../queue-min-limit/units = 'kbytes') and " +
                                   "  (((../units = 'bytes') and (../value >= (../../queue-min-limit/value * 1000))) or " +
                                   "   ((../units = 'kbytes') and (../value >= ../../queue-min-limit/value)) or " +
                                   "   ((../units = 'mbytes') and ((../value * 1000) >= ../../queue-min-limit/value)))) or " +
                                   " ((../../queue-min-limit/units = 'mbytes') and " +
                                   "  (((../units = 'bytes') or " +
                                   "   ((../units = 'kbytes') and (../value >= (../../queue-min-limit/value * 1000))) or " +
                                   "   ((../units = 'mbytes') and (../value >= ../../queue-min-limit/value))))))\"]"
          {
            tailf:dependency "/something";
            tailf:dependency "/smth-else";
            tailf:dependency "/yet-another";
          }
          ...
        }
1 Like

both options works nicely thank you. I chose to go for a little more dynamic code so I used the “condition” keyword and left the remaining intact.
My only question is, why did it use to work with “name” before? Seems like it should never have worked with it.
Go figure…

Thank you anyway!