A few easy dpkg optimizations for supermin
by Hilko Bengen
I have done some printf profiling and found that supermin's calls to
dpkg for individual packages are quite expensive. Here are some
patches that gather all information on demand where possible.
On my Debian/unstable-based workstation at home, preparing a minimal
appliance using
$ ./supermin --use-installed --prepare bash -o supermin.d
now takes ~3.5s (previously ~15s).
Turning that appliance into an image using
$ ./supermin --build -f ext2 supermin.d -o appliance.d
now takes ~6s (previously ~14.5s).
10 years, 9 months
[supermin 1/2] chroot: Fix corner case introduced with dpkg-divert support
by Hilko Bengen
---
src/chroot.ml | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/chroot.ml b/src/chroot.ml
index b5c1e53..9e522d9 100644
--- a/src/chroot.ml
+++ b/src/chroot.ml
@@ -26,7 +26,9 @@ let build_chroot debug files outputdir =
List.iter (
fun file ->
try
- let path = file.ft_source_path in
+ let path = if file_exists file.ft_source_path
+ then file.ft_source_path
+ else file.ft_path in
let st = lstat path in
let opath = outputdir // file.ft_path in
match st.st_kind with
@@ -68,7 +70,10 @@ let build_chroot debug files outputdir =
(* Second pass: fix up directory permissions in reverse. *)
let dirs = filter_map (
fun file ->
- let st = lstat file.ft_source_path in
+ let path =
+ if file_exists file.ft_source_path then file.ft_source_path
+ else file.ft_path in
+ let st = lstat path in
if st.st_kind = S_DIR then Some (file.ft_path, st) else None
) files in
List.iter (
--
1.9.0
10 years, 9 months
[PATCH 1/2] tests: provide a simple way to extract the tests data from run
by Pino Toscano
If the RUN_OUTPUT_FILE environment variable is set, "run" will output
to the file indicated by that snippets of XML with the results and
outputs of the tests run.
Together with the run-xml-to-junit.sh (and its associated
run-xml-to-junit.xsl style sheet) it is possible to convert that output
file to a jUnit-like XML file, which could be used in CI systems.
---
run.in | 8 ++++++++
tests/run-xml-to-junit.sh | 24 ++++++++++++++++++++++++
tests/run-xml-to-junit.xsl | 41 +++++++++++++++++++++++++++++++++++++++++
3 files changed, 73 insertions(+)
create mode 100755 tests/run-xml-to-junit.sh
create mode 100644 tests/run-xml-to-junit.xsl
diff --git a/run.in b/run.in
index 55942c6..a508c38 100755
--- a/run.in
+++ b/run.in
@@ -260,5 +260,13 @@ else
cat $tmpout
echo "$b/run: command failed with exit code $fail"
fi
+if [ -n "$RUN_OUTPUT_FILE" ]; then
+ testname=`echo "$1" | sed -e 's,^./,,g'`
+ echo "<test rescode=\"$fail\" name=\"$testname\" time=\"$(($end_t - $start_t))\">" >> $RUN_OUTPUT_FILE
+ echo "<![CDATA[" >> $RUN_OUTPUT_FILE
+ cat $tmpout >> $RUN_OUTPUT_FILE
+ echo "]]>" >> $RUN_OUTPUT_FILE
+ echo "</test>" >> $RUN_OUTPUT_FILE
+fi
rm -f $tmpout
exit $fail
diff --git a/tests/run-xml-to-junit.sh b/tests/run-xml-to-junit.sh
new file mode 100755
index 0000000..b6f11fe
--- /dev/null
+++ b/tests/run-xml-to-junit.sh
@@ -0,0 +1,24 @@
+#!/bin/sh
+
+if [ $# -lt 2 ]; then
+ echo "$0: output-of-run destination-xml"
+ exit 1
+fi
+
+set -e
+
+infile=$1
+outfile=$2
+owndir=`dirname $0`
+ownname=`basename $0`
+tmpfile=`mktemp --tmpdir $ownname.XXXXXXXXXX`
+
+(
+ echo '<?xml version="1.0" encoding="UTF-8"?>';
+ echo '<tests>';
+ cat $infile;
+ echo '</tests>'
+) > $tmpfile
+
+xsltproc --encoding UTF-8 $owndir/run-xml-to-junit.xsl $tmpfile > $outfile
+unlink $tmpfile
diff --git a/tests/run-xml-to-junit.xsl b/tests/run-xml-to-junit.xsl
new file mode 100644
index 0000000..b0d56f3
--- /dev/null
+++ b/tests/run-xml-to-junit.xsl
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
+<xsl:output indent="yes" cdata-section-elements="system-out skipped error"/>
+
+<xsl:template match="/">
+ <xsl:variable name="TestsTotal"><xsl:value-of select="count(tests/test)"/></xsl:variable>
+ <xsl:variable name="TestsPassed"><xsl:value-of select="count(tests/test[@rescode = 0])"/></xsl:variable>
+ <xsl:variable name="TestsSkipped"><xsl:value-of select="count(tests/test[@rescode = 77])"/></xsl:variable>
+ <xsl:variable name="TestsTimedout"><xsl:value-of select="count(tests/test[@rescode = 124])"/></xsl:variable>
+ <xsl:variable name="TestsFailures"><xsl:value-of select="$TestsTotal - $TestsPassed - $TestsSkipped - $TestsTimedout"/></xsl:variable>
+
+<testsuites>
+ <testsuite name="libguestfs" tests="{$TestsTotal}" failures="{$TestsFailures}" skipped="{$TestsSkipped}" errors="{$TestsTimedout}">
+ <xsl:for-each select="tests/test">
+ <xsl:variable name="TestcaseName"><xsl:value-of select="@name"/></xsl:variable>
+ <xsl:variable name="TestcaseTime"><xsl:value-of select="@time"/></xsl:variable>
+ <xsl:variable name="TestcaseRescode"><xsl:value-of select="@rescode"/></xsl:variable>
+ <xsl:variable name="TestcaseOutput"><xsl:value-of select="."/></xsl:variable>
+ <testcase name="{$TestcaseName}" classname="TestSuite" time="{$TestcaseTime}">
+ <xsl:choose>
+ <xsl:when test="$TestcaseRescode = 0">
+ <system-out><xsl:value-of select="$TestcaseOutput"/></system-out>
+ </xsl:when>
+ <xsl:when test="$TestcaseRescode = 77">
+ <skipped><xsl:value-of select="$TestcaseOutput"/></skipped>
+ </xsl:when>
+ <xsl:when test="$TestcaseRescode = 124">
+ <error><xsl:value-of select="$TestcaseOutput"/></error>
+ </xsl:when>
+ <xsl:otherwise>
+ <error><xsl:value-of select="$TestcaseOutput"/></error>
+ </xsl:otherwise>
+ </xsl:choose>
+ </testcase>
+ </xsl:for-each>
+ </testsuite>
+</testsuites>
+
+</xsl:template>
+
+</xsl:stylesheet>
--
1.8.3.1
10 years, 9 months
Re: [Libguestfs] --rbd volume access--
by Richard W.M. Jones
On Fri, Mar 14, 2014 at 04:09:23PM +0500, Shumaila Naeem wrote:
> is there any way i can run both inspect-os and get-distro in one line
>
> something like this
> guestfish -- add /dev/null : config -set
> drive.hd0.file=rbd:ssd-clonetest-rule5/ubuntu-12.04--1.raw.img : run :
> inspect-get-distro inspect-os
Not like this. This is why I said before this is "awkward in
guestfish". TBH you're best off continuing with the Python program.
If you absolutely must use guestfish (which I don't recommend for this
case) then:
----------------------------------------------------------------------
#!/bin/bash -
guestfish <<'EOF'
add /dev/null readonly:true
# RHEL 6 hack for adding Ceph drives:
config -set drive.hd0.file=rbd:ssd-clonetest-rule5/ubuntu-12.04--1.raw.img
run
inspect-os | head -1 > /tmp/root
<! echo inspect-get-distro `cat /tmp/root`
EOF
----------------------------------------------------------------------
Rich.
--
Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones
virt-p2v converts physical machines to virtual machines. Boot with a
live CD or over the network (PXE) and turn machines into KVM guests.
http://libguestfs.org/virt-v2v
10 years, 9 months
--rbd volume access--
by Shumaila Naeem
http://rwmj.wordpress.com/2013/03/12/accessing-ceph-rbd-sheepdog-etc-usin...
I came across this link and and i was able to retrieve the rbd image.
$ guestfish
><fs> set-attach-method appliance
><fs> add-drive /dev/null
><fs> config -set drive.hd0.file=rbd:pool/volume
><fs> run
I was able to retrieve file from rbd image using the above method.
Would you please let know how to do this in a single command line. I am
getting the following error
guestfish add /dev/null : config -set
drive.hd0.file=rbd:ssd-clonetest-rule5/fullclone.img : run : list-partitions
guestfish: invalid option -- 's'
Try `guestfish -help' for more information.
anything I m doing wrong here.
I am using CentOS 6.4 2.6.32-358.6.2.el6.x86_64
qemu:
qemu-kvm-0.12.1.2-2.415.el6.3ceph.x86_64
qemu-kvm-tools-0.12.1.2-2.415.el6.3ceph.x86_64
guestfs:
libguestfs-tools-c-1.20.11-2.el6.x86_64
libguestfs-tools-1.20.11-2.el6.x86_64
libguestfs-1.20.11-2.el6.x86_64
libguestfs-winsupport-1.0-7.el6.x86_64
10 years, 9 months
supermin and dpkg-divert
by Hilko Bengen
While trying to run libguestfs tests after building with
"--enable-appliance --with-supermin-extra-options=--use-installed", I
ran into a peculiar error message in the c-api test:
,----
| libguestfs: error: strings: /abssymlink: strings: error while loading
| shared libraries: libbfd-2.24-multiarch.so: cannot open shared object
| file: No such file or directory
`----
The problem here is that I have the binutils-multiarch package installed
which has used dpkg-divert(8) to override the "regular" binutils
binaries.
,----
| $ dpkg-divert --list /usr/bin/strings
| diversion of /usr/bin/strings to /usr/bin/strings.single by binutils-multiarch
`----
I have been able to reproduce the problem with a minimal appliance
(again, with binutils-multiarch installed):
,----
| $ supermin --prepare bash binutils coreutils libc-bin -o supermin.d --use-installed
| $ cp init.tar supermin.d
| $ supermin --build --format ext2 supermin.d -o appliance.d
| $ qemu-system-x86_64 \
| > -display none \
| > -serial stdio \
| > -kernel appliance.d/kernel \
| > -initrd appliance.d/initrd \
| > -append 'console=ttyS0' \
| > -drive file=appliance.d/root,format=raw,if=virtio
| [...]
| I have no name!@(none):/# ldd /usr/bin/strings
| linux-vdso.so.1 (0x00007fffb1944000)
| libbfd-2.24-multiarch.so => not found
| libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f16c7429000)
| libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f16c7210000)
| libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f16c6e67000)
| /lib64/ld-linux-x86-64.so.2 (0x00007f16c762f000)
`----
Here are some patches that have fixed the issue for me.
Cheers,
-Hilko
10 years, 9 months
[PATCH 1/3] php: add a custom PHP runner for tests
by Pino Toscano
Since the default PHP test runner ignores a good number of environment
variables to potentially tampering the test suite execution, create a
custom php-for-tests.sh script which does nothing more than sourcing the
custom environment that our run-php-tests.sh outputs and running the
actual "php" executable (the one found by configure).
This fixes the loading of the guestfs_php.so module in the test suite,
as the libguestfs.so.0 library can be found by that module.
---
.gitignore | 1 +
configure.ac | 2 ++
php/extension/php-for-tests.sh.in | 4 ++++
php/run-php-tests.sh | 2 +-
4 files changed, 8 insertions(+), 1 deletion(-)
create mode 100755 php/extension/php-for-tests.sh.in
diff --git a/.gitignore b/.gitignore
index 0c61b5b..830a40d 100644
--- a/.gitignore
+++ b/.gitignore
@@ -360,6 +360,7 @@ Makefile.in
/php/extension/mkinstalldirs
/php/extension/missing
/php/extension/modules/
+/php/extension/php-for-tests.sh
/php/extension/php_guestfs_php.h
/php/extension/run-tests.php
/php/extension/tmp-php.ini
diff --git a/configure.ac b/configure.ac
index 35460e2..daa5236 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1595,6 +1595,8 @@ AC_CONFIG_FILES([appliance/libguestfs-make-fixed-appliance],
[chmod +x,-w appliance/libguestfs-make-fixed-appliance])
AC_CONFIG_FILES([inspector/test-xmllint.sh],
[chmod +x,-w inspector/test-xmllint.sh])
+AC_CONFIG_FILES([php/extension/php-for-tests.sh],
+ [chmod +x,-w php/extension/php-for-tests.sh])
AC_CONFIG_FILES([pick-guests.pl],
[chmod +x,-w pick-guests.pl])
AC_CONFIG_FILES([podwrapper.pl],
diff --git a/php/extension/php-for-tests.sh.in b/php/extension/php-for-tests.sh.in
new file mode 100755
index 0000000..0639ce3
--- /dev/null
+++ b/php/extension/php-for-tests.sh.in
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+. ./env
+@PHP@ $@
diff --git a/php/run-php-tests.sh b/php/run-php-tests.sh
index 63701e9..6f9ae10 100755
--- a/php/run-php-tests.sh
+++ b/php/run-php-tests.sh
@@ -45,4 +45,4 @@ TESTS=$(echo guestfs_php_*.phpt)
echo TESTS: $TESTS
# PHP ignores the result of the tests!
-make test TESTS="$TESTS"
+make test TESTS="$TESTS" PHP_EXECUTABLE="$PWD/php-for-tests.sh"
--
1.8.3.1
10 years, 9 months
[PATCH v3 00/10] Add discard support.
by Richard W.M. Jones
This set of patches:
- Adds new APIs to support discard in libguestfs.
- Adds discard support to virt-format.
- Adds discard support to virt-sysprep.
- Implements virt-sparsify --in-place.
This is now working, after fixing the rather stupid bug in fstrim.
I've pushed the ones which were ACKed previously + the fstrim fix.
Rich.
10 years, 9 months
[PATCH] builder: complete architecture handling
by Pino Toscano
Add the possibility to choose which architecture use to build the wanted
image (--arch). Since this implies that running commands on the guest is
usually not possible when the architecture is different than the host
one, another new option (--allow-foreign-arch-ops) allows to run
commands nevertheless.
The caching scheme is adapted to account for the architecture (with
--print-cache showing the architecture as well).
Furthermore, the short output of --list shows the architecture as well,
like the other --list outputs do.
---
builder/Makefile.am | 9 +++++-
builder/architecture.ml | 32 +++++++++++++++++++++
builder/builder.ml | 28 ++++++++++--------
builder/cmdline.ml | 29 +++++++++++++++++--
builder/downloader.ml | 8 +++---
builder/downloader.mli | 10 +++----
builder/index_parser.ml | 22 ++++++++++----
builder/list_entries.ml | 2 ++
builder/test-virt-builder-list.sh | 14 ++++-----
builder/test-virt-builder.sh | 1 +
builder/uname-c.c | 60 +++++++++++++++++++++++++++++++++++++++
builder/uname.ml | 27 ++++++++++++++++++
builder/uname.mli | 28 ++++++++++++++++++
builder/virt-builder.pod | 35 +++++++++++++++++++----
po/POTFILES | 1 +
po/POTFILES-ml | 2 ++
16 files changed, 264 insertions(+), 44 deletions(-)
create mode 100644 builder/architecture.ml
create mode 100644 builder/uname-c.c
create mode 100644 builder/uname.ml
create mode 100644 builder/uname.mli
diff --git a/builder/Makefile.am b/builder/Makefile.am
index 387913c..5a978e3 100644
--- a/builder/Makefile.am
+++ b/builder/Makefile.am
@@ -38,6 +38,7 @@ CLEANFILES = *~ *.cmi *.cmo *.cmx *.cmxa *.o virt-builder
# Alphabetical order.
SOURCES = \
+ architecture.ml \
builder.ml \
cmdline.ml \
downloader.mli \
@@ -61,7 +62,10 @@ SOURCES = \
sigchecker.mli \
sigchecker.ml \
sources.mli \
- sources.ml
+ sources.ml \
+ uname.ml \
+ uname.mli \
+ uname-c.c
man_MANS =
noinst_DATA =
@@ -99,6 +103,9 @@ deps = \
pxzcat.cmx \
setlocale-c.o \
setlocale.cmx \
+ uname-c.o \
+ uname.cmx \
+ architecture.cmx \
ini_reader.cmx \
paths.cmx \
get_kernel.cmx \
diff --git a/builder/architecture.ml b/builder/architecture.ml
new file mode 100644
index 0000000..2aa7e7e
--- /dev/null
+++ b/builder/architecture.ml
@@ -0,0 +1,32 @@
+(* virt-builder
+ * Copyright (C) 2014 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 Common_gettext.Gettext
+open Common_utils
+
+open Unix
+
+let filter_arch = function
+ | "amd64" | "x86_64" | "x64" -> "x86_64"
+ | "powerpc" | "ppc" -> "ppc"
+ | "armhfp" | "armhf" -> "armhf"
+ | arch -> arch
+
+let current_arch =
+ try filter_arch ((Uname.uname ()).Uname.machine)
+ with Unix_error _ -> "unknown"
diff --git a/builder/builder.ml b/builder/builder.ml
index 1800f2d..ed55de1 100644
--- a/builder/builder.ml
+++ b/builder/builder.ml
@@ -38,9 +38,9 @@ let () = Random.self_init ()
let main () =
(* Command line argument parsing - see cmdline.ml. *)
let mode, arg,
- attach, cache, check_signature, curl, debug, delete, delete_on_failure,
- edit, firstboot, run, format, gpg, hostname, install, list_format, links,
- memsize, mkdirs,
+ arch, attach, cache, check_signature, curl, debug, delete,
+ delete_on_failure, edit, firstboot, run, format, gpg, hostname, install,
+ list_format, links, memsize, mkdirs,
network, output, password_crypto, quiet, root_password, scrub,
scrub_logfile, selinux_relabel, size, smp, sources, sync, timezone,
update, upload, writes =
@@ -172,11 +172,11 @@ let main () =
| Some cachedir ->
printf (f_"cache directory: %s\n") cachedir;
List.iter (
- fun (name, { Index_parser.revision = revision; hidden = hidden }) ->
+ fun (name, { Index_parser.revision = revision; arch = arch; hidden = hidden }) ->
if not hidden then (
- let filename = Downloader.cache_of_name cachedir name revision in
+ let filename = Downloader.cache_of_name cachedir name arch revision in
let cached = Sys.file_exists filename in
- printf "%-24s %s\n" name
+ printf "%-24s %-10s %s\n" name arch
(if cached then s_"cached" else (*s_*)"no")
)
) index
@@ -193,7 +193,7 @@ let main () =
List.iter (
fun (name,
{ Index_parser.revision = revision; file_uri = file_uri }) ->
- let template = name, revision in
+ let template = name, arch, revision in
msg (f_"Downloading: %s") file_uri;
let progress_bar = not quiet in
ignore (Downloader.download ~prog downloader ~template ~progress_bar
@@ -205,12 +205,16 @@ let main () =
| (`Install|`Notes) as mode -> mode in
(* Which os-version (ie. index entry)? *)
- let entry =
- try List.assoc arg index
+ let item =
+ try List.find (
+ fun (name, { Index_parser.arch = a }) ->
+ name = arg && arch = Architecture.filter_arch a
+ ) index
with Not_found ->
- eprintf (f_"%s: cannot find os-version '%s'.\nUse --list to list available guest types.\n")
- prog arg;
+ eprintf (f_"%s: cannot find os-version '%s' with architecture '%s'.\nUse --list to list available guest types.\n")
+ prog arg arch;
exit 1 in
+ let entry = snd item in
let sigchecker = entry.Index_parser.sigchecker in
(match mode with
@@ -234,7 +238,7 @@ let main () =
let template =
let template, delete_on_exit =
let { Index_parser.revision = revision; file_uri = file_uri } = entry in
- let template = arg, revision in
+ let template = arg, arch, revision in
msg (f_"Downloading: %s") file_uri;
let progress_bar = not quiet in
Downloader.download ~prog downloader ~template ~progress_bar file_uri in
diff --git a/builder/cmdline.ml b/builder/cmdline.ml
index 6e8bfd8..0dd0ad2 100644
--- a/builder/cmdline.ml
+++ b/builder/cmdline.ml
@@ -44,6 +44,9 @@ let parse_cmdline () =
let print_cache_mode () = mode := `Print_cache in
let delete_cache_mode () = mode := `Delete_cache in
+ let arch = ref "" in
+ let allow_foreign_arch_ops = ref false in
+
let attach = ref [] in
let attach_format = ref None in
let set_attach_format = function
@@ -221,6 +224,9 @@ let parse_cmdline () =
let ditto = " -\"-" in
let argspec = Arg.align [
+ "--allow-foreign-arch-ops", Arg.Set allow_foreign_arch_ops,
+ " " ^ s_"Allow executing commands even on non-native output architectures";
+ "--arch", Arg.Set_string arch, "arch" ^ " " ^ s_"Set the output architecture";
"--attach", Arg.String attach_disk, "iso" ^ " " ^ s_"Attach data disk/ISO during install";
"--attach-format", Arg.String set_attach_format,
"format" ^ " " ^ s_"Set attach disk format";
@@ -319,6 +325,8 @@ read the man page virt-builder(1).
(* Dereference options. *)
let args = List.rev !args in
let mode = !mode in
+ let arch = !arch in
+ let allow_foreign_arch_ops = !allow_foreign_arch_ops in
let attach = List.rev !attach in
let cache = !cache in
let check_signature = !check_signature in
@@ -431,10 +439,25 @@ read the man page virt-builder(1).
(* Combine the sources and fingerprints into a single list of pairs. *)
List.combine sources fingerprints in
+ (* Check the architecture. *)
+ let arch =
+ match arch with
+ | "" -> Architecture.current_arch
+ | arch ->
+ let target_arch = Architecture.filter_arch arch in
+ if Architecture.current_arch <> target_arch && allow_foreign_arch_ops <> true then (
+ if install <> [] || run <> [] || update then (
+ eprintf (f_"%s: sorry, cannot run commands on a guest with a different architecture\n")
+ prog;
+ exit 1
+ );
+ );
+ target_arch in
+
mode, arg,
- attach, cache, check_signature, curl, debug, delete, delete_on_failure,
- edit, firstboot, run, format, gpg, hostname, install, list_format, links,
- memsize, mkdirs,
+ arch, attach, cache, check_signature, curl, debug, delete,
+ delete_on_failure, edit, firstboot, run, format, gpg, hostname, install,
+ list_format, links, memsize, mkdirs,
network, output, password_crypto, quiet, root_password, scrub,
scrub_logfile, selinux_relabel, size, smp, sources, sync, timezone,
update, upload, writes
diff --git a/builder/downloader.ml b/builder/downloader.ml
index e386c06..e23cb37 100644
--- a/builder/downloader.ml
+++ b/builder/downloader.ml
@@ -25,8 +25,8 @@ open Printf
let quote = Filename.quote
let (//) = Filename.concat
-let cache_of_name cachedir name revision =
- cachedir // sprintf "%s.%d" name revision
+let cache_of_name cachedir name arch revision =
+ cachedir // sprintf "%s.%s.%d" name arch revision
type uri = string
type filename = string
@@ -51,14 +51,14 @@ let rec download ~prog t ?template ?progress_bar uri =
download_to ~prog t ?progress_bar uri tmpfile;
(tmpfile, true)
- | Some (name, revision) ->
+ | Some (name, arch, revision) ->
match t.cache with
| None ->
(* Not using the cache at all? *)
download t ~prog ?progress_bar uri
| Some cachedir ->
- let filename = cache_of_name cachedir name revision in
+ let filename = cache_of_name cachedir name arch revision in
(* Is the requested template name + revision in the cache already?
* If not, download it.
diff --git a/builder/downloader.mli b/builder/downloader.mli
index 62d500d..7b26ba3 100644
--- a/builder/downloader.mli
+++ b/builder/downloader.mli
@@ -18,7 +18,7 @@
(** This module is a wrapper around curl, plus local caching. *)
-val cache_of_name : string -> string -> int -> string
+val cache_of_name : string -> string -> string -> int -> string
(** [cache_of_name cachedir name revision] returns the filename
of the cached file. (Note: It doesn't check if the filename
exists, this is just a simple string transformation). *)
@@ -32,15 +32,15 @@ type t
val create : debug:bool -> curl:string -> cache:string option -> t
(** Create the abstract type. *)
-val download : prog:string -> t -> ?template:(string*int) -> ?progress_bar:bool -> uri -> (filename * bool)
+val download : prog:string -> t -> ?template:(string*string*int) -> ?progress_bar:bool -> uri -> (filename * bool)
(** Download the URI, returning the downloaded filename and a
temporary file flag. The temporary file flag is [true] iff
the downloaded file is temporary and should be deleted by the
caller (otherwise it's in the cache and you shouldn't delete it).
- For templates, you must supply [~template:(name, revision)]. This
- causes the cache to be used (if possible). Name and revision are
- used for cache control (see the man page for details).
+ For templates, you must supply [~template:(name, arch, revision)].
+ This causes the cache to be used (if possible). Name, arch(itecture)
+ and revision are used for cache control (see the man page for details).
If [~progress_bar:true] then display a progress bar if the file
doesn't come from the cache. In debug mode, progress messages
diff --git a/builder/index_parser.ml b/builder/index_parser.ml
index 9fd9cda..472a6c7 100644
--- a/builder/index_parser.ml
+++ b/builder/index_parser.ml
@@ -123,16 +123,26 @@ let get_index ~prog ~debug ~downloader ~sigchecker source =
if delete_tmpfile then
(try Unix.unlink tmpfile with _ -> ());
- (* Check for repeated os-version names. *)
+ (* Check for repeated os-version+arch combination. *)
+ let name_arch_map = List.map (
+ fun (n, fields) ->
+ let rec find_arch = function
+ | ("arch", None, value) :: y -> value
+ | _ :: y -> find_arch y
+ | [] -> ""
+ in
+ n, (find_arch fields)
+ ) sections in
let nseen = Hashtbl.create 13 in
List.iter (
- fun (n, _) ->
- if Hashtbl.mem nseen n then (
- eprintf (f_"virt-builder: index is corrupt: os-version '%s' appears two or more times\n") n;
+ fun (n, arch) ->
+ let id = n, arch in
+ if Hashtbl.mem nseen id then (
+ eprintf (f_"virt-builder: index is corrupt: os-version '%s' with architecture '%s' appears two or more times\n") n arch;
corrupt_file ()
);
- Hashtbl.add nseen n true
- ) sections;
+ Hashtbl.add nseen id true
+ ) name_arch_map;
(* Check for repeated fields. *)
List.iter (
diff --git a/builder/list_entries.ml b/builder/list_entries.ml
index 476bf14..75149e7 100644
--- a/builder/list_entries.ml
+++ b/builder/list_entries.ml
@@ -48,9 +48,11 @@ let rec list_entries ~list_format ~sources index =
and list_entries_short index =
List.iter (
fun (name, { Index_parser.printable_name = printable_name;
+ arch = arch;
hidden = hidden }) ->
if not hidden then (
printf "%-24s" name;
+ printf " %-10s" arch;
(match printable_name with
| None -> ()
| Some s -> printf " %s" s
diff --git a/builder/test-virt-builder-list.sh b/builder/test-virt-builder-list.sh
index 2f9b319..1f62838 100755
--- a/builder/test-virt-builder-list.sh
+++ b/builder/test-virt-builder-list.sh
@@ -27,13 +27,13 @@ export XDG_CONFIG_DIRS="$abs_builddir/test-config"
short_list=$($VG ./virt-builder --no-check-signature --no-cache --list)
-if [ "$short_list" != "phony-debian Phony Debian
-phony-fedora Phony Fedora
-phony-fedora-qcow2 Phony Fedora qcow2
-phony-fedora-qcow2-uncompressed Phony Fedora qcow2 uncompressed
-phony-fedora-no-format Phony Fedora
-phony-ubuntu Phony Ubuntu
-phony-windows Phony Windows" ]; then
+if [ "$short_list" != "phony-debian x86_64 Phony Debian
+phony-fedora x86_64 Phony Fedora
+phony-fedora-qcow2 x86_64 Phony Fedora qcow2
+phony-fedora-qcow2-uncompressed x86_64 Phony Fedora qcow2 uncompressed
+phony-fedora-no-format x86_64 Phony Fedora
+phony-ubuntu x86_64 Phony Ubuntu
+phony-windows x86_64 Phony Windows" ]; then
echo "$0: unexpected --list output:"
echo "$short_list"
exit 1
diff --git a/builder/test-virt-builder.sh b/builder/test-virt-builder.sh
index 85a7888..8841984 100755
--- a/builder/test-virt-builder.sh
+++ b/builder/test-virt-builder.sh
@@ -52,6 +52,7 @@ rm -f $output
$VG ./virt-builder phony-fedora \
-v --no-cache --no-check-signature $no_network \
-o $output --size 2G --format $format \
+ --arch x86_64 --allow-foreign-arch-ops \
--hostname test.example.com \
--timezone Europe/London \
--root-password password:123456 \
diff --git a/builder/uname-c.c b/builder/uname-c.c
new file mode 100644
index 0000000..b4f2f61
--- /dev/null
+++ b/builder/uname-c.c
@@ -0,0 +1,60 @@
+/* virt-builder
+ * Copyright (C) 2014 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 handles the interface between the C/lex/yacc index file
+ * parser, and the OCaml world. See index_parser.ml for the OCaml
+ * type definition.
+ */
+
+#include <config.h>
+
+#include <errno.h>
+#include <sys/utsname.h>
+
+#include <caml/alloc.h>
+#include <caml/fail.h>
+#include <caml/memory.h>
+#include <caml/mlvalues.h>
+
+#ifdef HAVE_CAML_UNIXSUPPORT_H
+#include <caml/unixsupport.h>
+#else
+#define Nothing ((value) 0)
+extern void unix_error (int errcode, char * cmdname, value arg) Noreturn;
+#endif
+
+value
+virt_builder_uname (value unit)
+{
+ CAMLparam0 ();
+ CAMLlocal1 (rv);
+ struct utsname u;
+
+ if (uname (&u) < 0)
+ unix_error (errno, (char *) "uname", Val_int (0));
+
+ rv = caml_alloc (5, 0);
+
+ Store_field (rv, 0, caml_copy_string (u.sysname));
+ Store_field (rv, 1, caml_copy_string (u.nodename));
+ Store_field (rv, 2, caml_copy_string (u.release));
+ Store_field (rv, 3, caml_copy_string (u.version));
+ Store_field (rv, 4, caml_copy_string (u.machine));
+
+ CAMLreturn (rv);
+}
diff --git a/builder/uname.ml b/builder/uname.ml
new file mode 100644
index 0000000..c370c2c
--- /dev/null
+++ b/builder/uname.ml
@@ -0,0 +1,27 @@
+(* virt-builder
+ * Copyright (C) 2014 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.
+ *)
+
+type uname_struct = {
+ sysname : string;
+ nodename : string;
+ release : string;
+ version : string;
+ machine : string;
+}
+
+external uname : unit -> uname_struct = "virt_builder_uname"
diff --git a/builder/uname.mli b/builder/uname.mli
new file mode 100644
index 0000000..aea441b
--- /dev/null
+++ b/builder/uname.mli
@@ -0,0 +1,28 @@
+(* virt-builder
+ * Copyright (C) 2014 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.
+ *)
+
+type uname_struct = {
+ sysname : string;
+ nodename : string;
+ release : string;
+ version : string;
+ machine : string;
+}
+
+val uname : unit -> uname_struct
+(** [uname] Tiny wrapper to the C [uname]. *)
diff --git a/builder/virt-builder.pod b/builder/virt-builder.pod
index 32c0961..708bfd0 100644
--- a/builder/virt-builder.pod
+++ b/builder/virt-builder.pod
@@ -15,6 +15,8 @@ virt-builder - Build virtual machine images quickly
virt-builder os-version
[-o|--output DISKIMAGE] [--size SIZE] [--format raw|qcow2]
+ [--allow-foreign-arch-ops]
+ [--arch ARCHITECTURE]
[--attach ISOFILE]
[--root-password SELECTOR]
[--hostname HOSTNAME]
@@ -81,7 +83,9 @@ are any installation notes:
virt-builder fedora-20
-will build a Fedora 20 image. This will have all default
+will build a Fedora 20 image for the same architecture as virt-builder
+(so running it from an i386 installation will try to build an i386
+image, if available). This will have all default
configuration (minimal size, no user accounts, random root password,
only the bare minimum installed software, etc.).
@@ -109,6 +113,10 @@ As above, but the output size will be 20 GB. The guest OS is resized
as it is copied to the output (automatically, using
L<virt-resize(1)>).
+ virt-builder fedora-20 --arch i386
+
+As above, but using an i386 template, if available.
+
=head2 Setting the root password
virt-builder fedora-20 --root-password file:/tmp/rootpw
@@ -189,6 +197,21 @@ You can combine these options, and have multiple options of all types.
Display help.
+=item B<--allow-foreign-arch-ops>
+
+Forces the execution of commands on the target image even if its
+architecture is different than the current host ones.
+
+See also L</ARCHITECTURE>.
+
+=item B<--arch> ARCHITECTURE
+
+Use the specified architecture for the output image. This means
+there must be sources providing the requested template for the
+requested architecture.
+
+See also L</ARCHITECTURE>.
+
=item B<--attach> ISOFILE
During the customization phase, the given disk is attached to the
@@ -1635,13 +1658,13 @@ highly recommended that you always create signed index and templates.
Virt-builder can build a guest for any architecture no matter what the
host architecture is. For example an x86-64 guest on an ARM host.
-However certain options may not work correctly, specifically options
+However certain options may not work, specifically options
that require running commands in the guest during the build process:
I<--install>, I<--update>, I<--run>, I<--run-command>. You may need
-to replace these with their firstboot-equivalents.
-
-An x86-64 host building 32 bit i686 guests should work without any
-special steps.
+to replace these with their firstboot-equivalents, or specify
+I<--allow-foreign-arch-ops> if the target architecture is compatible
+with the host architecture (for example, you are building a 32 bit
+i686 guest on a x86-64 host).
=head2 SECURITY
diff --git a/po/POTFILES b/po/POTFILES
index 5b2ec57..5aeeb2e 100644
--- a/po/POTFILES
+++ b/po/POTFILES
@@ -6,6 +6,7 @@ builder/index-struct.c
builder/index-validate.c
builder/pxzcat-c.c
builder/setlocale-c.c
+builder/uname-c.c
cat/cat.c
cat/filesystems.c
cat/ls.c
diff --git a/po/POTFILES-ml b/po/POTFILES-ml
index 8725e5e..c96b451 100644
--- a/po/POTFILES-ml
+++ b/po/POTFILES-ml
@@ -1,3 +1,4 @@
+builder/architecture.ml
builder/builder.ml
builder/cmdline.ml
builder/downloader.ml
@@ -10,6 +11,7 @@ builder/pxzcat.ml
builder/setlocale.ml
builder/sigchecker.ml
builder/sources.ml
+builder/uname.ml
mllib/common_gettext.ml
mllib/common_utils.ml
mllib/common_utils_tests.ml
--
1.8.3.1
10 years, 9 months