All of lore.kernel.org
 help / color / mirror / Atom feed
From: Markus Armbruster <armbru@redhat.com>
To: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
Cc: Kevin Wolf <kwolf@redhat.com>, Peter Krempa <pkrempa@redhat.com>,
	qemu-devel@nongnu.org, qemu-block@nongnu.org
Subject: Re: [Qemu-devel] Non-flat command line option argument syntax
Date: Fri, 03 Feb 2017 08:50:27 +0100	[thread overview]
Message-ID: <87shnvhfwc.fsf@dusky.pond.sub.org> (raw)
In-Reply-To: <20170202202739.GA15804@work-vm> (David Alan Gilbert's message of "Thu, 2 Feb 2017 20:27:39 +0000")

"Dr. David Alan Gilbert" <dgilbert@redhat.com> writes:

> * Markus Armbruster (armbru@redhat.com) wrote:
>> = Introduction =
>> 
>
> <snip>
>
>> = Structured option argument syntax =
>> 
>> == JSON ==
>> 
>> The obvious way to provide the expressiveness of JSON on the command
>> line is JSON.  Easy enough[2].  However, besides not being compatible,
>> it's rather heavy on syntax, at least for simple cases.  Compare:
>> 
>>     -machine q35,accel=kvm
>>     -machine '{ "type": "q35", "accel": "kvm"}'
>> 
>> It compares a bit more favourably in cases that use our non-flat hacks.
>> Here's a flat list as KEY=VALUE,... with repeated keys, and as JSON:
>> 
>>     -semihosting-config enable,arg=eins,arg=zwei,arg=drei
>>     -semihosting-config '{ "enable": true, "arg": [ "eins", "zwei", "drei" ] }'
>> 
>> Arbitrary nesting with dotted key convention:
>> 
>>     -drive driver=qcow2,file.driver=gluster,
>>            file.volume=testvol,file.path=/path/a.qcow2,file.debug=9,
>>            file.server.0.type=tcp,
>>            file.server.0.host=1.2.3.4,
>>            file.server.0.port=24007,
>>            file.server.1.type=unix,
>>            file.server.1.socket=/var/run/glusterd.socket
>>     -drive '{ "driver": "qcow2",
>>               "file": {
>>                   "driver": "gluster", "volume": "testvol",
>>                   "path": "/path/a.qcow2", "debug": 9,
>>                   "server": [ { "type": "tcp",
>>                                 "host": "1.2.3.4", "port": "24007"},
>>                               { "type": "unix",
>>                                 "socket": "/var/run/glusterd.socket" } ] } }'
>
> So while I generally hate JSON, the -drive dotted key syntax makes
> me mad when it gets like this;  have a look
> at the block replication and quorum setups especially, that can end up
> with (from docs/COLO-FT.txt):
>
>   -drive if=virtio,id=primary-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\
>          children.0.file.filename=1.raw,\
>          children.0.driver=raw -S
>
>    that's just way too many .'s to ever properly understand.
> (I'm sure it used to be more complex).

Here's an idea to cut down on the dottery that drives you mad (and me
too): if KEY starts with '.', combine it with a prefix of the previous
one so that the result has the same number of name components.

Your example becomes

    -drive if=virtio,id=primary-disk0,driver=quorum,read-pattern=fifo,vote-threshold=1,\
           children.0.file.filename=1.raw,.driver=raw -S

My example

     -drive driver=qcow2,file.driver=gluster,
            file.volume=testvol,file.path=/path/a.qcow2,file.debug=9,
            file.server.0.type=tcp,
            file.server.0.host=1.2.3.4,
            file.server.0.port=24007,
            file.server.1.type=unix,
            file.server.1.socket=/var/run/glusterd.socket

becomes

     -drive driver=qcow2,
            file.driver=gluster,
                .volume=testvol,
                .path=/path/a.qcow2,
                .debug=9,
            file.server.0.type=tcp,
                         .host=1.2.3.4,
                         .port=24007,
            file.server.1.type=unix,
                         .socket=/var/run/glusterd.socket

Mind, I'm not at all sure this is a *good* idea.  I suspect it's more
magic than it's worth.

>> Lines broken and indented for legibility; you need to join them for
>> actual use.
>
> Why? What's a \n between friends for JSON?

You're right, the JSON works as is.  Only the KEY=VALUE example doesn't.

>> Once you do, both variants are basically illegible.  This
>> is simply something that belongs into a config file rather than the
>> command line.  In a config file, JSON would be a better choice.
>> 
>> There's also the -drive file=json:... syntax.  It's a bad fit for
>> QemuOpts, because QemuOpts and JSON fight for the comma.  I'd show you
>> if I could get it to work.
>> 
>> We obviously can't replace QemuOpts with JSON.  But accepting JSON in
>> addition to QemuOpts is a debatable feature: it lets management
>> applications reuse the code to build QMP arguments for option arguments.
>> 
>> Since structured option arguments are always dictionaries, a JSON option
>> argument always starts with '{'.  If no QemuOpts argument can ever start
>> with '{', accepting either QemuOpts or a JSON object is unambiguous.
>> For a more detailed discussion of the following argument, see [3].
>> 
>> A QemuOpts argument normally starts with KEY.  We need to outlaw KEYs
>> starting with '{'.  QAPI outlaws such names, see docs/qapi-code-gen.txt.
>> QOM doesn't, but no such keys exist as far as I know.
>> 
>> QemuOpts permit abbreviating KEY=VALUE to just VALUE for one specific
>> KEY (the "implied" key).  We need to limit this to KEYs whose VALUE
>> can't start with '{'.  Most implied keys can't have such values.
>> Troublemakers include qemu-img's use of implied "file" keys.  You'd have
>> to say "file={my-tastelessly-named-file}" instead of just
>> "{my-tastelessly-named-file}".
>
> What worries me a bit is building shell scripts which include ['s and {'s
> tends to be painful.

No more than it already is if your builder copes with arbitrary
filenames and such.  But point well taken.

> <snip>
>
>> === Structured values ===
>> 
>> The dotted key convention messes with KEY syntax to permit structured
>> values.  Works, but the more conventional way to support structured
>> values is a syntax for structured values.  
>> 
>> An obvious one is to use { KEY=VALUE, ...} for objects, and [ VALUE,
>> ... ] for arrays.  Looks like this:
>> 
>>     -drive 'driver=quorum,
>>             child=[{ driver=file, filename=disk1.img },
>>                    { driver=host_device, filename=/dev/sdb },
>>                    { driver=nbd, host=localhost } ]'
>> 
>> Again, lines broken and indented for legibility; you need to join them
>> for actual use.
>> 
>> There's a syntactic catch, though: a value of the form [ ... ] can
>> either be an array or a string.  Which one it is depends on the type of
>> the key.  To parse this syntax, you need to know the types, unlike JSON
>> or traditional QemuOpts.  Unless we outlaw strings starting with '{' or
>> '[', which feels impractical.
>
> I don't understand why [ could imply a string.

Consider

    -drive 'driver=quorum,
            child=[{ driver=file, filename={"foolish":"name"} },
                   { driver=host_device, filename=/dev/sdb },
                   { driver=nbd, host=[::1] } ]'

Three KEY=VALUE have their VALUE start with '[' or '{':

* child=[{ driver=file, ...

  This is an array, not a string, because child is an array.

* host=[::1]

  This is a string, not an array containing the string "::1", because
  host is a string.

* filename={"foolish":"name"}

  This is a string, not an object, because filename is a string.

Clearer now?

>> But wait, there's another syntactic catch: in traditional QemuOpts, a
>> value ends at the next unescaped ',' or '\0'.  Inside an object, it now
>> also ends at the next unescaped '}', and inside an array, at the next
>> unescaped ']'.  Or perhaps at the next space (the example above assumes
>> it does).  That means we either have to provide a way to escape '}', ']'
>> and space, or find another way to delimit string values, say require '"'
>> around strings whenever the string contains "funny" characters.
>
> How about a tighter rule that if you've got a structured value -
> i.e. you're inside either of [ or {, then you must " all strings
> (except keys that we keep clean).

Matter of taste.

Regardless, we need a way to escape '"'.  Doubling it would be
consistent with the existing escape of ','.

>> So, if escaped ',' wasn't ugly and confusing enough for you...
>> 
>> === Comparison ===
>> 
>> In my opinion, dotted keys are weird and ugly, but at least they don't
>> add to the quoting mess.  Structured values look better, except when
>> they do add to the quoting mess.
>> 
>> I'm having a hard time deciding which one I like less :)
>> 
>> Opinions?  Other ideas?
>
> Dave
>
>> 
>> 
>> 
>> 
>> [1] [PATCH v14 00/21] QAPI/QOM work for non-scalar object properties
>> (actually v15)
>> Message-Id: <1475246744-29302-1-git-send-email-berrange@redhat.com>
>> http://lists.gnu.org/archive/html/qemu-devel/2016-09/msg08238.html
>> 
>> [2] [RFC PATCH] block: Crude initial implementation of -blockdev
>> Message-Id: <1485968933-9162-1-git-send-email-armbru@redhat.com>
>> http://lists.gnu.org/archive/html/qemu-devel/2017-02/msg00182.html
>> 
>> [3] Message-ID: <87h989ncse.fsf@dusky.pond.sub.org>
>> http://lists.gnu.org/archive/html/qemu-devel/2016-10/msg04046.html
>> 
> --
> Dr. David Alan Gilbert / dgilbert@redhat.com / Manchester, UK

  reply	other threads:[~2017-02-03  7:50 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-02 19:42 [Qemu-devel] Non-flat command line option argument syntax Markus Armbruster
2017-02-02 20:06 ` Eric Blake
2017-02-02 20:23 ` Eric Blake
2017-02-03  7:57   ` Markus Armbruster
2017-02-02 20:27 ` Dr. David Alan Gilbert
2017-02-03  7:50   ` Markus Armbruster [this message]
2017-02-03 16:57     ` Dr. David Alan Gilbert
2017-02-04  9:44       ` Markus Armbruster
2017-02-06 10:20         ` Dr. David Alan Gilbert
2017-02-03 20:02     ` [Qemu-devel] [Qemu-block] " Max Reitz
2017-02-04  9:45       ` Markus Armbruster
2017-02-04 10:03         ` [Qemu-devel] " Paolo Bonzini
2017-02-04 11:52           ` Markus Armbruster
2017-02-04 12:43             ` Paolo Bonzini
2017-02-03 10:03 ` Daniel P. Berrange
2017-02-03 11:13   ` Markus Armbruster
2017-02-03 12:37 ` Peter Krempa
2017-02-03 13:53   ` Markus Armbruster
2017-02-03 17:25 ` Richard W.M. Jones
2017-02-04  9:51   ` Markus Armbruster
2017-02-05 20:46     ` [Qemu-devel] [Qemu-block] " Max Reitz
2017-02-03 20:28 ` Max Reitz
2017-02-04  9:56   ` Markus Armbruster
2017-02-04 12:21 ` [Qemu-devel] " Fam Zheng
2017-02-04 12:44   ` Paolo Bonzini
2017-02-04 13:02     ` Fam Zheng
2017-02-04 13:35   ` Markus Armbruster
2017-02-04 14:10     ` Fam Zheng
2017-02-06  6:24       ` Markus Armbruster
2017-02-06 11:08   ` Daniel P. Berrange
2017-02-06  6:57 ` Markus Armbruster
2017-02-06 13:23 ` Kevin Wolf
2017-02-06 15:36   ` Markus Armbruster
2017-02-06 16:33     ` Daniel P. Berrange
2017-02-06 17:24       ` Markus Armbruster
2017-02-06 17:50         ` Daniel P. Berrange
2017-02-06 18:56           ` Markus Armbruster
2017-02-06 17:38     ` Paolo Bonzini
2017-02-06 18:12       ` Markus Armbruster
2017-02-06 21:52         ` Paolo Bonzini
2017-02-07  7:02           ` Markus Armbruster
2017-02-07  9:26     ` Kevin Wolf
2017-02-24 16:04 ` Markus Armbruster
2017-02-24 16:39   ` Daniel P. Berrange
2017-02-24 17:17     ` Eric Blake
2017-02-24 19:15       ` Markus Armbruster
2017-02-27 10:27 ` Markus Armbruster
2017-02-27 10:59   ` Kevin Wolf
2017-02-27 13:36     ` Markus Armbruster
2017-02-27 19:47       ` Eric Blake
2017-02-28  8:24         ` Markus Armbruster
2017-02-27 19:43   ` Eric Blake
2017-02-28  8:41     ` Markus Armbruster
2017-03-01  9:24 ` Markus Armbruster
2017-03-21  8:40 ` Markus Armbruster

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87shnvhfwc.fsf@dusky.pond.sub.org \
    --to=armbru@redhat.com \
    --cc=dgilbert@redhat.com \
    --cc=kwolf@redhat.com \
    --cc=pkrempa@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.