[Fai-commit] r5686 - in trunk: bin debian lib lib/setup-storage man

Michael Tautschnig mt at alioth.debian.org
Tue Dec 1 20:43:36 UTC 2009


Author: mt
Date: 2009-12-01 20:43:35 +0000 (Tue, 01 Dec 2009)
New Revision: 5686

Modified:
   trunk/bin/setup-storage
   trunk/debian/changelog
   trunk/lib/setup-storage/Commands.pm
   trunk/lib/setup-storage/Fstab.pm
   trunk/lib/setup-storage/Init.pm
   trunk/lib/setup-storage/Parser.pm
   trunk/lib/setup-storage/Sizes.pm
   trunk/lib/setup-storage/Volumes.pm
   trunk/lib/subroutines
   trunk/man/setup-storage.8
Log:
merged crypto-related patches for setup-storage from experimental, merged sameas
option patch; thanks Julien Blache for all the work.


Modified: trunk/bin/setup-storage
===================================================================
--- trunk/bin/setup-storage	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/bin/setup-storage	2009-12-01 20:43:35 UTC (rev 5686)
@@ -52,7 +52,7 @@
 
 package FAI;
 
-my $version = "1.1.4";
+my $version = "1.2";
 
 # command line parameter handling
 use Getopt::Std;
@@ -174,6 +174,7 @@
 &FAI::build_disk_commands;
 &FAI::build_raid_commands;
 &FAI::build_lvm_commands;
+&FAI::build_cryptsetup_commands;
 &FAI::order_commands;
 
 # run all commands

Modified: trunk/debian/changelog
===================================================================
--- trunk/debian/changelog	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/debian/changelog	2009-12-01 20:43:35 UTC (rev 5686)
@@ -1,8 +1,15 @@
 fai (3.3.3) unstable; urgency=low
 
-  * 3.3.3
+  [ Michael Tautschnig ]
+  * setup-storage: Bumped version number to 1.2
+  * setup-storage: Encryption is now configured via a separate cryptsetup
+    stanza, deprecated the previous :encrypt option (thanks Julien BLACHE for
+    the patch).
+  * setup-storage.8: Updated documentation, added cryptsetup example.
+  * setup-storage/Parser.pm, setup-storage.8: Added new sameas disk_config
+    option (thanks Julien BLACHE for the patch).
 
- -- Thomas Lange <lange at debian.org>  Mon, 30 Nov 2009 22:15:39 +0100
+ -- Thomas Lange <lange at debian.org>  Tue, 01 Dec 2009 21:41:56 +0100
 
 fai (3.3.2) unstable; urgency=low
 

Modified: trunk/lib/setup-storage/Commands.pm
===================================================================
--- trunk/lib/setup-storage/Commands.pm	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/setup-storage/Commands.pm	2009-12-01 20:43:35 UTC (rev 5686)
@@ -48,6 +48,9 @@
 
   my ($device, $partition) = @_;
 
+  # check for old-style encryption requests
+  &FAI::handle_oldstyle_encrypt_device($device, $partition);
+
   defined ($partition->{filesystem})
     or &FAI::internal_error("filesystem is undefined");
   my $fs = $partition->{filesystem};
@@ -63,16 +66,11 @@
   print "$partition->{mountpoint} FS create_options: $create_options\n" if ($FAI::debug && $create_options);
   print "$partition->{mountpoint} FS tune_options: $tune_options\n" if ($FAI::debug && $tune_options);
 
-  # check for encryption requests
-  $device = &FAI::encrypt_device($device, $partition);
-
   # create the file system with options
   my $create_tool = "mkfs.$fs";
   ($fs eq "swap") and $create_tool = "mkswap";
   ($fs eq "xfs") and $create_options = "$create_options -f" unless ($create_options =~ m/-f/);
-  my $pre_encrypt = "exist_$device";
-  $pre_encrypt = "encrypted_$device" if ($partition->{encrypt});
-  &FAI::push_command( "$create_tool $create_options $device", $pre_encrypt,
+  &FAI::push_command( "$create_tool $create_options $device", "exist_$device",
     "has_fs_$device" );
 
   # possibly tune the file system - this depends on whether the file system
@@ -90,50 +88,44 @@
 
 ################################################################################
 #
-# @brief Encrypt a device and change the device name before formatting it
+# @brief Check for encrypt option and prepare corresponding CRYPT entry
 #
+# If encrypt is set, a corresponding CRYPT entry will be created and filesystem
+# and mountpoint get set to -
+#
 # @param $device Original device name of the target partition
 # @param $partition Reference to partition in the config hash
 #
-# @return Device name, may be the same as $device
-#
 ################################################################################
-sub encrypt_device {
+sub handle_oldstyle_encrypt_device {
 
   my ($device, $partition) = @_;
 
-  return $device unless $partition->{encrypt};
+  return unless ($partition->{encrypt});
 
-  # encryption requested, rewrite the device name
-  my $enc_dev_name = $device;
-  $enc_dev_name =~ s#/#_#g;
-  my $enc_dev_short_name = "crypt$enc_dev_name";
-  $enc_dev_name = "/dev/mapper/$enc_dev_short_name";
-  my $keyfile = "$ENV{LOGDIR}/$enc_dev_short_name";
-
-  # generate a key for encryption
-  &FAI::push_command( 
-    "head -c 2048 /dev/urandom | head -n 47 | tail -n 46 | od | tee $keyfile",
-    "", "keyfile_$device" );
-  # prepare encryption
-  my $prepare_deps = "keyfile_$device";
-  if ($partition->{encrypt} > 1) {
-    &FAI::push_command(
-      "dd if=/dev/urandom of=$device",
-      "exist_$device", "random_init_$device" );
-    $prepare_deps = "random_init_$device,$prepare_deps";
+  if (!defined($FAI::configs{CRYPT}{randinit})) {
+    $FAI::configs{CRYPT}{fstabkey} = "device";
+    $FAI::configs{CRYPT}{randinit} = 0;
+    $FAI::configs{CRYPT}{volumes} = {};
   }
-  &FAI::push_command(
-    "yes YES | cryptsetup luksFormat $device $keyfile -c aes-cbc-essiv:sha256 -s 256",
-    $prepare_deps, "crypt_format_$device" );
-  &FAI::push_command(
-    "cryptsetup luksOpen $device $enc_dev_short_name --key-file $keyfile",
-    "crypt_format_$device", "encrypted_$enc_dev_name" );
 
-  # add entries to crypttab
-  push @FAI::crypttab, "$enc_dev_short_name\t$device\t$keyfile\tluks";
+  $FAI::configs{CRYPT}{randinit} = 1 if ($partition->{encrypt} > 1);
 
-  return $enc_dev_name;
+  my $vol_id = scalar(keys %{ $FAI::configs{CRYPT}{volumes} });
+  $FAI::configs{CRYPT}{volumes}{$vol_id} = {
+    device => $device,
+    mode => "luks",
+    preserve => (defined($partition->{size}) ?
+        $partition->{size}->{preserve} : $partition->{preserve}),
+    mountpoint => $partition->{mountpoint},
+    mount_options => $partition->{mount_options},
+    filesystem => $partition->{filesystem},
+    createopts => $partition->{createopts},
+    tuneopts => $partition->{tuneopts}
+  };
+
+  $partition->{mountpoint} = "-";
+  $partition->{filesystem} = "-";
 }
 
 ################################################################################
@@ -162,6 +154,80 @@
 ################################################################################
 #
 # @brief Using the configurations from %FAI::configs, a list of commands is
+# built to create any encrypted devices
+#
+################################################################################
+sub build_cryptsetup_commands {
+  foreach my $config (keys %FAI::configs) { # loop through all configs
+    # no LVM or physical devices here
+    next if ($config ne "CRYPT");
+
+    # create all encrypted devices
+    foreach my $id (&numsort(keys %{ $FAI::configs{$config}{volumes} })) {
+
+      # keep a reference to the current volume
+      my $vol = (\%FAI::configs)->{$config}->{volumes}->{$id};
+      # the desired encryption mode
+      my $mode = $vol->{mode};
+
+      warn "cryptsetup support is incomplete - preserve is not supported\n"
+        if ($vol->{preserve});
+
+      # rewrite the device name
+      my $real_dev = $vol->{device};
+      my $enc_dev_name = &FAI::enc_name($real_dev);
+      my $enc_dev_short_name = $enc_dev_name;
+      $enc_dev_short_name =~ s#^/dev/mapper/##;
+
+      my $pre_dep = "exist_$real_dev";
+
+      if ($FAI::configs{$config}{randinit}) {
+        # ignore exit 1 caused by reaching the end of $real_dev
+        &FAI::push_command(
+          "dd if=/dev/urandom of=$real_dev || true",
+          $pre_dep, "random_init_$real_dev");
+        $pre_dep = "random_init_$real_dev";
+      }
+
+      if ($mode eq "luks") {
+        my $keyfile = "$ENV{LOGDIR}/$enc_dev_short_name";
+
+        # generate a key for encryption
+        &FAI::push_command(
+          "head -c 2048 /dev/urandom | head -n 47 | tail -n 46 | od | tee $keyfile",
+          "", "keyfile_$real_dev" );
+        # encrypt
+        &FAI::push_command(
+          "yes YES | cryptsetup luksFormat $real_dev $keyfile -c aes-cbc-essiv:sha256 -s 256",
+          "$pre_dep,keyfile_$real_dev", "crypt_format_$real_dev" );
+        &FAI::push_command(
+          "cryptsetup luksOpen $real_dev $enc_dev_short_name --key-file $keyfile",
+          "crypt_format_$real_dev", "exist_$enc_dev_name" );
+
+        # add entries to crypttab
+        push @FAI::crypttab, "$enc_dev_short_name\t$real_dev\t$keyfile\tluks";
+
+      } elsif ($mode eq "tmp" || $mode eq "swap") {
+        &FAI::push_command(
+          "cryptsetup --key-file=/dev/urandom create $enc_dev_short_name $real_dev",
+          $pre_dep, "exist_$enc_dev_name");
+
+        # add entries to crypttab
+        push @FAI::crypttab, "$enc_dev_short_name\t$real_dev\t/dev/urandom\t$mode";
+
+      }
+
+      # create the filesystem on the volume
+      &FAI::build_mkfs_commands($enc_dev_name,
+        \%{ $FAI::configs{$config}{volumes}{$id} });
+    }
+  }
+
+}
+
+################################################################################
+#
+# @brief Using the configurations from %FAI::configs, a list of commands is
 # built to create any RAID devices
 #
 ################################################################################
@@ -169,7 +235,7 @@
 
   foreach my $config (keys %FAI::configs) { # loop through all configs
     # no LVM or physical devices here
-    next if ($config =~ /^VG_./ || $config =~ /^PHY_./);
+    next if ($config eq "CRYPT" || $config =~ /^VG_./ || $config =~ /^PHY_./);
     ($config eq "RAID") or &FAI::internal_error("Invalid config $config");
 
     # create all raid devices
@@ -204,11 +270,12 @@
           next;
         } else {
           if ($vol->{devices}->{$d}->{spare}) {
-            push @spares, $d;
+            push @spares, &FAI::enc_name($d);
           } else {
-            push @eff_devs, $d;
+            push @eff_devs, &FAI::enc_name($d);
           }
         }
+        $d = &FAI::enc_name($d);
         &FAI::set_partition_type_on_phys_dev($d, "raid");
         if ((&FAI::phys_dev($d))[0]) {
           $pre_req .= ",type_raid_$d";
@@ -302,7 +369,8 @@
   # create the volume group, if it doesn't exist already
   if (!$vg_exists) {
     # create all the devices
-    my @devices = keys %{ $FAI::configs{$config}{devices} };
+    my @devices = ();
+    push @devices, &FAI::enc_name($_) foreach (keys %{ $FAI::configs{$config}{devices} });
     &FAI::erase_lvm_signature(\@devices);
     &FAI::push_command( "pvcreate $pv_create_options $_",
       "pv_sigs_removed,exist_$_", "pv_done_$_") foreach (@devices);
@@ -324,7 +392,8 @@
   # create an undefined entry for each new device
   @new_devs{ keys %{ $FAI::configs{$config}{devices} } } = ();
 
-  my @new_devices = keys %new_devs;
+  my @new_devices = ();
+  push @new_devices, &FAI::enc_name($_) foreach (keys %new_devs);
 
   # &FAI::erase_lvm_signature( \@new_devices );
 
@@ -452,8 +521,8 @@
   # loop through all configs
   foreach my $config (keys %FAI::configs) {
 
-    # no physical devices or RAID here
-    next if ($config =~ /^PHY_./ || $config eq "RAID");
+    # no physical devices, RAID or encrypted here
+    next if ($config =~ /^PHY_./ || $config eq "RAID" || $config eq "CRYPT");
     ($config =~ /^VG_(.+)$/) or &FAI::internal_error("Invalid config $config");
     next if ($1 eq "--ANY--");
     my $vg = $1; # the volume group
@@ -463,6 +532,7 @@
       foreach (keys %{ $FAI::configs{$config}{devices} });
     my $type_pre = "";
     foreach my $d (keys %{ $FAI::configs{$config}{devices} }) {
+      $d = &FAI::enc_name($d);
       if ((&FAI::phys_dev($d))[0]) {
         $type_pre .= ",type_lvm_$d"
       } else {
@@ -859,8 +929,8 @@
 
   # loop through all configs
   foreach my $config ( keys %FAI::configs ) {
-    # no RAID or LVM devices here
-    next if ($config eq "RAID" || $config =~ /^VG_./);
+    # no RAID, encrypted or LVM devices here
+    next if ($config eq "RAID" || $config eq "CRYPT" || $config =~ /^VG_./);
     ($config =~ /^PHY_(.+)$/) or &FAI::internal_error("Invalid config $config");
     my $disk = $1; # the device to be configured
 

Modified: trunk/lib/setup-storage/Fstab.pm
===================================================================
--- trunk/lib/setup-storage/Fstab.pm	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/setup-storage/Fstab.pm	2009-12-01 20:43:35 UTC (rev 5686)
@@ -169,11 +169,6 @@
         next if ($p_ref->{size}->{extended} || $p_ref->{mountpoint} eq "-");
 
         my $device_name = &FAI::make_device_name($device, $p_ref->{number});
-        if ($p_ref->{encrypt}) {
-          # encryption requested, rewrite the device name
-          $device_name =~ s#/#_#g;
-          $device_name = "/dev/mapper/crypt$device_name";
-        }
 
         # if the mount point is / or /boot, the variables should be set, unless
         # they are already
@@ -218,14 +213,7 @@
         ($FAI::no_dry_run == 0 || -b $fstab_key[0]) 
           or die "Failed to resolve /dev/$device/$l\n";
 
-        my $device_name = "/dev/$device/$l";
-        if ($l_ref->{encrypt}) {
-          # encryption requested, rewrite the device name
-          $device_name =~ s#/#_#g;
-          $device_name = "/dev/mapper/crypt$device_name";
-        } else {
-          $device_name = $fstab_key[0];
-        }
+        my $device_name = $fstab_key[0];
 
         # according to http://grub.enbug.org/LVMandRAID, this should work...
         # if the mount point is / or /boot, the variables should be set, unless
@@ -253,11 +241,6 @@
         next if ($r_ref->{mountpoint} eq "-");
 
         my $device_name = "/dev/md$r";
-        if ($r_ref->{encrypt}) {
-          # encryption requested, rewrite the device name
-          $device_name =~ s#/#_#g;
-          $device_name = "/dev/mapper/crypt$device_name";
-        } 
 
         # according to http://grub.enbug.org/LVMandRAID, this should work...
         # if the mount point is / or /boot, the variables should be set, unless
@@ -273,6 +256,20 @@
         push @fstab, &FAI::create_fstab_line($r_ref,
           &FAI::get_fstab_key($device_name, $config->{RAID}->{fstabkey}), $device_name);
       }
+    } elsif ($c eq "CRYPT") {
+      foreach my $v (keys %{ $config->{$c}->{volumes} }) {
+        my $c_ref = $config->{$c}->{volumes}->{$v};
+
+        next if ($c_ref->{mountpoint} eq "-");
+
+        my $device_name = &FAI::enc_name($c_ref->{device});
+
+        ($c_ref->{mountpoint} eq "/boot" || ($c_ref->{mountpoint} eq "/" &&
+            !defined ($FAI::disk_var{BOOT_PARTITION}))) and
+          die "Boot partition cannot be encrypted\n";
+
+        push @fstab, &FAI::create_fstab_line($c_ref, $device_name, $device_name);
+      }
     } else {
       &FAI::internal_error("Unexpected key $c");
     }

Modified: trunk/lib/setup-storage/Init.pm
===================================================================
--- trunk/lib/setup-storage/Init.pm	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/setup-storage/Init.pm	2009-12-01 20:43:35 UTC (rev 5686)
@@ -130,6 +130,13 @@
 
 ################################################################################
 #
+# @brief Device alias names
+#
+################################################################################
+%FAI::dev_alias = ();
+
+################################################################################
+#
 # @brief Add command to hash
 #
 # @param cmd Command
@@ -185,6 +192,63 @@
 
 ################################################################################
 #
+# @brief Compute the name of $dev considering possible encryption
+#
+# @param $dev Device string
+#
+# @return $dev iff $dev is not encrypted, otherwise /dev/mapper/<mangled name>
+#
+################################################################################
+sub enc_name {
+  my ($dev) = @_;
+
+  return $FAI::dev_alias{$dev} if defined($FAI::dev_alias{$dev});
+
+  # handle old-style encryption entries
+  my ($i_p_d, $disk, $part_no) = &FAI::phys_dev($dev);
+  if ($i_p_d) {
+    defined ($FAI::configs{"PHY_$disk"}) or return $dev;
+    defined ($FAI::configs{"PHY_$disk"}{partitions}{$part_no}) or return $dev;
+    return $dev unless
+      ($FAI::configs{"PHY_$disk"}{partitions}{$part_no}{encrypt});
+  } elsif ($dev =~ /^\/dev\/md(\d+)$/) {
+    defined ($FAI::configs{RAID}) or return $dev;
+    defined ($FAI::configs{RAID}{volumes}{$1}) or return $dev;
+    return $dev unless ($FAI::configs{RAID}{volumes}{$1}{encrypt});
+  } elsif ($dev =~ /^\/dev\/([^\/]+)\/([^\/]+)$/) {
+    defined ($FAI::configs{"VG_$1"}) or return $dev;
+    defined ($FAI::configs{"VG_$1"}{volumes}{$2}) or return $dev;
+    return $dev unless ($FAI::configs{"VG_$1"}{volumes}{$2}{encrypt});
+  } else {
+    return $dev;
+  }
+
+  &FAI::mark_encrypted($dev);
+
+  return $FAI::dev_alias{$dev};
+}
+
+################################################################################
+#
+# @brief Store mangled name for $dev
+#
+# @param $dev Device string
+#
+################################################################################
+sub mark_encrypted {
+  my ($dev) = @_;
+
+  # encryption requested, rewrite the device name
+  my $enc_dev_name = $dev;
+  $enc_dev_name =~ s#/#_#g;
+  my $enc_dev_short_name = "crypt$enc_dev_name";
+  $enc_dev_name = "/dev/mapper/$enc_dev_short_name";
+
+  $FAI::dev_alias{$dev} = $enc_dev_name;
+}
+
+################################################################################
+#
 # @brief Convert a device name and a partition id to a proper device name,
 # handling cciss and the like
 #

Modified: trunk/lib/setup-storage/Parser.pm
===================================================================
--- trunk/lib/setup-storage/Parser.pm	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/setup-storage/Parser.pm	2009-12-01 20:43:35 UTC (rev 5686)
@@ -68,21 +68,17 @@
 }
 
 ################################################################################
+# @brief Determines a device's full path from a short name or number
 #
-# @brief Initialise a new entry in @ref $FAI::configs for a physical disk.
+# Resolves the device name (/dev/sda), short name (sda) or device number (0) to
+# a full device name (/dev/sda) and tests whether the device is a valid block
+# device.
 #
-# Besides creating the entry in the hash, the fully path of the device is
-# computed (see @ref $disk) and it is tested, whether this is a block device.
-# The device name is then used to define @ref $FAI::device.
-#
 # @param $disk Either an integer, occurring in the context of, e.g., disk2, or
 # a device name. The latter may be fully qualified, such as /dev/hda, or a short
 # name, such as sdb, in which case /dev/ is prepended.
-#
 ################################################################################
-sub init_disk_config {
-
-  # Initialise $disk
+sub resolve_disk_shortname {
   my ($disk) = @_;
 
   # test $disk for being numeric
@@ -104,6 +100,28 @@
   $disk = $candidates[0] if (scalar(@candidates) == 1);
   die "Device name $disk could not be substituted\n" if ($disk =~ m{[\*\?\[\{\~]});
 
+  return $disk;
+}
+
+################################################################################
+#
+# @brief Initialise a new entry in @ref $FAI::configs for a physical disk.
+#
+# Checks whether the specified device is valid, creates the entry in the hash
+# and sets @ref $FAI::device.
+#
+# @param $disk Either an integer, occurring in the context of, e.g., disk2, or
+# a device name. The latter may be fully qualified, such as /dev/hda, or a short
+# name, such as sdb, in which case /dev/ is prepended.
+#
+################################################################################
+sub init_disk_config {
+
+  # Initialise $disk
+  my ($disk) = @_;
+
+  $disk = &FAI::resolve_disk_shortname($disk);
+
   # prepend PHY_
   $FAI::device = "PHY_$disk";
 
@@ -325,6 +343,15 @@
           $FAI::configs{$FAI::device}{fstabkey} = "device";
         }
         raid_option(s?)
+        | 'cryptsetup'
+        {
+          &FAI::in_path("cryptsetup") or die "cryptsetup not found in PATH\n";
+          $FAI::device = "CRYPT";
+          $FAI::configs{$FAI::device}{fstabkey} = "device";
+          $FAI::configs{$FAI::device}{randinit} = 0;
+          $FAI::configs{$FAI::device}{volumes} = {};
+        }
+        cryptsetup_option(s?)
         | /^lvm/
         {
 
@@ -376,6 +403,11 @@
           $FAI::configs{$FAI::device}{fstabkey} = $1;
         }
 
+    cryptsetup_option: /^randinit/
+        {
+          $FAI::configs{$FAI::device}{randinit} = 1;
+        }
+
     lvm_option: m{^preserve_always:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
         {
           # set the preserve flag for all ids in all cases
@@ -411,6 +443,7 @@
           $FAI::configs{"VG_--ANY--"}{fstabkey} = $1;
         }
 
+
     option: /^preserve_always:(\d+(,\d+)*)/
         {
           # set the preserve flag for all ids in all cases
@@ -456,7 +489,25 @@
           # the information preferred for fstab device identifieres
           $FAI::configs{$FAI::device}{fstabkey} = $1;
         }
+	| /^sameas:disk(\d+)/
+	{
+	  my $ref_dev = &FAI::resolve_disk_shortname($1);
+	  defined($FAI::configs{"PHY_" . $ref_dev}) or die "Reference device $ref_dev not found in config\n";
 
+	  use Storable qw(dclone);
+
+	  $FAI::configs{$FAI::device} = dclone($FAI::configs{"PHY_" . $ref_dev});
+	}
+	| /^sameas:(\S+)/
+	{
+	  my $ref_dev = &FAI::resolve_disk_shortname($1);
+	  defined($FAI::configs{"PHY_" . $ref_dev}) or die "Reference device $ref_dev not found in config\n";
+
+	  use Storable qw(dclone);
+
+	  $FAI::configs{$FAI::device} = dclone($FAI::configs{"PHY_" . $ref_dev});
+	}
+
     volume: /^vg\s+/ name devices vgcreateopt(s?)
         | /^raid([0156]|10)\s+/
         {
@@ -464,7 +515,8 @@
           ($FAI::device eq "RAID") or die "RAID entry invalid in this context\n";
           # initialise RAID entry, if it doesn't exist already
           defined ($FAI::configs{RAID}) or $FAI::configs{RAID}{volumes} = {};
-          # compute the next available index - the size of the entry
+          # compute the next available index - the size of the entry or the
+          # first not fully defined entry
           my $vol_id = 0;
           foreach my $ex_vol_id (&FAI::numsort(keys %{ $FAI::configs{RAID}{volumes} })) {
             defined ($FAI::configs{RAID}{volumes}{$ex_vol_id}{mode}) or last;
@@ -482,6 +534,25 @@
           $FAI::partition_pointer = (\%FAI::configs)->{RAID}->{volumes}->{$vol_id};
         }
         mountpoint devices filesystem mount_options mdcreateopts
+        | /^(luks|tmp|swap)\s+/
+        {
+          ($FAI::device eq "CRYPT") or die "Encryted entry invalid in this context\n";
+          defined ($FAI::configs{CRYPT}) or &FAI::internal_error("CRYPT entry missing");
+
+          my $vol_id = 0;
+          foreach my $ex_vol_id (&FAI::numsort(keys %{ $FAI::configs{CRYPT}{volumes} })) {
+            defined ($FAI::configs{CRYPT}{volumes}{$ex_vol_id}{mode}) or last;
+            $vol_id++;
+          }
+
+          $FAI::configs{CRYPT}{volumes}{$vol_id}{mode} = $1;
+
+          # We don't do preserve for encrypted devices
+          $FAI::configs{CRYPT}{volumes}{$vol_id}{preserve} = 0;
+
+          $FAI::partition_pointer = (\%FAI::configs)->{CRYPT}->{volumes}->{$vol_id};
+        }
+        mountpoint devices filesystem mount_options lv_or_fsopts
         | type mountpoint size filesystem mount_options lv_or_fsopts
 
     type: 'primary'
@@ -523,6 +594,7 @@
           $FAI::partition_pointer->{mountpoint} = $1;
           $FAI::partition_pointer->{mountpoint} = "none" if ($1 eq "swap");
           if (defined($2)) {
+            warn "Old-style inline encrypt will be deprecated. Please add cryptsetup definitions (see man 8 setup-storage).\n";
             &FAI::in_path("cryptsetup") or die "cryptsetup not found in PATH\n";
             $FAI::partition_pointer->{encrypt} = 1;
             ++$FAI::partition_pointer->{encrypt} if (defined($3));
@@ -651,6 +723,10 @@
                 "spare" => $spare,
                 "missing" => $missing
               };
+            } elsif ($FAI::device eq "CRYPT") {
+              die "Failed to resolve $dev to a unique device name\n" if (scalar(@candidates) != 1);
+              $FAI::partition_pointer->{device} = $candidates[0];
+              &FAI::mark_encrypted($candidates[0]);
             } else {
               die "Failed to resolve $dev to a unique device name\n" if (scalar(@candidates) != 1);
               $dev = $candidates[0];
@@ -679,7 +755,7 @@
         {
           $FAI::partition_pointer->{filesystem} = $item[ 1 ];
           my $to_be_preserved = 0;
-          if ($FAI::device eq "RAID") {
+          if ($FAI::device eq "RAID" or $FAI::device eq "CRYPT") {
             $to_be_preserved = $FAI::partition_pointer->{preserve};
           } else {
             $to_be_preserved = $FAI::partition_pointer->{size}->{preserve};

Modified: trunk/lib/setup-storage/Sizes.pm
===================================================================
--- trunk/lib/setup-storage/Sizes.pm	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/setup-storage/Sizes.pm	2009-12-01 20:43:35 UTC (rev 5686)
@@ -201,8 +201,8 @@
   # loop through all device configurations
   foreach my $config (keys %FAI::configs) {
 
-    # for RAID or physical disks there is nothing to be done here
-    next if ($config eq "RAID" || $config =~ /^PHY_./);
+    # for RAID, encrypted or physical disks there is nothing to be done here
+    next if ($config eq "RAID" || $config eq "CRYPT" || $config =~ /^PHY_./);
     ($config =~ /^VG_(.+)$/) or &FAI::internal_error("invalid config entry $config");
     next if ($1 eq "--ANY--");
     my $vg = $1; # the volume group name
@@ -611,8 +611,8 @@
   # loop through all device configurations
   foreach my $config (keys %FAI::configs) {
 
-    # for RAID or LVM, there is nothing to be done here
-    next if ($config eq "RAID" || $config =~ /^VG_./);
+    # for RAID, encrypted or LVM, there is nothing to be done here
+    next if ($config eq "RAID" || $config eq "CRYPT" || $config =~ /^VG_./);
     ($config =~ /^PHY_(.+)$/) or &FAI::internal_error("invalid config entry $config");
     # nothing to be done, if this is a configuration for a virtual disk
     next if $FAI::configs{$config}{virtual};

Modified: trunk/lib/setup-storage/Volumes.pm
===================================================================
--- trunk/lib/setup-storage/Volumes.pm	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/setup-storage/Volumes.pm	2009-12-01 20:43:35 UTC (rev 5686)
@@ -459,6 +459,9 @@
           "Can't preserve /dev/md$r because it is not defined in the current config\n";
         &FAI::mark_preserve($_) foreach (keys %{ $FAI::configs{$config}{volumes}{$r}{devices} });
       }
+    } elsif ($config eq "CRYPT") {
+      # We don't do preserve for encrypted partitions
+      next;
     } else {
       &FAI::internal_error("Unexpected key $config");
     }

Modified: trunk/lib/subroutines
===================================================================
--- trunk/lib/subroutines	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/lib/subroutines	2009-12-01 20:43:35 UTC (rev 5686)
@@ -777,6 +777,8 @@
     # now we can copy fstab
     [ -f $fs ] && mv $fs $fs.old
     [ -f $LOGDIR/fstab ] && cp -p $LOGDIR/fstab $fs
+    # copy crypttab, if setup-storage created one
+    [ -f $LOGDIR/crypttab ] && cp -p $LOGDIR/crypttab $FAI_ROOT/etc/crypttab
 }
 # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 ### BEGIN SUBROUTINE INFO

Modified: trunk/man/setup-storage.8
===================================================================
--- trunk/man/setup-storage.8	2009-11-30 21:16:07 UTC (rev 5685)
+++ trunk/man/setup-storage.8	2009-12-01 20:43:35 UTC (rev 5686)
@@ -1,4 +1,4 @@
-.TH setup-storage 8 "September 16, 2008" "Debian/GNU Linux"
+.TH setup-storage 8 "November 23, 2009" "Debian/GNU Linux"
 .SH NAME
 \fBsetup-storage\fP
 \- automatically prepare storage devices
@@ -136,6 +136,8 @@
 .br
            | disk_config raid( <raidoption>)*
 .br
+           | disk_config cryptsetup( <cryptsetupoption>)*
+.br
            | disk_config end 
 .br
            | disk_config disk[[:digit:]]+( <option>)*
@@ -200,6 +202,14 @@
 .br
 
 
+cryptsetupoption ::= /* empty */
+.br
+           | randinit
+.br
+           /* initialise all encrypted partitions with random data */
+.br
+
+
 option ::= /* empty */
 .br
            | preserve_always:[[:digit:]]+(,[[:digit:]]+)*
@@ -234,8 +244,20 @@
 .br
            may be the device (/dev/xxx), a label given using \-L, or the uuid
 .br
-           */  
+           */
 .br
+           | sameas:(disk[[:digit:]]+|[^[:space:]]+)
+.br
+           /* Indicate that this disk will use the same scheme
+.br
+           as the given device. The referenced device must be
+.br
+           defined before the device using this option. Use only
+.br
+           with identical hardware.
+.br
+           */
+.br
 
 
 volume ::= <type> <mountpoint> <size> <filesystem> <mount_options> <fs_options>
@@ -258,22 +280,36 @@
 .br
          /* raid level */
 .br
+         | luks
+.br
+         /* encrypted partition using LUKS */
+.br
+         | tmp
+.br
+         /* encrypted partition for /tmp usage, will be
+.br
+            recreated with a random key at each boot and
+.br
+            reformatted as ext2 */
+.br
+         | swap
+.br
+         /* encrypted partition for swap space usage, will
+.br
+            be recreated with a random key at each boot and
+.br
+            reformatted as swap space */
+.br
          | [^/[:space:]]+-[^/[:space:]]+
 .br
          /* lvm logical volume: vg name and lv name*/
 .br
 
 
-mountpoint ::= (-|swap|/[^\:[:space:]]*)(:encrypt(:randinit)?)?
+mountpoint ::= (-|swap|/[^\:[:space:]]*)
 .br
-               /* do not mount, mount as swap, or mount at fully qualified path;
+               /* do not mount, mount as swap, or mount at fully qualified path */
 .br
-                * if :encrypt is given the partition will be encrypted, the key
-.br
-                * is generated automatically; :randinit adds random
-.br
-                * initialization of the partition  */
-.br
 
 
 name ::= [^/[:space:]]+
@@ -353,7 +389,7 @@
 .sp
 .nf
 .ta 10n 20n 30n 40n 50n
-disk_config  hda	preserve_always:6,7	disklabel:msdos  bootable:3
+disk_config hda preserve_always:6,7 disklabel:msdos bootable:3
 
 primary	/boot	20-100	ext3	rw
 primary	swap	1000	swap	sw
@@ -387,10 +423,10 @@
 Create a softRAID
 .sp
 .nf
-.ta 6n 9n 40n 45n
+.ta 6n 9n 43n 48n
 disk_config raid
 raid1	/	sda1,sdd1	ext2	rw,errors=remount-ro
-raid0	-	disk2.2,sdc1,sde1:spare:missing	ext2  default
+raid0	-	disk2.2,sdc1,sde1:spare:missing	ext2	default
 .sp
 .fi
 .PP
@@ -406,22 +442,43 @@
 .sp
 .nf
 .ta 15n 22n 30n 40n
-disk_config sda  bootable:1
+disk_config sda bootable:1
 primary	/boot	500	ext3	rw
 primary	-	4096-	-	-
+
 disk_config lvm
-vg  my_pv  sda2
+vg	my_pv	sda2
 my_pv-_swap	swap	2048	swap	sw
 my_pv-_root	/	2048	ext3	rw
 .sp
 .fi
 .PP
+
+.TP
+Crypt example
+.sp
+.nf
+.ta 10n 20n 30n 40n 50n
+disk_config /dev/sdb
+primary	/	21750	ext3	defaults,errors=remount-ro
+primary	/boot	250	ext3	defaults
+logical	-	4000	-	-
+logical	-	2000	-	-
+logical	-	10-	-	-
+
+disk_config cryptsetup
+swap	swap	/dev/sdb5	swap	defaults
+tmp	/tmp	/dev/sdb6	ext2	defaults
+luks	/local00	/dev/sdb7	ext3	defaults,errors=remount-ro	createopts="-m	0"
+.sp
+.fi
+.PP
 .SH CAVEATS
 .IP \(bu
 Partition UUID cannot be obtained: In case a partition was previously used as
 part of a software RAID volume and now is intended as swap space, udev fails
 when asked for a UUID. This happens because mkswap does not overwrite the
-previous RAID superblock. You can remove it using mdadm --zero-superblock
+previous RAID superblock. You can remove it using mdadm \-\-zero-superblock
 <device>.
 .IP \(bu
 Machine does not boot because not partition is marked as bootable: If the
@@ -432,6 +489,11 @@
 If you want to be sure not boot failures happen because of a missing bootable
 marker, explicitly set the bootable option. Of course, there are lots of other
 reasons why a system may fail to boot.
+.IP \(bu
+Crypto support requires some site-specific changes: If you use cryptsetup
+stanza, a crypttab file and key files for all luks volumes will be created. The
+key files are left in /tmp/fai; you will want to copy these to some removable
+media.
 .SH SEE ALSO
 This program is part of FAI (Fully Automatic Installation).
 The FAI homepage is http://www.informatik.uni-koeln.de/fai.




More information about the Fai-commit mailing list