diff --git a/.gitignore b/.gitignore index 2228d0b1a..6781feb74 100644 --- a/.gitignore +++ b/.gitignore @@ -122,48 +122,6 @@ Makefile.in /cat/virt-tail /cat/virt-tail.1 /ChangeLog -/common/errnostring/errnostring.c -/common/errnostring/errnostring-gperf.c -/common/errnostring/errnostring-gperf.gperf -/common/errnostring/errnostring.h -/common/mlaugeas/.depend -/common/mlcustomize/.depend -/common/mlcustomize/test-firstboot-*.sh -/common/mlgettext/.depend -/common/mlgettext/common_gettext.ml -/common/mllibvirt/.depend -/common/mllibvirt/libvirt_c.c -/common/mlpcre/.depend -/common/mlpcre/pcre_tests -/common/mlprogress/.depend -/common/mlstdutils/.depend -/common/mlstdutils/bytes.ml -/common/mlstdutils/bytes.mli -/common/mlstdutils/guestfs_config.ml -/common/mlstdutils/oUnit-* -/common/mlstdutils/std_utils_tests -/common/mltools/.depend -/common/mltools/getopt_tests -/common/mltools/JSON_tests -/common/mltools/JSON_parser_tests -/common/mltools/machine_readable_tests -/common/mltools/tools_messages_tests -/common/mltools/tools_utils_tests -/common/mltools/oUnit-* -/common/mlutils/.depend -/common/mlutils/c_utils_unit_tests -/common/mlutils/oUnit-* -/common/mlvisit/.depend -/common/mlvisit/visit_tests -/common/mlxml/.depend -/common/protocol/guestfs_protocol.c -/common/protocol/guestfs_protocol.h -/common/protocol/guestfs_protocol.x -/common/qemuopts/qemuopts-tests -/common/structs/structs-cleanups.c -/common/structs/structs-cleanups.h -/common/structs/structs-print.c -/common/structs/structs-print.h /compile /config.cache /config.guess diff --git a/.gitmodules b/.gitmodules index f8d0cf321..fb96af879 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,6 @@ [submodule "gnulib"] path = .gnulib url = https://git.savannah.gnu.org/git/gnulib.git +[submodule "common"] + path = common + url = https://github.com/libguestfs/libguestfs-common diff --git a/Makefile.am b/Makefile.am index 9ce0a75a7..dead252cd 100644 --- a/Makefile.am +++ b/Makefile.am @@ -596,7 +596,9 @@ maintainer-check-authors: maintainer-check-extra-dist: zcat $(PACKAGE_NAME)-$(VERSION).tar.gz | tar tf - | sort | \ sed 's,^$(PACKAGE_NAME)-$(VERSION)/,,' > tmp/tarfiles - git ls-files | \ + ( git ls-files ; \ + cd common; git ls-files | sed 's,^,common/,' ) | \ + grep -v '^common$$' | \ grep -v '^intltool-.*\.in' | \ grep -v '^\.gitmodules' | \ grep -v '^\.gnulib' | \ diff --git a/common b/common new file mode 160000 index 000000000..9de0cb48e --- /dev/null +++ b/common @@ -0,0 +1 @@ +Subproject commit 9de0cb48ef32b6704209d47b879b4342e4f0694e diff --git a/common/edit/Makefile.am b/common/edit/Makefile.am deleted file mode 100644 index 45ef9b2d6..000000000 --- a/common/edit/Makefile.am +++ /dev/null @@ -1,35 +0,0 @@ -# libguestfs -# Copyright (C) 2009-2019 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 $(top_srcdir)/subdir-rules.mk - -# libedit.la contains the common code used by virt-edit, guestfish -# 'edit' command, virt-customize and virt-builder. -noinst_LTLIBRARIES = libedit.la - -libedit_la_SOURCES = \ - file-edit.c \ - file-edit.h -libedit_la_CPPFLAGS = \ - -DGUESTFS_NO_DEPRECATED=1 \ - -I$(top_srcdir)/common/utils -I$(top_builddir)/common/utils \ - -I$(top_srcdir)/lib -I$(top_builddir)/lib -libedit_la_CFLAGS = \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) -libedit_la_LIBADD = \ - $(top_builddir)/common/utils/libutils.la \ - $(top_builddir)/lib/libguestfs.la diff --git a/common/edit/file-edit.c b/common/edit/file-edit.c deleted file mode 100644 index ef56ed13d..000000000 --- a/common/edit/file-edit.c +++ /dev/null @@ -1,348 +0,0 @@ -/* libguestfs - shared file editing - * Copyright (C) 2009-2019 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. - */ - -/** - * This file implements common file editing in a range of utilities - * including L, L, L - * and L. - * - * It contains the code for both interactive-(editor-)based editing - * and non-interactive editing using Perl snippets. - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "guestfs-utils.h" - -#include "file-edit.h" - -static int do_download (guestfs_h *g, const char *filename, char **tempfile); -static int do_upload (guestfs_h *g, const char *filename, const char *tempfile, - const char *backup_extension); -static char *generate_random_name (const char *filename); -static char *generate_backup_name (const char *filename, - const char *backup_extension); - -/** - * Edit C using the specified C application. - * - * If C is not null, then a copy of C is - * saved with C appended to its file name. - * - * If C is null, then the C<$EDITOR> environment variable will - * be queried for the editor application, leaving C as fallback if - * not set. - * - * Returns C<-1> for failure, C<0> on success, C<1> if the editor did - * not change the file (e.g. the user closed the editor without - * saving). - */ -int -edit_file_editor (guestfs_h *g, const char *filename, const char *editor, - const char *backup_extension, int verbose) -{ - CLEANUP_UNLINK_FREE char *tmpfilename = NULL; - CLEANUP_FREE char *cmd = NULL; - struct stat oldstat, newstat; - int r; - struct utimbuf times; - - if (editor == NULL) { - editor = getenv ("EDITOR"); - if (editor == NULL) - editor = "vi"; - } - - /* Download the file and write it to a temporary. */ - if (do_download (g, filename, &tmpfilename) == -1) - return -1; - - /* Set the time back a few seconds on the original file. This is so - * that if the user is very fast at editing, or if EDITOR is an - * automatic editor, then the edit might happen within the 1 second - * granularity of mtime, and we would think the file hasn't changed. - */ - if (stat (tmpfilename, &oldstat) == -1) { - perror (tmpfilename); - return -1; - } - - times.actime = oldstat.st_atime - 5; - times.modtime = oldstat.st_mtime - 5; - if (utime (tmpfilename, ×) == -1) { - perror ("utimes"); - return -1; - } - - /* Get the old stat. */ - if (stat (tmpfilename, &oldstat) == -1) { - perror (tmpfilename); - return -1; - } - - /* Edit it. */ - if (asprintf (&cmd, "%s %s", editor, tmpfilename) == -1) { - perror ("asprintf"); - return -1; - } - - if (verbose) - fprintf (stderr, "%s\n", cmd); - - r = system (cmd); - if (r == -1 || WEXITSTATUS (r) != 0) { - perror (cmd); - return -1; - } - - /* Get the new stat. */ - if (stat (tmpfilename, &newstat) == -1) { - perror (tmpfilename); - return -1; - } - - /* Changed? */ - if (oldstat.st_ctime == newstat.st_ctime && - oldstat.st_size == newstat.st_size) - return 1; - - if (do_upload (g, filename, tmpfilename, backup_extension) == -1) - return -1; - - return 0; -} - -/** - * Edit C running the specified C using Perl. - * - * If C is not null, then a copy of C is - * saved with C appended to its file name. - * - * Returns C<-1> for failure, C<0> on success. - */ -int -edit_file_perl (guestfs_h *g, const char *filename, const char *perl_expr, - const char *backup_extension, int verbose) -{ - CLEANUP_UNLINK_FREE char *tmpfilename = NULL; - CLEANUP_FREE char *cmd = NULL; - CLEANUP_FREE char *outfile = NULL; - int r; - - /* Download the file and write it to a temporary. */ - if (do_download (g, filename, &tmpfilename) == -1) - return -1; - - if (asprintf (&outfile, "%s.out", tmpfilename) == -1) { - perror ("asprintf"); - return -1; - } - - /* Pass the expression to Perl via the environment. This sidesteps - * any quoting problems with the already complex Perl command line. - */ - setenv ("virt_edit_expr", perl_expr, 1); - - /* Call out to a canned Perl script. */ - if (asprintf (&cmd, - "perl -e '" - "$lineno = 0; " - "$expr = $ENV{virt_edit_expr}; " - "while () { " - " $lineno++; " - " eval $expr; " - " die if $@; " - " print STDOUT $_ or die \"print: $!\"; " - "} " - "close STDOUT or die \"close: $!\"; " - "' < %s > %s", - tmpfilename, outfile) == -1) { - perror ("asprintf"); - return -1; - } - - if (verbose) - fprintf (stderr, "%s\n", cmd); - - r = system (cmd); - if (r == -1 || WEXITSTATUS (r) != 0) - return -1; - - if (rename (outfile, tmpfilename) == -1) { - perror ("rename"); - return -1; - } - - if (do_upload (g, filename, tmpfilename, backup_extension) == -1) - return -1; - - return 0; -} - -static int -do_download (guestfs_h *g, const char *filename, char **tempfile) -{ - CLEANUP_FREE char *tmpdir = guestfs_get_tmpdir (g); - CLEANUP_UNLINK_FREE char *tmpfilename = NULL; - char buf[256]; - int fd; - - /* Download the file and write it to a temporary. */ - if (asprintf (&tmpfilename, "%s/libguestfsXXXXXX", tmpdir) == -1) { - perror ("asprintf"); - return -1; - } - - fd = mkstemp (tmpfilename); - if (fd == -1) { - perror ("mkstemp"); - return -1; - } - - snprintf (buf, sizeof buf, "/dev/fd/%d", fd); - - if (guestfs_download (g, filename, buf) == -1) { - close (fd); - return -1; - } - - if (close (fd) == -1) { - perror (tmpfilename); - return -1; - } - - /* Hand over the temporary file. */ - *tempfile = tmpfilename; - tmpfilename = NULL; - - return 0; -} - -static int -do_upload (guestfs_h *g, const char *fn, const char *tempfile, - const char *backup_extension) -{ - CLEANUP_FREE char *filename = NULL; - CLEANUP_FREE char *newname = NULL; - - /* Resolve the file name and write to the actual target, since - * that is the file it was opened earlier; otherwise, if it is - * a symlink it will be overwritten by a regular file with the - * new content. - * - * Theoretically realpath should work, but just check again - * to be safe. - */ - filename = guestfs_realpath (g, fn); - if (filename == NULL) - return -1; - - /* Upload to a new file in the same directory, so if it fails we - * don't end up with a partially written file. Give the new file - * a completely random name so we have only a tiny chance of - * overwriting some existing file. - */ - newname = generate_random_name (filename); - if (!newname) - return -1; - - /* Write new content. */ - if (guestfs_upload (g, tempfile, newname) == -1) - return -1; - - /* Set the permissions, UID, GID and SELinux context of the new - * file to match the old file (RHBZ#788641). - */ - if (guestfs_copy_attributes (g, filename, newname, - GUESTFS_COPY_ATTRIBUTES_ALL, 1, -1) == -1) - return -1; - - /* Backup or overwrite the file. */ - if (backup_extension) { - CLEANUP_FREE char *backupname = NULL; - - backupname = generate_backup_name (filename, backup_extension); - if (backupname == NULL) - return -1; - - if (guestfs_mv (g, filename, backupname) == -1) - return -1; - } - if (guestfs_mv (g, newname, filename) == -1) - return -1; - - return 0; -} - -static char * -generate_random_name (const char *filename) -{ - char *ret, *p; - - ret = malloc (strlen (filename) + 16); - if (!ret) { - perror ("malloc"); - return NULL; - } - strcpy (ret, filename); - - p = strrchr (ret, '/'); - assert (p); - p++; - - /* Because of "+ 16" above, there should be enough space in the - * output buffer to write 8 random characters here plus the - * trailing \0. - */ - if (guestfs_int_random_string (p, 8) == -1) { - perror ("guestfs_int_random_string"); - free (ret); - return NULL; - } - - return ret; /* caller will free */ -} - -static char * -generate_backup_name (const char *filename, const char *backup_extension) -{ - char *ret; - - assert (backup_extension != NULL); - - if (asprintf (&ret, "%s%s", filename, backup_extension) == -1) { - perror ("asprintf"); - return NULL; - } - - return ret; /* caller will free */ -} diff --git a/common/edit/file-edit.h b/common/edit/file-edit.h deleted file mode 100644 index 4120b6d0a..000000000 --- a/common/edit/file-edit.h +++ /dev/null @@ -1,32 +0,0 @@ -/* libguestfs - shared file editing - * Copyright (C) 2009-2019 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. - */ - -#ifndef FISH_FILE_EDIT_H -#define FISH_FILE_EDIT_H - -#include - -extern int edit_file_editor (guestfs_h *g, const char *filename, - const char *editor, const char *backup_extension, - int verbose); - -extern int edit_file_perl (guestfs_h *g, const char *filename, - const char *perl_expr, - const char *backup_extension, int verbose); - -#endif diff --git a/common/errnostring/Makefile.am b/common/errnostring/Makefile.am deleted file mode 100644 index 2fe5b2414..000000000 --- a/common/errnostring/Makefile.am +++ /dev/null @@ -1,45 +0,0 @@ -# libguestfs -# Copyright (C) 2017 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 $(top_srcdir)/subdir-rules.mk - -generator_built = \ - errnostring-gperf.gperf \ - errnostring.c \ - errnostring.h - -BUILT_SOURCES = \ - $(generator_built) \ - errnostring-gperf.c - -EXTRA_DIST = \ - $(BUILT_SOURCES) - -noinst_LTLIBRARIES = liberrnostring.la - -# Build the errnostring perfect hash code. The generated code has lots -# of warnings so we must compile it in a separate mini-library. -liberrnostring_la_SOURCES = \ - errnostring-gperf.c \ - errnostring.h \ - errnostring.c -liberrnostring_la_CFLAGS = $(GCC_VISIBILITY_HIDDEN) - -errnostring-gperf.c: errnostring-gperf.gperf - rm -f $@ - $(GPERF) -t $< > $@-t - mv $@-t $@ diff --git a/common/mlaugeas/Makefile.am b/common/mlaugeas/Makefile.am deleted file mode 100644 index 3baae008e..000000000 --- a/common/mlaugeas/Makefile.am +++ /dev/null @@ -1,92 +0,0 @@ -# libguestfs OCaml tools common code -# Copyright (C) 2011-2019 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 $(top_srcdir)/subdir-rules.mk - -EXTRA_DIST = \ - $(SOURCES_MLI) \ - $(SOURCES_ML) \ - $(SOURCES_C) \ - augeas.README - -SOURCES_MLI = \ - augeas.mli - -SOURCES_ML = \ - augeas.ml - -SOURCES_C = \ - augeas-c.c - -# We pretend that we're building a C library. automake handles the -# compilation of the C sources for us. At the end we take the C -# objects and OCaml objects and link them into the OCaml library. -# This C library is never used. - -noinst_LIBRARIES = libmlaugeas.a - -if !HAVE_OCAMLOPT -MLAUGEAS_CMA = mlaugeas.cma -else -MLAUGEAS_CMA = mlaugeas.cmxa -endif - -noinst_DATA = $(MLAUGEAS_CMA) - -libmlaugeas_a_SOURCES = $(SOURCES_C) -libmlaugeas_a_CPPFLAGS = \ - -I. \ - -I$(top_builddir) \ - -I$(shell $(OCAMLC) -where) -libmlaugeas_a_CFLAGS = \ - $(WARN_CFLAGS) $(NO_SNV_CFLAGS) $(NO_UM_CFLAGS) $(WERROR_CFLAGS) \ - $(LIBVIRT_CFLAGS) $(LIBXML2_CFLAGS) \ - -fPIC - -BOBJECTS = $(SOURCES_ML:.ml=.cmo) -XOBJECTS = $(BOBJECTS:.cmo=.cmx) - -OCAMLPACKAGES = -OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)' - -if !HAVE_OCAMLOPT -OBJECTS = $(BOBJECTS) -else -OBJECTS = $(XOBJECTS) -endif - -libmlaugeas_a_DEPENDENCIES = $(OBJECTS) - -$(MLAUGEAS_CMA): $(OBJECTS) libmlaugeas.a - $(OCAMLFIND) mklib $(OCAMLPACKAGES) \ - $(OBJECTS) $(libmlaugeas_a_OBJECTS) -cclib -laugeas -o mlaugeas - -# Dependencies. -depend: .depend - -.depend: $(wildcard $(abs_srcdir)/*.mli) $(wildcard $(abs_srcdir)/*.ml) - rm -f $@ $@-t - $(OCAMLFIND) ocamldep -I ../../ocaml -I $(abs_srcdir) $^ | \ - $(SED) 's/ *$$//' | \ - $(SED) -e :a -e '/ *\\$$/N; s/ *\\\n */ /; ta' | \ - $(SED) -e 's,$(abs_srcdir)/,$(builddir)/,g' | \ - sort > $@-t - mv $@-t $@ - --include .depend - -.PHONY: depend docs diff --git a/common/mlaugeas/augeas-c.c b/common/mlaugeas/augeas-c.c deleted file mode 100644 index 3e0ba67ba..000000000 --- a/common/mlaugeas/augeas-c.c +++ /dev/null @@ -1,443 +0,0 @@ -/* Augeas OCaml bindings - * Copyright (C) 2008-2019 Red Hat Inc., Richard W.M. Jones - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $Id: augeas_c.c,v 1.1 2008/05/06 10:48:20 rjones Exp $ - */ - -#include "config.h" - -#include - -#include -#include -#include -#include -#include -#include - -#ifdef __GNUC__ - #define NORETURN __attribute__ ((noreturn)) -#else - #define NORETURN -#endif - -extern CAMLprim value ocaml_augeas_create (value rootv, value loadpathv, value flagsv); -extern CAMLprim value ocaml_augeas_close (value tv); -extern CAMLprim value ocaml_augeas_get (value tv, value pathv); -extern CAMLprim value ocaml_augeas_exists (value tv, value pathv); -extern CAMLprim value ocaml_augeas_insert (value tv, value beforev, value pathv, value labelv); -extern CAMLprim value ocaml_augeas_rm (value tv, value pathv); -extern CAMLprim value ocaml_augeas_match (value tv, value pathv); -extern CAMLprim value ocaml_augeas_count_matches (value tv, value pathv); -extern CAMLprim value ocaml_augeas_save (value tv); -extern CAMLprim value ocaml_augeas_load (value tv); -extern CAMLprim value ocaml_augeas_set (value tv, value pathv, value valuev); -extern CAMLprim value ocaml_augeas_transform (value tv, value lensv, value filev, value modev); -extern CAMLprim value ocaml_augeas_source (value tv, value pathv) -#ifndef HAVE_AUG_SOURCE - NORETURN -#endif -; - -typedef augeas *augeas_t; - -/* Map C aug_errcode_t to OCaml error_code. */ -static const int error_map[] = { - /* AugErrInternal */ AUG_EINTERNAL, - /* AugErrPathX */ AUG_EPATHX, - /* AugErrNoMatch */ AUG_ENOMATCH, - /* AugErrMMatch */ AUG_EMMATCH, - /* AugErrSyntax */ AUG_ESYNTAX, - /* AugErrNoLens */ AUG_ENOLENS, - /* AugErrMXfm */ AUG_EMXFM, - /* AugErrNoSpan */ AUG_ENOSPAN, - /* AugErrMvDesc */ AUG_EMVDESC, - /* AugErrCmdRun */ AUG_ECMDRUN, - /* AugErrBadArg */ AUG_EBADARG, - /* AugErrLabel */ AUG_ELABEL, - /* AugErrCpDesc */ AUG_ECPDESC, -}; -static const int error_map_len = sizeof error_map / sizeof error_map[0]; - -/* Raise an Augeas.Error exception. */ -static void -raise_error (augeas_t t, const char *msg) -{ - value *exn = caml_named_value ("Augeas.Error"); - value args[4]; - const int code = aug_error (t); - const char *aug_err_minor; - const char *aug_err_details; - int ocaml_code = -1; - int i; - - if (code == AUG_ENOMEM) - caml_raise_out_of_memory (); - - aug_err_minor = aug_error_minor_message (t); - aug_err_details = aug_error_details (t); - - for (i = 0; i < error_map_len; ++i) - if (error_map[i] == code) { - ocaml_code = i; - break; - } - - if (ocaml_code != -1) - args[0] = Val_int (ocaml_code); - else { - args[0] = caml_alloc (1, 0); - Store_field (args[0], 0, Val_int (code)); - } - args[1] = caml_copy_string (msg); - args[2] = caml_copy_string (aug_err_minor ? : ""); - args[3] = caml_copy_string (aug_err_details ? : ""); - - caml_raise_with_args (*exn, 4, args); -} - -static void -raise_init_error (const char *msg) -{ - value *exn = caml_named_value ("Augeas.Error"); - value args[4]; - - args[0] = caml_alloc (1, 0); - Store_field (args[0], 0, Val_int (-1)); - args[1] = caml_copy_string (msg); - args[2] = caml_copy_string ("augeas initialization failed"); - args[3] = caml_copy_string (""); - - caml_raise_with_args (*exn, 4, args); -} - -/* Map OCaml flags to C flags. */ -static const int flag_map[] = { - /* AugSaveBackup */ AUG_SAVE_BACKUP, - /* AugSaveNewFile */ AUG_SAVE_NEWFILE, - /* AugTypeCheck */ AUG_TYPE_CHECK, - /* AugNoStdinc */ AUG_NO_STDINC, - /* AugSaveNoop */ AUG_SAVE_NOOP, - /* AugNoLoad */ AUG_NO_LOAD, -}; - -/* Wrap and unwrap augeas_t handles, with a finalizer. */ -#define Augeas_t_val(rv) (*(augeas_t *)Data_custom_val(rv)) - -static void -augeas_t_finalize (value tv) -{ - augeas_t t = Augeas_t_val (tv); - if (t) aug_close (t); -} - -static struct custom_operations custom_operations = { - (char *) "augeas_t_custom_operations", - augeas_t_finalize, - custom_compare_default, - custom_hash_default, - custom_serialize_default, - custom_deserialize_default, - custom_compare_ext_default, -}; - -static value Val_augeas_t (augeas_t t) -{ - CAMLparam0 (); - CAMLlocal1 (rv); - /* We could choose these so that the GC can make better decisions. - * See 18.9.2 of the OCaml manual. - */ - const int used = 0; - const int max = 1; - - rv = caml_alloc_custom (&custom_operations, - sizeof (augeas_t), used, max); - Augeas_t_val(rv) = t; - - CAMLreturn (rv); -} - -#pragma GCC diagnostic ignored "-Wmissing-prototypes" - -/* val create : string -> string option -> flag list -> t */ -CAMLprim value -ocaml_augeas_create (value rootv, value loadpathv, value flagsv) -{ - CAMLparam1 (rootv); - const char *root = String_val (rootv); - const char *loadpath; - int flags = 0, i; - augeas_t t; - - /* Optional loadpath. */ - loadpath = - loadpathv == Val_int (0) - ? NULL - : String_val (Field (loadpathv, 0)); - - /* Convert list of flags to C. */ - for (; flagsv != Val_int (0); flagsv = Field (flagsv, 1)) { - i = Int_val (Field (flagsv, 0)); - flags |= flag_map[i]; - } - - t = aug_init (root, loadpath, flags); - - if (t == NULL) - raise_init_error ("Augeas.create"); - - CAMLreturn (Val_augeas_t (t)); -} - -/* val close : t -> unit */ -CAMLprim value -ocaml_augeas_close (value tv) -{ - CAMLparam1 (tv); - augeas_t t = Augeas_t_val (tv); - - if (t) { - aug_close (t); - Augeas_t_val(tv) = NULL; /* So the finalizer doesn't double-free. */ - } - - CAMLreturn (Val_unit); -} - -/* val get : t -> path -> value option */ -CAMLprim value -ocaml_augeas_get (value tv, value pathv) -{ - CAMLparam2 (tv, pathv); - CAMLlocal2 (optv, v); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - const char *val; - int r; - - r = aug_get (t, path, &val); - if (r == 1 && val) { /* Return Some val */ - v = caml_copy_string (val); - optv = caml_alloc (1, 0); - Field (optv, 0) = v; - } else if (r == 0 || !val) /* Return None */ - optv = Val_int (0); - else if (r == -1) /* Error or multiple matches */ - raise_error (t, "Augeas.get"); - else - caml_failwith ("Augeas.get: bad return value"); - - CAMLreturn (optv); -} - -/* val exists : t -> path -> bool */ -CAMLprim value -ocaml_augeas_exists (value tv, value pathv) -{ - CAMLparam2 (tv, pathv); - CAMLlocal1 (v); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - int r; - - r = aug_get (t, path, NULL); - if (r == 1) /* Return true. */ - v = Val_int (1); - else if (r == 0) /* Return false */ - v = Val_int (0); - else if (r == -1) /* Error or multiple matches */ - raise_error (t, "Augeas.exists"); - else - failwith ("Augeas.exists: bad return value"); - - CAMLreturn (v); -} - -/* val insert : t -> ?before:bool -> path -> string -> unit */ -CAMLprim value -ocaml_augeas_insert (value tv, value beforev, value pathv, value labelv) -{ - CAMLparam4 (tv, beforev, pathv, labelv); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - const char *label = String_val (labelv); - int before; - - before = beforev == Val_int (0) ? 0 : Int_val (Field (beforev, 0)); - - if (aug_insert (t, path, label, before) == -1) - raise_error (t, "Augeas.insert"); - - CAMLreturn (Val_unit); -} - -/* val rm : t -> path -> int */ -CAMLprim value -ocaml_augeas_rm (value tv, value pathv) -{ - CAMLparam2 (tv, pathv); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - int r; - - r = aug_rm (t, path); - if (r == -1) - raise_error (t, "Augeas.rm"); - - CAMLreturn (Val_int (r)); -} - -/* val matches : t -> path -> path list */ -CAMLprim value -ocaml_augeas_match (value tv, value pathv) -{ - CAMLparam2 (tv, pathv); - CAMLlocal3 (rv, v, cons); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - char **matches; - int r, i; - - r = aug_match (t, path, &matches); - if (r == -1) - raise_error (t, "Augeas.matches"); - - /* Copy the paths to a list. */ - rv = Val_int (0); - for (i = 0; i < r; ++i) { - v = caml_copy_string (matches[i]); - free (matches[i]); - cons = caml_alloc (2, 0); - Field (cons, 1) = rv; - Field (cons, 0) = v; - rv = cons; - } - - free (matches); - - CAMLreturn (rv); -} - -/* val count_matches : t -> path -> int */ -CAMLprim value -ocaml_augeas_count_matches (value tv, value pathv) -{ - CAMLparam2 (tv, pathv); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - int r; - - r = aug_match (t, path, NULL); - if (r == -1) - raise_error (t, "Augeas.count_matches"); - - CAMLreturn (Val_int (r)); -} - -/* val save : t -> unit */ -CAMLprim value -ocaml_augeas_save (value tv) -{ - CAMLparam1 (tv); - augeas_t t = Augeas_t_val (tv); - - if (aug_save (t) == -1) - raise_error (t, "Augeas.save"); - - CAMLreturn (Val_unit); -} - -/* val load : t -> unit */ -CAMLprim value -ocaml_augeas_load (value tv) -{ - CAMLparam1 (tv); - augeas_t t = Augeas_t_val (tv); - - if (aug_load (t) == -1) - raise_error (t, "Augeas.load"); - - CAMLreturn (Val_unit); -} - -/* val set : t -> -> path -> value option -> unit */ -CAMLprim value -ocaml_augeas_set (value tv, value pathv, value valuev) -{ - CAMLparam3 (tv, pathv, valuev); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - const char *val; - - val = - valuev == Val_int (0) - ? NULL - : String_val (Field (valuev, 0)); - - if (aug_set (t, path, val) == -1) - raise_error (t, "Augeas.set"); - - CAMLreturn (Val_unit); -} - -/* val transform : t -> string -> string -> transform_mode -> unit */ -CAMLprim value -ocaml_augeas_transform (value tv, value lensv, value filev, value modev) -{ - CAMLparam4 (tv, lensv, filev, modev); - augeas_t t = Augeas_t_val (tv); - const char *lens = String_val (lensv); - const char *file = String_val (filev); - const int excl = Int_val (modev) == 1 ? 1 : 0; - - if (aug_transform (t, lens, file, excl) == -1) - raise_error (t, "Augeas.transform"); - - CAMLreturn (Val_unit); -} - -/* val source : t -> path -> path option */ -CAMLprim value -ocaml_augeas_source (value tv, value pathv) -{ -#ifdef HAVE_AUG_SOURCE - CAMLparam2 (tv, pathv); - CAMLlocal2 (optv, v); - augeas_t t = Augeas_t_val (tv); - const char *path = String_val (pathv); - char *file_path; - int r; - - r = aug_source (t, path, &file_path); - if (r == 0) { - if (file_path) { /* Return Some file_path */ - v = caml_copy_string (file_path); - optv = caml_alloc (1, 0); - Field (optv, 0) = v; - free (file_path); - } else /* Return None */ - optv = Val_int (0); - } - else /* Error */ - raise_error (t, "Augeas.source"); - - CAMLreturn (optv); -#else - caml_failwith ("Augeas.source: function not implemented"); -#endif -} diff --git a/common/mlaugeas/augeas.README b/common/mlaugeas/augeas.README deleted file mode 100644 index 938dfd255..000000000 --- a/common/mlaugeas/augeas.README +++ /dev/null @@ -1,8 +0,0 @@ -The files augeas-c.c, augeas.ml and augeas.mli come from the -ocaml-augeas library: - - http://git.annexia.org/?p=ocaml-augeas.git - -which is released under a compatible license. We try to keep them -identical, so if you make changes to these files then you must also -submit the changes to ocaml-augeas, and vice versa. \ No newline at end of file diff --git a/common/mlaugeas/augeas.ml b/common/mlaugeas/augeas.ml deleted file mode 100644 index a2d345d7a..000000000 --- a/common/mlaugeas/augeas.ml +++ /dev/null @@ -1,85 +0,0 @@ -(* Augeas OCaml bindings - * Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $Id: augeas.ml,v 1.2 2008/05/06 10:48:20 rjones Exp $ - *) - -type t - -type flag = - | AugSaveBackup - | AugSaveNewFile - | AugTypeCheck - | AugNoStdinc - | AugSaveNoop - | AugNoLoad - -type error_code = - | AugErrInternal - | AugErrPathX - | AugErrNoMatch - | AugErrMMatch - | AugErrSyntax - | AugErrNoLens - | AugErrMXfm - | AugErrNoSpan - | AugErrMvDesc - | AugErrCmdRun - | AugErrBadArg - | AugErrLabel - | AugErrCpDesc - | AugErrUnknown of int - -type transform_mode = - | Include - | Exclude - -exception Error of error_code * string * string * string - -type path = string - -type value = string - -external create : string -> string option -> flag list -> t - = "ocaml_augeas_create" -external close : t -> unit - = "ocaml_augeas_close" -external get : t -> path -> value option - = "ocaml_augeas_get" -external exists : t -> path -> bool - = "ocaml_augeas_exists" -external insert : t -> ?before:bool -> path -> string -> unit - = "ocaml_augeas_insert" -external rm : t -> path -> int - = "ocaml_augeas_rm" -external matches : t -> path -> path list - = "ocaml_augeas_match" -external count_matches : t -> path -> int - = "ocaml_augeas_count_matches" -external save : t -> unit - = "ocaml_augeas_save" -external load : t -> unit - = "ocaml_augeas_load" -external set : t -> path -> value option -> unit - = "ocaml_augeas_set" -external transform : t -> string -> string -> transform_mode -> unit - = "ocaml_augeas_transform" -external source : t -> path -> path option - = "ocaml_augeas_source" - -let () = - Callback.register_exception "Augeas.Error" (Error (AugErrInternal, "", "", "")) diff --git a/common/mlaugeas/augeas.mli b/common/mlaugeas/augeas.mli deleted file mode 100644 index dfada4a27..000000000 --- a/common/mlaugeas/augeas.mli +++ /dev/null @@ -1,134 +0,0 @@ -(** Augeas OCaml bindings *) -(* Copyright (C) 2008 Red Hat Inc., Richard W.M. Jones - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library 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 - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - * - * $Id: augeas.mli,v 1.2 2008/05/06 10:48:20 rjones Exp $ - *) - -type t - (** Augeas library handle. *) - -type flag = - | AugSaveBackup (** Rename original with .augsave *) - | AugSaveNewFile (** Save changes to .augnew *) - | AugTypeCheck (** Type-check lenses *) - | AugNoStdinc - | AugSaveNoop - | AugNoLoad - (** Flags passed to the {!create} function. *) - -type error_code = - | AugErrInternal (** Internal error (bug) *) - | AugErrPathX (** Invalid path expression *) - | AugErrNoMatch (** No match for path expression *) - | AugErrMMatch (** Too many matches for path expression *) - | AugErrSyntax (** Syntax error in lens file *) - | AugErrNoLens (** Lens lookup failed *) - | AugErrMXfm (** Multiple transforms *) - | AugErrNoSpan (** No span for this node *) - | AugErrMvDesc (** Cannot move node into its descendant *) - | AugErrCmdRun (** Failed to execute command *) - | AugErrBadArg (** Invalid argument in funcion call *) - | AugErrLabel (** Invalid label *) - | AugErrCpDesc (** Cannot copy node into its descendant *) - | AugErrUnknown of int - (** Possible error codes. *) - -type transform_mode = - | Include - | Exclude - (** The operation mode for the {!transform} function. *) - -exception Error of error_code * string * string * string - (** This exception is thrown when the underlying Augeas library - returns an error. The tuple represents: - - the Augeas error code - - the ocaml-augeas error string - - the human-readable explanation of the Augeas error, if available - - a string with details of the Augeas error - *) - -type path = string - (** A path expression. - - Note in future we may replace this with a type-safe path constructor. *) - -type value = string - (** A value. *) - -val create : string -> string option -> flag list -> t - (** [create root loadpath flags] creates an Augeas handle. - - [root] is a file system path describing the location - of the configuration files. - - [loadpath] is an optional colon-separated list of directories - which are searched for schema definitions. - - [flags] is a list of flags. *) - -val close : t -> unit - (** [close handle] closes the handle. - - You don't need to close handles explicitly with this function: - they will be finalized eventually by the garbage collector. - However calling this function frees up any resources used by the - underlying Augeas library immediately. - - Do not use the handle after closing it. *) - -val get : t -> path -> value option - (** [get t path] returns the value at [path], or [None] if there - is no value. *) - -val exists : t -> path -> bool - (** [exists t path] returns true iff there is a value at [path]. *) - -val insert : t -> ?before:bool -> path -> string -> unit - (** [insert t ?before path label] inserts [label] as a sibling - of [path]. By default it is inserted after [path], unless - [~before:true] is specified. *) - -val rm : t -> path -> int - (** [rm t path] removes all nodes matching [path]. - - Returns the number of nodes removed (which may be 0). *) - -val matches : t -> path -> path list - (** [matches t path] returns a list of path expressions - of all nodes matching [path]. *) - -val count_matches : t -> path -> int - (** [count_matches t path] counts the number of nodes matching - [path] but does not return them (see {!matches}). *) - -val save : t -> unit - (** [save t] saves all pending changes to disk. *) - -val load : t -> unit - (** [load t] loads files into the tree. *) - -val set : t -> path -> value option -> unit - (** [set t path] sets [value] as new value at [path]. *) - -val transform : t -> string -> string -> transform_mode -> unit - (** [transform t lens file mode] adds or removes (depending on - [mode]) the transformation of the specified [lens] for [file]. *) - -val source : t -> path -> path option - (** [source t path] returns the path to the node representing the - file to which [path] belongs, or [None] if [path] does not - represent any file. *) diff --git a/common/mlcustomize/Makefile.am b/common/mlcustomize/Makefile.am deleted file mode 100644 index 149a76175..000000000 --- a/common/mlcustomize/Makefile.am +++ /dev/null @@ -1,184 +0,0 @@ -# libguestfs OCaml virt-customize common code -# Copyright (C) 2011-2019 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 $(top_srcdir)/subdir-rules.mk - -EXTRA_DIST = \ - $(generator_built) \ - $(SOURCES_MLI) \ - $(SOURCES_ML) \ - $(SOURCES_C) \ - test-firstboot.sh \ - test-selinuxrelabel.sh - -# Note: So that I don't have to move many modules from virt-customize -# to here, we don't compile customize_cmdline.ml into the mlcustomize -# library. Instead virt-customize links to these files. They are -# only located here because they have to be placed in common/ because -# they are generated (since the repository split). -generator_built = \ - customize_cmdline.mli \ - customize_cmdline.ml \ - customize-options.pod \ - customize-synopsis.pod - -SOURCES_MLI = \ - firstboot.mli \ - SELinux_relabel.mli - -SOURCES_ML = \ - firstboot.ml \ - SELinux_relabel.ml - -if HAVE_OCAML - -# We pretend that we're building a C library. automake handles the -# compilation of the C sources for us. At the end we take the C -# objects and OCaml objects and link them into the OCaml library. -# This C library is never used. - -noinst_LIBRARIES = libmlcustomize.a - -if !HAVE_OCAMLOPT -MLCUSTOMIZE_CMA = mlcustomize.cma -else -MLCUSTOMIZE_CMA = mlcustomize.cmxa -endif - -noinst_DATA = $(MLCUSTOMIZE_CMA) - -libmlcustomize_a_SOURCES = dummy.c -libmlcustomize_a_CPPFLAGS = \ - -DCAML_NAME_SPACE \ - -I. \ - -I$(top_builddir) \ - -I$(top_srcdir)/gnulib/lib -I$(top_builddir)/gnulib/lib \ - -I$(shell $(OCAMLC) -where) \ - -I$(top_srcdir)/common/utils \ - -I$(top_srcdir)/lib \ - -I$(top_srcdir)/common/mlstdutils \ - -I$(top_srcdir)/common/mlgettext \ - -I$(top_srcdir)/common/mlpcre \ - -I$(top_srcdir)/common/mltools -libmlcustomize_a_CFLAGS = \ - $(WARN_CFLAGS) $(WERROR_CFLAGS) \ - -fPIC - -BOBJECTS = $(SOURCES_ML:.ml=.cmo) -XOBJECTS = $(BOBJECTS:.cmo=.cmx) - -# -I $(top_builddir)/lib/.libs is a hack which forces corresponding -L -# option to be passed to gcc, so we don't try linking against an -# installed copy of libguestfs. -OCAMLPACKAGES = \ - -package str,unix \ - -I $(top_builddir)/common/utils/.libs \ - -I $(top_builddir)/lib/.libs \ - -I $(top_builddir)/gnulib/lib/.libs \ - -I $(top_builddir)/ocaml \ - -I $(top_builddir)/common/mlstdutils \ - -I $(top_builddir)/common/mlgettext \ - -I $(top_builddir)/common/mlpcre \ - -I $(top_builddir)/common/mltools \ - -I $(builddir) -OCAMLPACKAGES_TESTS = $(MLCUSTOMIZE_CMA) -if HAVE_OCAML_PKG_GETTEXT -OCAMLPACKAGES += -package gettext-stub -endif - -OCAMLCLIBS = \ - -lutils \ - $(LIBINTL) \ - -lgnu - -OCAMLFLAGS = $(OCAML_FLAGS) $(OCAML_WARN_ERROR) -ccopt '$(CFLAGS)' - -if !HAVE_OCAMLOPT -OBJECTS = $(BOBJECTS) -else -OBJECTS = $(XOBJECTS) -endif - -libmlcustomize_a_DEPENDENCIES = $(OBJECTS) - -$(MLCUSTOMIZE_CMA): $(OBJECTS) libmlcustomize.a - $(OCAMLFIND) mklib $(OCAMLPACKAGES) \ - $(OBJECTS) $(libmlcustomize_a_OBJECTS) -o mlcustomize - -# Tests. - -TESTS_ENVIRONMENT = $(top_builddir)/run --test - -TESTS = - -if ENABLE_APPLIANCE -TESTS += \ - $(SLOW_TESTS) -endif - -check-valgrind: - $(MAKE) VG="@VG@" check - -# Slow tests of virt-customize functionality in real guests. - -SLOW_TESTS = \ - $(firstboot_test_scripts) \ - test-selinuxrelabel.sh - -check-slow: - $(MAKE) check TESTS="$(SLOW_TESTS)" SLOW=1 - -firstboot_test_scripts := \ - test-firstboot-rhel-4.9.sh \ - test-firstboot-rhel-5.11.sh \ - test-firstboot-rhel-6.8.sh \ - test-firstboot-rhel-7.2.sh \ - test-firstboot-debian-6.sh \ - test-firstboot-debian-7.sh \ - test-firstboot-debian-8.sh \ - test-firstboot-fedora-26.sh \ - test-firstboot-fedora-27.sh \ - test-firstboot-ubuntu-10.04.sh \ - test-firstboot-ubuntu-12.04.sh \ - test-firstboot-ubuntu-14.04.sh \ - test-firstboot-ubuntu-16.04.sh \ - test-firstboot-ubuntu-18.04.sh \ - test-firstboot-windows-6.2-server.sh \ - test-firstboot-windows-6.3-server.sh \ - test-firstboot-windows-10.0-server.sh -# Firstboot is known-broken on RHEL 3: -# test-firstboot-rhel-3.9.sh - -test-firstboot-%.sh: - rm -f $@ $@-t - f=`echo "$@" | $(SED) 's/test-firstboot-\(.*\).sh/\1/'`; \ - echo 'script=$@ exec $$srcdir/test-firstboot.sh' "$$f" > $@-t - chmod 0755 $@-t - mv $@-t $@ - -CLEANFILES += \ - $(firstboot_test_scripts) \ - firstboot-*.img - -# Dependencies. -.depend: $(srcdir)/*.mli $(srcdir)/*.ml - $(top_builddir)/ocaml-dep.sh $^ --include .depend - -endif - -.PHONY: docs diff --git a/common/mlcustomize/SELinux_relabel.ml b/common/mlcustomize/SELinux_relabel.ml deleted file mode 100644 index 44995df6b..000000000 --- a/common/mlcustomize/SELinux_relabel.ml +++ /dev/null @@ -1,92 +0,0 @@ -(* virt-customize - * Copyright (C) 2016 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. - *) - -open Std_utils -open Tools_utils -open Common_gettext.Gettext - -open Printf - -module G = Guestfs - -(* Simple reimplementation of Array.mem, available only with OCaml >= 4.03. *) -let array_find a l = - List.mem a (Array.to_list l) - -let relabel (g : G.guestfs) = - (* Is the guest using SELinux? *) - if g#is_file ~followsymlinks:true "/usr/sbin/load_policy" && - g#is_file ~followsymlinks:true "/etc/selinux/config" then ( - (* Is setfiles / SELinux relabelling functionality available? *) - if g#feature_available [| "selinuxrelabel" |] then ( - (* Use Augeas to parse /etc/selinux/config. *) - g#aug_init "/" (16+32) (* AUG_SAVE_NOOP | AUG_NO_LOAD *); - (* See: https://bugzilla.redhat.com/show_bug.cgi?id=975412#c0 *) - ignore (g#aug_rm "/augeas/load/*[\"/etc/selinux/config/\" !~ regexp('^') + glob(incl) + regexp('/.*')]"); - g#aug_load (); - debug_augeas_errors g; - - (* Get the SELinux policy name, eg. "targeted", "minimum". - * Use "targeted" if not specified, just like libselinux does. - *) - let policy = - let config_path = "/files/etc/selinux/config" in - let selinuxtype_path = config_path ^ "/SELINUXTYPE" in - let keys = g#aug_ls config_path in - if array_find selinuxtype_path keys then - g#aug_get selinuxtype_path - else - "targeted" in - - g#aug_close (); - - (* Get the spec file name. *) - let specfile = - sprintf "/etc/selinux/%s/contexts/files/file_contexts" policy in - - (* RHEL 6.2 - 6.5 had a malformed specfile that contained the - * invalid regular expression "/var/run/spice-vdagentd.\pid" - * (instead of "\.p"). This stops setfiles from working on - * the guest. - * - * Because an SELinux relabel writes all over the filesystem, - * it seems reasonable to fix this problem in the specfile - * at the same time. (RHBZ#1374232) - *) - if g#grep ~fixed:true "vdagentd.\\pid" specfile <> [||] then ( - debug "fixing invalid regular expression in %s" specfile; - let old_specfile = specfile ^ "~" in - g#mv specfile old_specfile; - let content = g#read_file old_specfile in - let content = - String.replace content "vdagentd.\\pid" "vdagentd\\.pid" in - g#write specfile content; - g#copy_attributes ~all:true old_specfile specfile - ); - - (* Relabel everything. *) - g#selinux_relabel ~force:true specfile "/"; - - (* If that worked, we don't need to autorelabel. *) - g#rm_f "/.autorelabel" - ) - else ( - (* SELinux guest, but not SELinux host. Fallback to this. *) - g#touch "/.autorelabel" - ) - ) diff --git a/common/mlcustomize/SELinux_relabel.mli b/common/mlcustomize/SELinux_relabel.mli deleted file mode 100644 index 7b4f7ff26..000000000 --- a/common/mlcustomize/SELinux_relabel.mli +++ /dev/null @@ -1,29 +0,0 @@ -(* virt-customize - * Copyright (C) 2016 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. - *) - -(** SELinux-relabel the filesystem. *) - -val relabel : Guestfs.guestfs -> unit -(** Relabel the mounted guestfs filesystem using the current SELinux - policy that applies to the guest. - - If the guest does not look like it uses SELinux, this does nothing. - - In case relabelling is not possible (since it is an optional - feature which requires the setfiles(8) program), instead we - fall back to touching [/.autorelabel]. *) diff --git a/common/mlcustomize/customize-options.pod b/common/mlcustomize/customize-options.pod deleted file mode 100644 index 1c4fcb213..000000000 --- a/common/mlcustomize/customize-options.pod +++ /dev/null @@ -1,406 +0,0 @@ -=begin comment - -libguestfs generated file - WARNING: THIS FILE IS GENERATED FROM THE FOLLOWING FILES: - generator/customize.ml - and from the code in the generator/ subdirectory. - ANY CHANGES YOU MAKE TO THIS FILE WILL BE LOST. - - Copyright (C) 2009-2019 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. - -=end comment - -=over 4 - -=item B<--append-line> FILE:LINE - -Append a single line of text to the C. If the file does not already -end with a newline, then one is added before the appended -line. Also a newline is added to the end of the C string -automatically. - -For example (assuming ordinary shell quoting) this command: - - --append-line '/etc/hosts:10.0.0.1 foo' - -will add either C<10.0.0.1 foo⏎> or C<⏎10.0.0.1 foo⏎> to -the file, the latter only if the existing file does not -already end with a newline. - -C<⏎> represents a newline character, which is guessed by -looking at the existing content of the file, so this command -does the right thing for files using Unix or Windows line endings. -It also works for empty or non-existent files. - -To insert several lines, use the same option several times: - - --append-line '/etc/hosts:10.0.0.1 foo' - --append-line '/etc/hosts:10.0.0.2 bar' - -To insert a blank line before the appended line, do: - - --append-line '/etc/hosts:' - --append-line '/etc/hosts:10.0.0.1 foo' - -=item B<--chmod> PERMISSIONS:FILE - -Change the permissions of C to C. - -I: C by default would be decimal, unless you prefix -it with C<0> to get octal, ie. use C<0700> not C<700>. - -=item B<--commands-from-file> FILENAME - -Read the customize commands from a file, one (and its arguments) -each line. - -Each line contains a single customization command and its arguments, -for example: - - delete /some/file - install some-package - password some-user:password:its-new-password - -Empty lines are ignored, and lines starting with C<#> are comments -and are ignored as well. Furthermore, arguments can be spread across -multiple lines, by adding a C<\> (continuation character) at the of -a line, for example - - edit /some/file:\ - s/^OPT=.*/OPT=ok/ - -The commands are handled in the same order as they are in the file, -as if they were specified as I<--delete /some/file> on the command -line. - -=item B<--copy> SOURCE:DEST - -Copy files or directories recursively inside the guest. - -Wildcards cannot be used. - -=item B<--copy-in> LOCALPATH:REMOTEDIR - -Copy local files or directories recursively into the disk image, -placing them in the directory C (which must exist). - -Wildcards cannot be used. - -=item B<--delete> PATH - -Delete a file from the guest. Or delete a directory (and all its -contents, recursively). - -You can use shell glob characters in the specified path. Be careful -to escape glob characters from the host shell, if that is required. -For example: - - virt-customize --delete '/var/log/*.log'. - -See also: I<--upload>, I<--scrub>. - -=item B<--edit> FILE:EXPR - -Edit C using the Perl expression C. - -Be careful to properly quote the expression to prevent it from -being altered by the shell. - -Note that this option is only available when Perl 5 is installed. - -See L. - -=item B<--firstboot> SCRIPT - -Install C