Be more careful about removing files in fakeroot during minimization.
authorRichard Jones <rjones@redhat.com>
Mon, 11 May 2009 13:51:22 +0000 (14:51 +0100)
committerRichard Jones <rjones@redhat.com>
Mon, 11 May 2009 14:41:41 +0000 (15:41 +0100)
Added febootstrap-install program.

.gitignore
Makefile.am
febootstrap-install.pod [new file with mode: 0644]
febootstrap-install.sh [new file with mode: 0755]
febootstrap-minimize.sh
febootstrap-run.pod
febootstrap-to-initramfs.sh
febootstrap.pod

index db68bd9..24fc34d 100644 (file)
@@ -13,6 +13,7 @@ config.status
 configure
 febootstrap
 febootstrap-run
 configure
 febootstrap
 febootstrap-run
+febootstrap-install
 febootstrap-minimize
 febootstrap-to-initramfs
 install-sh
 febootstrap-minimize
 febootstrap-to-initramfs
 install-sh
index c23498b..b239bbf 100644 (file)
@@ -22,6 +22,7 @@ SUBDIRS = examples
 bin_SCRIPTS = \
        febootstrap \
        febootstrap-run \
 bin_SCRIPTS = \
        febootstrap \
        febootstrap-run \
+       febootstrap-install \
        febootstrap-minimize \
        febootstrap-to-initramfs
 DISTCLEANFILES = $(bin_SCRIPTS)
        febootstrap-minimize \
        febootstrap-to-initramfs
 DISTCLEANFILES = $(bin_SCRIPTS)
@@ -38,6 +39,12 @@ febootstrap-run: febootstrap-run.sh
        chmod 0555 $@-t
        mv $@-t $@
 
        chmod 0555 $@-t
        mv $@-t $@
 
+febootstrap-install: febootstrap-install.sh
+       rm -f $@
+       cp $< $@-t
+       chmod 0555 $@-t
+       mv $@-t $@
+
 febootstrap-minimize: febootstrap-minimize.sh
        rm -f $@
        cp $< $@-t
 febootstrap-minimize: febootstrap-minimize.sh
        rm -f $@
        cp $< $@-t
@@ -53,6 +60,7 @@ febootstrap-to-initramfs: febootstrap-to-initramfs.sh
 man_MANS = \
        febootstrap.8 \
        febootstrap-run.8 \
 man_MANS = \
        febootstrap.8 \
        febootstrap-run.8 \
+       febootstrap-install.8 \
        febootstrap-minimize.8 \
        febootstrap-to-initramfs.8
 
        febootstrap-minimize.8 \
        febootstrap-to-initramfs.8
 
@@ -78,6 +86,16 @@ febootstrap-run.8: febootstrap-run.pod
 febootstrap-run.txt: febootstrap-run.pod
        pod2text $< > $@
 
 febootstrap-run.txt: febootstrap-run.pod
        pod2text $< > $@
 
+febootstrap-install.8: febootstrap-install.pod
+       pod2man \
+         --section 8 \
+         -c "Virtualization Support" \
+         --release "$(PACKAGE_NAME)-$(PACKAGE_VERSION)" \
+         $< > $@
+
+febootstrap-install.txt: febootstrap-install.pod
+       pod2text $< > $@
+
 febootstrap-minimize.8: febootstrap-minimize.pod
        pod2man \
          --section 8 \
 febootstrap-minimize.8: febootstrap-minimize.pod
        pod2man \
          --section 8 \
@@ -107,6 +125,8 @@ EXTRA_DIST = \
          febootstrap.sh \
        febootstrap-run.8 febootstrap-run.txt febootstrap-run.pod \
          febootstrap-run.sh \
          febootstrap.sh \
        febootstrap-run.8 febootstrap-run.txt febootstrap-run.pod \
          febootstrap-run.sh \
+       febootstrap-install.8 febootstrap-install.txt febootstrap-install.pod \
+         febootstrap-install.sh \
        febootstrap-minimize.8 febootstrap-minimize.txt \
          febootstrap-minimize.pod \
          febootstrap-minimize.sh \
        febootstrap-minimize.8 febootstrap-minimize.txt \
          febootstrap-minimize.pod \
          febootstrap-minimize.sh \
diff --git a/febootstrap-install.pod b/febootstrap-install.pod
new file mode 100644 (file)
index 0000000..f48d217
--- /dev/null
@@ -0,0 +1,49 @@
+=head1 NAME
+
+febootstrap-install - Install a file in an febootstrap root filesystem
+
+=head1 SYNOPSIS
+
+ febootstrap-install ROOT LOCALFILE TARGETPATH MODE OWNER[.GROUP]
+
+=head1 DESCRIPTION
+
+This can be used to safely install a new file in an febootstrap
+root filesystem.
+
+Just copying a file in isn't usually safe, for reasons which are to do
+with the L<fakeroot(8)> command.
+
+=head1 EXAMPLE
+
+ febootstrap-install initramfs new-fstab /etc/fstab ugo=rw root.root
+
+=head1 SEE ALSO
+
+L<febootstrap(8)>,
+L<febootstrap-run(8)>,
+L<fakeroot(1)>,
+L<fakechroot(1)>.
+
+=head1 AUTHORS
+
+Richard W.M. Jones <rjones @ redhat . com>
+
+=head1 COPYRIGHT
+
+(C) Copyright 2009 Red Hat Inc.,
+L<http://et.redhat.com/~rjones/febootstrap>.
+
+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., 675 Mass Ave, Cambridge, MA 02139, USA.
diff --git a/febootstrap-install.sh b/febootstrap-install.sh
new file mode 100755 (executable)
index 0000000..76b99b7
--- /dev/null
@@ -0,0 +1,45 @@
+#!/bin/bash -
+# febootstrap-install
+# (C) Copyright 2009 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+# Written by Richard W.M. Jones <rjones@redhat.com>
+
+unset CDPATH
+
+usage ()
+{
+    echo "Usage: febootstrap-install ROOT LOCALFILE TARGETPATH MODE OWNER[.GROUP]"
+    echo "Please read febootstrap-install(8) man page for more information."
+}
+
+if [ $# != 5 ]; then
+    usage
+    exit 1
+fi
+
+set -e
+
+# This is a carefully chosen sequence of commands which
+# tries not to disturb any inode numbers apart from the
+# one for the new file.
+cp "$2" "$1"/"$3"
+ino=$(ls -i "$1"/"$3" | awk '{print $1}')
+cp "$1"/fakeroot.log "$1"/fakeroot.log.old
+grep -v "ino=$ino," "$1"/fakeroot.log.old > "$1"/fakeroot.log
+rm "$1"/fakeroot.log.old
+febootstrap-run "$1" -- chmod "$4" "$3"
+febootstrap-run "$1" -- chown "$5" "$3"
index 148de5c..efee844 100755 (executable)
@@ -176,43 +176,48 @@ trap remove_tmpdir EXIT
 
 #----------------------------------------------------------------------
 
 
 #----------------------------------------------------------------------
 
+# ***NOTE*** Wildcards cannot be passed to febootstrap-run.
+
 if [ "$keep_locales" != "yes" ]; then
 if [ "$keep_locales" != "yes" ]; then
-    rm -rf "$target"/usr/lib/locale/*
-    rm -rf "$target"/usr/share/locale
-    rm -rf "$target"/usr/lib*/gconv
-    rm -f "$target"/usr/bin/localedef
-    rm -f "$target"/usr/sbin/build-locale-archive
+    febootstrap-run "$target" -- rm -rf usr/lib/locale
+    febootstrap-run "$target" -- rm -rf usr/share/locale
+    febootstrap-run "$target" -- rm -rf usr/lib/gconv usr/lib64/gconv
+    febootstrap-run "$target" -- rm -f usr/bin/localedef
+    febootstrap-run "$target" -- rm -f usr/sbin/build-locale-archive
 fi
 
 if [ "$keep_docs" != "yes" ]; then
 fi
 
 if [ "$keep_docs" != "yes" ]; then
-    rm -rf "$target"/usr/share/man
-    rm -rf "$target"/usr/share/doc
-    rm -rf "$target"/usr/share/info
-    rm -rf "$target"/usr/share/gnome/help
+    febootstrap-run "$target" -- rm -rf usr/share/man
+    febootstrap-run "$target" -- rm -rf usr/share/doc
+    febootstrap-run "$target" -- rm -rf usr/share/info
+    febootstrap-run "$target" -- rm -rf usr/share/gnome/help
 fi
 
 if [ "$keep_cracklib" != "yes" ]; then
 fi
 
 if [ "$keep_cracklib" != "yes" ]; then
-    rm -rf "$target"/usr/share/cracklib
+    febootstrap-run "$target" -- rm -rf usr/share/cracklib
 fi
 
 if [ "$keep_i18n" != "yes" ]; then
 fi
 
 if [ "$keep_i18n" != "yes" ]; then
-    rm -rf "$target"/usr/share/i18n
+    febootstrap-run "$target" -- rm -rf usr/share/i18n
 fi
 
 if [ "$keep_zoneinfo" != "yes" ]; then
     mv "$target"/usr/share/zoneinfo/{UCT,UTC,Universal,Zulu,GMT*,*.tab} \
       "$target"
 fi
 
 if [ "$keep_zoneinfo" != "yes" ]; then
     mv "$target"/usr/share/zoneinfo/{UCT,UTC,Universal,Zulu,GMT*,*.tab} \
       "$target"
-    rm -rf "$target"/usr/share/zoneinfo/*
+    febootstrap-run "$target" -- rm -rf usr/share/zoneinfo
+    febootstrap-run "$target" -- mkdir -p --mode=0755 usr/share/zoneinfo
     mv "$target"/{UCT,UTC,Universal,Zulu,GMT*,*.tab} \
       "$target"/usr/share/zoneinfo/
 fi
 
 if [ "$keep_rpmdb" != "yes" ]; then
     mv "$target"/{UCT,UTC,Universal,Zulu,GMT*,*.tab} \
       "$target"/usr/share/zoneinfo/
 fi
 
 if [ "$keep_rpmdb" != "yes" ]; then
-    rm -rf "$target"/var/lib/rpm/*
+    febootstrap-run "$target" -- rm -rf var/lib/rpm
+    febootstrap-run "$target" -- mkdir -p --mode=0755 var/lib/rpm
 fi
 
 if [ "$keep_yum_cache" != "yes" ]; then
 fi
 
 if [ "$keep_yum_cache" != "yes" ]; then
-    rm -rf "$target"/var/cache/yum/*
+    febootstrap-run "$target" -- rm -rf var/cache/yum
+    febootstrap-run "$target" -- mkdir -p --mode=0755 var/cache/yum
 fi
 
 if [ "$keep_services" != "yes" ]; then
 fi
 
 if [ "$keep_services" != "yes" ]; then
@@ -270,13 +275,14 @@ __EOF__
 fi
 
 if [ "$keep_sln" != "yes" ]; then
 fi
 
 if [ "$keep_sln" != "yes" ]; then
-    rm -f "$target"/sbin/sln
+    febootstrap-run "$target" -- rm -f sbin/sln
 fi
 
 if [ "$keep_ldconfig" != "yes" ]; then
 fi
 
 if [ "$keep_ldconfig" != "yes" ]; then
-    rm -f "$target"/sbin/ldconfig
-    rm -f "$target"/etc/ld.so.cache
-    rm -rf "$target"/var/cache/ldconfig/*
+    febootstrap-run "$target" -- rm -f sbin/ldconfig
+    febootstrap-run "$target" -- rm -f etc/ld.so.cache
+    febootstrap-run "$target" -- rm -rf var/cache/ldconfig
+    febootstrap-run "$target" -- mkdir -p --mode=0755 var/cache/ldconfig
 fi
 
 if [ "$pack_executables" = "yes" ]; then
 fi
 
 if [ "$pack_executables" = "yes" ]; then
index 9072f5a..d6440ca 100644 (file)
@@ -39,20 +39,11 @@ contents still happen).
 
 =head1 EXAMPLES
 
 
 =head1 EXAMPLES
 
-One way to create a new file with specific ownership and permissions
-from a script is to create new content for a file as C<root/file.new>:
+Remove a directory subtree safely:
 
 
- #!/bin/bash
-
- echo blah > root/file.new
-
-then "install" it with the correct ownership and permissions.
-
- febootstrap-run root -- install -m 0644 -o root -g root /file.new /file
- rm root/file.new
+ febootstrap-run initramfs -- rm -r /etc
 
 
-(This requires that the C</usr/bin/install> command from coreutils
-exists inside the root.)
+(This requires that you have a compatible 'rm' command in the root).
 
 Another way to do complex operations from a script is to export a
 function:
 
 Another way to do complex operations from a script is to export a
 function:
@@ -76,6 +67,7 @@ particular you may want to set:
 =head1 SEE ALSO
 
 L<febootstrap(8)>,
 =head1 SEE ALSO
 
 L<febootstrap(8)>,
+L<febootstrap-install(8)>,
 L<fakeroot(1)>,
 L<fakechroot(1)>.
 
 L<fakeroot(1)>,
 L<fakechroot(1)>.
 
index 6dfc3f9..849aa7b 100755 (executable)
@@ -32,6 +32,8 @@ if [ ! -f fakeroot.log -a $(id -u) -ne 0 ]; then
     exit 1
 fi
 
     exit 1
 fi
 
+set -e
+
 if [ -f fakeroot.log ]; then
     fakeroot -i fakeroot.log \
     sh -c 'find -not -name fakeroot.log -a -print0 | cpio -o0c | gzip --best'
 if [ -f fakeroot.log ]; then
     fakeroot -i fakeroot.log \
     sh -c 'find -not -name fakeroot.log -a -print0 | cpio -o0c | gzip --best'
index 109f6a2..e208603 100644 (file)
@@ -129,8 +129,8 @@ so that yum thinks it is running as root.  Fakeroot keeps track of
 directory as C<I<TARGET>/fakeroot.log>.
 
 This logfile is indexed by inode number, which makes certain
 directory as C<I<TARGET>/fakeroot.log>.
 
 This logfile is indexed by inode number, which makes certain
-operations safe and other operations unsafe.  For example, deleting
-files is usually safe.  Files should be replaced only by doing:
+operations safe and other operations unsafe.
+Files should be replaced only by doing:
 
  echo updated-content > old-file
 
 
  echo updated-content > old-file
 
@@ -139,9 +139,12 @@ files is usually safe.  Files should be replaced only by doing:
 Deleting files and then creating new ones (even with a different name)
 is usually unsafe, because the new files might reuse inodes claimed by
 the old files, and so appear with peculiar permissions
 Deleting files and then creating new ones (even with a different name)
 is usually unsafe, because the new files might reuse inodes claimed by
 the old files, and so appear with peculiar permissions
-(eg. unreadable, or as a symbolic link).  (XXX We need an
-C<febootstrap-install> utility to automate installing new files safely
-into a filesystem).
+(eg. unreadable, or as a symbolic link).
+
+Deleting files is also usually unsafe, although the reasons are more
+subtle.  If you just use C<rm> then the inode number is not deleted
+from C<fakeroot.log> which means it can be reused by another file
+later on.
 
 In most cases it's usually safest to use C<febootstrap-run>.
 
 
 In most cases it's usually safest to use C<febootstrap-run>.
 
@@ -156,6 +159,11 @@ permissions.
 
 =item *
 
 
 =item *
 
+Use L<febootstrap-install(8)> to install a file with permissions
+in the root filesystem.
+
+=item *
+
 Generate an initramfs (compressed cpio) file containing the correct
 permissions using the tool C<febootstrap-to-initramfs>.
 
 Generate an initramfs (compressed cpio) file containing the correct
 permissions using the tool C<febootstrap-to-initramfs>.
 
@@ -218,6 +226,7 @@ L<http://et.redhat.com/~rjones/febootstrap>
 L<febootstrap-to-initramfs(8)>,
 L<febootstrap-minimize(8)>,
 L<febootstrap-run(8)>,
 L<febootstrap-to-initramfs(8)>,
 L<febootstrap-minimize(8)>,
 L<febootstrap-run(8)>,
+L<febootstrap-install(8)>,
 L<fakeroot(1)>,
 L<fakechroot(1)>,
 L<yum(8)>,
 L<fakeroot(1)>,
 L<fakechroot(1)>,
 L<yum(8)>,