qga: allow configuration file path via the cli
Allowing the user to set the QGA_CONF environment variable to change the default configuration file path is very unusual practice, made more obscure since this ability is not documented. This introduces the more normal '-c PATH' / '--config=PATH' command line argument approach. This requires that we parse the comamnd line twice, since we want the command line arguments to take priority over the configuration file settings in general. Signed-off-by: Daniel P. Berrangé <berrange@redhat.com> Reviewed-by: Konstantin Kostiuk <kkostiuk@redhat.com> Message-ID: <20240712132459.3974109-22-berrange@redhat.com> Signed-off-by: Konstantin Kostiuk <kkostiuk@redhat.com>
This commit is contained in:
parent
8909fc1732
commit
f8bf2347ed
@ -33,6 +33,11 @@ Options
|
||||
|
||||
.. program:: qemu-ga
|
||||
|
||||
.. option:: -c, --config=PATH
|
||||
|
||||
Configuration file path (the default is |CONFDIR|\ ``/qemu-ga.conf``,
|
||||
unless overriden by the QGA_CONF environment variable)
|
||||
|
||||
.. option:: -m, --method=METHOD
|
||||
|
||||
Transport method: one of ``unix-listen``, ``virtio-serial``, or
|
||||
|
43
qga/main.c
43
qga/main.c
@ -248,12 +248,16 @@ static void usage(const char *cmd)
|
||||
#ifdef CONFIG_FSFREEZE
|
||||
g_autofree char *fsfreeze_hook = get_relocated_path(QGA_FSFREEZE_HOOK_DEFAULT);
|
||||
#endif
|
||||
g_autofree char *conf_path = get_relocated_path(QGA_CONF_DEFAULT);
|
||||
|
||||
printf(
|
||||
"Usage: %s [-m <method> -p <path>] [<options>]\n"
|
||||
"QEMU Guest Agent " QEMU_FULL_VERSION "\n"
|
||||
QEMU_COPYRIGHT "\n"
|
||||
"\n"
|
||||
" -c, --config=PATH configuration file path (default is\n"
|
||||
" %s/qemu-ga.conf\n"
|
||||
" unless overriden by the QGA_CONF environment variable)\n"
|
||||
" -m, --method transport method: one of unix-listen, virtio-serial,\n"
|
||||
" isa-serial, or vsock-listen (virtio-serial is the default)\n"
|
||||
" -p, --path device/socket path (the default for virtio-serial is:\n"
|
||||
@ -294,8 +298,8 @@ QEMU_COPYRIGHT "\n"
|
||||
" plug/unplug, etc.)\n"
|
||||
" -h, --help display this help and exit\n"
|
||||
"\n"
|
||||
QEMU_HELP_BOTTOM "\n"
|
||||
, cmd, QGA_VIRTIO_PATH_DEFAULT, QGA_SERIAL_PATH_DEFAULT,
|
||||
QEMU_HELP_BOTTOM "\n",
|
||||
cmd, conf_path, QGA_VIRTIO_PATH_DEFAULT, QGA_SERIAL_PATH_DEFAULT,
|
||||
dfl_pathnames.pidfile,
|
||||
#ifdef CONFIG_FSFREEZE
|
||||
fsfreeze_hook,
|
||||
@ -1018,15 +1022,14 @@ static GList *split_list(const gchar *str, const gchar *delim)
|
||||
return list;
|
||||
}
|
||||
|
||||
static void config_load(GAConfig *config)
|
||||
static void config_load(GAConfig *config, const char *confpath, bool required)
|
||||
{
|
||||
GError *gerr = NULL;
|
||||
GKeyFile *keyfile;
|
||||
g_autofree char *conf = g_strdup(g_getenv("QGA_CONF")) ?: get_relocated_path(QGA_CONF_DEFAULT);
|
||||
|
||||
/* read system config */
|
||||
keyfile = g_key_file_new();
|
||||
if (!g_key_file_load_from_file(keyfile, conf, 0, &gerr)) {
|
||||
if (!g_key_file_load_from_file(keyfile, confpath, 0, &gerr)) {
|
||||
goto end;
|
||||
}
|
||||
if (g_key_file_has_key(keyfile, "general", "daemon", NULL)) {
|
||||
@ -1092,10 +1095,10 @@ static void config_load(GAConfig *config)
|
||||
|
||||
end:
|
||||
g_key_file_free(keyfile);
|
||||
if (gerr &&
|
||||
!(gerr->domain == G_FILE_ERROR && gerr->code == G_FILE_ERROR_NOENT)) {
|
||||
if (gerr && (required ||
|
||||
!(gerr->domain == G_FILE_ERROR && gerr->code == G_FILE_ERROR_NOENT))) {
|
||||
g_critical("error loading configuration from path: %s, %s",
|
||||
conf, gerr->message);
|
||||
confpath, gerr->message);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
g_clear_error(&gerr);
|
||||
@ -1167,12 +1170,13 @@ static void config_dump(GAConfig *config)
|
||||
|
||||
static void config_parse(GAConfig *config, int argc, char **argv)
|
||||
{
|
||||
const char *sopt = "hVvdm:p:l:f:F::b:a:s:t:Dr";
|
||||
const char *sopt = "hVvdc:m:p:l:f:F::b:a:s:t:Dr";
|
||||
int opt_ind = 0, ch;
|
||||
bool block_rpcs = false, allow_rpcs = false;
|
||||
const struct option lopt[] = {
|
||||
{ "help", 0, NULL, 'h' },
|
||||
{ "version", 0, NULL, 'V' },
|
||||
{ "config", 1, NULL, 'c' },
|
||||
{ "dump-conf", 0, NULL, 'D' },
|
||||
{ "logfile", 1, NULL, 'l' },
|
||||
{ "pidfile", 1, NULL, 'f' },
|
||||
@ -1192,6 +1196,26 @@ static void config_parse(GAConfig *config, int argc, char **argv)
|
||||
{ "retry-path", 0, NULL, 'r' },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
g_autofree char *confpath = g_strdup(g_getenv("QGA_CONF")) ?:
|
||||
get_relocated_path(QGA_CONF_DEFAULT);
|
||||
bool confrequired = false;
|
||||
|
||||
while ((ch = getopt_long(argc, argv, sopt, lopt, NULL)) != -1) {
|
||||
switch (ch) {
|
||||
case 'c':
|
||||
g_free(confpath);
|
||||
confpath = g_strdup(optarg);
|
||||
confrequired = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
config_load(config, confpath, confrequired);
|
||||
|
||||
/* Reset for second pass */
|
||||
optind = 1;
|
||||
|
||||
while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
|
||||
switch (ch) {
|
||||
@ -1582,7 +1606,6 @@ int main(int argc, char **argv)
|
||||
qga_qmp_init_marshal(&ga_commands);
|
||||
|
||||
init_dfl_pathnames();
|
||||
config_load(config);
|
||||
config_parse(config, argc, argv);
|
||||
|
||||
if (config->pid_filepath == NULL) {
|
||||
|
Loading…
Reference in New Issue
Block a user