From: Paolo Bonzini <pbonzini@redhat.com>
To: "Marc-André Lureau" <marcandre.lureau@gmail.com>
Cc: "P. Berrange, Daniel" <berrange@redhat.com>,
Sergio Lopez Pascual <slp@redhat.com>,
"Hajnoczi, Stefan" <stefanha@gmail.com>,
Markus Armbruster <armbru@redhat.com>,
qemu-devel <qemu-devel@nongnu.org>, John Snow <jsnow@redhat.com>
Subject: Re: [PATCH] PoC: Rust binding for QAPI (qemu-ga only, for now)
Date: Tue, 29 Sep 2020 12:14:51 +0200 [thread overview]
Message-ID: <8c1783d1-70f4-d751-3d5d-83459cb1db45@redhat.com> (raw)
In-Reply-To: <CAJ+F1CLowpdHaJ58Vt7GYukAYvYAfuEJvnuw_ZM5kO_4=gh9XA@mail.gmail.com>
On 29/09/20 09:45, Marc-André Lureau wrote:
> Hi
>
> On Tue, Sep 22, 2020 at 9:08 PM Paolo Bonzini <pbonzini@redhat.com
> <mailto:pbonzini@redhat.com>> wrote:
> > So a QEMU D-Bus interface could have a name like org.qemu.Qemu51,
> > org.qemu.Qemu52.. for example, if we can't provide better API
> stability...
>
> That would be a problem for backports.
>
> Yes.. Backports could expose a subset of the new version interface? Or
> the interface can be divided for each Qmp command. (unorthodox)
That seems like a workaround for an IDL that is not the right solution
for the problem.
> qapi::qga::commands::GuestShutdown::new()
> .mode("halt")
> .invoke_on(qapi_channel)?;
>
>
> Or simply use the same approach as qapi-rs
> (https://github.com/arcnmx/qapi-rs) which is simply generating data
> structures based on the schema, and not binding commands to Rust
> functions for ex.
>
> qga.execute(&qga::guest_shutdown { mode: Some(GuestShutdownMode::Halt) })
That would not be backwards compatible as you would have to set all
optional fields. Every time the command grows a new optional argument,
all clients would have to specify it; if a command becomes optional,
you'd have to add Some() around it. So I would say that...
> Less idiomatic, but it also works around the optional arguments and
> ordering issue.
... the builder pattern is not a workaround: it's the best and most
common Rust idiom to achieve what QAPI expresses as optional fields.
Likewise for keyword-only arguments in Python.
> Yes, the python binding will have a similar issue. And if we want to add
> typing to the mix, representing everything as a dict is not going to
> help much. Fortunately, there are other options I believe. But I would
> rather aim for the obvious, having non-optional & ordered arguments, and
> interface/methods versioning.
You shouldn't just state what you want; you really should take a look at
how the ability to add optional arguments has been used in the past, and
see if an alternative RPC without optional and unordered arguments would
have been as effective. D-Bus is probably a perfectly good API for
qemu-ga. The experience with qemu-ga however does not necessarily
extend to QEMU.
The main issue with D-Bus is that it conflates the transport and the IDL
so that you have to resort to passing arguments as key-value pairs. QMP
does the same, but the IDL is much more flexible and not QEMU-specific,
so we don't pay as high a price. Remember that while the specific
transport of QMP ("JSON dictionaries over a socket with 'execute' and
'arguments' keys") is QEMU-specific, the concept of using JSON payloads
for RPC is very common. For example, REST APIs almost invariably use
JSON and the resulting API even "feel" somewhat similar to QMP.
In fact, The first Google result for "openapi backwards compatible
extensions"
(https://github.com/zalando/restful-api-guidelines/blob/master/chapters/compatibility.adoc#107)
might as well be written for QMP:
* [server] Add only optional, never mandatory fields.
* [client] Be tolerant with unknown fields in the payload
* [server] Unknown input fields in payload or URL should not be ignored
* [client] API clients consuming data must not assume that objects are
closed for extension
* [server] When changing your RESTful APIs, do so in a compatible way
and avoid generating additional API versions
* [server] MUST not use URI versioning
and so on.
If you want to "reinvent" QMP, instead of focusing on D-Bus you should
take a look at alternative IDLs and protocols (D-Bus is one but there's
also Protobuf and Flexbuffers), see how QAPI declarations would map to
those protocols, see how you would deal with extensibility, and rank
them according to various criteria. For example:
* JSON "just works" but needs a custom code generator and imposes some
extra complexity on the clients for the simplest commands
* D-Bus has a good ecosystem and would keep simple commands simpler but
has issues with upgrade paths and is uglier for complex commands
* Protobufs probably would also just work and would have better code
generators, but would require some kind of lint to ensure
backwards-compatibility
* etc.
> Well, I wouldn't say it's not a problem. It makes working with QMP as a
> client quite an unpleasant experience overall imho...
With automatically-generated bindings, the experience writing a QMP
client is as pleasant as the code generator makes it.
Paolo
next prev parent reply other threads:[~2020-09-29 10:16 UTC|newest]
Thread overview: 36+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-09-10 17:48 [PATCH] PoC: Rust binding for QAPI (qemu-ga only, for now) marcandre.lureau
2020-09-11 10:24 ` Paolo Bonzini
2020-09-11 13:08 ` Paolo Bonzini
2020-09-11 14:00 ` Marc-André Lureau
2020-09-11 15:17 ` Paolo Bonzini
2020-09-29 17:55 ` Marc-André Lureau
2020-09-29 18:23 ` Paolo Bonzini
2020-09-30 9:15 ` Marc-André Lureau
2020-09-30 14:02 ` Paolo Bonzini
2020-09-11 10:46 ` Daniel P. Berrangé
2020-09-11 11:03 ` Marc-André Lureau
2020-09-11 11:28 ` Paolo Bonzini
2020-09-11 11:31 ` Daniel P. Berrangé
2020-09-11 14:19 ` John Snow
2020-09-11 14:17 ` Marc-André Lureau
2020-09-21 9:16 ` Markus Armbruster
2020-09-21 9:30 ` Paolo Bonzini
2020-09-22 14:59 ` Markus Armbruster
2020-09-21 10:04 ` Marc-André Lureau
2020-09-22 15:09 ` Markus Armbruster
2020-09-22 16:35 ` Marc-André Lureau
2020-09-22 17:08 ` Paolo Bonzini
2020-09-29 7:45 ` Marc-André Lureau
2020-09-29 10:14 ` Paolo Bonzini [this message]
2020-09-29 10:34 ` Marc-André Lureau
2020-09-29 11:00 ` Paolo Bonzini
2020-09-29 11:34 ` Marc-André Lureau
2020-09-30 7:34 ` Markus Armbruster
2020-09-30 7:51 ` Marc-André Lureau
2020-09-30 13:14 ` Paolo Bonzini
2020-09-22 16:52 ` Daniel P. Berrangé
2020-09-23 11:51 ` Markus Armbruster
2020-09-21 10:11 ` Marc-André Lureau
2020-09-22 15:37 ` Markus Armbruster
2020-09-22 16:25 ` Marc-André Lureau
2020-09-24 7:31 ` 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=8c1783d1-70f4-d751-3d5d-83459cb1db45@redhat.com \
--to=pbonzini@redhat.com \
--cc=armbru@redhat.com \
--cc=berrange@redhat.com \
--cc=jsnow@redhat.com \
--cc=marcandre.lureau@gmail.com \
--cc=qemu-devel@nongnu.org \
--cc=slp@redhat.com \
--cc=stefanha@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).