1 2FAQs 3==== 4 5This section contains the set of questions that users typically ask, 6along with answers that might be helpful. 7 8General 9------- 10 11Can you share the history of libxo? 12~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 13 14In 2001, we added an XML API to the JUNOS operating system, which is 15built on top of FreeBSD_. Eventually this API became standardized as 16the NETCONF API (:RFC:`6241`). As part of this effort, we modified many 17FreeBSD utilities to emit XML, typically via a "-X" switch. The 18results were mixed. The cost of maintaining this code, updating it, 19and carrying it were non-trivial, and contributed to our expense (and 20the associated delay) with upgrading the version of FreeBSD on which 21each release of JUNOS is based. 22 23.. _FreeBSD: https://www.freebsd.org 24 25A recent (2014) effort within JUNOS aims at removing our modifications 26to the underlying FreeBSD code as a means of reducing the expense and 27delay in tracking HEAD. JUNOS is structured to have system components 28generate XML that is rendered by the CLI (think: login shell) into 29human-readable text. This allows the API to use the same plumbing as 30the CLI, and ensures that all components emit XML, and that it is 31emitted with knowledge of the consumer of that XML, yielding an API 32that have no incremental cost or feature delay. 33 34libxo is an effort to mix the best aspects of the JUNOS strategy into 35FreeBSD in a seemless way, allowing commands to make printf-like 36output calls with a single code path. 37 38Did the complex semantics of format strings evolve over time? 39~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40 41The history is both long and short: libxo's functionality is based 42on what JUNOS does in a data modeling language called ODL (output 43definition language). In JUNOS, all subcomponents generate XML, 44which is feed to the CLI, where data from the ODL files tell is 45how to render that XML into text. ODL might had a set of tags 46like:: 47 48 tag docsis-state { 49 help "State of the DOCSIS interface"; 50 type string; 51 } 52 53 tag docsis-mode { 54 help "DOCSIS mode (2.0/3.0) of the DOCSIS interface"; 55 type string; 56 } 57 58 tag docsis-upstream-speed { 59 help "Operational upstream speed of the interface"; 60 type string; 61 } 62 63 tag downstream-scanning { 64 help "Result of scanning in downstream direction"; 65 type string; 66 } 67 68 tag ranging { 69 help "Result of ranging action"; 70 type string; 71 } 72 73 tag signal-to-noise-ratio { 74 help "Signal to noise ratio for all channels"; 75 type string; 76 } 77 78 tag power { 79 help "Operational power of the signal on all channels"; 80 type string; 81 } 82 83 format docsis-status-format { 84 picture " 85 State : @, Mode: @, Upstream speed: @ 86 Downstream scanning: @, Ranging: @ 87 Signal to noise ratio: @ 88 Power: @ 89 "; 90 line { 91 field docsis-state; 92 field docsis-mode; 93 field docsis-upstream-speed; 94 field downstream-scanning; 95 field ranging; 96 field signal-to-noise-ratio; 97 field power; 98 } 99 } 100 101These tag definitions are compiled into field definitions 102that are triggered when matching XML elements are seen. ODL 103also supports other means of defining output. 104 105The roles and modifiers describe these details. 106 107In moving these ideas to bsd, two things had to happen: the 108formatting had to happen at the source since BSD won't have 109a JUNOS-like CLI to do the rendering, and we can't depend on 110external data models like ODL, which was seen as too hard a 111sell to the BSD community. 112 113The results were that the xo_emit strings are used to encode the 114roles, modifiers, names, and formats. They are dense and a bit 115cryptic, but not so unlike printf format strings that developers will 116be lost. 117 118libxo is a new implementation of these ideas and is distinct from 119the previous implementation in JUNOS. 120 121.. index:: XOF_UNDERSCORES 122 123.. _good-field-names: 124 125What makes a good field name? 126~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 127 128To make useful, consistent field names, follow these guidelines: 129 130Use lower case, even for TLAs 131 Lower case is more civilized. Even TLAs should be lower case 132 to avoid scenarios where the differences between "XPath" and 133 "Xpath" drive your users crazy. Using "xpath" is simpler and better. 134 135Use hyphens, not underscores 136 Use of hyphens is traditional in XML, and the XOF_UNDERSCORES 137 flag can be used to generate underscores in JSON, if desired. 138 But the raw field name should use hyphens. 139 140Use full words 141 Don't abbreviate especially when the abbreviation is not obvious or 142 not widely used. Use "data-size", not "dsz" or "dsize". Use 143 "interface" instead of "ifname", "if-name", "iface", "if", or "intf". 144 145Use <verb>-<units> 146 Using the form <verb>-<units> or <verb>-<classifier>-<units> helps in 147 making consistent, useful names, avoiding the situation where one app 148 uses "sent-packet" and another "packets-sent" and another 149 "packets-we-have-sent". The <units> can be dropped when it is 150 obvious, as can obvious words in the classification. 151 Use "receive-after-window-packets" instead of 152 "received-packets-of-data-after-window". 153 154Reuse existing field names 155 Nothing's worse than writing expressions like:: 156 157 if ($src1/process[pid == $pid]/name == 158 $src2/proc-table/proc-list 159 /prc-entry[prcss-id == $pid]/proc-name) { 160 ... 161 } 162 163 Find someone else who is expressing similar data and follow their 164 fields and hierarchy. Remember the quote is not "Consistency is the 165 hobgoblin of little minds", but "A *foolish* consistency is the 166 hobgoblin of little minds". Consistency rocks! 167 168Use containment as scoping 169 In the previous example, all the names are prefixed with "proc-", 170 which is redundant given that they are nested under the process table. 171 172Think about your users 173 Have empathy for your users, choosing clear and useful fields that 174 contain clear and useful data. You may need to augment the display 175 content with xo_attr() calls (:ref:`xo_attr`) or "{e:}" 176 fields (:ref:`encoding-modifier`) to make the data useful. 177 178Don't use an arbitrary number postfix 179 What does "errors2" mean? No one will know. "errors-after-restart" 180 would be a better choice. Think of your users, and think of the 181 future. If you make "errors2", the next guy will happily make 182 "errors3" and before you know it, someone will be asking what's the 183 difference between errors37 and errors63. 184 185Be consistent, uniform, unsurprising, and predictable 186 Think of your field vocabulary as an API. You want it useful, 187 expressive, meaningful, direct, and obvious. You want the client 188 application's programmer to move between without the need to 189 understand a variety of opinions on how fields are named. They 190 should see the system as a single cohesive whole, not a sack of 191 cats. 192 193Field names constitute the means by which client programmers interact 194with our system. By choosing wise names now, you are making their 195lives better. 196 197After using `xolint` to find errors in your field descriptors, use 198"`xolint -V`" to spell check your field names and to help you detect 199different names for the same data. "dropped-short" and 200"dropped-too-short" are both reasonable names, but using them both 201will lead users to ask the difference between the two fields. If 202there is no difference, use only one of the field names. If there is 203a difference, change the names to make that difference more obvious. 204 205What does this message mean? 206~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 207 208.. include:: xolint.rst 209