[Fai-commit] r4953 - people/michael/features/setup_harddisks_2/implementation/lib trunk/lib/setup-storage
lange at alioth.debian.org
lange at alioth.debian.org
Thu Jun 12 11:37:51 UTC 2008
Author: lange
Date: 2008-06-12 11:37:48 +0000 (Thu, 12 Jun 2008)
New Revision: 4953
Added:
trunk/lib/setup-storage/Parser.pm
Removed:
people/michael/features/setup_harddisks_2/implementation/lib/parser.pm
Log:
moving setup-storage to trunk
Deleted: people/michael/features/setup_harddisks_2/implementation/lib/parser.pm
===================================================================
--- people/michael/features/setup_harddisks_2/implementation/lib/parser.pm 2008-06-12 11:37:47 UTC (rev 4952)
+++ people/michael/features/setup_harddisks_2/implementation/lib/parser.pm 2008-06-12 11:37:48 UTC (rev 4953)
@@ -1,690 +0,0 @@
-#!/usr/bin/perl -w
-
-#*********************************************************************
-# 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.
-#
-# A copy of the GNU General Public License is available as
-# `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
-# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
-# can also obtain it by writing to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
-#*********************************************************************
-
-use strict;
-
-################################################################################
-#
-# @file parser.pm
-#
-# @brief A parser for the disk_config files within FAI.
-#
-# $Id$
-#
-# @author Christian Kern, Michael Tautschnig, Sam Vilain, Andreas Schludei
-# @date Sun Jul 23 16:09:36 CEST 2006
-#
-################################################################################
-
-use Parse::RecDescent;
-
-package FAI;
-
-################################################################################
-#
-# @brief the name of the device currently being configured, including a prefix
-# such as PHY_ or VG_ to indicate physical devices or LVM volume groups. For
-# RAID, the entry is only "RAID"
-#
-################################################################################
-$FAI::device = "";
-
-################################################################################
-#
-# @brief Test, whether @ref $cmd is available on the system using $PATH
-#
-# @param $cmd Command that is to be found in $PATH
-#
-# @return 1, if the command is found, else 0
-#
-################################################################################
-sub in_path {
-
- # initialize the parameter
- my ($cmd) = @_;
-
- # split $PATH into its components, search all of its components
- # and test for $cmd being executable
- (-x "$_/$cmd") and return 1 foreach (split (":", $ENV{PATH}));
- # return 0 otherwise
- return 0;
-}
-
-################################################################################
-#
-# @brief Initialise a new entry in @ref $FAI::configs for a physical disk.
-#
-# 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
- my ($disk) = @_;
-
- # test $disk for being numeric
- if ($disk =~ /^\d+$/) {
-
- # $disk-1 must be a valid index in the map of all disks in the system
- (scalar(@FAI::disks) >= $disk)
- or die "this system does not have a physical disk $disk\n";
-
- # fetch the (short) device name
- $disk = $FAI::disks[ $disk - 1 ];
- }
-
- # test, whether the device name starts with a / and prepend /dev/, if
- # appropriate
- ($disk =~ m{^/}) or $disk = "/dev/$disk";
-
- # prepend PHY_
- $FAI::device = "PHY_$disk";
-
- # test, whether this is the first disk_config stanza to configure $disk
- defined ($FAI::configs{$FAI::device})
- and die "Duplicate configuration for disk $FAI::disks[ $1-1 ]\n";
-
- # Initialise the entry in $FAI::configs
- $FAI::configs{$FAI::device} = {
- virtual => 0,
- disklabel => "msdos",
- bootable => -1,
- fstabkey => "device",
- partitions => {}
- };
-}
-
-################################################################################
-#
-# @brief Initialise the entry of a partition in @ref $FAI::configs
-#
-# @param $type The type of the partition. It must be either primary or logical.
-#
-################################################################################
-sub init_part_config {
-
- # the type of the partition to be created
- my ($type) = @_;
-
- # type must either be primary or logical, nothing else may be accepted by the
- # parser
- ($type eq "primary" || $type eq "logical") or
- &FAI::internal_error("invalid type $type");
-
- # check that a physical device is being configured; logical partitions are
- # only supported on msdos disk labels.
- ($FAI::device =~ /^PHY_/ && ($type ne "logical"
- || $FAI::configs{$FAI::device}{disklabel} eq "msdos")) or
- die "Syntax error: invalid partition type";
-
- # the index of the new partition
- my $part_number = 0;
-
- # create a primary partition
- if ($type eq "primary") {
-
- # find all previously defined primary partitions
- foreach my $part_id (&numsort(keys %{ $FAI::configs{$FAI::device}{partitions} })) {
-
- # break, if the partition has not been created by init_part_config
- defined ($FAI::configs{$FAI::device}{partitions}{$part_id}{size}{extended}) or last;
-
- # on msdos disklabels we cannot have more than 4 primary partitions
- last if ($part_id > 4 && ! $FAI::configs{$FAI::device}{virtual}
- && $FAI::configs{$FAI::device}{disklabel} eq "msdos");
-
- # store the latest index found
- $part_number = $part_id;
- }
-
- # the next index available - note that $part_number might have been 0
- $part_number++;
-
- # msdos disk labels don't allow for more than 4 primary partitions
- ($part_number < 5 || $FAI::configs{$FAI::device}{virtual} ||
- $FAI::configs{$FAI::device}{disklabel} ne "msdos")
- or die "$part_number are too many primary partitions\n";
- } else {
-
- # no further checks for the disk label being msdos have to be performed in
- # this branch, it has been ensured above
-
- # find the index of the new partition, initialise it to the highest current index
- foreach my $part_id (&numsort(keys %{ $FAI::configs{$FAI::device}{partitions} })) {
-
- # skip primary partitions
- next if ($part_id < 5);
-
- # break, if the partition has not been created by init_part_config
- defined($FAI::configs{$FAI::device}{partitions}{$part_id}{size}{extended})
- or last;
-
- # store the latest index found
- $part_number = $part_id;
- }
-
- # and use the next one available
- $part_number++;
-
- # if this is the first logical partition, the index must be set to 5 and an
- # extended partition must be created
- if ($part_number <= 5) {
- $part_number = 5;
-
- # the proposed index of the extended partition
- my $extended = 0;
-
- # find all previously defined primary partitions
- foreach my $part_id (&numsort(keys %{ $FAI::configs{$FAI::device}{partitions} })) {
-
- # break, if the partition has not been created by init_part_config
- defined ($FAI::configs{$FAI::device}{partitions}{$part_id}{size}{extended}) or last;
-
- # we cannot have more than 4 primary partitions
- last if ($part_id > 4);
-
- # store the latest index found
- $extended = $part_id;
- }
-
- # the next index available
- $extended++;
-
- # msdos disk labels don't allow for more than 4 primary partitions
- ($extended < 5)
- or die "Too many primary partitions while creating extended\n";
-
- # initialize the entry
- (\%FAI::configs)->{$FAI::device}->{partitions}->{$extended} = {
- size => {}
- };
-
- my $part_size =
- (\%FAI::configs)->{$FAI::device}->{partitions}->{$extended}->{size};
-
- # mark the entry as an extended partition
- $part_size->{extended} = 1;
-
- # add the preserve = 0 flag, if it doesn't exist already
- defined ($part_size->{preserve})
- or $part_size->{preserve} = 0;
-
- # add the resize = 0 flag, if it doesn't exist already
- defined ($part_size->{resize}) or $part_size->{resize} = 0;
- }
- }
-
- # initialise the hash for the partitions, if it doesn't exist already
- # note that it might exists due to options, such as preserve:x,y
- # the initialisation is required for the reference defined next
- defined ($FAI::configs{$FAI::device}{partitions}{$part_number})
- or $FAI::configs{$FAI::device}{partitions}{$part_number} = {};
-
- # set the reference to the current partition
- # the reference is used by all further processing of this config line
- $FAI::partition_pointer =
- (\%FAI::configs)->{$FAI::device}->{partitions}->{$part_number};
-
- # as we can't compute the index from the reference, we need to store the
- # $part_number explicitly
- $FAI::partition_pointer->{number} = $part_number;
-
- # the partition is not an extended one
- $FAI::partition_pointer->{size}->{extended} = 0;
-
- # add the preserve = 0 flag, if it doesn't exist already
- defined ($FAI::partition_pointer->{size}->{preserve})
- or $FAI::partition_pointer->{size}->{preserve} = 0;
-
- # add the resize = 0 flag, if it doesn't exist already
- defined ($FAI::partition_pointer->{size}->{resize})
- or $FAI::partition_pointer->{size}->{resize} = 0;
-}
-
-################################################################################
-#
-# @brief This function converts different sizes to Mbyte
-#
-# @param $val is the number with its unit
-#
-################################################################################
-sub convert_unit
-{
- my ($val) = @_;
- ($val =~ /^(\d+(\.\d+)?)([kMGTP%]?)(B)?\s*$/) or
- &FAI::internal_error("convert_unit $val");
- $val = $1 * (1 / 1024) * (1 / 1024) if ($3 eq "" && defined ($4) && $4 eq "B");
- $val = $1 * (1 / 1024) if ($3 eq "k");
- $val = $1 if ($3 eq "M");
- $val = $1 * 1024 if ($3 eq "G");
- $val = $1 * (1024 * 1024) if ($3 eq "T");
- $val = $1 * (1024 * 1024 * 1024) if ($3 eq "P");
- # % is returned as is
- return $val;
-}
-
-# have RecDescent do proper error reporting
-$::RD_HINT = 1;
-
-################################################################################
-#
-# @brief The effective implementation of the parser is instantiated here
-#
-################################################################################
-$FAI::Parser = Parse::RecDescent->new(
- q{
- file: line(s?) /\Z/
- {
- $return = 1;
- }
- | <error>
-
- line: <skip: qr/[ \t]*/> "\\n"
- | <skip: qr/[ \t]*/> comment "\\n"
- | <skip: qr/[ \t]*/> config "\\n"
-
- comment: /^\s*#.*/
-
- config: 'disk_config' disk_config_arg
- | volume
-
- disk_config_arg: 'raid'
- {
- # check, whether raid tools are available
- &FAI::in_path("mdadm") or die "mdadm not found in PATH\n";
- $FAI::device = "RAID";
- $FAI::configs{$FAI::device}{fstabkey} = "device";
- }
- raid_option(s?)
- | /^lvm/
- {
-
- # check, whether lvm tools are available
- &FAI::in_path("lvcreate") or die "LVM tools not found in PATH\n";
- # initialise $FAI::device to inform the following lines about the LVM
- # being configured
- $FAI::device = "VG_";
- $FAI::configs{"VG_--ANY--"}{fstabkey} = "device";
- }
- lvm_option(s?)
- | 'end'
- {
- # exit config mode
- $FAI::device = "";
- }
- | /^disk(\d+)/
- {
- # check, whether parted is available
- &FAI::in_path("parted") or die "parted not found in PATH\n";
- # initialise the entry of the hash corresponding to disk$1
- &FAI::init_disk_config($1);
- }
- option(s?)
- | /^\S+/
- {
- # check, whether parted is available
- &FAI::in_path("parted") or die "parted not found in PATH\n";
- # initialise the entry of the hash corresponding to $item[1]
- &FAI::init_disk_config($item[ 1 ]);
- }
- option(s?)
-
- raid_option: /^preserve_always:(\d+(,\d+)*)/
- {
- # set the preserve flag for all ids in all cases
- $FAI::configs{RAID}{volumes}{$_}{preserve} = 1 foreach (split (",", $1));
- }
- | /^preserve_reinstall:(\d+(,\d+)*)/
- {
- # set the preserve flag for all ids if $FAI::reinstall is set
- if ($FAI::reinstall) {
- $FAI::configs{RAID}{volumes}{$_}{preserve} = 1 foreach (split(",", $1));
- }
- }
- | /^fstabkey:(device|label|uuid)/
- {
- # the information preferred for fstab device identifieres
- $FAI::configs{$FAI::device}{fstabkey} = $1;
- }
-
- lvm_option: m{^preserve_always:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
- {
- # set the preserve flag for all ids in all cases
- foreach (split (",", $1)) {
- (m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}) or
- die &FAI::internal_error("VG re-parse failed");
- $FAI::configs{"VG_$1"}{volumes}{$2}{size}{preserve} = 1
- }
- }
- | m{^preserve_reinstall:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
- {
- # set the preserve flag for all ids if $FAI::reinstall is set
- if ($FAI::reinstall) {
- foreach (split (",", $1)) {
- (m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}) or
- die &FAI::internal_error("VG re-parse failed");
- $FAI::configs{"VG_$1"}{volumes}{$2}{size}{preserve} = 1
- }
- }
- }
- | m{^resize:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
- {
- # set the resize flag for all ids
- foreach (split (",", $1)) {
- (m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}) or
- die &FAI::internal_error("VG re-parse failed");
- $FAI::configs{"VG_$1"}{volumes}{$2}{size}{resize} = 1
- }
- }
- | /^fstabkey:(device|label|uuid)/
- {
- # the information preferred for fstab device identifieres
- $FAI::configs{"VG_--ANY--"}{fstabkey} = $1;
- }
-
- option: /^preserve_always:(\d+(,\d+)*)/
- {
- # set the preserve flag for all ids in all cases
- $FAI::configs{$FAI::device}{partitions}{$_}{size}{preserve} = 1 foreach (split (",", $1));
- }
- | /^preserve_reinstall:(\d+(,\d+)*)/
- {
- # set the preserve flag for all ids if $FAI::reinstall is set
- if ($FAI::reinstall) {
- $FAI::configs{$FAI::device}{partitions}{$_}{size}{preserve} = 1 foreach (split(",", $1));
- }
- }
- | /^resize:(\d+(,\d+)*)/
- {
- # set the resize flag for all ids
- $FAI::configs{$FAI::device}{partitions}{$_}{size}{resize} = 1 foreach (split(",", $1));
- }
- | /^disklabel:(msdos|gpt)/
- {
- # set the disk label - actually not only the above, but all types
- # supported by parted could be allowed, but others are not implemented
- # yet
- $FAI::configs{$FAI::device}{disklabel} = $1;
- }
- | /^bootable:(\d+)/
- {
- # specify a partition that should get the bootable flag set
- $FAI::configs{$FAI::device}{bootable} = $1;
- ($FAI::device =~ /^PHY_(.+)$/) or
- &FAI::internal_error("unexpected device name");
- $FAI::disk_var{BOOT_DEVICE} .= " $1";
- }
- | 'virtual'
- {
- # this is a configuration for a virtual disk
- $FAI::configs{$FAI::device}{virtual} = 1;
- }
- | /^fstabkey:(device|label|uuid)/
- {
- # the information preferred for fstab device identifieres
- $FAI::configs{$FAI::device}{fstabkey} = $1;
- }
-
- volume: /^vg\s+/ name devices
- | /^raid([0156])\s+/
- {
- # make sure that this is a RAID configuration
- ($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
- my $vol_id = scalar (keys %{ $FAI::configs{RAID}{volumes} });
- # set the RAID type of this volume
- $FAI::configs{RAID}{volumes}{$vol_id}{mode} = $1;
- # initialise the hash of devices
- $FAI::configs{RAID}{volumes}{$vol_id}{devices} = {};
- # set the reference to the current volume
- # the reference is used by all further processing of this config line
- $FAI::partition_pointer = (\%FAI::configs)->{RAID}->{volumes}->{$vol_id};
- }
- mountpoint devices filesystem mount_options fs_options
- | type mountpoint size filesystem mount_options fs_options
-
- type: 'primary'
- {
- # initialise a primary partition
- &FAI::init_part_config($item[ 1 ]);
- }
- | 'logical'
- {
- # initialise a logical partition
- &FAI::init_part_config($item[ 1 ]);
- }
- | m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}
- {
- # set $FAI::device to VG_$1
- $FAI::device = "VG_$1";
- # make sure, the volume group $1 has been defined before
- defined ($FAI::configs{$FAI::device}) or
- die "Volume group $1 has not been declared yet.\n";
- # make sure, $2 has not been defined already
- defined ($FAI::configs{$FAI::device}{volumes}{$2}{size}{range}) and
- die "Logical volume $2 has been defined already.\n";
- # initialise the new hash
- defined($FAI::configs{$FAI::device}{volumes}{$2}) or
- $FAI::configs{$FAI::device}{volumes}{$2} = {};
- # initialise the preserve and resize flags
- defined($FAI::configs{$FAI::device}{volumes}{$2}{size}{preserve}) or
- $FAI::configs{$FAI::device}{volumes}{$2}{size}{preserve} = 0;
- defined($FAI::configs{$FAI::device}{volumes}{$2}{size}{resize}) or
- $FAI::configs{$FAI::device}{volumes}{$2}{size}{resize} = 0;
- # set the reference to the current volume
- # the reference is used by all further processing of this config line
- $FAI::partition_pointer = (\%FAI::configs)->{$FAI::device}->{volumes}->{$2};
- }
-
- mountpoint: '-'
- {
- # this partition should not be mounted
- $FAI::partition_pointer->{mountpoint} = "-";
- $FAI::partition_pointer->{encrypt} = 0;
- }
- | 'swap'
- {
- # this partition is swap space, not mounted
- $FAI::partition_pointer->{mountpoint} = "none";
- $FAI::partition_pointer->{encrypt} = 0;
- }
- | m{^/\S*}
- {
- # set the mount point, may include encryption-request
- if ($item[ 1 ] =~ m{^(/[^:]*):encrypt$}) {
- &FAI::in_path("cryptsetup") or die "cryptsetup not found in PATH\n";
- $FAI::partition_pointer->{mountpoint} = $1;
- $FAI::partition_pointer->{encrypt} = 1;
- } else {
- $FAI::partition_pointer->{mountpoint} = $item[ 1 ];
- $FAI::partition_pointer->{encrypt} = 0;
- }
- }
-
- name: m{^([^/,\s\-]+)}
- {
- # set the device name to VG_ and the name of the volume group
- $FAI::device = "VG_$1";
- # make sure, the volume group $1 not has been defined already
- defined ($FAI::configs{$FAI::device}) and
- die "Volume group $1 has been defined already.\n";
- # make sure this line is part of an LVM configuration
- ($FAI::device =~ /^VG_/) or
- die "vg is invalid in a non LVM-context.\n";
- # initialise the new hash
- $FAI::configs{$FAI::device}{volumes} = {};
- # initialise the list of physical devices
- $FAI::configs{$FAI::device}{devices} = ();
- # the rule must not return undef
- 1;
- }
-
- size: /^(\d+[kMGTP%]?(-(\d+[kMGTP%]?)?)?)(:resize)?\s+/
- {
- # complete the size specification to be a range in all cases
- my $range = $1;
- # the size is fixed
- if (!defined ($2))
- {
- # make it a range of the form x-x
- $range = "$range-$1";
- }
- elsif (!defined ($3))
- {
- # range has no upper limit, assume the whole disk
- $range = "${range}100%";
- }
-
- # convert the units, if necessary
- my ($min, $max) = split (/-/, $range);
- $min = &FAI::convert_unit($min);
- $max = &FAI::convert_unit($max);
- $range = "$min-$max";
- # enter the range into the hash
- $FAI::partition_pointer->{size}->{range} = $range;
- # set the resize flag, if required
- defined ($4) and $FAI::partition_pointer->{size}->{resize} = 1;
- }
- | /^(-\d+[kMGTP%]?)(:resize)?\s+/
- {
- # complete the range by assuming 0 as the lower limit
- my $range = "0$1";
- # convert the units, if necessary
- my ($min, $max) = split (/-/, $range);
- $min = &FAI::convert_unit($min);
- $max = &FAI::convert_unit($max);
- $range = "$min-$max";
- # enter the range into the hash
- $FAI::partition_pointer->{size}->{range} = $range;
- # set the resize flag, if required
- defined( $2 ) and $FAI::partition_pointer->{size}->{resize} = 1;
- }
- | <error: invalid partition size near "$text">
-
- devices: /^([^\d,:\s\-][^,:\s]*(:(spare|missing))*(,[^,:\s]+(:(spare|missing))*)*)/
- {
- # split the device list by ,
- foreach my $dev (split(",", $1))
- {
- # match the substrings
- ($dev =~ /^([^\d,:\s\-][^,:\s]*)(:(spare|missing))*$/) or
- &FAI::internal_error("PARSER ERROR");
- # redefine the device string
- $dev = $1;
- # make $dev a full path name; can't validate device name yet as it
- # might be created later on
- unless ($dev =~ m{^/}) {
- if ($dev =~ m/^disk(\d+)\.(\d+)/) {
- $dev = &FAI::make_device_name("/dev/" . $FAI::disks[ $1 - 1 ], $2);
- } else {
- $dev = "/dev/$dev";
- }
- }
- # options are only valid for RAID
- defined ($2) and ($FAI::device ne "RAID") and die "Option $2 invalid in a non-RAID context\n";
- if ($FAI::device eq "RAID") {
- # parse all options
- my $spare = 0;
- my $missing = 0;
- if (defined ($2)) {
- ($2 =~ /spare/) and $spare = 1;
- ($2 =~ /missing/) and $missing = 1;
- }
- # each device may only appear once
- defined ($FAI::partition_pointer->{devices}->{$dev}) and
- die "$dev is already part of the RAID volume\n";
- # set the options
- $FAI::partition_pointer->{devices}->{$dev}->{options} = {
- "spare" => $spare,
- "missing" => $missing
- };
- } else {
- # create an empty hash for each device
- $FAI::configs{$FAI::device}{devices}{$dev} = {};
- }
- }
- 1;
- }
- | <error: invalid device spec "$text">
-
- mount_options: /\S+/
- {
- $FAI::partition_pointer->{mount_options} = $item[ 1 ];
- }
-
- filesystem: '-'
- {
- $FAI::partition_pointer->{filesystem} = $item[ 1 ];
- }
- | 'swap'
- {
- $FAI::partition_pointer->{filesystem} = $item[ 1 ];
- }
- | /^\S+/
- {
- &FAI::in_path("mkfs.$item[1]") or
- die "unknown/invalid filesystem type $item[1] (mkfs.$item[1] not found in PATH)\n";
- $FAI::partition_pointer->{filesystem} = $item[ 1 ];
- }
-
- fs_options: /[^;\n]*/
- {
- $FAI::partition_pointer->{fs_options} = $item[ 1 ];
- }
-}
-);
-
-################################################################################
-#
-# @brief Parse the data from <$IN> using @ref $FAI::Parser
-#
-# @param IN file handle for input file, may be STDIN
-#
-################################################################################
-sub run_parser {
- my ($IN) = @_;
-
- # read <$IN> to a single string (not a list), thus $/ has to be unset
- my $ifs = $/;
- undef $/;
- my $input = <$IN>;
- $/ = $ifs;
-
- # print the contents of <$IN> for debugging purposes
- $FAI::debug and print "Input was:\n" . $input;
-
- # check for old-style configuration files
- ($input =~ m{(^|\n)[^\n#]+;})
- and die "Old style configuration files are not supported\n";
-
- # attempt to parse $input - any error will lead to termination
- defined $FAI::Parser->file($input) or die "Syntax error\n";
-}
-
-1;
-
Copied: trunk/lib/setup-storage/Parser.pm (from rev 4952, people/michael/features/setup_harddisks_2/implementation/lib/parser.pm)
===================================================================
--- trunk/lib/setup-storage/Parser.pm (rev 0)
+++ trunk/lib/setup-storage/Parser.pm 2008-06-12 11:37:48 UTC (rev 4953)
@@ -0,0 +1,690 @@
+#!/usr/bin/perl -w
+
+#*********************************************************************
+# 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.
+#
+# A copy of the GNU General Public License is available as
+# `/usr/share/common-licences/GPL' in the Debian GNU/Linux distribution
+# or on the World Wide Web at http://www.gnu.org/copyleft/gpl.html. You
+# can also obtain it by writing to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
+#*********************************************************************
+
+use strict;
+
+################################################################################
+#
+# @file parser.pm
+#
+# @brief A parser for the disk_config files within FAI.
+#
+# $Id$
+#
+# @author Christian Kern, Michael Tautschnig, Sam Vilain, Andreas Schludei
+# @date Sun Jul 23 16:09:36 CEST 2006
+#
+################################################################################
+
+use Parse::RecDescent;
+
+package FAI;
+
+################################################################################
+#
+# @brief the name of the device currently being configured, including a prefix
+# such as PHY_ or VG_ to indicate physical devices or LVM volume groups. For
+# RAID, the entry is only "RAID"
+#
+################################################################################
+$FAI::device = "";
+
+################################################################################
+#
+# @brief Test, whether @ref $cmd is available on the system using $PATH
+#
+# @param $cmd Command that is to be found in $PATH
+#
+# @return 1, if the command is found, else 0
+#
+################################################################################
+sub in_path {
+
+ # initialize the parameter
+ my ($cmd) = @_;
+
+ # split $PATH into its components, search all of its components
+ # and test for $cmd being executable
+ (-x "$_/$cmd") and return 1 foreach (split (":", $ENV{PATH}));
+ # return 0 otherwise
+ return 0;
+}
+
+################################################################################
+#
+# @brief Initialise a new entry in @ref $FAI::configs for a physical disk.
+#
+# 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
+ my ($disk) = @_;
+
+ # test $disk for being numeric
+ if ($disk =~ /^\d+$/) {
+
+ # $disk-1 must be a valid index in the map of all disks in the system
+ (scalar(@FAI::disks) >= $disk)
+ or die "this system does not have a physical disk $disk\n";
+
+ # fetch the (short) device name
+ $disk = $FAI::disks[ $disk - 1 ];
+ }
+
+ # test, whether the device name starts with a / and prepend /dev/, if
+ # appropriate
+ ($disk =~ m{^/}) or $disk = "/dev/$disk";
+
+ # prepend PHY_
+ $FAI::device = "PHY_$disk";
+
+ # test, whether this is the first disk_config stanza to configure $disk
+ defined ($FAI::configs{$FAI::device})
+ and die "Duplicate configuration for disk $FAI::disks[ $1-1 ]\n";
+
+ # Initialise the entry in $FAI::configs
+ $FAI::configs{$FAI::device} = {
+ virtual => 0,
+ disklabel => "msdos",
+ bootable => -1,
+ fstabkey => "device",
+ partitions => {}
+ };
+}
+
+################################################################################
+#
+# @brief Initialise the entry of a partition in @ref $FAI::configs
+#
+# @param $type The type of the partition. It must be either primary or logical.
+#
+################################################################################
+sub init_part_config {
+
+ # the type of the partition to be created
+ my ($type) = @_;
+
+ # type must either be primary or logical, nothing else may be accepted by the
+ # parser
+ ($type eq "primary" || $type eq "logical") or
+ &FAI::internal_error("invalid type $type");
+
+ # check that a physical device is being configured; logical partitions are
+ # only supported on msdos disk labels.
+ ($FAI::device =~ /^PHY_/ && ($type ne "logical"
+ || $FAI::configs{$FAI::device}{disklabel} eq "msdos")) or
+ die "Syntax error: invalid partition type";
+
+ # the index of the new partition
+ my $part_number = 0;
+
+ # create a primary partition
+ if ($type eq "primary") {
+
+ # find all previously defined primary partitions
+ foreach my $part_id (&numsort(keys %{ $FAI::configs{$FAI::device}{partitions} })) {
+
+ # break, if the partition has not been created by init_part_config
+ defined ($FAI::configs{$FAI::device}{partitions}{$part_id}{size}{extended}) or last;
+
+ # on msdos disklabels we cannot have more than 4 primary partitions
+ last if ($part_id > 4 && ! $FAI::configs{$FAI::device}{virtual}
+ && $FAI::configs{$FAI::device}{disklabel} eq "msdos");
+
+ # store the latest index found
+ $part_number = $part_id;
+ }
+
+ # the next index available - note that $part_number might have been 0
+ $part_number++;
+
+ # msdos disk labels don't allow for more than 4 primary partitions
+ ($part_number < 5 || $FAI::configs{$FAI::device}{virtual} ||
+ $FAI::configs{$FAI::device}{disklabel} ne "msdos")
+ or die "$part_number are too many primary partitions\n";
+ } else {
+
+ # no further checks for the disk label being msdos have to be performed in
+ # this branch, it has been ensured above
+
+ # find the index of the new partition, initialise it to the highest current index
+ foreach my $part_id (&numsort(keys %{ $FAI::configs{$FAI::device}{partitions} })) {
+
+ # skip primary partitions
+ next if ($part_id < 5);
+
+ # break, if the partition has not been created by init_part_config
+ defined($FAI::configs{$FAI::device}{partitions}{$part_id}{size}{extended})
+ or last;
+
+ # store the latest index found
+ $part_number = $part_id;
+ }
+
+ # and use the next one available
+ $part_number++;
+
+ # if this is the first logical partition, the index must be set to 5 and an
+ # extended partition must be created
+ if ($part_number <= 5) {
+ $part_number = 5;
+
+ # the proposed index of the extended partition
+ my $extended = 0;
+
+ # find all previously defined primary partitions
+ foreach my $part_id (&numsort(keys %{ $FAI::configs{$FAI::device}{partitions} })) {
+
+ # break, if the partition has not been created by init_part_config
+ defined ($FAI::configs{$FAI::device}{partitions}{$part_id}{size}{extended}) or last;
+
+ # we cannot have more than 4 primary partitions
+ last if ($part_id > 4);
+
+ # store the latest index found
+ $extended = $part_id;
+ }
+
+ # the next index available
+ $extended++;
+
+ # msdos disk labels don't allow for more than 4 primary partitions
+ ($extended < 5)
+ or die "Too many primary partitions while creating extended\n";
+
+ # initialize the entry
+ (\%FAI::configs)->{$FAI::device}->{partitions}->{$extended} = {
+ size => {}
+ };
+
+ my $part_size =
+ (\%FAI::configs)->{$FAI::device}->{partitions}->{$extended}->{size};
+
+ # mark the entry as an extended partition
+ $part_size->{extended} = 1;
+
+ # add the preserve = 0 flag, if it doesn't exist already
+ defined ($part_size->{preserve})
+ or $part_size->{preserve} = 0;
+
+ # add the resize = 0 flag, if it doesn't exist already
+ defined ($part_size->{resize}) or $part_size->{resize} = 0;
+ }
+ }
+
+ # initialise the hash for the partitions, if it doesn't exist already
+ # note that it might exists due to options, such as preserve:x,y
+ # the initialisation is required for the reference defined next
+ defined ($FAI::configs{$FAI::device}{partitions}{$part_number})
+ or $FAI::configs{$FAI::device}{partitions}{$part_number} = {};
+
+ # set the reference to the current partition
+ # the reference is used by all further processing of this config line
+ $FAI::partition_pointer =
+ (\%FAI::configs)->{$FAI::device}->{partitions}->{$part_number};
+
+ # as we can't compute the index from the reference, we need to store the
+ # $part_number explicitly
+ $FAI::partition_pointer->{number} = $part_number;
+
+ # the partition is not an extended one
+ $FAI::partition_pointer->{size}->{extended} = 0;
+
+ # add the preserve = 0 flag, if it doesn't exist already
+ defined ($FAI::partition_pointer->{size}->{preserve})
+ or $FAI::partition_pointer->{size}->{preserve} = 0;
+
+ # add the resize = 0 flag, if it doesn't exist already
+ defined ($FAI::partition_pointer->{size}->{resize})
+ or $FAI::partition_pointer->{size}->{resize} = 0;
+}
+
+################################################################################
+#
+# @brief This function converts different sizes to Mbyte
+#
+# @param $val is the number with its unit
+#
+################################################################################
+sub convert_unit
+{
+ my ($val) = @_;
+ ($val =~ /^(\d+(\.\d+)?)([kMGTP%]?)(B)?\s*$/) or
+ &FAI::internal_error("convert_unit $val");
+ $val = $1 * (1 / 1024) * (1 / 1024) if ($3 eq "" && defined ($4) && $4 eq "B");
+ $val = $1 * (1 / 1024) if ($3 eq "k");
+ $val = $1 if ($3 eq "M");
+ $val = $1 * 1024 if ($3 eq "G");
+ $val = $1 * (1024 * 1024) if ($3 eq "T");
+ $val = $1 * (1024 * 1024 * 1024) if ($3 eq "P");
+ # % is returned as is
+ return $val;
+}
+
+# have RecDescent do proper error reporting
+$::RD_HINT = 1;
+
+################################################################################
+#
+# @brief The effective implementation of the parser is instantiated here
+#
+################################################################################
+$FAI::Parser = Parse::RecDescent->new(
+ q{
+ file: line(s?) /\Z/
+ {
+ $return = 1;
+ }
+ | <error>
+
+ line: <skip: qr/[ \t]*/> "\\n"
+ | <skip: qr/[ \t]*/> comment "\\n"
+ | <skip: qr/[ \t]*/> config "\\n"
+
+ comment: /^\s*#.*/
+
+ config: 'disk_config' disk_config_arg
+ | volume
+
+ disk_config_arg: 'raid'
+ {
+ # check, whether raid tools are available
+ &FAI::in_path("mdadm") or die "mdadm not found in PATH\n";
+ $FAI::device = "RAID";
+ $FAI::configs{$FAI::device}{fstabkey} = "device";
+ }
+ raid_option(s?)
+ | /^lvm/
+ {
+
+ # check, whether lvm tools are available
+ &FAI::in_path("lvcreate") or die "LVM tools not found in PATH\n";
+ # initialise $FAI::device to inform the following lines about the LVM
+ # being configured
+ $FAI::device = "VG_";
+ $FAI::configs{"VG_--ANY--"}{fstabkey} = "device";
+ }
+ lvm_option(s?)
+ | 'end'
+ {
+ # exit config mode
+ $FAI::device = "";
+ }
+ | /^disk(\d+)/
+ {
+ # check, whether parted is available
+ &FAI::in_path("parted") or die "parted not found in PATH\n";
+ # initialise the entry of the hash corresponding to disk$1
+ &FAI::init_disk_config($1);
+ }
+ option(s?)
+ | /^\S+/
+ {
+ # check, whether parted is available
+ &FAI::in_path("parted") or die "parted not found in PATH\n";
+ # initialise the entry of the hash corresponding to $item[1]
+ &FAI::init_disk_config($item[ 1 ]);
+ }
+ option(s?)
+
+ raid_option: /^preserve_always:(\d+(,\d+)*)/
+ {
+ # set the preserve flag for all ids in all cases
+ $FAI::configs{RAID}{volumes}{$_}{preserve} = 1 foreach (split (",", $1));
+ }
+ | /^preserve_reinstall:(\d+(,\d+)*)/
+ {
+ # set the preserve flag for all ids if $FAI::reinstall is set
+ if ($FAI::reinstall) {
+ $FAI::configs{RAID}{volumes}{$_}{preserve} = 1 foreach (split(",", $1));
+ }
+ }
+ | /^fstabkey:(device|label|uuid)/
+ {
+ # the information preferred for fstab device identifieres
+ $FAI::configs{$FAI::device}{fstabkey} = $1;
+ }
+
+ lvm_option: m{^preserve_always:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
+ {
+ # set the preserve flag for all ids in all cases
+ foreach (split (",", $1)) {
+ (m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}) or
+ die &FAI::internal_error("VG re-parse failed");
+ $FAI::configs{"VG_$1"}{volumes}{$2}{size}{preserve} = 1
+ }
+ }
+ | m{^preserve_reinstall:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
+ {
+ # set the preserve flag for all ids if $FAI::reinstall is set
+ if ($FAI::reinstall) {
+ foreach (split (",", $1)) {
+ (m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}) or
+ die &FAI::internal_error("VG re-parse failed");
+ $FAI::configs{"VG_$1"}{volumes}{$2}{size}{preserve} = 1
+ }
+ }
+ }
+ | m{^resize:([^/,\s\-]+-[^/,\s\-]+(,[^/,\s\-]+-[^/,\s\-]+)*)}
+ {
+ # set the resize flag for all ids
+ foreach (split (",", $1)) {
+ (m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}) or
+ die &FAI::internal_error("VG re-parse failed");
+ $FAI::configs{"VG_$1"}{volumes}{$2}{size}{resize} = 1
+ }
+ }
+ | /^fstabkey:(device|label|uuid)/
+ {
+ # the information preferred for fstab device identifieres
+ $FAI::configs{"VG_--ANY--"}{fstabkey} = $1;
+ }
+
+ option: /^preserve_always:(\d+(,\d+)*)/
+ {
+ # set the preserve flag for all ids in all cases
+ $FAI::configs{$FAI::device}{partitions}{$_}{size}{preserve} = 1 foreach (split (",", $1));
+ }
+ | /^preserve_reinstall:(\d+(,\d+)*)/
+ {
+ # set the preserve flag for all ids if $FAI::reinstall is set
+ if ($FAI::reinstall) {
+ $FAI::configs{$FAI::device}{partitions}{$_}{size}{preserve} = 1 foreach (split(",", $1));
+ }
+ }
+ | /^resize:(\d+(,\d+)*)/
+ {
+ # set the resize flag for all ids
+ $FAI::configs{$FAI::device}{partitions}{$_}{size}{resize} = 1 foreach (split(",", $1));
+ }
+ | /^disklabel:(msdos|gpt)/
+ {
+ # set the disk label - actually not only the above, but all types
+ # supported by parted could be allowed, but others are not implemented
+ # yet
+ $FAI::configs{$FAI::device}{disklabel} = $1;
+ }
+ | /^bootable:(\d+)/
+ {
+ # specify a partition that should get the bootable flag set
+ $FAI::configs{$FAI::device}{bootable} = $1;
+ ($FAI::device =~ /^PHY_(.+)$/) or
+ &FAI::internal_error("unexpected device name");
+ $FAI::disk_var{BOOT_DEVICE} .= " $1";
+ }
+ | 'virtual'
+ {
+ # this is a configuration for a virtual disk
+ $FAI::configs{$FAI::device}{virtual} = 1;
+ }
+ | /^fstabkey:(device|label|uuid)/
+ {
+ # the information preferred for fstab device identifieres
+ $FAI::configs{$FAI::device}{fstabkey} = $1;
+ }
+
+ volume: /^vg\s+/ name devices
+ | /^raid([0156])\s+/
+ {
+ # make sure that this is a RAID configuration
+ ($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
+ my $vol_id = scalar (keys %{ $FAI::configs{RAID}{volumes} });
+ # set the RAID type of this volume
+ $FAI::configs{RAID}{volumes}{$vol_id}{mode} = $1;
+ # initialise the hash of devices
+ $FAI::configs{RAID}{volumes}{$vol_id}{devices} = {};
+ # set the reference to the current volume
+ # the reference is used by all further processing of this config line
+ $FAI::partition_pointer = (\%FAI::configs)->{RAID}->{volumes}->{$vol_id};
+ }
+ mountpoint devices filesystem mount_options fs_options
+ | type mountpoint size filesystem mount_options fs_options
+
+ type: 'primary'
+ {
+ # initialise a primary partition
+ &FAI::init_part_config($item[ 1 ]);
+ }
+ | 'logical'
+ {
+ # initialise a logical partition
+ &FAI::init_part_config($item[ 1 ]);
+ }
+ | m{^([^/,\s\-]+)-([^/,\s\-]+)\s+}
+ {
+ # set $FAI::device to VG_$1
+ $FAI::device = "VG_$1";
+ # make sure, the volume group $1 has been defined before
+ defined ($FAI::configs{$FAI::device}) or
+ die "Volume group $1 has not been declared yet.\n";
+ # make sure, $2 has not been defined already
+ defined ($FAI::configs{$FAI::device}{volumes}{$2}{size}{range}) and
+ die "Logical volume $2 has been defined already.\n";
+ # initialise the new hash
+ defined($FAI::configs{$FAI::device}{volumes}{$2}) or
+ $FAI::configs{$FAI::device}{volumes}{$2} = {};
+ # initialise the preserve and resize flags
+ defined($FAI::configs{$FAI::device}{volumes}{$2}{size}{preserve}) or
+ $FAI::configs{$FAI::device}{volumes}{$2}{size}{preserve} = 0;
+ defined($FAI::configs{$FAI::device}{volumes}{$2}{size}{resize}) or
+ $FAI::configs{$FAI::device}{volumes}{$2}{size}{resize} = 0;
+ # set the reference to the current volume
+ # the reference is used by all further processing of this config line
+ $FAI::partition_pointer = (\%FAI::configs)->{$FAI::device}->{volumes}->{$2};
+ }
+
+ mountpoint: '-'
+ {
+ # this partition should not be mounted
+ $FAI::partition_pointer->{mountpoint} = "-";
+ $FAI::partition_pointer->{encrypt} = 0;
+ }
+ | 'swap'
+ {
+ # this partition is swap space, not mounted
+ $FAI::partition_pointer->{mountpoint} = "none";
+ $FAI::partition_pointer->{encrypt} = 0;
+ }
+ | m{^/\S*}
+ {
+ # set the mount point, may include encryption-request
+ if ($item[ 1 ] =~ m{^(/[^:]*):encrypt$}) {
+ &FAI::in_path("cryptsetup") or die "cryptsetup not found in PATH\n";
+ $FAI::partition_pointer->{mountpoint} = $1;
+ $FAI::partition_pointer->{encrypt} = 1;
+ } else {
+ $FAI::partition_pointer->{mountpoint} = $item[ 1 ];
+ $FAI::partition_pointer->{encrypt} = 0;
+ }
+ }
+
+ name: m{^([^/,\s\-]+)}
+ {
+ # set the device name to VG_ and the name of the volume group
+ $FAI::device = "VG_$1";
+ # make sure, the volume group $1 not has been defined already
+ defined ($FAI::configs{$FAI::device}) and
+ die "Volume group $1 has been defined already.\n";
+ # make sure this line is part of an LVM configuration
+ ($FAI::device =~ /^VG_/) or
+ die "vg is invalid in a non LVM-context.\n";
+ # initialise the new hash
+ $FAI::configs{$FAI::device}{volumes} = {};
+ # initialise the list of physical devices
+ $FAI::configs{$FAI::device}{devices} = ();
+ # the rule must not return undef
+ 1;
+ }
+
+ size: /^(\d+[kMGTP%]?(-(\d+[kMGTP%]?)?)?)(:resize)?\s+/
+ {
+ # complete the size specification to be a range in all cases
+ my $range = $1;
+ # the size is fixed
+ if (!defined ($2))
+ {
+ # make it a range of the form x-x
+ $range = "$range-$1";
+ }
+ elsif (!defined ($3))
+ {
+ # range has no upper limit, assume the whole disk
+ $range = "${range}100%";
+ }
+
+ # convert the units, if necessary
+ my ($min, $max) = split (/-/, $range);
+ $min = &FAI::convert_unit($min);
+ $max = &FAI::convert_unit($max);
+ $range = "$min-$max";
+ # enter the range into the hash
+ $FAI::partition_pointer->{size}->{range} = $range;
+ # set the resize flag, if required
+ defined ($4) and $FAI::partition_pointer->{size}->{resize} = 1;
+ }
+ | /^(-\d+[kMGTP%]?)(:resize)?\s+/
+ {
+ # complete the range by assuming 0 as the lower limit
+ my $range = "0$1";
+ # convert the units, if necessary
+ my ($min, $max) = split (/-/, $range);
+ $min = &FAI::convert_unit($min);
+ $max = &FAI::convert_unit($max);
+ $range = "$min-$max";
+ # enter the range into the hash
+ $FAI::partition_pointer->{size}->{range} = $range;
+ # set the resize flag, if required
+ defined( $2 ) and $FAI::partition_pointer->{size}->{resize} = 1;
+ }
+ | <error: invalid partition size near "$text">
+
+ devices: /^([^\d,:\s\-][^,:\s]*(:(spare|missing))*(,[^,:\s]+(:(spare|missing))*)*)/
+ {
+ # split the device list by ,
+ foreach my $dev (split(",", $1))
+ {
+ # match the substrings
+ ($dev =~ /^([^\d,:\s\-][^,:\s]*)(:(spare|missing))*$/) or
+ &FAI::internal_error("PARSER ERROR");
+ # redefine the device string
+ $dev = $1;
+ # make $dev a full path name; can't validate device name yet as it
+ # might be created later on
+ unless ($dev =~ m{^/}) {
+ if ($dev =~ m/^disk(\d+)\.(\d+)/) {
+ $dev = &FAI::make_device_name("/dev/" . $FAI::disks[ $1 - 1 ], $2);
+ } else {
+ $dev = "/dev/$dev";
+ }
+ }
+ # options are only valid for RAID
+ defined ($2) and ($FAI::device ne "RAID") and die "Option $2 invalid in a non-RAID context\n";
+ if ($FAI::device eq "RAID") {
+ # parse all options
+ my $spare = 0;
+ my $missing = 0;
+ if (defined ($2)) {
+ ($2 =~ /spare/) and $spare = 1;
+ ($2 =~ /missing/) and $missing = 1;
+ }
+ # each device may only appear once
+ defined ($FAI::partition_pointer->{devices}->{$dev}) and
+ die "$dev is already part of the RAID volume\n";
+ # set the options
+ $FAI::partition_pointer->{devices}->{$dev}->{options} = {
+ "spare" => $spare,
+ "missing" => $missing
+ };
+ } else {
+ # create an empty hash for each device
+ $FAI::configs{$FAI::device}{devices}{$dev} = {};
+ }
+ }
+ 1;
+ }
+ | <error: invalid device spec "$text">
+
+ mount_options: /\S+/
+ {
+ $FAI::partition_pointer->{mount_options} = $item[ 1 ];
+ }
+
+ filesystem: '-'
+ {
+ $FAI::partition_pointer->{filesystem} = $item[ 1 ];
+ }
+ | 'swap'
+ {
+ $FAI::partition_pointer->{filesystem} = $item[ 1 ];
+ }
+ | /^\S+/
+ {
+ &FAI::in_path("mkfs.$item[1]") or
+ die "unknown/invalid filesystem type $item[1] (mkfs.$item[1] not found in PATH)\n";
+ $FAI::partition_pointer->{filesystem} = $item[ 1 ];
+ }
+
+ fs_options: /[^;\n]*/
+ {
+ $FAI::partition_pointer->{fs_options} = $item[ 1 ];
+ }
+}
+);
+
+################################################################################
+#
+# @brief Parse the data from <$IN> using @ref $FAI::Parser
+#
+# @param IN file handle for input file, may be STDIN
+#
+################################################################################
+sub run_parser {
+ my ($IN) = @_;
+
+ # read <$IN> to a single string (not a list), thus $/ has to be unset
+ my $ifs = $/;
+ undef $/;
+ my $input = <$IN>;
+ $/ = $ifs;
+
+ # print the contents of <$IN> for debugging purposes
+ $FAI::debug and print "Input was:\n" . $input;
+
+ # check for old-style configuration files
+ ($input =~ m{(^|\n)[^\n#]+;})
+ and die "Old style configuration files are not supported\n";
+
+ # attempt to parse $input - any error will lead to termination
+ defined $FAI::Parser->file($input) or die "Syntax error\n";
+}
+
+1;
+
More information about the Fai-commit
mailing list