The previous translation from Perl slavishly followed the Perl code a
bit too much and used a named pipe to communicate between the
uncompressing subprocess and libguestfs tar-in. From C we can use an
anonymous pipe instead.
This updates commit d3512deb67.
Otherwise it moans about:
mkfs: ntfs: /dev/sda: /dev/sda is entire device, not just one partition.
Refusing to make a filesystem here!
This has been happening for a while, so I don't know why we didn't
notice it before. It even happens on RHEL 6.
A simple reproducer is:
virt-make-fs -t ntfs any-tarball.tar.gz test.img
Strictly speaking this reduces the number of formats that virt-make-fs
can output to, but it's likely that no one cares and if they do we can
add new formats in future.
The following commit managed to not actually add the --foreground
option to the timeout command, just test for it. Add it this time.
commit 6814888774
Author: Richard W.M. Jones <rjones@redhat.com>
Date: Thu Dec 19 08:21:53 2013 +0000
run: Use timeout --foreground option.
If timeout doesn't have this option (RHEL 6) don't use timeout at all.
Attempt to fix RHBZ#1025269.
Commit 72afcf450a was partially
incorrect. If the guest userspace is expecting /selinux to exist,
then we should bind-mount /sys/fs/selinux from the appliance kernel
there.
virt-builder and virt-sysprep may make use of
Common_utils.string_random8 (which uses Random.int) for constructing
temporary paths; not initialising the random generator means that every
invocation will reuse the same name used previously (!).
Thus just call Random.self_init, just like virt-sparsify already does.
Expand the test-virt-sysprep-script.sh test to ensure that virt-sysprep
is not affected again by this issue.
All it did was checking for a libvirt version, which is what
libvirt-is-version now does; hence remove the C part, and use guestfish,
ignoring the launch failure (as the C test did).
This adds the --selinux-relabel option which enables selinux in the
appliance and runs:
if load_policy && fixfiles restore; then
rm -f /.autorelabel
else
touch /.autorelabel
fi
at the end of installation.
When possible this fixes SELinux labels in the guest and makes the
autorelabel step unnecessary.
Notes:
- The previous commit is required so that load_policy works.
- During the build, SELinux is enabled but no policy is loaded. This
works because SELinux is in permissive mode.
- This flag does not work if the appliance kernel and the guest have
greatly differing versions, eg. a RHEL 6 guest with a Fedora 20
appliance. This is because SELinux changes the policy format and
breaks backwards compatibility. You would see errors like this:
libsepol.policydb_write: policy version 15 cannot support MLS
libsepol.policydb_to_image: could not compute policy length
libsepol.policydb_to_image: could not create policy image
SELinux: Could not downgrade policy file /etc/selinux/targeted/policy/policy.24, searching for an older version.
SELinux: Could not open policy file <= /etc/selinux/targeted/policy/policy.24: No such file or directory
These errors are ignored (they go to the log file) and relabelling
is done at boot instead.
- It's not clear if loading guest policy is safe. You should trust
the virt-builder templates and to use libguestfs confinement for
additional protection.
Even though we are already bind-mounting /sys, it is necessary to also
bind-mount /sys/fs/selinux in order for SELinux commands (in
particular, 'load_policy') to work.
This fixes/reverts commit 7367729ec7.
It is never normally valid to use the mount-local* APIs when you
haven't mounted some filesystems in the libguestfs namespace.
If you try it, it results in some odd errors. The mount-local-run
call is successful, but subsequent operations fail:
$ mkdir -p /tmp/mnt
$ guestfish -x -N fs mount-local /tmp/mnt : mount-local-run
libguestfs: error: lstat: lstat_stub: you must call 'mount' first to mount the root filesystem
libguestfs: error: lstat: lstat_stub: you must call 'mount' first to mount the root filesystem
With this commit, the mount-local-run call gives an error:
libguestfs: error: you must call 'guestfs_mount' first to mount a filesystem on '/'.
Note: '/tmp/mnt' is still mounted. Use 'guestunmount /tmp/mnt' to clean up.
The error is implemented by calling guestfs_exists (g, "/") which has
the side effect of running the NEED_ROOT macro in the daemon. (There
is no simple equivalent of NEED_ROOT on the library side.)
This fixes the handling of paths for the protocols named above, with
respect to leading '/' (or not) on the volume/export name.
See previous commits which did the same fixes for Ceph:
commit 53a3ff9c00
commit 992a6b2970
If we rely on OCaml's internal exception printing, then it will
truncate error messages like this:
Fatal error: exception Guestfs.Error("could not create appliance
through libvirt.
Try running qemu directly without libvirt using this environment
variable: export LIBGUESTFS_BACKEND=direct
Original error from libvirt: unable to set security context
'unconfined_u:object_r:svi
note the truncation here ^^^^^^^
Instead of using the internal exception printing, wrap the whole
program in a 'main ()' function and add an exception handler.
This large change is non-functional apart from the addition of the
exception handlers at the end.
This tests that libvirt domain XML (ie. guestfish -d option) is parsed
correctly and results in the correct qemu command line when using the
direct backend.
This is a good end-to-end test of various layers.
This is valid for some network drives, for example:
<source protocol='nbd'>
<host name='foo' port='1234'/>
</source>
We pass an empty string as path to the guestfs_add_drive_opts API in
this case.
This is valid for some network drives:
<source protocol='rbd' name='abc-def/ghi-jkl'/>
instead of this:
<source protocol='rbd' name='abc-def/ghi-jkl'>
<host name='foo' port='1234'/>
</source>
Allow both forms.
The path at the API level (for guestfs_add_drive_opts) is:
pool/disk
The URI syntax is either rbd:///pool/disk or rbd://server:port/pool/disk.
Because of the way URI parsing works we may need to remove a leading
'/' character before passing the path down to the API.
The path at the protocol level is:
pool/disk
(with no leading '/' character). This is now what you have to pass to
guestfs_add_drive_opts.
Also Ceph can be called with no explicit servers (it uses the contents
of /etc/ceph/ceph.conf instead). So allow zero servers to be used.