[PATCH] builder: support aliases for images (RHBZ#1098718).
by Pino Toscano
---
builder/builder.ml | 12 ++++++++++++
builder/index_parser.ml | 16 ++++++++++++++++
builder/index_parser.mli | 4 ++++
builder/list_entries.ml | 17 +++++++++++++++++
builder/virt-builder.pod | 8 ++++++++
5 files changed, 57 insertions(+)
diff --git a/builder/builder.ml b/builder/builder.ml
index a0ef6d7..c317816 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -192,6 +192,18 @@ let main () =
| (`Install|`Notes) as mode -> mode in
(* Which os-version (ie. index entry)? *)
+ let arg =
+ (* Try to resolve the alias. *)
+ try
+ let item =
+ List.find (
+ fun (name, { Index_parser.aliases = aliases }) ->
+ match aliases with
+ | None -> false
+ | Some l -> List.mem arg l
+ ) index in
+ fst item
+ with Not_found -> arg in
let item =
try List.find (
fun (name, { Index_parser.arch = a }) ->
diff --git a/builder/index_parser.ml b/builder/index_parser.ml
index 40b2116..0040bf9 100644
--- a/builder/index_parser.ml
+++ b/builder/index_parser.ml
@@ -38,11 +38,14 @@ and entry = {
lvexpand : string option;
notes : (string * string) list;
hidden : bool;
+ aliases : string list option;
sigchecker : Sigchecker.t;
proxy : Downloader.proxy_mode;
}
+let list_separator = " "
+
let print_entry chan (name, { printable_name = printable_name;
file_uri = file_uri;
arch = arch;
@@ -56,6 +59,7 @@ let print_entry chan (name, { printable_name = printable_name;
expand = expand;
lvexpand = lvexpand;
notes = notes;
+ aliases = aliases;
hidden = hidden }) =
let fp fs = fprintf chan fs in
fp "[%s]\n" name;
@@ -101,6 +105,10 @@ let print_entry chan (name, { printable_name = printable_name;
| "" -> fp "notes=%s\n" notes
| lang -> fp "notes[%s]=%s\n" lang notes
) notes;
+ (match aliases with
+ | None -> ()
+ | Some l -> fp "aliases=%s\n" (String.concat list_separator l)
+ );
if hidden then fp "hidden=true\n"
let get_index ~prog ~debug ~downloader ~sigchecker ~proxy source =
@@ -245,6 +253,13 @@ let get_index ~prog ~debug ~downloader ~sigchecker ~proxy source =
eprintf (f_"virt-builder: cannot parse 'hidden' field for '%s'\n")
n;
corrupt_file () in
+ let aliases =
+ let l =
+ try string_nsplit list_separator (List.assoc ("aliases", None) fields)
+ with Not_found -> [] in
+ match l with
+ | [] -> None
+ | l -> Some l in
let entry = { printable_name = printable_name;
osinfo = osinfo;
@@ -260,6 +275,7 @@ let get_index ~prog ~debug ~downloader ~sigchecker ~proxy source =
lvexpand = lvexpand;
notes = notes;
hidden = hidden;
+ aliases = aliases;
proxy = proxy;
sigchecker = sigchecker } in
n, entry
diff --git a/builder/index_parser.mli b/builder/index_parser.mli
index a714d05..97f8c40 100644
--- a/builder/index_parser.mli
+++ b/builder/index_parser.mli
@@ -32,9 +32,13 @@ and entry = {
lvexpand : string option;
notes : (string * string) list;
hidden : bool;
+ aliases : string list option;
sigchecker : Sigchecker.t;
proxy : Downloader.proxy_mode;
}
val get_index : prog:string -> debug:bool -> downloader:Downloader.t -> sigchecker:Sigchecker.t -> proxy:Downloader.proxy_mode -> string -> index
+
+(* The separator string for elements in values of type list. *)
+val list_separator : string
diff --git a/builder/list_entries.ml b/builder/list_entries.ml
index 505a1b9..9264cfc 100644
--- a/builder/list_entries.ml
+++ b/builder/list_entries.ml
@@ -65,6 +65,7 @@ and list_entries_long ~sources index =
size = size;
compressed_size = compressed_size;
notes = notes;
+ aliases = aliases;
hidden = hidden }) ->
if not hidden then (
printf "%-24s %s\n" "os-version:" name;
@@ -79,6 +80,11 @@ and list_entries_long ~sources index =
| Some size ->
printf "%-24s %s\n" (s_"Download size:") (human_size size);
);
+ (match aliases with
+ | None -> ()
+ | Some l -> printf "%-24s %s\n" (s_"Aliases:")
+ (String.concat Index_parser.list_separator l);
+ );
let notes = Languages.find_notes langs notes in
(match notes with
| notes :: _ ->
@@ -116,6 +122,15 @@ and list_entries_json ~sources index =
| None -> ()
| Some n ->
printf " \"%s\": \"%Ld\",\n" key n in
+ let json_optional_printf_stringlist key = function
+ | None -> ()
+ | Some l ->
+ printf " \"%s\": [" key;
+ iteri (
+ fun i alias ->
+ printf " \"%s\"%s" alias (trailing_comma i (List.length l))
+ ) l;
+ printf " ],\n" in
let print_notes = function
| [] -> ()
| notes ->
@@ -156,6 +171,7 @@ and list_entries_json ~sources index =
size = size;
compressed_size = compressed_size;
notes = notes;
+ aliases = aliases;
hidden = hidden }) ->
printf " {\n";
printf " \"os-version\": \"%s\",\n" name;
@@ -164,6 +180,7 @@ and list_entries_json ~sources index =
printf " \"size\": %Ld,\n" size;
json_optional_printf_int64 "compressed-size" compressed_size;
print_notes notes;
+ json_optional_printf_stringlist "aliases" aliases;
printf " \"hidden\": %s\n" (json_string_of_bool hidden);
printf " }%s\n" (trailing_comma i (List.length index))
) index;
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index 5c531de..a70767f 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -1288,6 +1288,14 @@ Using the hidden flag prevents the template from being listed by the
I<--list> option (but it is still installable). This is used for test
images.
+=item C<aliases=ALIAS1 ALIAS2 ...>
+
+This optional field specifies a list of aliases, separated by spaces,
+for the image. For example, an alias could be used to always point
+to the latest version of a certain image, leaving the old versions
+available in the index instead of updating the same image (see the
+C<revision> field).
+
=back
=head3 Running virt-builder against multiple sources
--
1.9.3
10 years, 6 months
ANNOUNCE: libguestfs RHEL 7.1 preview packages available
by Richard W.M. Jones
If you are running RHEL 7 betas or the RHEL 7 Release Candidate[1], or
(in the near future) when RHEL 7 GA or CentOS 7.0 is released, then
you may be interested in previewing the libguestfs packages for RHEL 7.1.
We intend to rebase[2] libguestfs to 1.26 or 1.28 in RHEL 7.1. This
will deliver many new features[3] including virt-builder,
virt-customize, and the new virt-p2v/virt-v2v, while retaining
complete compatibility with RHEL 7 GA.
To install the preview repository, run the following command as root:
cat >/etc/yum.repos.d/libguestfs-RHEL-7.1-preview.repo <<EOF
[libguestfs-RHEL-7.1-preview]
name=libguestfs RHEL 7.1 preview - x86_64
baseurl=http://people.redhat.com/~rjones/libguestfs-RHEL-7.1-preview/
enabled=1
gpgcheck=0
EOF
Then:
yum install libguestfs-tools
Running 'libguestfs-test-tool' after this is a good idea, since it
will tell you if the new version of libguestfs is working or not. If
you want to try a more thorough set of tests, then see:
http://libguestfs.org/guestfs-testing.1.html
These packages are *not* supported by Red Hat.
To go back to the supported packages, uninstall libguestfs, delete the
file /etc/yum.repos.d/libguestfs-RHEL-7.1-preview.repo and install
libguestfs again.
If you find bugs, please let me know or file them in Bugzilla.
For a list of known bugs in libguestfs on RHEL 7, see:
https://bugzilla.redhat.com/buglist.cgi?component=libguestfs&product=Red+...
Rich.
[1] ftp://ftp.redhat.com/redhat/rhel/rc/7/Server
[2] https://bugzilla.redhat.com/show_bug.cgi?id=1021149
[3] http://libguestfs.org/guestfs-release-notes.1.html
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
virt-builder quickly builds VMs from scratch
http://libguestfs.org/virt-builder.1.html
10 years, 6 months
[PATCH] daemon: scrub-file: resolve the path before calling scrub (RHBZ#1099490).
by Pino Toscano
Resolve the given path within the chroot, so scrub can be invoked
outside the chroot on an already-resolved path.
Given that realpath is used, its availability is checked manually,
since scrub-file already depends on the "scrub" feature. Slightly ugly,
but on the other hand realpath is generally available nowadays, so the
check should not be failing.
Add few tests in scrub-file for this and other similar issues.
---
daemon/scrub.c | 24 +++++++++++++++++++++++-
generator/actions.ml | 13 ++++++++++++-
2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/daemon/scrub.c b/daemon/scrub.c
index cd880b9..f500a08 100644
--- a/daemon/scrub.c
+++ b/daemon/scrub.c
@@ -54,12 +54,34 @@ do_scrub_device (const char *device)
int
do_scrub_file (const char *file)
{
+ CLEANUP_FREE char *rp = NULL;
CLEANUP_FREE char *buf = NULL;
CLEANUP_FREE char *err = NULL;
int r;
+ if (! optgroup_realpath_available ()) {
+ reply_with_error_errno (ENOTSUP,
+ "feature '%s' is not available in this\n"
+ "build of libguestfs. Read 'AVAILABILITY' in the guestfs(3) man page for\n"
+ "how to check for the availability of features.",
+ "realpath");
+ return -1;
+ }
+
+ /* Resolve the path to the file. If it fails, then the file
+ * most probably does not exist or "file" is a symlink pointing
+ * outside the chroot.
+ */
+ CHROOT_IN;
+ rp = realpath (file, NULL);
+ CHROOT_OUT;
+ if (rp == NULL) {
+ reply_with_perror ("realpath: %s", file);
+ return -1;
+ }
+
/* Make the path relative to /sysroot. */
- buf = sysroot_path (file);
+ buf = sysroot_path (rp);
if (!buf) {
reply_with_perror ("malloc");
return -1;
diff --git a/generator/actions.ml b/generator/actions.ml
index 0826137..01f6ab5 100644
--- a/generator/actions.ml
+++ b/generator/actions.ml
@@ -5719,7 +5719,18 @@ manual page for more details." };
tests = [
InitScratchFS, Always, TestRun (
[["write"; "/scrub_file"; "content"];
- ["scrub_file"; "/scrub_file"]]), []
+ ["scrub_file"; "/scrub_file"]]), [];
+ InitScratchFS, Always, TestRun (
+ [["write"; "/scrub_file_2"; "content"];
+ ["ln_s"; "/scrub_file_2"; "/scrub_file_2_link"];
+ ["scrub_file"; "/scrub_file_2_link"]]), [];
+ InitScratchFS, Always, TestLastFail (
+ [["ln_s"; "/scrub_file_3_notexisting"; "/scrub_file_3_link"];
+ ["scrub_file"; "/scrub_file_3_link"]]), [];
+ InitScratchFS, Always, TestLastFail (
+ [["write"; "/scrub_file_4"; "content"];
+ ["ln_s"; "../sysroot/scrub_file_4"; "/scrub_file_4_link"];
+ ["scrub_file"; "/scrub_file_4_link"]]), [];
];
shortdesc = "scrub (securely wipe) a file";
longdesc = "\
--
1.9.0
10 years, 6 months
[PATCH] fish: simplify output of 'supported'
by Pino Toscano
Print each line at once, making use of the padding features of printf
instead of doing it manually.
---
fish/supported.c | 15 +++------------
1 file changed, 3 insertions(+), 12 deletions(-)
diff --git a/fish/supported.c b/fish/supported.c
index 651e3aa..b49011a 100644
--- a/fish/supported.c
+++ b/fish/supported.c
@@ -49,20 +49,11 @@ run_supported (const char *cmd, size_t argc, char *argv[])
}
for (i = 0; groups[i] != NULL; ++i) {
- size_t l = strlen (groups[i]);
- size_t j;
- for (j = 0; j < len-l; ++j)
- putchar (' ');
- printf ("%s", groups[i]);
- putchar (' ');
-
char *gg[] = { groups[i], NULL };
int r = guestfs_available (g, gg);
- if (r == 0)
- printf ("%s", _("yes"));
- else
- printf ("%s", _("no"));
- putchar ('\n');
+ const char *str = r == 0 ? _("yes") : _("no");
+
+ printf ("%*s %s\n", (int) len, groups[i], str);
}
/* Restore error handler. */
--
1.9.0
10 years, 6 months
Labelling /etc/resolv.conf (rh#1089100)
by Pino Toscano
Hi,
I was investigating rh#1089100, which is about /etc/resolv.conf not
being properly SELinux-labelled.
Basically the problem is due to /etc/resolv.conf in the guest (so
available as /sysroot/etc/resolv.conf in the appliance) being moved when
executing shell commands (eg guestfs_sh) by the daemon.
This operation involves:
a) moving away guest's /etc/resolv.conf
b) replacing it with the /etc/resolv.conf in the appliance
c) executing the actual shell command
d) moving the guest's /etc/resolv.conf back
... but only if the network is enabled (which is by default).
So far all the ideas I found (to fix the label of /etc/resolv.conf when
--selinux-relabel is asked) were:
1) get the security.selinux xattr before (a), and restore it after (d).
This seems to not have worked at all, at least for me: the read xattr
is "unlabeled", which SELinux obviously refuses later; hence I
discarded it
2) closing the guestfs handle, open a new one with the network disabled
and do the relabel.
This works for me, but has the drawback to slow the process if the
relabel is asked and the network is enabled, as closing+opening an
appliance could not be that fast
3) allow to switch the network on/off also when the appliance is up.
This would require to actually turn on/off the networking at
runtime, which surely cannot be done with the direct backend and most
probably neither with libvirt (but I didn't research hard on this).
Is anything obvious I'm missing? Can I go with solution #2?
--
Pino Toscano
10 years, 6 months
Opening compressed filesystems
by Richard W.M. Jones
This is in reply to a question on IRC about opening compressed disk
images.
This is already possible -- in fact quite easy -- using nbdkit.
It only works well for xz-compressed files which have been prepared
using the --block-size option like this:
xz --best --block-size=16777216 disk.img
You can then run nbdkit as a captive process like this:
nbdkit xz file=disk.img.xz \
--run 'guestfish --format=raw -a $nbd -i'
or if you feel like it, boot the guest:
nbdkit xz file=disk.img.xz \
--run 'qemu-kvm -m 1024 -drive file=$nbd,if=virtio'
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
Read my programming and virtualization blog: http://rwmj.wordpress.com
Fedora Windows cross-compiler. Compile Windows programs, test, and
build Windows installers. Over 100 libraries supported.
http://fedoraproject.org/wiki/MinGW
10 years, 6 months
guestfsd crashes when the handle is closed
by Safa Rekik
Hello,
I launched guestfsd in my guest with this command : guestfsd* -rv*.
When i close the handle the deamon crashes.
This is the output i got (Deamon side) :
guestfsd: main_loop : new request, len 0x28
fsync /dev/sda
/dev/sr0 : No medium found
guestfsd : main_loop : proc 282
(internal_autosynx) took 0.19 seconds
*read: unexpected end of file on fd 3 *
I got the same error with both ubuntu12.04 and fedora 20 guests. I know
that in ubuntu the guestfsd version is quite but fedora 20 has 1.26
libguestfs version i think.
Any help would be match appreciated !
Thanks !
*Note : *BTW, although i think it's guest side problem, this are details
about the host : Fedora 20 , guestfish
1.26.1fedora=20,release=2.fc20,libvirt
--
10 years, 6 months
[PATCH 1/2] builder: save the proxy for each entry
by Pino Toscano
Copy the information about the proxy of a source in all the entries of
that source; this way it is possible to use it later when accessing to
the actual image of an entry.
---
builder/index_parser.ml | 2 ++
builder/index_parser.mli | 1 +
2 files changed, 3 insertions(+)
diff --git a/builder/index_parser.ml b/builder/index_parser.ml
index 2040656..40b2116 100644
--- a/builder/index_parser.ml
+++ b/builder/index_parser.ml
@@ -40,6 +40,7 @@ and entry = {
hidden : bool;
sigchecker : Sigchecker.t;
+ proxy : Downloader.proxy_mode;
}
let print_entry chan (name, { printable_name = printable_name;
@@ -259,6 +260,7 @@ let get_index ~prog ~debug ~downloader ~sigchecker ~proxy source =
lvexpand = lvexpand;
notes = notes;
hidden = hidden;
+ proxy = proxy;
sigchecker = sigchecker } in
n, entry
) sections in
diff --git a/builder/index_parser.mli b/builder/index_parser.mli
index c2c5d11..a714d05 100644
--- a/builder/index_parser.mli
+++ b/builder/index_parser.mli
@@ -34,6 +34,7 @@ and entry = {
hidden : bool;
sigchecker : Sigchecker.t;
+ proxy : Downloader.proxy_mode;
}
val get_index : prog:string -> debug:bool -> downloader:Downloader.t -> sigchecker:Sigchecker.t -> proxy:Downloader.proxy_mode -> string -> index
--
1.9.0
10 years, 6 months