I'm submitting this fasttrack for John Leser and Peter Memishian. The
timer is set for June 18th, 2008.
Overview
========
This case proposes to revise the parseable output format for dladm(1M)
to be both robust and easy to parse. It also proposes a set of
guidelines that we anticipate future networking CLIs will follow (and,
where appropriate and feasible, could be applied to existing CLIs).
Stability level is Committed. Release Binding is Minor.
Background
==========
In general, it's helpful for building administrative scripts as well as
test cases that there be some way to cause commands to issue output in
a format that is stable and easy for scripts to parse. While dladm(1M)
currently provides a parseable output mode, it is not that easy to
parse, especially from a shell:
# dladm show-link -p
LINK="e1000g0" CLASS="phys" MTU="1500" STATE="up" OVER=""
LINK="e1000g1" CLASS="phys" MTU="1500" STATE="unknown" OVER=""
LINK="e1000g2" CLASS="phys" MTU="1500" STATE="unknown" OVER=""
LINK="e1000g3" CLASS="phys" MTU="1500" STATE="unknown" OVER=""
Although one might think that "eval" could be used in the shell to
access the set of values one line at a time, this has major pitfalls:
* Each eval runs the risk possibly clobbering variables already in
use by the script. This means that any time a new field is
added, there is small but very real potential to break any
script that happened to use that field name as a local variable.
* Use of eval presents a significant security risk: any command
where a non-privileged user might gain control over any field's
value makes eval as root (say, in an admin script) unsafe.
Proposal
========
We propose that parseable output employ a simple field separator scheme
similar to what is already used by "zoneadm list -p":
$ zoneadm list -p
0:global:running:/::native:shared
However, given that ":" is common in MAC and IPv6 addresses, we propose
to use "|" as the field separator. Also of note:
* Since it's possible that a field value could contain a literal
"|", parseable output will escape literal "|" as "\|", and
literal "\" as "\\". As it happens, this escape format is
already handled automatically by the "read" and "while read"
shell constructs, ensuring that parsing remains simple.
* Fields with no value will be shown as being empty (see the
example below), rather than "-" or "--", as might be used in
normal output.
* As before, headers will be omitted in parseable output mode.
Further, we propose that the existing "-o" switch (which is used to
enumerate fields to display) be required in parseable output mode.
This ensure that we will be able to add new fields in the future
without potentially breaking existing scripts.
Output format examples:
# dladm show-link -o link,over,state
LINK OVER STATE
e1000g0 -- up
e1000g1 -- unknown
e1000g2 -- unknown
e1000g3 -- unknown
# dladm show-link -p
dladm: output field list (-o) required in parsable output mode
# dladm show-link -p -o link,over,state
e1000g0||up
e1000g1||unknown
e1000g2||unknown
e1000g3||unknown
Note that this is a change to a Committed interface, but it is a
relatively safe change. The Solaris 10 parseable output format was not
usable and was already modified in Nevada build 83 to the format
described in the Background section. Changing the format again doesn't
break anything new, and the project team is aware of the existing
consumers of this format since they needed to be altered in build 83.