[libvirt] [Matahari] [libvirt-qpid PATCH 1/3] Convert to QMFv2 APIs
Andrew Beekhof
andrew at beekhof.net
Wed Jul 13 06:49:21 UTC 2011
On Wed, Jul 13, 2011 at 2:46 AM, Daniel P. Berrange <berrange at redhat.com> wrote:
> On Tue, Jul 12, 2011 at 06:28:46PM +0200, Zane Bitter wrote:
>> diff --git a/src/DomainWrap.cpp b/src/DomainWrap.cpp
>> index 47876de..eab6bbc 100644
>> --- a/src/DomainWrap.cpp
>> +++ b/src/DomainWrap.cpp
>> @@ -2,266 +2,310 @@
>> #include "NodeWrap.h"
>> #include "DomainWrap.h"
>> #include "Error.h"
>> +#include "Exception.h"
>>
>> -#include "ArgsDomainMigrate.h"
>> -#include "ArgsDomainRestore.h"
>> -#include "ArgsDomainSave.h"
>> -#include "ArgsDomainGetXMLDesc.h"
>> +#include <cstdio>
>>
>> -namespace _qmf = qmf::com::redhat::libvirt;
>>
>> -DomainWrap::DomainWrap(ManagementAgent *agent, NodeWrap *parent,
>> - virDomainPtr _domain_ptr, virConnectPtr _conn) :
>> - domain_ptr(_domain_ptr), conn(_conn)
>> +DomainWrap::DomainWrap(
>> + NodeWrap *parent,
>> + virDomainPtr domain_ptr,
>> + virConnectPtr conn):
>> + PackageOwner<NodeWrap::PackageDefinition>(parent),
>> + ManagedObject(package().data_Domain),
>> + _domain_ptr(domain_ptr), _conn(conn)
>> {
>> char dom_uuid[VIR_UUID_STRING_BUFLEN];
>>
>> - domain = NULL;
>> -
>> - if (virDomainGetUUIDString(domain_ptr, dom_uuid) < 0) {
>> - REPORT_ERR(conn, "DomainWrap: Unable to get UUID string of domain.");
>> + if (virDomainGetUUIDString(_domain_ptr, dom_uuid) < 0) {
>> + REPORT_ERR(_conn, "DomainWrap: Unable to get UUID string of domain.");
>> throw 1;
>
> I've noticed that most (all?) objects are being passed in
> a virConnectPtr instance too. This should be redundant for
> two reasons
>
> - If you have a virDomainPtr, you can call virDomainGetConnect()
> to get back the associated virConnectPtr (likewise for other
> libvirt objects)
> - We should kill the 'virConnectPtr' parameter from the
> REPORT_ERR macro/functions, and use 'virGetLastError'
> exclusively. This function is thread-safe, unlike the
> current virConnGetLastError being used.
>
> Since this problem was pre-existing, I'll leave it upto you
> whether you want to incorporate such a change into this patch
> or do it as a later followup.
Personally I'd prefer it be in a follow-up patch.
>> void
>> DomainWrap::update()
>> {
>> virDomainInfo info;
>> int ret;
>>
>> - ret = virDomainGetInfo(domain_ptr, &info);
>> + ret = virDomainGetInfo(_domain_ptr, &info);
>> if (ret < 0) {
>> - REPORT_ERR(conn, "Domain get info failed.");
>> + REPORT_ERR(_conn, "Domain get info failed.");
>> /* Next domainSync() will take care of this in the node wrapper if the domain is
>> * indeed dead. */
>> return;
>> } else {
>> + const char *state = NULL;
>> switch (info.state) {
>> -
>> case VIR_DOMAIN_NOSTATE:
>
> Add a 'default:' clause here
>
>> - domain->set_state("nostate");
>> + state = "nostate";
>> break;
>> case VIR_DOMAIN_RUNNING:
>> - domain->set_state("running");
>> + state = "running";
>> break;
>> case VIR_DOMAIN_BLOCKED:
>> - domain->set_state("blocked");
>> + state = "blocked";
>> break;
>> case VIR_DOMAIN_PAUSED:
>> - domain->set_state("paused");
>> + state = "paused";
>> break;
>> case VIR_DOMAIN_SHUTDOWN:
>> - domain->set_state("shutdown");
>> + state = "shutdown";
>> break;
>> case VIR_DOMAIN_SHUTOFF:
>> - domain->set_state("shutoff");
>> + state = "shutoff";
>> break;
>> case VIR_DOMAIN_CRASHED:
>> - domain->set_state("crashed");
>> + state = "crashed";
>> break;
>> }
>>
>> - domain->set_numVcpus(info.nrVirtCpu);
>> - domain->set_maximumMemory(info.maxMem);
>> - domain->set_memory(info.memory);
>> - domain->set_cpuTime(info.cpuTime);
>> + if (state) {
>> + _data.setProperty("state", state);
>> + }
>
> We shouldn't skip out 'NOSTATE' here, juust make this
> unconditional
>
>> + _data.setProperty("numVcpus", info.nrVirtCpu);
>> + _data.setProperty("maximumMemory", info.maxMem);
>> + _data.setProperty("memory", (uint64_t)info.memory);
>> + _data.setProperty("cpuTime", (uint64_t)info.cpuTime);
>> }
>>
>> +bool
>> +DomainWrap::migrate(qmf::AgentSession& session, qmf::AgentEvent& event)
>> +{
>> + virConnectPtr dest_conn;
>> + virDomainPtr rem_dom;
>> + qpid::types::Variant::Map args(event.getArguments());
>> + int ret;
>> +
>> + // This is actually quite broken. Most setups won't allow unauthorized
>> + // connection from one node to another directly like this.
>> + dest_conn = virConnectOpen(args["destinationUri"].asString().c_str());
>
> Since the agent was originally written, we now have a new migration API
> which avoids the need for a destination virConnectPtr object. Instead
> you can pass the 'destinationUri' directly to virDomainMigrateToURI,
> and set the PEER2PEER flag.
>
> NB, this still presumes that the source libvirtd can auth with the
> target libvirtd directly, but it avoids the need for matahari itself
> to authenticate. Typically we'd expect the libvirtd's to be setup
> with TLS+x590 or Kerberos so they can talk to each other
>
>> + if (!dest_conn) {
>> + std::string err = FORMAT_ERR(dest_conn, "Unable to connect to remote system for migration: virConnectOpen", &ret);
>> + raiseException(session, event, err, STATUS_USER + ret);
>> + return false;
>> + }
>> +
>> + const std::string newDomainName_arg(args["newDomainName"]);
>> + const char *new_dom_name = NULL;
>> + if (newDomainName_arg.size() > 0) {
>> + new_dom_name = newDomainName_arg.c_str();
>> + }
>> +
>> + const std::string uri_arg(args["uri"]);
>> + const char *uri = NULL;
>> + if (uri_arg.size() > 0) {
>> + uri = uri_arg.c_str();
>> + }
>> +
>> + uint32_t flags(args["flags"]);
>> + uint32_t bandwidth(args["bandwidth"]);
>> +
>> + printf ("calling migrate, new_dom_name: %s, uri: %s, flags: %d (live is %d)\n",
>> + new_dom_name ? new_dom_name : "NULL",
>> + uri ? uri : "NULL",
>> + flags,
>> + VIR_MIGRATE_LIVE);
>> +
>> + rem_dom = virDomainMigrate(_domain_ptr, dest_conn, flags,
>> + new_dom_name,
>> + uri,
>> + bandwidth);
>
> Ideally you want virDomainMigrateToURI, or even better
> virDomainMigrateToURI2 here.
No objection at all to making these sorts of changes, lets just do
them as a separate work item.
>
>
>> diff --git a/src/Error.h b/src/Error.h
>> index 388b41a..5bd7397 100644
>> --- a/src/Error.h
>> +++ b/src/Error.h
>> @@ -1,11 +1,19 @@
>> +#ifndef ERROR_H
>> +#define ERROR_H
>> +
>> +#include <libvirt/libvirt.h>
>> +#include <libvirt/virterror.h>
>> +
>>
>> #define REPORT_ERR(conn,msg) reportError(conn, msg, __func__, __LINE__, __FILE__)
>>
>> #define FORMAT_ERR(conn,msg,err_ret) formatError(conn, msg, err_ret, __func__, __LINE__, __FILE__)
>>
>> +
>> void
>> reportError(virConnectPtr conn, const char *msg, const char *function, int line, const char *file);
>>
>> std::string
>> formatError(virConnectPtr conn, const char *msg, int *err_ret, const char *function, int line, const char *file);
>>
>> +#endif
>
> We want to remove virConnectPtr from both these methods & macros
>
>> diff --git a/src/Exception.cpp b/src/Exception.cpp
>> new file mode 100644
>> index 0000000..105df27
>> --- /dev/null
>> +++ b/src/Exception.cpp
>> @@ -0,0 +1,38 @@
>> +#include "Exception.h"
>> +#include "Error.h"
>> +#include <qmf/Schema.h>
>> +#include <qmf/SchemaProperty.h>
>> +#include <qmf/Data.h>
>> +
>> +
>> +#define ERROR_TEXT "error_text"
>> +#define ERROR_CODE "error_code"
>> +
>> +
>> +static qmf::Schema errorSchema(qmf::SCHEMA_TYPE_DATA,
>> + "com.redhat.libvirt", "error");
>
> This should be 'org.libvirt' really.
>
>> generated_file_list = \
>> - qmf/com/redhat/libvirt/Domain.cpp\
>> - qmf/com/redhat/libvirt/Node.cpp\
>> - qmf/com/redhat/libvirt/Package.cpp\
>> - qmf/com/redhat/libvirt/Pool.cpp\
>> - qmf/com/redhat/libvirt/Volume.cpp\
>> - qmf/com/redhat/libvirt/ArgsDomainGetXMLDesc.h\
>> - qmf/com/redhat/libvirt/ArgsDomainMigrate.h\
>> - qmf/com/redhat/libvirt/ArgsDomainRestore.h\
>> - qmf/com/redhat/libvirt/ArgsDomainSave.h\
>> - qmf/com/redhat/libvirt/ArgsNodeDomainDefineXML.h\
>> - qmf/com/redhat/libvirt/ArgsNodeStoragePoolCreateXML.h\
>> - qmf/com/redhat/libvirt/ArgsNodeStoragePoolDefineXML.h\
>> - qmf/com/redhat/libvirt/ArgsPoolCreateVolumeXML.h\
>> - qmf/com/redhat/libvirt/ArgsPoolGetXMLDesc.h\
>> - qmf/com/redhat/libvirt/ArgsVolumeGetXMLDesc.h\
>> - qmf/com/redhat/libvirt/Domain.h\
>> - qmf/com/redhat/libvirt/Node.h\
>> - qmf/com/redhat/libvirt/Package.h\
>> - qmf/com/redhat/libvirt/Pool.h\
>> - qmf/com/redhat/libvirt/Volume.h
>> + qmf/com/redhat/libvirt/QmfPackage.cpp\
>> + qmf/com/redhat/libvirt/QmfPackage.h
>
> Can we change these to org/libvirt too, or will that be an
> incompatible schema change ?
I believe it would be. Ted would know for sure.
> Incidentally, is this fully backwards compatible from the
> POV of existing libvirt-qpid client apps, or are we starting
> a v2 libvirt schema here ?
I believe he has some tests which both versions pass. So I'm pretty
sure the API is more than backwards compatible, it should be
identical.
>
>> static void
>> @@ -521,7 +577,6 @@ print_usage()
>> printf("\t-d | --daemon run as a daemon.\n");
>> printf("\t-h | --help print this help message.\n");
>> printf("\t-b | --broker specify broker host name..\n");
>> - printf("\t-g | --gssapi force GSSAPI authentication.\n");
>> printf("\t-u | --username username to use for authentication purproses.\n");
>> printf("\t-s | --service service name to use for authentication purproses.\n");
>> printf("\t-p | --port specify broker port.\n");
>> @@ -536,8 +591,7 @@ int main(int argc, char** argv) {
>> int idx = 0;
>> bool verbose = false;
>> bool daemonize = false;
>> - bool gssapi = false;
>> - char *host = NULL;
>> + const char *host = NULL;
>> char *username = NULL;
>> char *service = NULL;
>> int port = 5672;
>> @@ -546,14 +600,13 @@ int main(int argc, char** argv) {
>> {"help", 0, 0, 'h'},
>> {"daemon", 0, 0, 'd'},
>> {"broker", 1, 0, 'b'},
>> - {"gssapi", 0, 0, 'g'},
>> {"username", 1, 0, 'u'},
>> {"service", 1, 0, 's'},
>> {"port", 1, 0, 'p'},
>> {0, 0, 0, 0}
>> };
>>
>> - while ((arg = getopt_long(argc, argv, "hdb:gu:s:p:", opt, &idx)) != -1) {
>> + while ((arg = getopt_long(argc, argv, "hdb:u:s:p:", opt, &idx)) != -1) {
>> switch (arg) {
>> case 'h':
>> case '?':
>> @@ -582,9 +635,6 @@ int main(int argc, char** argv) {
>> exit(1);
>> }
>> break;
>> - case 'g':
>> - gssapi = true;
>> - break;
>> case 'p':
>> if (optarg) {
>> port = atoi(optarg);
>> @@ -620,44 +670,42 @@ int main(int argc, char** argv) {
>> // This prevents us from dying if libvirt disconnects.
>> signal(SIGPIPE, SIG_IGN);
>>
>> - // Create the management agent
>> - ManagementAgent::Singleton singleton;
>> - ManagementAgent* agent = singleton.getInstance();
>> -
>> - // Register the schema with the agent
>> - _qmf::Package packageInit(agent);
>> -
>> - // Start the agent. It will attempt to make a connection to the
>> - // management broker. The third argument is the interval for sending
>> - // updates to stats/properties to the broker. The last is set to 'true'
>> - // to keep this all single threaded. Otherwise a second thread would be
>> - // used to implement methods.
>> -
>> - qpid::management::ConnectionSettings settings;
>> - settings.host = host ? host : "127.0.0.1";
>> - settings.port = port;
>> + qpid::types::Variant::Map options;
>>
>> if (username != NULL) {
>> - settings.username = username;
>> + options["username"] = username;
>> }
>> if (service != NULL) {
>> - settings.service = service;
>> + options["service"] = service;
>> }
>> - if (gssapi == true) {
>> - settings.mechanism = "GSSAPI";
>> +
>> + if (host == NULL) {
>> + host = "127.0.0.1";
>> }
>>
>> - agent->setName("Red Hat", "libvirt-qpid");
>> - agent->init(settings, 3, true);
>> + std::stringstream url;
>> +
>> + url << "amqp:" << "tcp" << ":" << host << ":" << port;
>> +
>> + qpid::messaging::Connection amqp_connection(url.str(), options);
>> + amqp_connection.open();
>> +
>> + qmf::AgentSession session(amqp_connection);
>> + session.setVendor("redhat.com");
>
> IMHO, this should really be 'org.libvirt' too
>
>> + session.setProduct("libvirt-qpid");
>> + session.setAttribute("hostname", host);
>
> Regards,
> Daniel
> --
> |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :|
> |: http://libvirt.org -o- http://virt-manager.org :|
> |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :|
> |: http://entangle-photo.org -o- http://live.gnome.org/gtk-vnc :|
> _______________________________________________
> Matahari mailing list
> Matahari at lists.fedorahosted.org
> https://fedorahosted.org/mailman/listinfo/matahari
>
More information about the libvir-list
mailing list