Plan for libguestfs 1.30
by Richard W.M. Jones
It has been a ludicrously long time (over 8 months) since the last
stable release of libguestfs. So I'd like to plan a new 1.30 release
soon.
Please follow-up if there are features / blockers / bugs that need to
be addressed for 1.30.
As usual, bugs which have "1.30" (without quotes) in the Devel
Whiteboard field in Bugzilla are nominated as blockers for the
release. You can see a list of those here [currently empty]:
https://bugzilla.redhat.com/buglist.cgi?bug_status=NEW&bug_status=ASSIGNE...
For a list of all bugs, go to:
https://bugzilla.redhat.com/buglist.cgi?component=libguestfs&product=Virt...
----------------------------------------------------------------------
It's also worth talking about what I'd like to do *after* 1.30 is out.
This includes:
- threading support
https://www.redhat.com/archives/libguestfs/2015-June/thread.html#00118
- external tests
https://www.redhat.com/archives/libguestfs/2014-October/thread.html#00042
While thread safety is oft talked about, it's external tests which I
consider to be the more important patch series, since it will allow us
to build and test libguestfs more easily and more comprehensively for
Fedora and RHEL. Unfortunately it's the most difficult and invasive
change of the two.
You may have your own ideas, if so follow up here.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
9 years
SELinux relabel API
by Richard W.M. Jones
[
I realized that we were discussing adding this feature, in various
private email, IRC, and this long bugzilla thread:
https://bugzilla.redhat.com/show_bug.cgi?id=1060423
That's not how we should do things. Let's discuss it on the
mailing list.
]
One thing that virt-customize/virt-sysprep/virt-builder have to do is
relabel SELinux guests.
What we do at the moment is run:
if load_policy && fixfiles restore; then
rm -f /.autorelabel
else
touch /.autorelabel
echo '%s: SELinux relabelling failed, will relabel at boot instead.'
fi
while chrooted into the guest (using the 'guestfs_sh' API).
This has a number of problems:
- It has to load the policy using 'load_policy', but this doesn't
work sometimes:
* RHEL 5 load_policy takes a parameter.
* Doesn't work if appliance kernel is significantly different from
guest kernel version, because the binary policy format changes
irregularly and is not backwards compatible.
* Requires the appliance [host] kernel to be compiled with
LSM/SELinux support.
- Touching /.autorelabel is often broken, eg. it's broken in Fedora 20
because of systemd (RHBZ#1049656).
- /etc/resolv.conf will not be relabelled if guestfs network is on,
because of resolv.conf shenanigans in libguestfs.git/daemon/command.c
- It requires running guest code, which we'd like to avoid.
What would be nice would be to have an API to just do this
relabelling. Libguestfs could change this API as required to handle
different guests.
Dan Walsh helpfully pointed out to us that we've been doing it wrong
all along :-) A much better way to relabel is to run:
setfiles /etc/selinux/targeted/contexts/files/file_contexts DIR
where 'file_contexts' is a file which contains the default labels for
files (a set of regexps), and 'DIR' is the directory at which
relabelling starts. Note that 'setfiles' would be the libguestfs
appliance binary, so no guest binary needs to be run.
A simple API could just look like this:
guestfs_selinux_relabel (g);
which would always use the 'targeted' policy from the guest, and
always start relabelling at the root. This would work fine for
virt-builder.
For Colin's requirements for Project Atomic, I suspect he will want to
be able to set the file_contexts file and the root directory, but I'll
leave him to describe what would be useful.
A couple of notes:
- I'd like to avoid baking in assumptions from the 'setfiles' command
as far as possible. libguestfs APIs last for many years and some
have caused us many years of regret (but that's our job) :-/
- Is it a good idea to tie this into inspection in some way -- for
example, inspection could provide us with the path to the current or
default SELinux policy.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-top is 'top' for virtual machines. Tiny program with many
powerful monitoring features, net stats, disk stats, logging, etc.
http://people.redhat.com/~rjones/virt-top
9 years
[PATCH] v2v: add --in-place mode
by Roman Kagan
In this mode, converting of the VM configuration, setting up the
rollback path for error cases, transforming the VM storage and so on is
taken care of by a third-party toolset, and virt-v2v is only supposed to
tune up the guest OS directly inside the source VM, to enable it to boot
and run under the input hypervisor.
Signed-off-by: Roman Kagan <rkagan(a)virtuozzo.com>
---
tests/guests/guests.xml.in | 16 +++++++
v2v/Makefile.am | 1 +
v2v/cmdline.ml | 7 +++-
v2v/test-v2v-in-place.sh | 81 +++++++++++++++++++++++++++++++++++
v2v/v2v.ml | 102 +++++++++++++++++++++++++++------------------
v2v/virt-v2v.pod | 17 ++++++++
6 files changed, 183 insertions(+), 41 deletions(-)
create mode 100755 v2v/test-v2v-in-place.sh
diff --git a/tests/guests/guests.xml.in b/tests/guests/guests.xml.in
index 8f7ac81..6f08b80 100644
--- a/tests/guests/guests.xml.in
+++ b/tests/guests/guests.xml.in
@@ -279,4 +279,20 @@
</devices>
</domain>
+ <domain type='test'>
+ <name>windows-overlay</name>
+ <memory>1048576</memory>
+ <os>
+ <type>hvm</type>
+ <boot dev='hd'/>
+ </os>
+ <devices>
+ <disk type='file' device='disk'>
+ <driver name='qemu' type='qcow2'/>
+ <source file='@abs_builddir(a)/windows-overlay.qcow2'/>
+ <target dev='vda' bus='virtio'/>
+ </disk>
+ </devices>
+ </domain>
+
</node>
diff --git a/v2v/Makefile.am b/v2v/Makefile.am
index 06da002..dae063c 100644
--- a/v2v/Makefile.am
+++ b/v2v/Makefile.am
@@ -232,6 +232,7 @@ TESTS += \
test-v2v-cdrom.sh \
test-v2v-i-ova.sh \
test-v2v-i-disk.sh \
+ test-v2v-in-place.sh \
test-v2v-machine-readable.sh \
test-v2v-networks-and-bridges.sh \
test-v2v-no-copy.sh \
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index eaf57dc..2a3224a 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -37,6 +37,7 @@ let parse_cmdline () =
let output_format = ref "" in
let output_name = ref "" in
let output_storage = ref "" in
+ let in_place = ref false in
let password_file = ref "" in
let print_source = ref false in
let qemu_boot = ref false in
@@ -160,6 +161,7 @@ let parse_cmdline () =
"-of", Arg.Set_string output_format, "raw|qcow2 " ^ s_"Set output format";
"-on", Arg.Set_string output_name, "name " ^ s_"Rename guest when converting";
"-os", Arg.Set_string output_storage, "storage " ^ s_"Set output storage location";
+ "--in-place", Arg.Set in_place, " " ^ s_"Only tune the guest in the input VM";
"--password-file", Arg.Set_string password_file, "file " ^ s_"Use password from file";
"--print-source", Arg.Set print_source, " " ^ s_"Print source and stop";
"--qemu-boot", Arg.Set qemu_boot, " " ^ s_"Boot in qemu (-o qemu only)";
@@ -226,6 +228,7 @@ read the man page virt-v2v(1).
let output_mode = !output_mode in
let output_name = match !output_name with "" -> None | s -> Some s in
let output_storage = !output_storage in
+ let in_place = !in_place in
let password_file = match !password_file with "" -> None | s -> Some s in
let print_source = !print_source in
let qemu_boot = !qemu_boot in
@@ -305,6 +308,8 @@ read the man page virt-v2v(1).
Input_ova.input_ova filename in
(* Parse the output mode. *)
+ if output_mode <> `Not_set && in_place then
+ error (f_"-o and --in-place cannot be used at the same time");
let output =
match output_mode with
| `Glance ->
@@ -386,5 +391,5 @@ read the man page virt-v2v(1).
input, output,
debug_gc, debug_overlays, do_copy, network_map, no_trim,
- output_alloc, output_format, output_name,
+ output_alloc, output_format, output_name, in_place,
print_source, root_choice
diff --git a/v2v/test-v2v-in-place.sh b/v2v/test-v2v-in-place.sh
new file mode 100755
index 0000000..c19707e
--- /dev/null
+++ b/v2v/test-v2v-in-place.sh
@@ -0,0 +1,81 @@
+#!/bin/bash -
+# libguestfs virt-v2v test script
+# Copyright (C) 2014 Red Hat Inc.
+# Copyright (C) 2015 Parallels IP Holdings GmbH.
+#
+# 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.
+
+# Test --in-place.
+
+unset CDPATH
+export LANG=C
+set -e
+
+if [ -n "$SKIP_TEST_V2V_IN_PLACE_SH" ]; then
+ echo "$0: test skipped because environment variable is set"
+ exit 77
+fi
+
+if [ "$(guestfish get-backend)" = "uml" ]; then
+ echo "$0: test skipped because UML backend does not support network"
+ exit 77
+fi
+
+# You shouldn't be running the tests as root anyway, but in this case
+# it's especially bad because we don't want to start creating guests
+# or storage pools in the system namespace.
+if [ "$(id -u)" -eq 0 ]; then
+ echo "$0: test skipped because you're running tests as root. Don't do that!"
+ exit 77
+fi
+
+guests_dir="$(cd $(dirname $0)/../tests/guests && pwd)"
+libvirt_uri="test://$guests_dir/guests.xml"
+
+f="$guests_dir/windows.img"
+if ! test -f $f || ! test -s $f; then
+ echo "$0: test skipped because phony Windows image was not created"
+ exit 77
+fi
+
+virt_tools_data_dir=${VIRT_TOOLS_DATA_DIR:-/usr/share/virt-tools}
+if ! test -r $virt_tools_data_dir/rhsrvany.exe; then
+ echo "$0: test skipped because rhsrvany.exe is not installed"
+ exit 77
+fi
+
+fo="$guests_dir/windows-overlay.qcow2"
+rm -f $fo
+qemu-img create -f qcow2 -b $f -o compat=1.1,backing_fmt=raw $fo
+md5="$(md5sum $f)"
+
+$VG virt-v2v --debug-gc \
+ -i libvirt -ic "$libvirt_uri" windows-overlay \
+ --in-place
+
+# Test some aspects of the target disk image.
+guestfish --ro -a $fo -i <<EOF
+ is-dir "/Program Files/Red Hat/Firstboot"
+ is-file "/Program Files/Red Hat/Firstboot/firstboot.bat"
+ is-dir "/Program Files/Red Hat/Firstboot/scripts"
+ is-dir "/Windows/Drivers/VirtIO"
+EOF
+
+
+# Test the base image remained untouched
+test "$md5" = "$(md5sum $f)"
+
+# Clean up.
+rm -r $fo
diff --git a/v2v/v2v.ml b/v2v/v2v.ml
index 242f129..b744056 100644
--- a/v2v/v2v.ml
+++ b/v2v/v2v.ml
@@ -47,7 +47,8 @@ let rec main () =
(* Handle the command line. *)
let input, output,
debug_gc, debug_overlays, do_copy, network_map, no_trim,
- output_alloc, output_format, output_name, print_source, root_choice =
+ output_alloc, output_format, output_name, in_place, print_source,
+ root_choice =
Cmdline.parse_cmdline () in
(* Print the version, easier than asking users to tell us. *)
@@ -117,52 +118,70 @@ let rec main () =
) nics in
{ source with s_nics = nics } in
- (* Create a qcow2 v3 overlay to protect the source image(s). There
- * is a specific reason to use the newer qcow2 variant: Because the
- * L2 table can store zero clusters efficiently, and because
- * discarded blocks are stored as zero clusters, this should allow us
- * to fstrim/blkdiscard and avoid copying significant parts of the
- * data over the wire.
- *)
- message (f_"Creating an overlay to protect the source from being modified");
let overlay_dir = (new Guestfs.guestfs ())#get_cachedir () in
- let overlays =
- List.map (
- fun ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
- let overlay_file =
- Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
- unlink_on_exit overlay_file;
-
- let options =
- "compat=1.1" ^
- (match format with None -> ""
- | Some fmt -> ",backing_fmt=" ^ fmt) in
- let cmd =
- sprintf "qemu-img create -q -f qcow2 -b %s -o %s %s"
- (quote qemu_uri) (quote options) overlay_file in
- if verbose () then printf "%s\n%!" cmd;
- if Sys.command cmd <> 0 then
- error (f_"qemu-img command failed, see earlier errors");
-
- (* Sanity check created overlay (see below). *)
- if not ((new G.guestfs ())#disk_has_backing_file overlay_file) then
- error (f_"internal error: qemu-img did not create overlay with backing file");
-
- overlay_file, source
- ) source.s_disks in
+ let overlays = (
+ if not in_place then (
+ (* Create a qcow2 v3 overlay to protect the source image(s). There
+ * is a specific reason to use the newer qcow2 variant: Because the
+ * L2 table can store zero clusters efficiently, and because
+ * discarded blocks are stored as zero clusters, this should allow us
+ * to fstrim/blkdiscard and avoid copying significant parts of the
+ * data over the wire.
+ *)
+ message (f_"Creating an overlay to protect the source from being modified");
+ List.map (
+ fun ({ s_qemu_uri = qemu_uri; s_format = format } as source) ->
+ let overlay_file =
+ Filename.temp_file ~temp_dir:overlay_dir "v2vovl" ".qcow2" in
+ unlink_on_exit overlay_file;
+
+ let options =
+ "compat=1.1" ^
+ (match format with None -> ""
+ | Some fmt -> ",backing_fmt=" ^ fmt) in
+ let cmd =
+ sprintf "qemu-img create -q -f qcow2 -b %s -o %s %s"
+ (quote qemu_uri) (quote options) overlay_file in
+ if verbose () then printf "%s\n%!" cmd;
+ if Sys.command cmd <> 0 then
+ error (f_"qemu-img command failed, see earlier errors");
+
+ (* Sanity check created overlay (see below). *)
+ if not ((new G.guestfs ())#disk_has_backing_file overlay_file) then
+ error (f_"internal error: qemu-img did not create overlay with backing file");
+
+ overlay_file, source
+ ) source.s_disks
+ ) else []
+ ) in
(* Open the guestfs handle. *)
- message (f_"Opening the overlay");
+ if in_place then
+ message (f_"Opening the guest disks")
+ else
+ message (f_"Opening the overlay");
let g = new G.guestfs () in
if trace () then g#set_trace true;
if verbose () then g#set_verbose true;
g#set_network true;
- List.iter (
- fun (overlay_file, _) ->
- g#add_drive_opts overlay_file
- ~format:"qcow2" ~cachemode:"unsafe" ~discard:"besteffort"
- ~copyonread:true
- ) overlays;
+ if in_place then (
+ List.iter (
+ fun ({s_qemu_uri = qemu_uri; s_format = format}) ->
+ match format with
+ | None ->
+ g#add_drive_opts qemu_uri ~cachemode:"unsafe" ~discard:"besteffort"
+ | Some fmt ->
+ g#add_drive_opts qemu_uri ~format:fmt ~cachemode:"unsafe"
+ ~discard:"besteffort"
+ ) source.s_disks
+ ) else (
+ List.iter (
+ fun (overlay_file, _) ->
+ g#add_drive_opts overlay_file
+ ~format:"qcow2" ~cachemode:"unsafe" ~discard:"besteffort"
+ ~copyonread:true
+ ) overlays
+ );
g#launch ();
@@ -294,6 +313,9 @@ let rec main () =
g#shutdown ();
g#close ();
+ if in_place then
+ exit 0;
+
(* Does the guest require UEFI on the target? *)
message (f_"Checking if the guest needs BIOS or UEFI to boot");
let target_firmware =
diff --git a/v2v/virt-v2v.pod b/v2v/virt-v2v.pod
index ef2dee1..eda1cf7 100644
--- a/v2v/virt-v2v.pod
+++ b/v2v/virt-v2v.pod
@@ -9,6 +9,8 @@ virt-v2v - Convert a guest to use KVM
virt-v2v -ic vpx://vcenter.example.com/Datacenter/esxi vmware_guest \
-o rhev -os rhev.nfs:/export_domain --network rhevm
+ virt-v2v -ic qemu:///system qemu_guest --in-place
+
virt-v2v -i libvirtxml guest-domain.xml -o local -os /var/tmp
virt-v2v -i disk disk.img -o local -os /var/tmp
@@ -75,6 +77,9 @@ booting the guest directly in qemu (mainly for testing).
I<-o rhev> is used to write to a RHEV-M / oVirt target. I<-o vdsm>
is only used when virt-v2v runs under VDSM control.
+I<--in-place> instructs virt-v2v to customize the guest OS in the input
+virtual machine, instead of creating a new VM in the target hypervisor.
+
=head1 EXAMPLES
=head2 Convert from VMware vCenter server to local libvirt
@@ -518,6 +523,18 @@ C<root>.
You will get an error if virt-v2v is unable to mount/write to the
Export Storage Domain.
+=item B<--in-place>
+
+Do not create an output virtual machine in the target hypervisor.
+Instead, adjust the guest OS in the source VM to run in the input
+hypervisor.
+
+This mode is meant for integration with other toolsets, which take the
+responsibility of converting the VM configuration, providing for
+rollback in case of errors, transforming the storage, etc.
+
+Conflicts with all I<-o *> options.
+
=item B<--password-file> file
Instead of asking for password(s) interactively, pass the password
--
2.4.3
9 years, 2 months
[PATCH 0/4] v2v: simplify driver copying from virtio-win iso
by Roman Kagan
Libguestfs supports passing an ISO image as a source of virtio windows
drivers to v2v.
That support, however, looks too heavy-weight: in order to access those
drivers, a separate guestfs handle is created (and thus a new emulator
process is started), which runs until v2v completes.
This series attempts to make it simpler and lighter-weight, by making
the relevant code more local, and by hot-adding the image into the main
guestfs handle.
Roman Kagan (4):
v2v: drop useless forced gc
v2v: consolidate virtio-win file copying
v2v: copy virtio drivers without guestfs handle leak
v2v: reuse main guestfs for virtio win drivers iso
v2v/convert_windows.ml | 184 ++++++++++++++++++++--------------------
v2v/utils.ml | 224 ++++++++++++++++---------------------------------
v2v/v2v.ml | 8 --
3 files changed, 163 insertions(+), 253 deletions(-)
--
2.4.3
9 years, 2 months
ANNOUNCE: libguestfs & virt-v2v & virt-p2v RHEL 7.2 preview packages available
by Richard W.M. Jones
[The subject line isn't strictly correct, as virt-p2v packages aren't
available right now, but will be shortly]
If you are running RHEL 7.1 then you may be interested in trying out
the newer RHEL 7.2 preview versions of:
- libguestfs
- virt-v2v (Technical Preview in RHEL 7.1, Supported in RHEL 7.2)
- virt-p2v (Technical Preview in RHEL 7.2)
To install the preview repository, copy the attached file into
/etc/yum.repos.d/
Then use this command to update virt-v2v:
yum install virt-v2v libguestfs-tools-c libguestfs-xfs
To convert Windows guests you'll also need libguestfs-winsupport which
is finally available in RHN (V2VWIN channel) or you can get it from
http://people.redhat.com/~rjones/libguestfs-winsupport/
Please note these packages are *not* supported by Red Hat. If you
find bugs, please file them using the link below:
https://bugzilla.redhat.com/enter_bug.cgi?product=Red%20Hat%20Enterprise%...
To downgrade back to the RHEL 7.1 supported packages, delete
/etc/yum.repos.d/libguestfs-RHEL-7.2-preview.repo , uninstall
libguestfs, then reinstall libguestfs from RHN.
I have not tested these packages on CentOS 7.1, but they will probably
work there too, and if they don't then let me know.
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages. http://libguestfs.org
9 years, 3 months
missing btrfs subvol support
by Olaf Hering
Is btrfs subvol support failing just for me? Looks like nothing adds the
required '@/' string. virt-ls uses the first variant of the command:
><rescue> mount -vo subvol=var/spool,ro /dev/sda2 /sysroot/
[ 113.852047] BTRFS info (device sda2): disk space caching is enabled
[ 113.852869] BTRFS: has skinny extents
mount: mount(2) failed: No such file or directory
><rescue> mount -vo subvol=@var/spool,ro /dev/sda2 /sysroot/
[ 116.082642] BTRFS info (device sda2): disk space caching is enabled
[ 116.083476] BTRFS: has skinny extents
mount: mount(2) failed: No such file or directory
><rescue> mount -vo subvol=@/var/spool,ro /dev/sda2 /sysroot/
[ 123.995343] BTRFS info (device sda2): disk space caching is enabled
[ 123.996238] BTRFS: has skinny extents
mount: /dev/sda2 mounted on /sysroot.
><rescue> exit
fstab is:
UUID=d538a81f-9778-424d-96cc-e48dd2d4a323 swap swap defaults 0 0
UUID=65b72f12-eccb-4cf2-a4f4-9c4bb462456f / btrfs defaults 0 0
UUID=65b72f12-eccb-4cf2-a4f4-9c4bb462456f /var/spool btrfs subvol=@/var/spool 0 0
Olaf
9 years, 3 months
[PATCH v5 0/2] RFE: journal reader in guestfish
by Maros Zatko
There seems to be a minor issue when user wants to run it through pager (more)
and wants cancel it. User will end up with stuck guestfish until journal-view
transfers all journal items.
Output is configurable, it's the same format as virt-log has, since both
uses same code.
Maros Zatko (2):
cat: move get_journal_field to fish/journal.c
fish: add journal-view command (RHBZ#988100)
cat/Makefile.am | 1 +
cat/log.c | 114 ++--------------------------------------
fish/Makefile.am | 1 +
fish/journal.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++++
generator/Makefile.am | 6 ++-
generator/actions.ml | 22 ++++++++
generator/journal.ml | 97 ++++++++++++++++++++++++++++++++++
generator/main.ml | 3 ++
8 files changed, 272 insertions(+), 113 deletions(-)
create mode 100644 fish/journal.c
create mode 100644 generator/journal.ml
--
1.9.3
9 years, 3 months
[PATCH 1/2] mllib: add and use set_standard_options
by Pino Toscano
Introduce a new common helper to add the common options for libguestfs
tools (short/long options, version, verbose, trace), and sort them.
All the OCaml-based tools had these options already, so there are no
functional changes in the interface they provide.
The only difference is that now the options are always sorted, while
some tools didn't had them like that previously: because of this, a
couple of ditto markers (as descriptions) don't match what's above them
anymore, and thus their full description is put instead.
---
builder/cmdline.ml | 18 +-----------------
customize/customize_main.ml | 18 +-----------------
dib/cmdline.ml | 17 +----------------
get-kernel/get_kernel.ml | 12 ++----------
mllib/common_utils.ml | 19 +++++++++++++++++++
mllib/common_utils.mli | 6 ++++++
resize/resize.ml | 14 +++-----------
sparsify/cmdline.ml | 12 ++----------
sysprep/main.ml | 14 +-------------
v2v/cmdline.ml | 14 +++-----------
10 files changed, 39 insertions(+), 105 deletions(-)
diff --git a/builder/cmdline.ml b/builder/cmdline.ml
index 49435ae..1537208 100644
--- a/builder/cmdline.ml
+++ b/builder/cmdline.ml
@@ -126,8 +126,6 @@ let parse_cmdline () =
"--long", Arg.Unit list_set_long, " " ^ s_"Shortcut for --list-format short";
"--list-format", Arg.String list_set_format,
"short|long|json" ^ " " ^ s_"Set the format for --list (default: short)";
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
"-m", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size";
"--memsize", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size";
@@ -143,26 +141,12 @@ let parse_cmdline () =
"--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs";
"--source", Arg.String add_source, "URL" ^ " " ^ s_"Set source URL";
"--no-sync", Arg.Clear sync, " " ^ s_"Do not fsync output file on exit";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
] in
let customize_argspec, get_customize_ops = Customize_cmdline.argspec () in
let customize_argspec =
List.map (fun (spec, _, _) -> spec) customize_argspec in
let argspec = argspec @ customize_argspec in
- let argspec =
- let cmp (arg1, _, _) (arg2, _, _) =
- let arg1 = skip_dashes arg1 and arg2 = skip_dashes arg2 in
- compare (String.lowercase arg1) (String.lowercase arg2)
- in
- List.sort cmp argspec in
- let argspec = Arg.align argspec in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
let args = ref [] in
let anon_fun s = args := s :: !args in
diff --git a/customize/customize_main.ml b/customize/customize_main.ml
index 03c97e4..459e98a 100644
--- a/customize/customize_main.ml
+++ b/customize/customize_main.ml
@@ -85,8 +85,6 @@ let main () =
"--dryrun", Arg.Set dryrun, " " ^ s_"Perform a dry run";
"--dry-run", Arg.Set dryrun, " " ^ s_"Perform a dry run";
"--format", Arg.String set_format, s_"format" ^ " " ^ s_"Set format (default: auto)";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
"-m", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size";
"--memsize", Arg.Int set_memsize, "mb" ^ " " ^ s_"Set memory size";
"--network", Arg.Set network, " " ^ s_"Enable appliance network (default)";
@@ -94,27 +92,13 @@ let main () =
"-q", Arg.Unit set_quiet, " " ^ s_"Don't print log messages";
"--quiet", Arg.Unit set_quiet, " " ^ s_"Don't print log messages";
"--smp", Arg.Int set_smp, "vcpus" ^ " " ^ s_"Set number of vCPUs";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
] in
let customize_argspec, get_customize_ops =
Customize_cmdline.argspec () in
let customize_argspec =
List.map (fun (spec, _, _) -> spec) customize_argspec in
let argspec = argspec @ customize_argspec in
- let argspec =
- let cmp (arg1, _, _) (arg2, _, _) =
- let arg1 = skip_dashes arg1 and arg2 = skip_dashes arg2 in
- compare (String.lowercase arg1) (String.lowercase arg2)
- in
- List.sort cmp argspec in
- let argspec = Arg.align argspec in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
let anon_fun _ = raise (Arg.Bad (s_"extra parameter on the command line")) in
let usage_msg =
diff --git a/dib/cmdline.ml b/dib/cmdline.ml
index 2fe77da..e2f2ded 100644
--- a/dib/cmdline.ml
+++ b/dib/cmdline.ml
@@ -126,9 +126,6 @@ read the man page virt-dib(1).
extra_packages := List.rev (string_nsplit "," arg) @ !extra_packages in
let argspec = [
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
-
"-p", Arg.String append_element_path, "path" ^ " " ^ s_"Add new a elements location";
"--element-path", Arg.String append_element_path, "path" ^ " " ^ s_"Add new a elements location";
"--exclude-element", Arg.String append_excluded_element,
@@ -167,23 +164,11 @@ read the man page virt-dib(1).
" " ^ s_"Don't delete output file on failure";
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
- "-V", Arg.Unit print_version_and_exit, " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit, " " ^ s_"Display version and exit";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable libguestfs debugging messages";
- "--verbose", Arg.Unit set_verbose, " " ^ s_"Enable libguestfs debugging messages";
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
"--debug", Arg.Int set_debug, "level" ^ " " ^ s_"Set debug level";
"-B", Arg.Set_string basepath, "path" ^ " " ^ s_"Base path of diskimage-builder library";
] in
- let argspec =
- let cmp (arg1, _, _) (arg2, _, _) =
- let arg1 = skip_dashes arg1 and arg2 = skip_dashes arg2 in
- compare (String.lowercase arg1) (String.lowercase arg2)
- in
- List.sort cmp argspec in
- let argspec = Arg.align argspec in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
Arg.parse argspec append_element usage_msg;
diff --git a/get-kernel/get_kernel.ml b/get-kernel/get_kernel.ml
index 58193ab..8ca7ca0 100644
--- a/get-kernel/get_kernel.ml
+++ b/get-kernel/get_kernel.ml
@@ -53,7 +53,7 @@ let main () =
prefix := Some p in
let ditto = " -\"-" in
- let argspec = Arg.align [
+ let argspec = [
"-a", Arg.String set_file, s_"file" ^ " " ^ s_"Add disk image file";
"--add", Arg.String set_file, s_"file" ^ " " ^ s_"Add disk image file";
"-c", Arg.Set_string libvirturi, s_"uri" ^ " " ^ s_"Set libvirt URI";
@@ -61,22 +61,14 @@ let main () =
"-d", Arg.String set_domain, s_"domain" ^ " " ^ s_"Set libvirt guest name";
"--domain", Arg.String set_domain, s_"domain" ^ " " ^ s_"Set libvirt guest name";
"--format", Arg.Set_string format, s_"format" ^ " " ^ s_"Format of input disk";
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
"-o", Arg.Set_string output, s_"directory" ^ " " ^ s_"Output directory";
"--output", Arg.Set_string output, ditto;
"--unversioned-names", Arg.Set unversioned,
" " ^ s_"Use unversioned names for files";
"--prefix", Arg.String set_prefix, "prefix" ^ " " ^ s_"Prefix for files";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, ditto;
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit, ditto;
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
] in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
let anon_fun _ = raise (Arg.Bad (s_"extra parameter on the command line")) in
let usage_msg =
sprintf (f_"\
diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml
index 99d2098..2b7d88d 100644
--- a/mllib/common_utils.ml
+++ b/mllib/common_utils.ml
@@ -510,6 +510,25 @@ let display_long_options () =
) !long_options;
exit 0
+let set_standard_options argspec =
+ let argspec = [
+ "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
+ "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
+ "-V", Arg.Unit print_version_and_exit,
+ " " ^ s_"Display version and exit";
+ "--version", Arg.Unit print_version_and_exit,
+ " " ^ s_"Display version and exit";
+ "-v", Arg.Unit set_verbose, " " ^ s_"Enable libguestfs debugging messages";
+ "--verbose", Arg.Unit set_verbose, " " ^ s_"Enable libguestfs debugging messages";
+ "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
+ ] @ argspec in
+ let argspec =
+ let cmp (arg1, _, _) (arg2, _, _) = compare_command_line_args arg1 arg2 in
+ List.sort cmp argspec in
+ let argspec = Arg.align argspec in
+ long_options := argspec;
+ argspec
+
(* Compare two version strings intelligently. *)
let rex_numbers = Str.regexp "^\\([0-9]+\\)\\(.*\\)$"
let rex_letters = Str.regexp_case_fold "^\\([a-z]+\\)\\(.*\\)$"
diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli
index 9d1ee6a..5d93b53 100644
--- a/mllib/common_utils.mli
+++ b/mllib/common_utils.mli
@@ -122,6 +122,12 @@ val display_short_options : unit -> 'a
val display_long_options : unit -> 'a
(** Implements [--long-options]. *)
+val set_standard_options : (Arg.key * Arg.spec * Arg.doc) list -> (Arg.key * Arg.spec * Arg.doc) list
+(** Adds the standard libguestfs command line options to the specified ones,
+ sorting them, and setting [long_options] to them.
+
+ Returns the resulting options. *)
+
val compare_version : string -> string -> int
(** Compare two version strings. *)
diff --git a/resize/resize.ml b/resize/resize.ml
index 8ab14f7..f353158 100644
--- a/resize/resize.ml
+++ b/resize/resize.ml
@@ -189,7 +189,7 @@ let main () =
let sparse = ref true in
let ditto = " -\"-" in
- let argspec = Arg.align [
+ let argspec = [
"--align-first", Arg.Set_string align_first, s_"never|always|auto" ^ " " ^ s_"Align first partition (default: auto)";
"--alignment", Arg.Set_int alignment, s_"sectors" ^ " " ^ s_"Set partition alignment (default: 128 sectors)";
"--no-copy-boot-loader", Arg.Clear copy_boot_loader, " " ^ s_"Don't copy boot loader";
@@ -202,16 +202,14 @@ let main () =
"--no-extra-partition", Arg.Clear extra_partition, " " ^ s_"Don't create extra partition";
"--format", Arg.Set_string format, s_"format" ^ " " ^ s_"Format of input disk";
"--ignore", Arg.String (add ignores), s_"part" ^ " " ^ s_"Ignore partition";
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
"--lv-expand", Arg.String (add lv_expands), s_"lv" ^ " " ^ s_"Expand logical volume";
"--LV-expand", Arg.String (add lv_expands), s_"lv" ^ ditto;
"--lvexpand", Arg.String (add lv_expands), s_"lv" ^ ditto;
"--LVexpand", Arg.String (add lv_expands), s_"lv" ^ ditto;
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
"-n", Arg.Set dryrun, " " ^ s_"Don't perform changes";
+ "--dry-run", Arg.Set dryrun, " " ^ s_"Don't perform changes";
"--dryrun", Arg.Set dryrun, ditto;
- "--dry-run", Arg.Set dryrun, ditto;
"--ntfsresize-force", Arg.Set ntfsresize_force, " " ^ s_"Force ntfsresize";
"--output-format", Arg.Set_string output_format, s_"format" ^ " " ^ s_"Format of output disk";
"-q", Arg.Unit set_quiet, " " ^ s_"Don't print the summary";
@@ -220,14 +218,8 @@ let main () =
"--resize-force", Arg.String (add resizes_force), s_"part=size" ^ " " ^ s_"Forcefully resize partition";
"--shrink", Arg.String set_shrink, s_"part" ^ " " ^ s_"Shrink partition";
"--no-sparse", Arg.Clear sparse, " " ^ s_"Turn off sparse copying";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, ditto;
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit, ditto;
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
] in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
let disks = ref [] in
let anon_fun s = disks := s :: !disks in
let usage_msg =
diff --git a/sparsify/cmdline.ml b/sparsify/cmdline.ml
index b2a57c3..8cd26a4 100644
--- a/sparsify/cmdline.ml
+++ b/sparsify/cmdline.ml
@@ -55,7 +55,7 @@ let parse_cmdline () =
let zeroes = ref [] in
let ditto = " -\"-" in
- let argspec = Arg.align [
+ let argspec = [
"--check-tmpdir", Arg.String set_check_tmpdir, "ignore|..." ^ " " ^ s_"Check there is enough space in $TMPDIR";
"--compress", Arg.Set compress, " " ^ s_"Compressed output format";
"--convert", Arg.Set_string convert, s_"format" ^ " " ^ s_"Format of output disk (default: same as input)";
@@ -64,22 +64,14 @@ let parse_cmdline () =
"--ignore", Arg.String (add ignores), s_"fs" ^ " " ^ s_"Ignore filesystem";
"--in-place", Arg.Set in_place, " " ^ s_"Modify the disk image in-place";
"--inplace", Arg.Set in_place, ditto;
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
"-o", Arg.Set_string option, s_"option" ^ " " ^ s_"Add qemu-img options";
"-q", Arg.Unit set_quiet, " " ^ s_"Quiet output";
"--quiet", Arg.Unit set_quiet, ditto;
"--tmp", Arg.Set_string tmp, s_"block|dir|prebuilt:file" ^ " " ^ s_"Set temporary block device, directory or prebuilt file";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, ditto;
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit, ditto;
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
"--zero", Arg.String (add zeroes), s_"fs" ^ " " ^ s_"Zero filesystem";
] in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
let disks = ref [] in
let anon_fun s = disks := s :: !disks in
let usage_msg =
diff --git a/sysprep/main.ml b/sysprep/main.ml
index 8b71109..c9fe2ea 100644
--- a/sysprep/main.ml
+++ b/sysprep/main.ml
@@ -131,8 +131,6 @@ let main () =
"--enable", Arg.String set_enable, s_"operations" ^ " " ^ s_"Enable specific operations";
"--format", Arg.String set_format, s_"format" ^ " " ^ s_"Set format (default: auto)";
"--list-operations", Arg.Unit list_operations, " " ^ s_"List supported operations";
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
"--mount-options", Arg.Set_string mount_opts, s_"opts" ^ " " ^ s_"Set mount options (eg /:noatime;/var:rw,noatime)";
"--no-selinux-relabel", Arg.Unit (fun () -> ()),
" " ^ s_"Compatibility option, does nothing";
@@ -140,19 +138,9 @@ let main () =
"--operations", Arg.String set_operations, " " ^ s_"Enable/disable specific operations";
"-q", Arg.Unit set_quiet, " " ^ s_"Don't print log messages";
"--quiet", Arg.Unit set_quiet, " " ^ s_"Don't print log messages";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
] in
let args = basic_args @ Sysprep_operation.extra_args () in
- let args =
- List.sort (fun (a,_,_) (b,_,_) -> compare_command_line_args a b) args in
- let argspec = Arg.align args in
- long_options := argspec;
+ let argspec = set_standard_options args in
let anon_fun _ = raise (Arg.Bad (s_"extra parameter on the command line")) in
let usage_msg =
sprintf (f_"\
diff --git a/v2v/cmdline.ml b/v2v/cmdline.ml
index df65426..0a0349c 100644
--- a/v2v/cmdline.ml
+++ b/v2v/cmdline.ml
@@ -134,7 +134,7 @@ let parse_cmdline () =
String.concat "|" (Modules_list.output_modules ()) in
let ditto = " -\"-" in
- let argspec = Arg.align [
+ let argspec = [
"-b", Arg.String add_bridge, "in:out " ^ s_"Map bridge 'in' to 'out'";
"--bridge", Arg.String add_bridge, "in:out " ^ ditto;
"--debug-gc",Arg.Unit set_debug_gc, " " ^ s_"Debug GC and memory allocations";
@@ -146,8 +146,6 @@ let parse_cmdline () =
"-ic", Arg.Set_string input_conn, "uri " ^ s_"Libvirt URI";
"-if", Arg.Set_string input_format,
"format " ^ s_"Input format (for -i disk)";
- "--short-options", Arg.Unit display_short_options, " " ^ s_"List short options";
- "--long-options", Arg.Unit display_long_options, " " ^ s_"List long options";
"--machine-readable", Arg.Set machine_readable, " " ^ s_"Make output machine readable";
"-n", Arg.String add_network, "in:out " ^ s_"Map network 'in' to 'out'";
"--network", Arg.String add_network, "in:out " ^ ditto;
@@ -163,7 +161,7 @@ let parse_cmdline () =
"--print-source", Arg.Set print_source, " " ^ s_"Print source and stop";
"--qemu-boot", Arg.Set qemu_boot, " " ^ s_"Boot in qemu (-o qemu only)";
"-q", Arg.Unit set_quiet, " " ^ s_"Quiet output";
- "--quiet", Arg.Unit set_quiet, ditto;
+ "--quiet", Arg.Unit set_quiet, " " ^ s_"Quiet output";
"--root", Arg.String set_root_choice,"ask|... " ^ s_"How to choose root filesystem";
"--vdsm-image-uuid",
Arg.String add_vdsm_image_uuid, "uuid " ^ s_"Output image UUID(s)";
@@ -173,15 +171,9 @@ let parse_cmdline () =
Arg.Set_string vdsm_vm_uuid, "uuid " ^ s_"Output VM UUID";
"--vdsm-ovf-output",
Arg.Set_string vdsm_ovf_output, " " ^ s_"Output OVF file";
- "-v", Arg.Unit set_verbose, " " ^ s_"Enable debugging messages";
- "--verbose", Arg.Unit set_verbose, ditto;
- "-V", Arg.Unit print_version_and_exit,
- " " ^ s_"Display version and exit";
- "--version", Arg.Unit print_version_and_exit, ditto;
"--vmtype", Arg.Set_string vmtype, "server|desktop " ^ s_"Set vmtype (for RHEV)";
- "-x", Arg.Unit set_trace, " " ^ s_"Enable tracing of libguestfs calls";
] in
- long_options := argspec;
+ let argspec = set_standard_options argspec in
let args = ref [] in
let anon_fun s = args := s :: !args in
let usage_msg =
--
2.1.0
9 years, 3 months
[PATCH] customize: fix running commands on the same architecture
by Pino Toscano
Wrap the command around an heredoc only if setarch needs to be used;
otherwise the heredoc will not be run at all.
Fix commit d875346ad441d4762455ea1b41d57ad6174d9b63.
---
customize/customize_run.ml | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
diff --git a/customize/customize_run.ml b/customize/customize_run.ml
index 2283272..9d97522 100644
--- a/customize/customize_run.ml
+++ b/customize/customize_run.ml
@@ -70,18 +70,20 @@ let run (g : Guestfs.guestfs) root (ops : ops) =
) [ "http_proxy"; "https_proxy"; "ftp_proxy"; "no_proxy" ] in
let env_vars = String.concat "\n" env_vars ^ "\n" in
- let setarch =
+ let cmd =
match Config.host_cpu, guest_arch with
- | "x86_64", ("i386"|"i486"|"i586"|"i686") -> "setarch i686"
- | _ -> "" in
+ | "x86_64", ("i386"|"i486"|"i586"|"i686") ->
+ sprintf "setarch i686 <<\"__EOCMD\"
+%s
+__EOCMD
+" cmd
+ | _ -> cmd in
let cmd = sprintf "\
exec >>%s 2>&1
%s
-%s <<\"__EOCMD\"
%s
-__EOCMD
-" (quote logfile) env_vars setarch cmd in
+" (quote logfile) env_vars cmd in
if verbose () then printf "running command:\n%s\n%!" cmd;
try ignore (g#sh cmd)
--
2.1.0
9 years, 4 months
v2v: -i libvirtxml: Map empty network or bridge name to a default (RHBZ#1257895).
by Richard W.M. Jones
When importing from VMware via the libvirt driver, the libvirt driver
can add an empty source bridge name:
<interface type='bridge'>
<mac address='00:01:02:03:04:05:06'/>
<source bridge=''/>
</interface>
Replicate what we do on the -i ova path, and map these to "eth0",
"eth1" etc.
This also includes a bunch of changes to how we do xpath parsing to
make it type-safe.
Rich.
9 years, 4 months