virt-sysprep: Use Augeas for config file manipulation.
[libguestfs.git] / clone / virt-sysprep.in
index 4448860..cf4ad96 100644 (file)
@@ -167,6 +167,11 @@ fi
 # Create a temporary directory for general purpose use during operations.
 tmpdir="$(mktemp -d)"
 
+# Increase the amount of memory allocated to the appliance because
+# we're using augeas.  The user can override this by setting
+# $LIBGUESTFS_MEMSIZE before running the script.
+export LIBGUESTFS_MEMSIZE=${LIBGUESTFS_MEMSIZE:-2048}
+
 # Call guestfish.
 GUESTFISH_PID=
 eval $("${guestfish[@]}")
@@ -175,15 +180,15 @@ if [ -z "$GUESTFISH_PID" ]; then
     exit 1
 fi
 
+# Helper.
+gf="guestfish --remote --"
+
 cleanup ()
 {
-    kill $GUESTFISH_PID >/dev/null 2>&1 ||:
+    $gf exit >/dev/null 2>&1 ||:
     rm -rf "$tmpdir" ||:
 }
-trap cleanup EXIT
-
-# Helper.
-gf="guestfish --remote --"
+trap cleanup EXIT ERR
 
 # Launch back-end, inspect for operating systems, and get the guest
 # root disk.
@@ -209,6 +214,12 @@ if [ "$type" = "windows" ]; then
     systemroot="$($gf -inspect-get-windows-systemroot $root)"
 fi
 
+# Start Augeas if it's a Linux guest.
+if [ "$type" = "linux" ]; then
+    $gf aug-init / 0
+    using_augeas=yes
+fi
+
 #----------------------------------------------------------------------
 # Useful functions.
 
@@ -222,6 +233,18 @@ erase_line ()
     $gf upload "$tmpdir/file.1" "$1"
 }
 
+# prepend_line filename line
+#
+# Prepend a line to a file (this is better than appending, because it
+# works even when the original file isn't terminated with a newline).
+prepend_line ()
+{
+    $gf download "$1" "$tmpdir/file"
+    echo "$2" > "$tmpdir/file.1"
+    cat "$tmpdir/file.1" "$tmpdir/file" >> "$tmpdir/file.2"
+    $gf upload "$tmpdir/file.2" "$1"
+}
+
 # rm_files wildcard
 #
 # Remove files.  Doesn't fail if no files exist.  Note the wildcard
@@ -253,12 +276,12 @@ rm_file ()
 if [ "$hostname" = "yes" ]; then
     case "$type/$distro" in
         linux/fedora)
-            $gf download /etc/sysconfig/network "$tmpdir/network"
-            echo "HOSTNAME=$hostname_param" > "$tmpdir/network.1"
-            sed '/^HOSTNAME=/d' < "$tmpdir/network" >> "$tmpdir/network.1"
-            $gf upload "$tmpdir/network.1" /etc/sysconfig/network ;;
+            $gf aug-set /files/etc/sysconfig/network/HOSTNAME "$hostname_param"
+            augeas_save_needed=yes
+            ;;
         linux/debian|linux/ubuntu)
             $gf write /etc/hostname "$hostname_param"
+            ;;
     esac
 fi
 
@@ -266,10 +289,13 @@ if [ "$net_hwaddr" = "yes" ]; then
     case "$type/$distro" in
         linux/fedora)
             # XXX these filenames can have spaces and untrusted chars in them!
-            files=$($gf glob-expand '/etc/sysconfig/network-scripts/ifcfg-*')
-            for f in $files; do
-                erase_line "$f" "^HWADDR="
+            nodes=$( $gf aug-ls /files/etc/sysconfig/network-scripts |
+                     grep /files/etc/sysconfig/network-scripts/ifcfg- )
+            for node in $nodes; do
+                $gf -aug-rm "$node/HWADDR" >/dev/null
+                augeas_save_needed=yes
             done
+            ;;
     esac
 fi
 
@@ -281,8 +307,14 @@ if [ "$udev_persistent_net" = "yes" -a "$type" = "linux" ]; then
     rm_file /etc/udev/rules.d/70-persistent-net.rules
 fi
 
+#----------------------------------------------------------------------
 # Clean up and close down.
 
+if [ "$using_augeas" = "yes" -a "$augeas_save_needed" = "yes" ]; then
+    $gf aug-save
+    $gf aug-close
+fi
+
 $gf umount-all
 $gf sync
 $gf exit