mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-03 11:35:19 +00:00
admin: Add URI support and introduce virAdmGetDefaultURI
Since virt-admin should be able to connect to various admin servers on hosted different daemons, we need to provide URI support to libvirt-admin.
This commit is contained in:
parent
0ecf9b3e09
commit
dbecb87f94
@ -59,6 +59,7 @@ int virAdmConnectIsAlive(virAdmConnectPtr conn);
|
|||||||
|
|
||||||
int virAdmGetVersion(unsigned long long *libVer);
|
int virAdmGetVersion(unsigned long long *libVer);
|
||||||
|
|
||||||
|
char *virAdmConnectGetURI(virAdmConnectPtr conn);
|
||||||
|
|
||||||
# ifdef __cplusplus
|
# ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
@ -832,4 +832,6 @@ virAdmConnectDispose(void *obj)
|
|||||||
|
|
||||||
if (conn->privateDataFreeFunc)
|
if (conn->privateDataFreeFunc)
|
||||||
conn->privateDataFreeFunc(conn);
|
conn->privateDataFreeFunc(conn);
|
||||||
|
|
||||||
|
virURIFree(conn->uri);
|
||||||
}
|
}
|
||||||
|
@ -397,6 +397,7 @@ struct _virConnect {
|
|||||||
*/
|
*/
|
||||||
struct _virAdmConnect {
|
struct _virAdmConnect {
|
||||||
virObjectLockable object;
|
virObjectLockable object;
|
||||||
|
virURIPtr uri;
|
||||||
|
|
||||||
void *privateData;
|
void *privateData;
|
||||||
virFreeCallback privateDataFreeFunc;
|
virFreeCallback privateDataFreeFunc;
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#include "configmake.h"
|
#include "configmake.h"
|
||||||
|
|
||||||
#include "viralloc.h"
|
#include "viralloc.h"
|
||||||
|
#include "virconf.h"
|
||||||
#include "virlog.h"
|
#include "virlog.h"
|
||||||
#include "virnetclient.h"
|
#include "virnetclient.h"
|
||||||
#include "virobject.h"
|
#include "virobject.h"
|
||||||
@ -95,60 +96,54 @@ virAdmInitialize(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
getSocketPath(const char *name)
|
getSocketPath(virURIPtr uri)
|
||||||
{
|
{
|
||||||
char *rundir = virGetUserRuntimeDirectory();
|
char *rundir = virGetUserRuntimeDirectory();
|
||||||
char *sock_path = NULL;
|
char *sock_path = NULL;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
virURIPtr uri = NULL;
|
|
||||||
|
|
||||||
if (name) {
|
if (!uri)
|
||||||
if (!(uri = virURIParse(name)))
|
goto cleanup;
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (STRNEQ(uri->scheme, "admin") ||
|
|
||||||
uri->server || uri->user || uri->fragment) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
_("Invalid connection name '%s'"), name);
|
|
||||||
goto error;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < uri->paramsCount; i++) {
|
for (i = 0; i < uri->paramsCount; i++) {
|
||||||
virURIParamPtr param = &uri->params[i];
|
virURIParamPtr param = &uri->params[i];
|
||||||
|
|
||||||
if (STREQ(param->name, "socket")) {
|
if (STREQ(param->name, "socket")) {
|
||||||
VIR_FREE(sock_path);
|
VIR_FREE(sock_path);
|
||||||
if (VIR_STRDUP(sock_path, param->value) < 0)
|
if (VIR_STRDUP(sock_path, param->value) < 0)
|
||||||
goto error;
|
|
||||||
} else {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
|
||||||
_("Unknown URI parameter '%s'"), param->name);
|
|
||||||
goto error;
|
goto error;
|
||||||
}
|
} else {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Unknown URI parameter '%s'"), param->name);
|
||||||
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sock_path) {
|
if (!sock_path) {
|
||||||
if (!uri || !uri->path || STREQ(uri->path, "/system")) {
|
if (STRNEQ(uri->scheme, "libvirtd")) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("Unsupported URI scheme '%s'"),
|
||||||
|
uri->scheme);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
if (STREQ_NULLABLE(uri->path, "/system")) {
|
||||||
if (VIR_STRDUP(sock_path, LIBVIRTD_ADMIN_UNIX_SOCKET) < 0)
|
if (VIR_STRDUP(sock_path, LIBVIRTD_ADMIN_UNIX_SOCKET) < 0)
|
||||||
goto error;
|
goto error;
|
||||||
} else if (STREQ_NULLABLE(uri->path, "/session")) {
|
} else if (STREQ_NULLABLE(uri->path, "/session")) {
|
||||||
if (!rundir)
|
if (!rundir || virAsprintf(&sock_path, "%s%s", rundir,
|
||||||
goto error;
|
LIBVIRTD_ADMIN_SOCK_NAME) < 0)
|
||||||
|
|
||||||
if (virAsprintf(&sock_path,
|
|
||||||
"%s%s", rundir, LIBVIRTD_ADMIN_SOCK_NAME) < 0)
|
|
||||||
goto error;
|
goto error;
|
||||||
} else {
|
} else {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
_("Invalid URI path '%s'"), uri->path);
|
_("Invalid URI path '%s', try '/system'"),
|
||||||
|
uri->path ? uri->path : "");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(rundir);
|
VIR_FREE(rundir);
|
||||||
virURIFree(uri);
|
|
||||||
return sock_path;
|
return sock_path;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -156,6 +151,37 @@ getSocketPath(const char *name)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const char *
|
||||||
|
virAdmGetDefaultURI(virConfPtr conf)
|
||||||
|
{
|
||||||
|
virConfValuePtr value = NULL;
|
||||||
|
const char *uristr = NULL;
|
||||||
|
|
||||||
|
uristr = virGetEnvAllowSUID("LIBVIRT_ADMIN_DEFAULT_URI");
|
||||||
|
if (uristr && *uristr) {
|
||||||
|
VIR_DEBUG("Using LIBVIRT_ADMIN_DEFAULT_URI '%s'", uristr);
|
||||||
|
} else if ((value = virConfGetValue(conf, "admin_uri_default"))) {
|
||||||
|
if (value->type != VIR_CONF_STRING) {
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
||||||
|
_("Expected a string for 'admin_uri_default' config "
|
||||||
|
"parameter"));
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
VIR_DEBUG("Using config file uri '%s'", value->str);
|
||||||
|
uristr = value->str;
|
||||||
|
} else {
|
||||||
|
/* Since we can't probe connecting via any hypervisor driver as libvirt
|
||||||
|
* does, if no explicit URI was given and neither the environment
|
||||||
|
* variable, nor the configuration parameter had previously been set,
|
||||||
|
* we set the default admin server URI to 'libvirtd://system'.
|
||||||
|
*/
|
||||||
|
uristr = "libvirtd:///system";
|
||||||
|
}
|
||||||
|
|
||||||
|
return uristr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* virAdmConnectOpen:
|
* virAdmConnectOpen:
|
||||||
* @name: uri of the daemon to connect to, NULL for default
|
* @name: uri of the daemon to connect to, NULL for default
|
||||||
@ -170,6 +196,7 @@ virAdmConnectOpen(const char *name, unsigned int flags)
|
|||||||
{
|
{
|
||||||
char *sock_path = NULL;
|
char *sock_path = NULL;
|
||||||
virAdmConnectPtr conn = NULL;
|
virAdmConnectPtr conn = NULL;
|
||||||
|
virConfPtr conf = NULL;
|
||||||
|
|
||||||
if (virAdmInitialize() < 0)
|
if (virAdmInitialize() < 0)
|
||||||
goto error;
|
goto error;
|
||||||
@ -180,7 +207,16 @@ virAdmConnectOpen(const char *name, unsigned int flags)
|
|||||||
if (!(conn = virAdmConnectNew()))
|
if (!(conn = virAdmConnectNew()))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(sock_path = getSocketPath(name)))
|
if (virConfLoadConfig(&conf, "libvirt-admin.conf") < 0)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!name && !(name = virAdmGetDefaultURI(conf)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(conn->uri = virURIParse(name)))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
if (!(sock_path = getSocketPath(conn->uri)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
if (!(conn->privateData = remoteAdminPrivNew(sock_path)))
|
if (!(conn->privateData = remoteAdminPrivNew(sock_path)))
|
||||||
@ -193,6 +229,7 @@ virAdmConnectOpen(const char *name, unsigned int flags)
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
VIR_FREE(sock_path);
|
VIR_FREE(sock_path);
|
||||||
|
virConfFree(conf);
|
||||||
return conn;
|
return conn;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
@ -340,3 +377,30 @@ virAdmConnectIsAlive(virAdmConnectPtr conn)
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* virAdmConnectGetURI:
|
||||||
|
* @conn: pointer to an admin connection
|
||||||
|
*
|
||||||
|
* String returned by this method is normally the same as the string passed
|
||||||
|
* to the virAdmConnectOpen. Even if NULL was passed to virAdmConnectOpen,
|
||||||
|
* this method returns a non-null URI string.
|
||||||
|
*
|
||||||
|
* Returns an URI string related to the connection or NULL in case of an error.
|
||||||
|
* Caller is responsible for freeing the string.
|
||||||
|
*/
|
||||||
|
char *
|
||||||
|
virAdmConnectGetURI(virAdmConnectPtr conn)
|
||||||
|
{
|
||||||
|
char *uri = NULL;
|
||||||
|
VIR_DEBUG("conn=%p", conn);
|
||||||
|
|
||||||
|
virResetLastError();
|
||||||
|
|
||||||
|
virCheckAdmConnectReturn(conn, NULL);
|
||||||
|
|
||||||
|
if (!(uri = virURIFormat(conn->uri)))
|
||||||
|
virDispatchError(NULL);
|
||||||
|
|
||||||
|
return uri;
|
||||||
|
}
|
||||||
|
@ -12,7 +12,8 @@
|
|||||||
#]
|
#]
|
||||||
|
|
||||||
#
|
#
|
||||||
# This can be used to prevent probing of the hypervisor
|
# These can be used in cases when no URI is supplied by the application
|
||||||
# driver when no URI is supplied by the application.
|
# (@uri_default also prevents probing of the hypervisor driver).
|
||||||
|
#
|
||||||
#uri_default = "qemu:///system"
|
#uri_default = "qemu:///system"
|
||||||
|
#uri_default_admin = "libvirtd:///system"
|
||||||
|
@ -17,4 +17,5 @@ LIBVIRT_ADMIN_1.3.0 {
|
|||||||
virAdmConnectRef;
|
virAdmConnectRef;
|
||||||
virAdmGetVersion;
|
virAdmGetVersion;
|
||||||
virAdmConnectIsAlive;
|
virAdmConnectIsAlive;
|
||||||
|
virAdmConnectGetURI;
|
||||||
};
|
};
|
||||||
|
@ -113,6 +113,39 @@ vshAdmReconnect(vshControl *ctl)
|
|||||||
priv->wantReconnect = false;
|
priv->wantReconnect = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* 'uri' command
|
||||||
|
*/
|
||||||
|
|
||||||
|
static const vshCmdInfo info_uri[] = {
|
||||||
|
{.name = "help",
|
||||||
|
.data = N_("print the admin server URI")
|
||||||
|
},
|
||||||
|
{.name = "desc",
|
||||||
|
.data = ""
|
||||||
|
},
|
||||||
|
{.name = NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool
|
||||||
|
cmdURI(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED)
|
||||||
|
{
|
||||||
|
char *uri;
|
||||||
|
vshAdmControlPtr priv = ctl->privData;
|
||||||
|
|
||||||
|
uri = virAdmConnectGetURI(priv->conn);
|
||||||
|
if (!uri) {
|
||||||
|
vshError(ctl, "%s", _("failed to get URI"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
vshPrint(ctl, "%s\n", uri);
|
||||||
|
VIR_FREE(uri);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* ---------------
|
/* ---------------
|
||||||
* Command Connect
|
* Command Connect
|
||||||
* ---------------
|
* ---------------
|
||||||
@ -425,6 +458,12 @@ static const vshCmdDef vshAdmCmds[] = {
|
|||||||
VSH_CMD_HELP,
|
VSH_CMD_HELP,
|
||||||
VSH_CMD_PWD,
|
VSH_CMD_PWD,
|
||||||
VSH_CMD_QUIT,
|
VSH_CMD_QUIT,
|
||||||
|
{.name = "uri",
|
||||||
|
.handler = cmdURI,
|
||||||
|
.opts = NULL,
|
||||||
|
.info = info_uri,
|
||||||
|
.flags = 0
|
||||||
|
},
|
||||||
{.name = "connect",
|
{.name = "connect",
|
||||||
.handler = cmdConnect,
|
.handler = cmdConnect,
|
||||||
.opts = opts_connect,
|
.opts = opts_connect,
|
||||||
|
Loading…
Reference in New Issue
Block a user