(** The public interface to the slave thread.
Please see HACKING file. *)
-(** {2 Commands and callbacks} *)
+(** {2 Commands and callbacks}
+
+ Commands for libvirt and libguestfs are executed in a separate slave
+ thread. This file describes the interface with that thread that the
+ rest of the program sees.
+
+ Commands are intentionally as high level as possible. Often a
+ single command may perform many libvirt and libguestfs operations
+ before returing a result. This is to make use of the slave thread
+ as simple as possible.
+
+ Commands are executed in a "continuation-passing style" (CPS),
+ which means that you call a function to issue the command, passing
+ in a callback ("continuation"). The function returns immediately.
+ The callback may be called some time later once the issued command
+ completes successfully. Several commands can be queued up for
+ execution. Commands are executed and callbacks are performed in
+ sequence.
+
+ The callback returns the result of the command. The callback does
+ not get invoked if there was an error, or if the command was
+ cancelled before it runs (see {!discard_command_queue}). For some
+ commands the callback can be called multiple times (see
+ documentation below).
+*)
type 'a callback = 'a -> unit
(** A callback function in the main thread which is called when the
- command finishes (successfully).
+ command finishes successfully.
This can also return some data (the ['a] parameter). A command
that returns a list of strings might have callback type [string
list callback], and a command that returns nothing would have
callback type [unit callback].
- Note that errors are not returned this way. Errors result
- in the command queue being discarded and the failure_hook
- function being called. *)
+ Note that errors are not returned this way. Each function can
+ optionally supply an extra callback to handle errors, or if
+ not supplied then it defaults to the failure hook set by
+ {!set_failure_hook}. *)
val no_callback : 'a callback
(** The main thread uses this as a callback if it doesn't care about
the return value from a command. *)
-val connect : string option -> unit callback -> unit
- (** [connect uri cb] sends the [Connect] message to the slave
- thread.
-
- This causes the slave thread to disconnect from libvirt and
- connect to the libvirt [uri]. If this succeeds, [cb] is called
- in the main thread.
-
- Although you can connect to remote hosts, libguestfs won't
- usually be able to see the drives on those hosts, so it normally
- doesn't make sense to use remote URIs. *)
-
type domain = {
dom_id : int;
dom_name : string;
dom_state : Libvirt.Domain.state;
}
- (** List of domains as returned in the [Get_domains] message callback.
+ (** List of domains as returned in the {!connect} callback. *)
- Note that [dom_state] is the state of the domain and should
- control whether we are allowed to write to the domain's
- filesystem (disallowed if [dom_state] is not [InfoShutoff]). *)
+val connect : ?fail:exn callback -> string option -> domain list callback -> unit
+ (** [connect uri cb] causes the slave thread to disconnect from
+ libvirt and connect to the libvirt [uri]. If this succeeds,
+ then the list of all domains fetched from libvirt and [cb] is
+ called in the main thread.
-val get_domains : domain list callback -> unit
- (** [get_domains cb] sends the [Get_domains] message to the
- slave thread.
-
- This causes the slave thread to retrieve the list of domains
- from libvirt (active and inactive ones). If this succeeds,
- [cb] is called in the main thread with the list of
- domains. See also the {!domain} type. *)
+ Although you can connect to remote hosts, libguestfs won't
+ usually be able to see the drives on those hosts, so it normally
+ doesn't make sense to use remote URIs.
-type rw_flag = RO | RW
- (** This flag is passed to open callbacks to indicate whether
- we could open the disks read-only ([RO]) or read-write ([RW]). *)
+ If [fail] is passed, then failures cause this callback to
+ be called. If not, the global failure hook is called. *)
-val open_domain : string -> rw_flag callback -> unit
- (** [open_domain name cb] sends the [Open_domain] message to the
- slave thread.
+type inspection_data = {
+ insp_all_filesystems : (string * string) list;
+ (** see {!Guestfs.list_filesystems} *)
+ insp_oses : inspection_os list;
+ (** one entry per root (operating system), see {!Guestfs.inspect_os} *)
+}
+ (** The inspection data returned in the callback from
+ {!open_domain} and {!open_images}. *)
+and inspection_os = {
+ insp_root : string; (** see {!Guestfs.inspect_os} *)
+ insp_arch : string;
+ insp_distro : string;
+ insp_filesystems : string array;
+ insp_hostname : string;
+ insp_major_version : int;
+ insp_minor_version : int;
+ insp_mountpoints : (string * string) list;
+ insp_package_format : string;
+ insp_package_management : string;
+ insp_product_name : string;
+ insp_type : string;
+ insp_windows_systemroot : string option;
+ insp_winreg_DEFAULT : string option; (* registry files *)
+ insp_winreg_SAM : string option;
+ insp_winreg_SECURITY : string option;
+ insp_winreg_SOFTWARE : string option;
+ insp_winreg_SYSTEM : string option;
+}
- This causes the slave thread to retrieve the list of
- block devices for the libvirt domain [name], create a
- libguestfs handle, add those block devices, and launch
- the handle. If this is successful, then [cb] is called
- in the main thread.
+val open_domain : ?fail:exn callback -> string -> inspection_data callback -> unit
+ (** [open_domain name cb] retrieves the list of block devices for
+ the libvirt domain [name], creates a libguestfs handle, adds
+ those block devices, launches the handle, and performs
+ inspection.
- If the domain is live then the disks are opened read only,
- else they are opened read write if write_flag is true.
- The [rw_flag] is passed into the callback accordingly.
+ If this is successful, then [cb] is called in the main thread
+ with the list of filesystems and the results of inspection.
The slave thread must be connected to libvirt (see {!connect})
- else this command will fail. *)
-
-val open_images : string list -> rw_flag callback -> unit
- (** [open_images images cb] is like {!open_domain} except
- that it opens local disk image(s) directly. *)
-
-type volume = {
- vol_device : string;
- vol_type : string;
- vol_label : string;
- vol_uuid : string;
- vol_statvfs : Guestfs.statvfs;
-}
- (** The volume structure which is passed to the {!get_volumes} callback. *)
+ else this command will fail.
+
+ If [fail] is passed, then failures cause this callback to
+ be called. If not, the global failure hook is called. *)
-val get_volumes : volume callback -> unit
- (** [get_volumes cb] sends the [Get_volumes] message to the
- slave thread.
+val open_images : ?fail:exn callback -> (string * string option) list -> inspection_data callback -> unit
+ (** [open_images images cb] is like {!open_domain} except that it
+ opens local disk image(s) directly. [images] is a list of
+ [(filename, format)] pairs.
- This causes the slave thread to examine all partitions, LVs
- etc within the current disk image, and for each that contains
- a mountable filesystem, [cb] is called. (Note [cb] can be
- called multiple times). *)
+ If [fail] is passed, then failures cause this callback to
+ be called. If not, the global failure hook is called. *)
+
+type source = OS of inspection_os | Volume of string
+ (** Source type used by {!read_directory}. *)
type direntry = {
dent_name : string; (** Basename in directory. *)
dent_stat : Guestfs.stat; (** stat(2) for this entry. *)
dent_link : string; (** (for symlinks only) readlink(2). *)
}
+ (** Directory entry returned by {!read_directory}. *)
-val read_directory : string -> string -> direntry list callback -> unit
- (** [read_directory dev dir cb] sends the [Read_directory] message
- to the slave thread.
+val read_directory : ?fail:exn callback -> source -> string -> direntry list callback -> unit
+ (** [read_directory src dir cb] reads the contents of the directory
+ [dir] from source [src], and calls the callback function [cb]
+ with the resulting list of directory entries, if successful.
- This causes the slave thread to read the contents of the
- directory [dir] from volume [dev], and call [cb] with the
- complete result. If [dir] is not a directory then this
- is an error.
+ The source may be either a filesystem (if [src] is [Volume
+ dev]), or a fully mounted up operating system (if [src] is [OS ...]).
+ In the second case all the mountpoints of the operating system
+ are mounted up so that the path may span mountpoints in the
+ natural way.
- Note that [.] and [..] entries are not included in the result,
- and the list is sorted on the [filename] field. *)
+ If [fail] is passed, then failures cause this callback to
+ be called. If not, the global failure hook is called. *)
-val disk_usage : string -> string -> int64 callback -> unit
- (** [disk_usage dev dir cb] sends the [Disk_usage] message to the
- slave thread.
+val download_file : ?fail:exn callback -> source -> string -> string -> unit callback -> unit
+ (** [download_file src pathname localfile cb] downloads [pathname]
+ to the named local file, and then calls the callback function. *)
- This causes the slave thread to estimate the disk usage of the
- directory (or file) [dir] from volume [dev], and call [cb] with
- the result (size in {b kilobytes}). *)
+type download_dir_tarball_format = Tar | TGZ | TXZ
-type export_t =
- | Export_tar (** uncompressed tar archive *)
- | Export_tgz (** gzip compressed tar archive *)
- | Export_checksums of string (** checksums using algorithm *)
- | Export_list (** list of file names, \0-separated *)
- (** Export format used by {!export_dir_to}. *)
+val download_dir_tarball : ?fail:exn callback -> source -> string -> download_dir_tarball_format -> string -> unit callback -> unit
+ (** [download_dir_tarball_format src pathname format localfile cb]
+ downloads directory [pathname] to the named local file (a
+ tarball), and then calls the callback function.
-val export_dir_to : export_t -> string -> string -> string -> unit callback -> unit
- (** [export_dir_to t dev dir file cb] sends the [Export_dir_to] message
- to the slave thread.
+ [format] controls the download format, which is one of
+ uncompressed tar, gzip-compressed tar, or xz-compressed tar. *)
- This causes the slave thread to export the directory [dir] on
- device [dev] to the host file called [file]. The precise
- operation (ie. what is exported) is controlled by the type
- [export_t]. When the export has been completed, the callback
- [cb] is called in the main thread.
+val download_dir_find0 : ?fail:exn callback -> source -> string -> string -> unit callback -> unit
+ (** [download_dir_find0 src pathname localfile cb] downloads the
+ list of filenames of directory [pathname] to the named local
+ file (a ASCII NUL-separated text file), and then calls the
+ callback function. *)
- Libguestfs doesn't offer any way to view progress of this
- operation, which could potentially take a long time. *)
+val disk_usage : ?fail:exn callback -> source -> string -> int64 callback -> unit
+ (** [disk_usage src pathname cb] calculates the disk usage of
+ directory [pathname] and calls the callback with the answer
+ (size of {b kilobytes}). *)
val discard_command_queue : unit -> unit
(** [discard_command_queue ()] discards any commands on the command
- queue. The currently running command is not (and can not be)
- stopped. *)
+ queue.
+
+ The currently running command cannot be discarded (because of
+ the design of libguestfs). Instead the callback is discarded,
+ so from the point of view of the main thread, the effect is
+ similar. *)
val exit_thread : unit -> unit
(** [exit_thread ()] causes the slave thread to exit, and returns
(** {2 Hooks}
Hooks are like callbacks, except they hook into special events
- that happen in the slave threads, rather than just being a
- response to commands.
+ that happen in the slave thread, rather than just being a response
+ to commands.
The other difference is that hooks are global variables. You can
only set one hook of each type.
and display those in the main thread.
{!set_busy_hook} and {!set_idle_hook} are used to implement a
- "throbber". *)
+ "throbber".
+
+ {!set_progress_hook} is used to implement a progress bar. *)
val set_failure_hook : exn callback -> unit
(** Set the function in the main thread which is called if there is
(** Set the function in the main thread which is called whenever
the slave thread stops working on a command {i and} has no
more commands left in the queue to work on. *)
+
+val set_status_hook : string callback -> unit
+ (** Set the function in the main thread which is called to
+ update the status bar. The slave thread updates the
+ status bar when an operation starts or stops, keeping the
+ user informed of what is happening. *)
+
+val set_progress_hook : (int64 * int64) callback -> unit
+ (** Set the function in the main thread which is called whenever
+ the slave thread receives a progress notification message
+ from libguestfs. *)