summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--resize/progress.ml32
-rw-r--r--resize/progress.mli2
-rw-r--r--resize/progress_c.c10
-rw-r--r--resize/resize.ml30
-rw-r--r--resize/virt-resize.pod58
5 files changed, 109 insertions, 23 deletions
diff --git a/resize/progress.ml b/resize/progress.ml
index 00181727..0ae72a38 100644
--- a/resize/progress.ml
+++ b/resize/progress.ml
@@ -23,30 +23,32 @@ open Utils
module G = Guestfs
type progress_bar
-external progress_bar_init : unit -> progress_bar
+external progress_bar_init : machine_readable:bool -> progress_bar
= "virt_resize_progress_bar_init"
external progress_bar_reset : progress_bar -> unit
= "virt_resize_progress_bar_reset"
external progress_bar_set : progress_bar -> int64 -> int64 -> unit
= "virt_resize_progress_bar_set"
-(* Initialize the C mini library. *)
-let bar = progress_bar_init ()
+let set_up_progress_bar ?(machine_readable = false) (g : Guestfs.guestfs) =
+ (* Initialize the C mini library. *)
+ let bar = progress_bar_init ~machine_readable in
-(* Reset the progress bar before every libguestfs function. *)
-let enter_callback g event evh buf array =
- if event = G.EVENT_ENTER then
- progress_bar_reset bar
+ (* Reset the progress bar before every libguestfs function. *)
+ let enter_callback g event evh buf array =
+ if event = G.EVENT_ENTER then
+ progress_bar_reset bar
+ in
-(* A progress event: move the progress bar. *)
-let progress_callback g event evh buf array =
- if event = G.EVENT_PROGRESS && Array.length array >= 4 then (
- let position = array.(2)
- and total = array.(3) in
+ (* A progress event: move the progress bar. *)
+ let progress_callback g event evh buf array =
+ if event = G.EVENT_PROGRESS && Array.length array >= 4 then (
+ let position = array.(2)
+ and total = array.(3) in
- progress_bar_set bar position total
- )
+ progress_bar_set bar position total
+ )
+ in
-let set_up_progress_bar (g : Guestfs.guestfs) =
ignore (g#set_event_callback enter_callback [G.EVENT_ENTER]);
ignore (g#set_event_callback progress_callback [G.EVENT_PROGRESS])
diff --git a/resize/progress.mli b/resize/progress.mli
index 31deb09b..cd20e21a 100644
--- a/resize/progress.mli
+++ b/resize/progress.mli
@@ -16,4 +16,4 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*)
-val set_up_progress_bar : Guestfs.guestfs -> unit
+val set_up_progress_bar : ?machine_readable:bool -> Guestfs.guestfs -> unit
diff --git a/resize/progress_c.c b/resize/progress_c.c
index dddf7870..52e653be 100644
--- a/resize/progress_c.c
+++ b/resize/progress_c.c
@@ -53,18 +53,22 @@ static struct custom_operations progress_bar_custom_operations = {
};
value
-virt_resize_progress_bar_init (value unitv)
+virt_resize_progress_bar_init (value machine_readablev)
{
- CAMLparam1 (unitv);
+ CAMLparam1 (machine_readablev);
CAMLlocal1 (barv);
struct progress_bar *bar;
+ int machine_readable = Bool_val (machine_readablev);
+ unsigned flags = 0;
/* XXX Have to do this to get nl_langinfo to work properly. However
* we should really only call this from main.
*/
setlocale (LC_ALL, "");
- bar = progress_bar_init (0);
+ if (machine_readable)
+ flags |= PROGRESS_BAR_MACHINE_READABLE;
+ bar = progress_bar_init (flags);
if (bar == NULL)
caml_raise_out_of_memory ();
diff --git a/resize/resize.ml b/resize/resize.ml
index d4455eb2..1bd9632b 100644
--- a/resize/resize.ml
+++ b/resize/resize.ml
@@ -30,7 +30,7 @@ let prog = Filename.basename Sys.executable_name
let infile, outfile, copy_boot_loader, debug, deletes, dryrun,
expand, expand_content, extra_partition, format, ignores,
- lv_expands, ntfsresize_force, output_format,
+ lv_expands, machine_readable, ntfsresize_force, output_format,
quiet, resizes, resizes_force, shrink =
let display_version () =
let g = new G.guestfs () in
@@ -57,6 +57,7 @@ let infile, outfile, copy_boot_loader, debug, deletes, dryrun,
let format = ref "" in
let ignores = ref [] in
let lv_expands = ref [] in
+ let machine_readable = ref false in
let ntfsresize_force = ref false in
let output_format = ref "" in
let quiet = ref false in
@@ -83,6 +84,7 @@ let infile, outfile, copy_boot_loader, debug, deletes, dryrun,
"--LV-expand", Arg.String (add lv_expands), "lv -\"-";
"--lvexpand", Arg.String (add lv_expands), "lv -\"-";
"--LVexpand", Arg.String (add lv_expands), "lv -\"-";
+ "--machine-readable", Arg.Set machine_readable, " Make output machine readable";
"-n", Arg.Set dryrun, " Don't perform changes";
"--dryrun", Arg.Set dryrun, " -\"-";
"--dry-run", Arg.Set dryrun, " -\"-";
@@ -125,6 +127,7 @@ read the man page virt-resize(1).
let format = match !format with "" -> None | str -> Some str in
let ignores = List.rev !ignores in
let lv_expands = List.rev !lv_expands in
+ let machine_readable = !machine_readable in
let ntfsresize_force = !ntfsresize_force in
let output_format = match !output_format with "" -> None | str -> Some str in
let quiet = !quiet in
@@ -132,6 +135,25 @@ read the man page virt-resize(1).
let resizes_force = List.rev !resizes_force in
let shrink = match !shrink with "" -> None | str -> Some str in
+ (* No arguments and machine-readable mode? Print out some facts
+ * about what this binary supports. We only need to print out new
+ * things added since this option, or things which depend on features
+ * of the appliance.
+ *)
+ if !disks = [] && machine_readable then (
+ printf "virt-resize\n";
+ printf "ntfsresize-force\n";
+ printf "32bitok\n";
+ let g = new G.guestfs () in
+ g#add_drive_opts "/dev/null";
+ g#launch ();
+ if feature_available g [| "ntfsprogs"; "ntfs3g" |] then
+ printf "ntfs\n";
+ if feature_available g [| "btrfs" |] then
+ printf "btrfs\n";
+ exit 0
+ );
+
(* Verify we got exactly 2 disks. *)
let infile, outfile =
match List.rev !disks with
@@ -141,7 +163,7 @@ read the man page virt-resize(1).
infile, outfile, copy_boot_loader, debug, deletes, dryrun,
expand, expand_content, extra_partition, format, ignores,
- lv_expands, ntfsresize_force, output_format,
+ lv_expands, machine_readable, ntfsresize_force, output_format,
quiet, resizes, resizes_force, shrink
(* Default to true, since NTFS and btrfs support are usually available. *)
@@ -154,7 +176,7 @@ let connect_both_disks () =
if debug then g#set_trace true;
g#add_drive_opts ?format ~readonly:true infile;
g#add_drive_opts ?format:output_format ~readonly:false outfile;
- if not quiet then Progress.set_up_progress_bar g;
+ if not quiet then Progress.set_up_progress_bar ~machine_readable g;
g#launch ();
(* Set the filter to /dev/sda, in case there are any rogue
@@ -910,7 +932,7 @@ let g =
let g = new G.guestfs () in
if debug then g#set_trace true;
g#add_drive_opts ?format:output_format ~readonly:false outfile;
- if not quiet then Progress.set_up_progress_bar g;
+ if not quiet then Progress.set_up_progress_bar ~machine_readable g;
g#launch ();
g (* Return new handle. *)
diff --git a/resize/virt-resize.pod b/resize/virt-resize.pod
index 3a6af183..d03906c5 100644
--- a/resize/virt-resize.pod
+++ b/resize/virt-resize.pod
@@ -349,6 +349,12 @@ You can give this option multiple times, I<but> it doesn't
make sense to do this unless the logical volumes you specify
are all in different volume groups.
+=item B<--machine-readable>
+
+This option is used to make the output more machine friendly
+when being parsed by other programs. See
+L</MACHINE READABLE OUTPUT> below.
+
=item B<-n>
=item B<--dryrun>
@@ -483,6 +489,58 @@ Display version number and exit.
=back
+=head1 MACHINE READABLE OUTPUT
+
+The I<--machine-readable> option can be used to make the output more
+machine friendly, which is useful when calling virt-resize from other
+programs, GUIs etc.
+
+There are two ways to use this option.
+
+Firstly use the option on its own to query the capabilities of the
+virt-resize binary. Typical output looks like this:
+
+ $ virt-resize --machine-readable
+ virt-resize
+ ntfsresize-force
+ 32bitok
+ ntfs
+ btrfs
+
+A list of features is printed, one per line, and the program exits
+with status 0.
+
+Secondly use the option in conjunction with other options to make the
+regular program output more machine friendly.
+
+At the moment this means:
+
+=over 4
+
+=item 1.
+
+Progress bar messages can be parsed from stdout by looking for this
+regular expression:
+
+ ^[0-9]+/[0-9]+$
+
+=item 2.
+
+The calling program should treat messages sent to stdout (except for
+progress bar messages) as status messages. They can be logged and/or
+displayed to the user.
+
+=item 3.
+
+The calling program should treat messages sent to stderr as error
+messages. In addition, virt-resize exits with a non-zero status code
+if there was a fatal error.
+
+=back
+
+Versions of the program prior to 1.13.9 did not support the
+I<--machine-readable> option and will return an error.
+
=head1 NOTES
=head2 "Partition 1 does not end on cylinder boundary."