contrib/extractDS.px: Allow extration of multiple DSes into one file with multiple...
authorFlorian Forster <octo@leeloo.lan.home.verplant.org>
Thu, 17 May 2007 13:11:17 +0000 (15:11 +0200)
committerFlorian Forster <octo@leeloo.lan.home.verplant.org>
Thu, 17 May 2007 13:11:17 +0000 (15:11 +0200)
This is needed to migrate the old disk-RRD-files.

contrib/extractDS.px

index 5826c65..f5370e6 100755 (executable)
@@ -23,19 +23,19 @@ use XML::Simple (qw(xml_in xml_out));
 use Data::Dumper ();
 
 our $InFile;
-our $InDS;
+our $InDS = [];
 our $OutFile;
-our $OutDS;
+our $OutDS = [];
 
 GetOptions ("infile|i=s" => \$InFile,
-       "inds|s=s" => \$InDS,
+       "inds|s=s" => sub { push (@$InDS, $_[1]); },
        "outfile|o=s" => \$OutFile,
-       "outds|d=s" => \$OutDS) or exit (1);
+       "outds|d=s" => sub { push (@$OutDS, $_[1]); })
+       or exit (1);
 
-if (!$InFile || !$OutFile || !$InDS || !$OutDS)
+if (!$InFile || !$OutFile || !@$InDS || !@$OutDS)
 {
-       print "$InFile $InDS $OutFile $OutDS\n";
-       print STDERR "Usage: $0 -i <infile> -I <inds> -o <outfile> -O <outds>\n";
+       print STDERR "Usage: $0 -i <infile> -s <inds> -o <outfile> -d <outds>\n";
        exit (1);
 }
 if (!-f $InFile)
@@ -48,19 +48,23 @@ if (-f $OutFile)
        print STDERR "Output file does exist\n";
        exit (1);
 }
+if ((1 + @$InDS) != (1 + @$OutDS))
+{
+       print STDERR "You need the same amount of in- and out-DSes\n";
+       exit (1);
+}
 
-extract_ds ($InFile, $OutFile, $InDS, $OutDS);
+extract_ds ($InFile, $OutFile);
 exit (0);
 
 {
-my $ds_index = -1;
-my $current_index = -1;
+my $ds_index;
+my $current_index;
 # state 0 == searching for DS index
 # state 1 == parse RRA header
-# state 2 == parse <ds> in RRA header
-# state 3 == parse values
-my $state = 0;
-my $out_cache = '';
+# state 2 == parse values
+my $state;
+my $out_cache;
 sub handle_line
 {
        my $fh = shift;
@@ -68,48 +72,75 @@ sub handle_line
 
        if (!defined ($state))
        {
-               $ds_index = -1;
                $current_index = -1;
                $state = 0;
-               $out_cache = '';
+               $out_cache = [];
+
+               # $ds_index->[new_index] = old_index
+               $ds_index = [];
+               for (my $i = 0; $i < @$InDS; $i++)
+               {
+                       $ds_index->[$i] = -1;
+               }
        }
 
        if ($state == 0)
        {
                if ($line =~ m/<ds>/)
                {
-                       $out_cache = $line;
                        $current_index++;
+                       $out_cache->[$current_index] = $line;
                }
                elsif ($line =~ m#<name>\s*([^<\s]+)\s*</name>#)
                {
-                       if ($1 eq $InDS)
+                       # old_index == $current_index
+                       # new_index == $i
+                       for (my $i = 0; $i < @$InDS; $i++)
                        {
-                               $ds_index = $current_index;
-                               $out_cache .= "\t\t<name>$OutDS</name>\n";
+                               next if ($ds_index->[$i] >= 0);
+
+                               if ($1 eq $InDS->[$i])
+                               {
+                                       $line =~ s#<name>\s*([^<\s]+)\s*</name>#<name> $OutDS->[$i] </name>#;
+                                       $ds_index->[$i] = $current_index;
+                                       last;
+                               }
                        }
+
+                       $out_cache->[$current_index] .= $line;
                }
                elsif ($line =~ m#</ds>#)
                {
-                       $out_cache .= $line;
-                       if ($ds_index == $current_index)
-                       {
-                               print $fh $out_cache;
-                       }
+                       $out_cache->[$current_index] .= $line;
                }
                elsif ($line =~ m#<rra>#)
                {
+                       # Print out all the DS definitions we need
+                       for (my $new_index = 0; $new_index < @$InDS; $new_index++)
+                       {
+                               my $old_index = $ds_index->[$new_index];
+                               print $fh $out_cache->[$old_index];
+                       }
+
+                       # Clear the cache - it's used in state1, too.
+                       for (my $i = 0; $i <= $current_index; $i++)
+                       {
+                               $out_cache->[$i] = '';
+                       }
+
                        print $fh $line;
                        $current_index = -1;
                        $state = 1;
                }
                elsif ($current_index == -1)
                {
+                       # Print all the lines before the first DS definition
                        print $fh $line;
                }
                else
                {
-                       $out_cache .= $line;
+                       # Something belonging to a DS-definition
+                       $out_cache->[$current_index] .= $line;
                }
        }
        elsif ($state == 1)
@@ -117,37 +148,44 @@ sub handle_line
                if ($line =~ m#<ds>#)
                {
                        $current_index++;
-                       if ($current_index == $ds_index)
+                       $out_cache->[$current_index] .= $line;
+               }
+               elsif ($line =~ m#</cdp_prep>#)
+               {
+                       # Print out all the DS definitions we need
+                       for (my $new_index = 0; $new_index < @$InDS; $new_index++)
                        {
-                               print $fh $line;
+                               my $old_index = $ds_index->[$new_index];
+                               print $fh $out_cache->[$old_index];
+                       }
+
+                       # Clear the cache
+                       for (my $i = 0; $i <= $current_index; $i++)
+                       {
+                               $out_cache->[$i] = '';
                        }
 
-                       if ($line =~ m#</ds>#) { $state = 1; }
-                       else { $state = 2; }
-               }
-               elsif ($line =~ m#<database>#)
-               {
                        print $fh $line;
-                       $state = 3;
+                       $current_index = -1;
                }
-               else
+               elsif ($line =~ m#<database>#)
                {
                        print $fh $line;
+                       $state = 2;
                }
-       }
-       elsif ($state == 2)
-       {
-               if ($current_index == $ds_index)
+               elsif ($current_index == -1)
                {
-                       print STDERR $line;
+                       # Print all the lines before the first DS definition
+                       # and after cdp_prep
                        print $fh $line;
                }
-               if ($line =~ m#</ds>#)
+               else
                {
-                       $state = 1;
+                       # Something belonging to a DS-definition
+                       $out_cache->[$current_index] .= $line;
                }
        }
-       else
+       elsif ($state == 2)
        {
                if ($line =~ m#</database>#)
                {
@@ -157,39 +195,49 @@ sub handle_line
                }
                else
                {
-                       my $line_begin = "\t\t";
-                       $current_index = 0;
+                       my @values = ();
+                       my $i;
+                       my $output = "\t\t";
+
                        if ($line =~ m#(<!-- .*? -->)#)
                        {
-                               $line_begin .= "$1 ";
+                               $output .= "$1 ";
                        }
+                       $output .= "<row> ";
 
-                       while ($line =~ m#<v>\s*([^<\s]+)\s*</v>#)
+                       $i = 0;
+                       while ($line =~ m#<v>\s*([^<\s]+)\s*</v>#g)
                        {
-                               my $value = $1;
-                               if ($current_index == $ds_index)
-                               {
-                                       print $fh "$line_begin<row> <v>$value</v> </row>\n";
-                                       last;
-                               }
-                               $current_index++;
+                               $values[$i] = $1;
+                               $i++;
                        }
+
+                       for (my $new_index = 0; $new_index < @$InDS; $new_index++)
+                       {
+                               my $old_index = $ds_index->[$new_index];
+                               $output .= '<v> ' . $values[$old_index] . ' </v> ';
+                       }
+                       $output .= "</row>\n";
+                       print $fh $output;
                }
        }
+       else
+       {
+               die;
+       }
 }} # handle_line
 
 sub extract_ds
 {
        my $in_file = shift;
        my $out_file = shift;
-       my $in_ds = shift;
-       my $out_ds = shift;
 
        my $in_fh;
        my $out_fh;
 
        open ($in_fh,  '-|', 'rrdtool', 'dump', $in_file) or die ("open (rrdtool): $!");
-       open ($out_fh, '|-', 'rrdtool', 'restore', '-', $out_file) or die ("open (rrdtool): $!");
+#      open ($out_fh, '|-', 'rrdtool', 'restore', '-', $out_file) or die ("open (rrdtool): $!");
+       $out_fh = \*STDOUT;
 
        while (my $line = <$in_fh>)
        {