diff --git a/tools/virsh-domain.c b/tools/virsh-domain.c index 8984c2f3b4..201fc176c7 100644 --- a/tools/virsh-domain.c +++ b/tools/virsh-domain.c @@ -14051,6 +14051,86 @@ cmdDomFSInfo(vshControl *ctl, const vshCmd *cmd) return ret; } +/* + * "guestinfo" command + */ +static const vshCmdInfo info_guestinfo[] = { + {.name = "help", + .data = N_("query information about the guest (via agent)") + }, + {.name = "desc", + .data = N_("Use the guest agent to query various information from guest's " + "point of view") + }, + {.name = NULL} +}; + +static const vshCmdOptDef opts_guestinfo[] = { + VIRSH_COMMON_OPT_DOMAIN_FULL(VIR_CONNECT_LIST_DOMAINS_ACTIVE), + {.name = "user", + .type = VSH_OT_BOOL, + .help = N_("report active users"), + }, + {.name = "os", + .type = VSH_OT_BOOL, + .help = N_("report operating system information"), + }, + {.name = "timezone", + .type = VSH_OT_BOOL, + .help = N_("report timezone information"), + }, + {.name = "hostname", + .type = VSH_OT_BOOL, + .help = N_("report hostname"), + }, + {.name = "filesystem", + .type = VSH_OT_BOOL, + .help = N_("report filesystem information"), + }, + {.name = NULL} +}; + +static bool +cmdGuestInfo(vshControl *ctl, const vshCmd *cmd) +{ + virDomainPtr dom; + bool ret = false; + virTypedParameterPtr params = NULL; + int nparams = 0; + size_t i; + unsigned int types = 0; + + if (vshCommandOptBool(cmd, "user")) + types |= VIR_DOMAIN_GUEST_INFO_USERS; + if (vshCommandOptBool(cmd, "os")) + types |= VIR_DOMAIN_GUEST_INFO_OS; + if (vshCommandOptBool(cmd, "timezone")) + types |= VIR_DOMAIN_GUEST_INFO_TIMEZONE; + if (vshCommandOptBool(cmd, "hostname")) + types |= VIR_DOMAIN_GUEST_INFO_HOSTNAME; + if (vshCommandOptBool(cmd, "filesystem")) + types |= VIR_DOMAIN_GUEST_INFO_FILESYSTEM; + + if (!(dom = virshCommandOptDomain(ctl, cmd, NULL))) + return false; + + if (virDomainGetGuestInfo(dom, types, ¶ms, &nparams, 0) < 0) + goto cleanup; + + for (i = 0; i < nparams; i++) { + char *str = vshGetTypedParamValue(ctl, ¶ms[i]); + vshPrint(ctl, "%-20s: %s\n", params[i].field, str); + VIR_FREE(str); + } + + ret = true; + + cleanup: + virTypedParamsFree(params, nparams); + virshDomainFree(dom); + return ret; +} + const vshCmdDef domManagementCmds[] = { {.name = "attach-device", .handler = cmdAttachDevice, @@ -14666,5 +14746,11 @@ const vshCmdDef domManagementCmds[] = { .info = info_domblkthreshold, .flags = 0 }, + {.name = "guestinfo", + .handler = cmdGuestInfo, + .opts = opts_guestinfo, + .info = info_guestinfo, + .flags = 0 + }, {.name = NULL} }; diff --git a/tools/virsh.pod b/tools/virsh.pod index aa0eb16f1a..d9b3290cb8 100644 --- a/tools/virsh.pod +++ b/tools/virsh.pod @@ -1714,6 +1714,70 @@ events until a timeout or interrupt key. When I<--timestamp> is used, a human-readable timestamp will be printed before the event. +=item B I [I<--user>] [I<--os>] [I<--timezone>] +[I<--hostname>] [I<--filesystem>] + +Print information about the guest from the point of view of the guest agent. +Note that this command requires a guest agent to be configured and running in +the domain's guest OS. + +When run without any arguments, this command prints all information types that +are supported by the guest agent. You can limit the types of information that +are returned by specifying one or more flags. If a requested information +type is not supported, the processes will provide an exit code of 1. +Available information types flags are I<--user>, I<--os>, +I<--timezone>, I<--hostname>, and I<--filesystem>. + +Note that depending on the hypervisor type and the version of the guest agent +running within the domain, not all of the following information may be +returned. + +When selecting the I<--user> information type, the following fields may be +returned: + + "user.count" - the number of active users on this domain + "user..name" - username of user + "user..domain" - domain of the user (may only be present on certain + guest types) + "user..login-time" - the login time of user in milliseconds since + the epoch + +I<--os> returns: + + "os.id" - a string identifying the operating system + "os.name" - the name of the operating system + "os.pretty-name" - a pretty name for the operating system + "os.version" - the version of the operating system + "os.version-id" - the version id of the operating system + "os.kernel-release" - the release of the operating system kernel + "os.kernel-version" - the version of the operating system kernel + "os.machine" - the machine hardware name + "os.variant" - a specific variant or edition of the operating system + "os.variant-id" - the id for a specific variant or edition of the operating + system + +I<--timezone> returns: + + "timezone.name" - the name of the timezone + "timezone.offset" - the offset to UTC in seconds + +I<--hostname> returns: + + "hostname" - the hostname of the domain + +I<--filesystem> returns: + + "fs.count" - the number of filesystems defined on this domain + "fs..mountpoint" - the path to the mount point for filesystem + "fs..name" - device name in the guest (e.g. "sda1") for filesystem + "fs..fstype" - the type of filesystem + "fs..total-bytes" - the total size of filesystem + "fs..used-bytes" - the number of bytes used in filesystem + "fs..disk.count" - the number of disks targeted by filesystem + "fs..disk..alias" - the device alias of disk (e.g. sda) + "fs..disk..serial" - the serial number of disk + "fs..disk..device" - the device node of disk + =item B I [[I<--live>] [I<--config>] | [I<--current>]] Display basic domain IOThreads information including the IOThread ID and