From b8e1dee73a1deef1bfd5937e2abfbe9afef7b1ef Mon Sep 17 00:00:00 2001 From: "Richard W.M. Jones" Date: Wed, 30 Mar 2011 17:03:11 +0100 Subject: [PATCH] Add /etc/libguestfs-tools.conf configuration file. This allows the default for --ro or --rw to be controlled for the three tools guestfish, guestmount and virt-rescue. --- README | 2 + cat/Makefile.am | 15 +++-- configure.ac | 9 +++ df/Makefile.am | 5 +- fish/Makefile.am | 15 ++++- fish/config.c | 142 +++++++++++++++++++++++++++++++++++++++++++++ fish/fish.c | 2 + fish/guestfish.pod | 48 +++++++++------ fish/libguestfs-tools.conf | 24 ++++++++ fish/options.h | 3 + fuse/Makefile.am | 3 + fuse/guestmount.c | 2 + fuse/guestmount.pod | 19 +++++- inspector/Makefile.am | 5 +- po/POTFILES.in | 1 + rescue/Makefile.am | 5 +- rescue/virt-rescue.c | 2 + rescue/virt-rescue.pod | 23 +++++++- 18 files changed, 295 insertions(+), 30 deletions(-) create mode 100644 fish/config.c create mode 100644 fish/libguestfs-tools.conf diff --git a/README b/README index 4c9c078..7fa9e9e 100644 --- a/README +++ b/README @@ -32,6 +32,8 @@ Requirements - libxml2 (optional) +- libconfig (optional, to parse /etc/libguestfs-tools.conf) + - Augeas (http://augeas.net/) (optional) - gperf diff --git a/cat/Makefile.am b/cat/Makefile.am index 026a561..d7bc7e8 100644 --- a/cat/Makefile.am +++ b/cat/Makefile.am @@ -1,5 +1,5 @@ # libguestfs virt-cat, virt-filesystems and virt-ls. -# Copyright (C) 2010 Red Hat Inc. +# Copyright (C) 2010-2011 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -33,6 +33,7 @@ CLEANFILES = stamp-virt-cat.pod stamp-virt-ls.pod stamp-virt-filesystems.pod bin_PROGRAMS = virt-cat virt-filesystems virt-ls SHARED_SOURCE_FILES = \ + ../fish/config.c \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ @@ -48,9 +49,11 @@ virt_cat_CFLAGS = \ -I$(top_srcdir)/fish \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBCONFIG_CFLAGS) virt_cat_LDADD = \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ ../gnulib/lib/libgnu.la @@ -63,9 +66,11 @@ virt_filesystems_CFLAGS = \ -I$(top_srcdir)/fish \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBCONFIG_CFLAGS) virt_filesystems_LDADD = \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ ../gnulib/lib/libgnu.la @@ -78,9 +83,11 @@ virt_ls_CFLAGS = \ -I$(top_srcdir)/fish \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBCONFIG_CFLAGS) virt_ls_LDADD = \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ ../gnulib/lib/libgnu.la diff --git a/configure.ac b/configure.ac index 2373452..7736bd7 100644 --- a/configure.ac +++ b/configure.ac @@ -431,6 +431,15 @@ PKG_CHECK_MODULES([LIBXML2], [libxml-2.0], [AC_MSG_WARN([libxml2 not found, some core features will be disabled])]) AM_CONDITIONAL([HAVE_LIBXML2],[test "x$LIBXML2_LIBS" != "x"]) +dnl libconfig (highly recommended) +PKG_CHECK_MODULES([LIBCONFIG], [libconfig], + [AC_SUBST([LIBCONFIG_CFLAGS]) + AC_SUBST([LIBCONFIG_LIBS]) + AC_DEFINE([HAVE_LIBCONFIG],[1],[libconfig found at compile time.]) + ], + [AC_MSG_WARN([libconfig not found, some features will be disabled])]) +AM_CONDITIONAL([HAVE_LIBCONFIG],[test "x$LIBCONFIG_LIBS" != "x"]) + dnl hivex library (highly recommended) dnl This used to be a part of libguestfs, but was spun off into its dnl own separate upstream project in libguestfs 1.0.85. diff --git a/df/Makefile.am b/df/Makefile.am index 2f0eff0..81c190f 100644 --- a/df/Makefile.am +++ b/df/Makefile.am @@ -1,5 +1,5 @@ # libguestfs virt-df -# Copyright (C) 2010 Red Hat Inc. +# Copyright (C) 2010-2011 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -28,6 +28,7 @@ CLEANFILES = stamp-virt-df.pod bin_PROGRAMS = virt-df SHARED_SOURCE_FILES = \ + ../fish/config.c \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ @@ -48,9 +49,11 @@ virt_df_CFLAGS = \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBCONFIG_CFLAGS) \ $(LIBVIRT_CFLAGS) virt_df_LDADD = \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ ../gnulib/lib/libgnu.la \ $(LIBVIRT_LIBS) \ diff --git a/fish/Makefile.am b/fish/Makefile.am index 311da89..3eae8e4 100644 --- a/fish/Makefile.am +++ b/fish/Makefile.am @@ -1,5 +1,5 @@ # libguestfs -# Copyright (C) 2009-2010 Red Hat Inc. +# Copyright (C) 2009-2011 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -60,6 +60,7 @@ EXTRA_DIST = \ # so we know which ones are shared. These files must not include # other guestfish files. SHARED_SOURCE_FILES = \ + config.c \ inspect.c \ keys.c \ options.h \ @@ -118,10 +119,13 @@ guestfish_CFLAGS = \ -DGUESTFS_DEFAULT_PATH='"$(libdir)/guestfs"' \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) + $(WARN_CFLAGS) $(WERROR_CFLAGS) \ + $(LIBCONFIG_CFLAGS) guestfish_LDADD = \ - $(top_builddir)/src/libguestfs.la $(LIBREADLINE) -lm + $(LIBCONFIG_LIBS) \ + $(LIBREADLINE) \ + $(top_builddir)/src/libguestfs.la -lm # Make guestfish use the convenience libraries. noinst_LTLIBRARIES = libcmds.la librc_protocol.la @@ -207,6 +211,11 @@ stamp-virt-tar-out.pod: virt-tar-out.pod $< touch $@ +# libguestfs tools config file. + +toolsconfdir = $(sysconfdir) +toolsconf_DATA = libguestfs-tools.conf + # Bash completion script. bashcompletiondir = $(sysconfdir)/bash_completion.d diff --git a/fish/config.c b/fish/config.c new file mode 100644 index 0000000..c92bc4e --- /dev/null +++ b/fish/config.c @@ -0,0 +1,142 @@ +/* libguestfs - guestfish and guestmount shared option parsing + * Copyright (C) 2011 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include + +#include +#include + +#ifdef HAVE_LIBCONFIG +#include +#endif + +#include "guestfs.h" + +#include "options.h" + +static const char *home_filename = /* $HOME/ */ ".libguestfs-tools.rc"; +static const char *etc_filename = "/etc/libguestfs-tools.conf"; + +#ifdef HAVE_LIBCONFIG + +/* Note that parse_config is called very early, before command line + * parsing and before the verbose flag has been set. + */ + +void +parse_config (void) +{ + const char *home; + size_t len; + char *path; + FILE *fp; + config_t conf; + + config_init (&conf); + + /* Try $HOME first. */ + home = getenv ("HOME"); + if (home != NULL) { + len = strlen (home) + 1 + strlen (home_filename) + 1; + path = malloc (len); + if (path == NULL) { + perror ("malloc"); + exit (EXIT_FAILURE); + } + snprintf (path, len, "%s/%s", home, home_filename); + + fp = fopen (path, "r"); + if (fp != NULL) { + /* + if (verbose) + fprintf (stderr, "%s: reading configuration from %s\n", + program_name, path); + */ + + if (config_read (&conf, fp) == CONFIG_FALSE) { + fprintf (stderr, + _("%s: %s: line %d: error parsing configuration file: %s\n"), + program_name, path, config_error_line (&conf), + config_error_text (&conf)); + exit (EXIT_FAILURE); + } + + if (fclose (fp) == -1) { + perror (path); + exit (EXIT_FAILURE); + } + + /* Notes: + * + * (1) It's not obvious from the documentation, that config_read + * completely resets the 'conf' structure. This means we cannot + * call config_read twice on the two possible configuration + * files, but instead have to copy out settings into our + * variables between calls. + * + * (2) If the next call fails then 'read_only' variable is not + * updated. Failure could happen just because the setting is + * missing from the configuration file, so we ignore it here. + */ + config_lookup_bool (&conf, "read_only", &read_only); + } + + free (path); + } + + fp = fopen (etc_filename, "r"); + if (fp != NULL) { + /* + if (verbose) + fprintf (stderr, "%s: reading configuration from %s\n", + program_name, etc_filename); + */ + + if (config_read (&conf, fp) == CONFIG_FALSE) { + fprintf (stderr, + _("%s: %s: line %d: error parsing configuration file: %s\n"), + program_name, etc_filename, config_error_line (&conf), + config_error_text (&conf)); + exit (EXIT_FAILURE); + } + + if (fclose (fp) == -1) { + perror (path); + exit (EXIT_FAILURE); + } + + config_lookup_bool (&conf, "read_only", &read_only); + } + + config_destroy (&conf); +} + +#else /* !HAVE_LIBCONFIG */ + +void +parse_config (void) +{ + /* + if (verbose) + fprintf (stderr, + _("%s: compiled without libconfig, guestfish configuration file ignored\n"), + program_name); + */ +} + +#endif /* !HAVE_LIBCONFIG */ diff --git a/fish/fish.c b/fish/fish.c index 65a0c1d..c4fdf79 100644 --- a/fish/fish.c +++ b/fish/fish.c @@ -158,6 +158,8 @@ main (int argc, char *argv[]) bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); + parse_config (); + set_up_terminal (); enum { HELP_OPTION = CHAR_MAX + 1 }; diff --git a/fish/guestfish.pod b/fish/guestfish.pod index 98286d1..58f0bd9 100644 --- a/fish/guestfish.pod +++ b/fish/guestfish.pod @@ -402,7 +402,9 @@ Display the guestfish / libguestfs version number and exit. =item B<--rw> -This option does nothing at the moment. +This changes the I<-a>, I<-d> and I<-m> options so that disks are +added and mounts are done read-write. + See L below. =item B<-x> @@ -466,27 +468,30 @@ asked for without doing this. =head1 OPENING DISKS FOR READ AND WRITE -The guestfish (and L) options I<--ro> and I<--rw> -affect whether the other command line options I<-a>, I<-c>, I<-d>, -I<-i> and I<-m> open disk images read-only or for writing. +The guestfish, L and L options I<--ro> +and I<--rw> affect whether the other command line options I<-a>, +I<-c>, I<-d>, I<-i> and I<-m> open disk images read-only or for +writing. -In libguestfs E 1.6.2, guestfish and guestmount defaulted to -opening disk images supplied on the command line for write. To open a -disk image read-only you have to do I<-a image --ro>. +In libguestfs E 1.8, guestfish, guestmount and virt-rescue +defaulted to opening disk images supplied on the command line for +write. To open a disk image read-only you have to do I<-a image --ro>. This matters: If you accidentally open a live VM disk image writable then you will cause irreversible disk corruption. -By libguestfs 1.10 we intend to change the default the other way. Disk -images will be opened read-only. You will have to either specify -I or change a configuration file in order to get write -access for disk images specified by those other command line options. +By libguestfs 1.10 we intend to change the default the other way. +Disk images will be opened read-only. You will have to either specify +I, I, I, or change +the configuration file C in order to get +write access for disk images specified by those other command line +options. -This version of guestfish has a I<--rw> option which does nothing (it -is already the default). However it is highly recommended that you -use this option to indicate that guestfish needs write access, and to -prepare your scripts for the day when this option will be required for -write access. +This version of guestfish, guestmount and virt-rescue has a I<--rw> +option which does nothing (it is already the default). However it is +highly recommended that you use this option to indicate that you need +write access, and prepare your scripts for the day when this option +will be required for write access. B This does I affect commands like L and L, or any other libguestfs program apart from guestfish and guestmount. @@ -1081,6 +1086,15 @@ enough. =over 4 +=item $HOME/.libguestfs-tools.rc + +=item /etc/libguestfs-tools.conf + +This configuration file controls the default read-only or read-write +mode (I<--ro> or I<--rw>). + +See L. + =item $HOME/.guestfish If compiled with GNU readline support, then the command history @@ -1156,7 +1170,7 @@ Richard W.M. Jones (C) =head1 COPYRIGHT -Copyright (C) 2009-2010 Red Hat Inc. +Copyright (C) 2009-2011 Red Hat Inc. L This program is free software; you can redistribute it and/or modify diff --git a/fish/libguestfs-tools.conf b/fish/libguestfs-tools.conf new file mode 100644 index 0000000..7e60468 --- /dev/null +++ b/fish/libguestfs-tools.conf @@ -0,0 +1,24 @@ +# /etc/libguestfs-tools.conf or .libguestfs-tools.rc +# +# This configuration file changes the defaults for the following programs: +# * guestfish +# * guestmount +# * virt-rescue +# For more information on these programs, read the manual pages +# (guestfish(1) etc). +# +# /etc/libguestfs-tools.conf is the global configuration file for all +# of the above programs. Local users can override the global +# configuration by copying this file into '.libguestfs-tools.rc' in +# their home directory and modifying it accordingly. +# +# This file is parsed by the libconfig library. For more information +# about the format, see +# http://www.hyperrealm.com/libconfig/libconfig_manual.html + +# Uncomment the following line to make guestfish, guestmount, +# virt-rescue be read-only by default (as if the --ro flag was given). +# If it is commented out then the default is read-write. Note that +# the semi-colon (;) is required. + +#read_only = true; diff --git a/fish/options.h b/fish/options.h index e0cad01..9b9aee5 100644 --- a/fish/options.h +++ b/fish/options.h @@ -112,6 +112,9 @@ struct mp { char *options; }; +/* in config.c */ +extern void parse_config (void); + /* in inspect.c */ extern void inspect_mount (void); extern void print_inspect_prompt (void); diff --git a/fuse/Makefile.am b/fuse/Makefile.am index 1cdb993..577f51e 100644 --- a/fuse/Makefile.am +++ b/fuse/Makefile.am @@ -28,6 +28,7 @@ bin_PROGRAMS = guestmount # These source files (all related to option parsing) are shared # between guestfish and guestmount. SHARED_SOURCE_FILES = \ + ../fish/config.c \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ @@ -48,10 +49,12 @@ guestmount_CFLAGS = \ -DGUESTFS_DEFAULT_PATH='"$(libdir)/guestfs"' \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ $(FUSE_CFLAGS) \ + $(LIBCONFIG_CFLAGS) \ $(WARN_CFLAGS) $(WERROR_CFLAGS) guestmount_LDADD = \ $(FUSE_LIBS) -lulockmgr \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ ../gnulib/lib/libgnu.la diff --git a/fuse/guestmount.c b/fuse/guestmount.c index f1f8480..5a89fcb 100644 --- a/fuse/guestmount.c +++ b/fuse/guestmount.c @@ -947,6 +947,8 @@ main (int argc, char *argv[]) bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); + parse_config (); + enum { HELP_OPTION = CHAR_MAX + 1 }; /* The command line arguments are broadly compatible with (a subset diff --git a/fuse/guestmount.pod b/fuse/guestmount.pod index ea0cb63..9fbefcf 100644 --- a/fuse/guestmount.pod +++ b/fuse/guestmount.pod @@ -236,7 +236,9 @@ Display the program version and exit. =item B<-w> | B<--rw> -This option does nothing at the moment. +This changes the I<-a>, I<-d> and I<-m> options so that disks are +added and mounts are done read-write. + See L. =item B<-x> | B<--trace> @@ -247,6 +249,21 @@ This also stops the daemon from forking into the background. =back +=head1 FILES + +=over 4 + +=item $HOME/.libguestfs-tools.rc + +=item /etc/libguestfs-tools.conf + +This configuration file controls the default read-only or read-write +mode (I<--ro> or I<--rw>). + +See L. + +=back + =head1 SEE ALSO L, diff --git a/inspector/Makefile.am b/inspector/Makefile.am index 24dcdef..69b5683 100644 --- a/inspector/Makefile.am +++ b/inspector/Makefile.am @@ -1,5 +1,5 @@ # libguestfs virt-inspector -# Copyright (C) 2009-2010 Red Hat Inc. +# Copyright (C) 2009-2011 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -48,6 +48,7 @@ if HAVE_LIBXML2 bin_PROGRAMS = virt-inspector SHARED_SOURCE_FILES = \ + ../fish/config.c \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ @@ -64,9 +65,11 @@ virt_inspector_CFLAGS = \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ $(LIBXML2_CFLAGS) \ + $(LIBCONFIG_CFLAGS) \ $(WARN_CFLAGS) $(WERROR_CFLAGS) virt_inspector_LDADD = \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ $(LIBXML2_LIBS) \ ../gnulib/lib/libgnu.la diff --git a/po/POTFILES.in b/po/POTFILES.in index afe4798..adb9700 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -82,6 +82,7 @@ fish/alloc.c fish/cmds.c fish/cmds_gperf.c fish/completion.c +fish/config.c fish/copy.c fish/destpaths.c fish/echo.c diff --git a/rescue/Makefile.am b/rescue/Makefile.am index f6f5b25..a490341 100644 --- a/rescue/Makefile.am +++ b/rescue/Makefile.am @@ -1,5 +1,5 @@ # libguestfs virt-rescue -# Copyright (C) 2010 Red Hat Inc. +# Copyright (C) 2010-2011 Red Hat Inc. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -26,6 +26,7 @@ CLEANFILES = stamp-virt-rescue.pod bin_PROGRAMS = virt-rescue SHARED_SOURCE_FILES = \ + ../fish/config.c \ ../fish/inspect.c \ ../fish/keys.c \ ../fish/options.h \ @@ -41,9 +42,11 @@ virt_rescue_CFLAGS = \ -I$(top_srcdir)/fish \ -I$(srcdir)/../gnulib/lib -I../gnulib/lib \ -DLOCALEBASEDIR=\""$(datadir)/locale"\" \ + $(LIBCONFIG_CFLAGS) \ $(WARN_CFLAGS) $(WERROR_CFLAGS) virt_rescue_LDADD = \ + $(LIBCONFIG_LIBS) \ $(top_builddir)/src/libguestfs.la \ ../gnulib/lib/libgnu.la diff --git a/rescue/virt-rescue.c b/rescue/virt-rescue.c index 8341e97..f129b1c 100644 --- a/rescue/virt-rescue.c +++ b/rescue/virt-rescue.c @@ -95,6 +95,8 @@ main (int argc, char *argv[]) bindtextdomain (PACKAGE, LOCALEBASEDIR); textdomain (PACKAGE); + parse_config (); + enum { HELP_OPTION = CHAR_MAX + 1 }; static const char *options = "a:c:d:m:rvVx"; diff --git a/rescue/virt-rescue.pod b/rescue/virt-rescue.pod index 9dbdd5e..f56acd0 100755 --- a/rescue/virt-rescue.pod +++ b/rescue/virt-rescue.pod @@ -167,6 +167,8 @@ The option must always be used if the disk image or virtual machine might be running, and is generally recommended in cases where you don't need write access to the disk. +See also L. + =item B<--selinux> Enable SELinux in the rescue appliance. You should read @@ -188,7 +190,9 @@ Display version number and exit. =item B<--rw> -This option does nothing at the moment. +This changes the I<-a> and I<-d> options so that disks are +added and mounts are done read-write. + See L. =item B<-x> @@ -261,6 +265,21 @@ have meaning to the shell such as C<#> and space. You may need to quote or escape these characters on the command line. See the shell manual page L for details. +=head1 FILES + +=over 4 + +=item $HOME/.libguestfs-tools.rc + +=item /etc/libguestfs-tools.conf + +This configuration file controls the default read-only or read-write +mode (I<--ro> or I<--rw>). + +See L. + +=back + =head1 SEE ALSO L, @@ -275,7 +294,7 @@ Richard W.M. Jones L =head1 COPYRIGHT -Copyright (C) 2009-2010 Red Hat Inc. +Copyright (C) 2009-2011 Red Hat Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -- 1.8.3.1