On Thu, Nov 12, 2020 at 12:55:23 +0100, Michal Privoznik wrote: > On 11/11/20 1:04 PM, Michal Privoznik wrote: > > On 11/11/20 11:32 AM, Peter Krempa wrote: > > > On Tue, Nov 10, 2020 at 16:11:40 +0100, Michal Privoznik wrote: > > > > Marc-André posted a patch that implements agent handling. I've written > > > > the rest. > > > > > > > > Marc-André Lureau (1): > > > >   qemu_agent: add qemuAgentSSH{Add,Remove,Get}AuthorizedKeys > > > > > > > > Michal PrÃvoznÃk (5): > > > >   Introduce OpenSSH authorized key file mgmt APIs > > > > > > One more thing to think about: > > > > > > Since we are getting random requests for setters of various bits which > > > we have to bend the rule "we don't care what's running in the VM" and > > > which don't really scale when adding new APIs. I propose we add a > > > generic guest agent setter which will be extensible using a typed > > > parameters and a type property. > > > > > > It will basically become the counterpart to virDomainGetGuestInfo. > > > > > > The extensions then become enum additions and code additions only and > > > will be more flexible for future use. > > > > > > The same way the getter forthe ssh keys should become part of > > > virDomainGetGuestInfo, obviously auditing whether a read-write > > > connection is used. > > > > > > example: > > > > > > int > > > qemuDomainSetGuestInfo(virDomainPtr dom, > > >                        virDomainSetGuestInfoType type, > > >                        virTypedParamPtr params, > > >                        unsigned int nparams, > > >                        unsigned int flags); > > > > > > Invocation for setting keys: > > > > > > virTypedParamsAddString(..., "user", "root") > > > virTypedParamsAddString(..., "key", "ssh-rsa AA.... root@localhost") > > > virTypedParamsAddString(..., "key", "ssh-rsa AA.... user@localhost") > > > > > > etc. > > > > > > > Yeah, this is much more extensible. Okay, let me send v2. > > My enthusiasm might had been premature. virDomainGetGuestInfo() does not > send anything but virDomainPtr, unsigned int types and flags down the wire. > While we can make @params be both in and out type of arguments, it's going > to require change of RPC. I mean the way that qemu-ga APIs are implemented > is that for listing ssh keys the API expects an user on the input so that it > can construct $HOME/.ssh/authorized_keys path. How to pass this through > virDomainGetGuestInfo()? Okay, we could work around it by just listing SSH > keys for all users and let caller filter our the interesting ones, but this > is: a) scary from security POV, b) suboptimal because we might hit message > size limit pretty soon. Also, there is no qemu-ga API to list all users, > just those logged in currently. And the whole point of these new APIs is to > set up SSH keys before user logs in. Yeah, using virDomainGetGuestInfo as the getter for the keys will not work. What I ultimately want to suggest is something more generic which will allow driving guest agent APIs libvirt doesn't actually care about without having to add single-use APIs for every single one of them. qemu-ga seems to support following APIs: $ ./qemu-ga --blacklist=? guest-sync-delimited guest-sync guest-ping guest-get-time guest-set-time guest-info guest-shutdown guest-file-open guest-file-close guest-file-read guest-file-write guest-file-seek guest-file-flush guest-fsfreeze-status guest-fsfreeze-freeze guest-fsfreeze-freeze-list guest-fsfreeze-thaw guest-fstrim guest-suspend-disk guest-suspend-ram guest-suspend-hybrid guest-network-get-interfaces guest-get-vcpus guest-set-vcpus guest-get-disks guest-get-fsinfo guest-set-user-password guest-get-memory-blocks guest-set-memory-blocks guest-get-memory-block-info guest-exec-status guest-exec guest-get-host-name guest-get-users guest-get-timezone guest-get-osinfo guest-get-devices guest-ssh-get-authorized-keys guest-ssh-add-authorized-keys guest-ssh-remove-authorized-keys Let's categorize them: Utility functions: guest-sync-delimited guest-sync guest-ping Functions which at least partially map to libvirt APIs: guest-shutdown guest-get-vcpus guest-set-vcpus Functions used internally but also useful externally: guest-fsfreeze-status guest-fsfreeze-freeze guest-fsfreeze-freeze-list guest-fsfreeze-thaw Functions which can be claimed to map to libvirt but don't really: guest-suspend-disk guest-suspend-ram guest-suspend-hybrid Functions which are not really relevant to libvirt but we expose wrappers: guest-get-time guest-set-time guest-fstrim guest-network-get-interfaces guest-get-disks guest-get-fsinfo guest-get-host-name guest-get-users guest-get-timezone guest-get-osinfo Functions which are not really relevant to libvirt, we expose wrappers and they are scary: guest-set-user-password Functions which are not really relevant to libvirt, we don't expose wrappers and they are scary: guest-file-open guest-file-close guest-file-read guest-file-write guest-file-seek guest-file-flush guest-exec-status guest-exec Other stats functions we might be asked for: guest-info guest-get-memory-blocks guest-set-memory-blocks guest-get-memory-block-info guest-get-devices And finally those we have here: guest-ssh-get-authorized-keys guest-ssh-add-authorized-keys guest-ssh-remove-authorized-keys So there's just a very tiny set of QGA APIs we really need. For the rest we are adding more-or-less direct wrappers to satisfy the access to the APIs. With more-and-more APIs added which really deal just with the guest state itself it's a bit weird to add libvirt APIs for them. I'd like us to prevent adding new APIs constantly especially those which deal just with the guest. Since libvirt actually can't ever rely on the state of the guest agent as it can be restarted at any time including the guest OS and thus we we have to internally treat it without any presumptions about state and re-probe everything and we really need just a tiny subset of the commands, we'd really benefint from just multiplexing access between libvirt and any other APP which can use the QGA QMP protocol directly. Thus I think we could arguably make virDomainQemuAgentCommand a supported API. Any guest state change which can be initiated via the GA needs to be supported also without that since the guest itself can trigger it. Saying that virDomainQemuAgentCommand is fully supported to be used would free us from having to add arbitrary unextendable APIs for every single guest agent API, but would still allow libvirt to use APIs we need. We just need to make 100% sure that it can't be abused as argument to to change status of virDomainQemuMonitorCommand.