On Fri, 13 May 2022 at 00:17, Darragh Bailey <daragh.bailey at gmail.com> wrote:> Hi, > > On Thu 12 May 2022, 21:34 Laine Stump, <laine at redhat.com> wrote: > >> The virDomainDefineXMLFlags API (and also the older/deprecated >> virDomainDefineXML API) doesn't require that the domain first be >> undefined (with one notable exception - see below[*]). If you define a >> domain that already exists with the same name and uuid, then the effect >> is to "redefine" (or "update" if you prefer) the existing domain of that >> name. If the domain is currently active, then the changes will take >> effect the next time the domain is shut down ("Destroy"ed in libvirt API >> parlance) and re-started. >> >Unfortunately trying to call this via ruby-libvirt doesn't appear to behave as expected. It appears that if I add an nvram element without a loader element to the os block, the following code block will execute without issue but also without changing the domain XML: # Apply XML changes directly if descr_changed begin env[:ui].info("Updating domain definition due to configuration change") new_descr = String.new xml_descr.write new_descr # env[:machine].provider.driver.connection.client provides access to the ruby-libvirt connection object libvirt_domain env[:machine].provider.driver.connection.client.define_domain_xml(new_descr, 1) domain env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s) rescue Fog::Errors::Error => e raise Errors::UpdateServerError, error_message: e.message end end I've by-passing the fog-libvirt to call the ruby-libvirt connection object directly to try and avoid any unexpected interference when testing the API call out e.g. https://libvirt.org/ruby/api/Libvirt/Connect.html#method-i-define_domain_xml So not only is there no exception thrown if the XML change is ignored, I've noticed there doesn't appear to be an easy way to check using the API either, in that https://libvirt.org/ruby/api/Libvirt/Domain.html#method-i-updated-3F doesn't indicate that the domain has been updated whether I call it on the libvirt_domain object returned, or an instance from before the define_domain_xml call is made. It appears that the only way is to perform a call to get the xml definition of the libvirt_domain object returned in the above block and see if that matches the xml that was sent, if not, error. Is this the expected usage of the API? Or should the call to define_domain_xml raise an exception if it cannot update the domain XML? as opposed to a schema validation error which does appear to be detected when I did something stupid. -- Darragh -------------- next part -------------- An HTML attachment was scrubbed... URL: <http://listman.redhat.com/archives/libvirt-users/attachments/20220514/2c15847c/attachment.htm>
On 5/14/22 3:23 PM, Darragh Bailey wrote:> > On Fri, 13 May 2022 at 00:17, Darragh Bailey <daragh.bailey at gmail.com > <mailto:daragh.bailey at gmail.com>> wrote: > > Hi, > > On Thu 12 May 2022, 21:34 Laine Stump, <laine at redhat.com > <mailto:laine at redhat.com>> wrote: > > The virDomainDefineXMLFlags API (and also the older/deprecated > virDomainDefineXML API) doesn't require that the domain first be > undefined (with one notable exception - see below[*]). If you > define a > domain that already exists with the same name and uuid, then the > effect > is to "redefine" (or "update" if you prefer) the existing domain > of that > name. If the domain is currently active, then the changes will take > effect the next time the domain is shut down ("Destroy"ed in > libvirt API > parlance) and re-started. > > > Unfortunately trying to call this via ruby-libvirt doesn't appear to > behave as expected. It appears that if I add an nvram element without a > loader element to the os block, the following code block will execute > without issue but also without changing the domain XML: > > # Apply XML changes directly > if descr_changed > ? begin > ? ? env[:ui].info("Updating domain definition due to configuration change") > ? ? new_descr = String.new > ? ? xml_descr.write new_descr > ??? # env[:machine].provider.driver.connection.client provides access > to the ruby-libvirt connection object > ? ? libvirt_domain = > env[:machine].provider.driver.connection.client.define_domain_xml(new_descr, > 1) > ? ? domain = > env[:machine].provider.driver.connection.servers.get(env[:machine].id.to_s) > ? rescue Fog::Errors::Error => e > ? ? raise Errors::UpdateServerError, error_message: e.message > ? end > end > > I've by-passing the fog-libvirt to call the ruby-libvirt connection > object directly to try and avoid any unexpected interference when > testing the API call out e.g. > https://libvirt.org/ruby/api/Libvirt/Connect.html#method-i-define_domain_xml > <https://libvirt.org/ruby/api/Libvirt/Connect.html#method-i-define_domain_xml> > > So not only is there no exception thrown if the XML change is ignored, > I've noticed there doesn't appear to be an easy way to check using the > API either, in that > https://libvirt.org/ruby/api/Libvirt/Domain.html#method-i-updated-3F > <https://libvirt.org/ruby/api/Libvirt/Domain.html#method-i-updated-3F> > doesn't indicate that the domain has been updated whether I call it on > the libvirt_domain object returned, or an instance from before the > define_domain_xml call is made. > > It appears that the only way is to perform a call to get the xml > definition of the libvirt_domain object returned in the above block and > see if that matches the xml that was sent, if not, error. > > Is this the expected usage of the API? Or should the call to > define_domain_xml raise an exception if it cannot update the domain XML? > as opposed to a schema validation error which does appear to be detected > when I did something stupid.Caveat - I'm completely unfamiliar with ruby and the libvirt-ruby API bindings. If there is a problem that causes the domain config to not be updated, libvirt will return an error. So I would suspect one of the two things is happening: 1) there may be a problem in the libvirt-ruby bindings that causes the error reported by the call (in whatever C code is behind the ruby bindings) to libvirt to be properly propagated to ruby. I would hope this isn't the case, but "bugs happen", so it should be considered as a possibility. 2) As I said in my earlier mail, any changes that are made will take effect the next time the domain is destroyed and restarted. This also means that the changes won't be reflected in the "live/status" XML of the domain until that time. If you want to see the new configuration after you've made changes, you should add the VIR_DOMAIN_XML_INACTIVE flag when requesting the domain XML. Possibly you haven't included this flag, and that's why you think that your change hasn't taken effect?
On 5/14/22 21:23, Darragh Bailey wrote:> > On Fri, 13 May 2022 at 00:17, Darragh Bailey <daragh.bailey at gmail.com > <mailto:daragh.bailey at gmail.com>> wrote: > > Hi, > > On Thu 12 May 2022, 21:34 Laine Stump, <laine at redhat.com > <mailto:laine at redhat.com>> wrote: > > The virDomainDefineXMLFlags API (and also the older/deprecated > virDomainDefineXML API) doesn't require that the domain first be > undefined (with one notable exception - see below[*]). If you > define a > domain that already exists with the same name and uuid, then the > effect > is to "redefine" (or "update" if you prefer) the existing domain > of that > name. If the domain is currently active, then the changes will take > effect the next time the domain is shut down ("Destroy"ed in > libvirt API > parlance) and re-started. > > > Unfortunately trying to call this via ruby-libvirt doesn't appear to > behave as expected. It appears that if I add an nvram element without a > loader element to the os block, the following code block will execute > without issue but also without changing the domain XML:I think that's kind of expected. If you take a look how libvirt parses that part of XML: https://gitlab.com/libvirt/libvirt/-/blob/master/src/conf/domain_conf.c#L18257 if no <loader/> is found then the function exits early without looking at <nvram/> at all. It kind of makes sense - what good does nvram do without loader? Michal