IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
Mar 6, 2008, 5:55:53 PM (18 years ago)
Author:
bills
Message:

dded support for product specific data and file type specific data.
Allow fileset contents to reside outside of the data store directory
and be referenced by symbolic link.
Add option to copy files from a source into the destination fileset.
Removed obsolete variables from the original mock up.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/DataStoreServer/scripts/dsreg

    r16765 r16867  
    11#!/usr/bin/env perl
    22#
    3 # DataStore fileset registration
    4 #
    5 # Does not enforce validity of metadata items.
     3# Data Store file set registration and de-registration
    64#
    75
     
    2927                       caturi
    3028                       );
     29my $product;
     30my $fileset;
     31
     32my $fstype;
     33my $ps0;
     34my $ps1;
     35my $ps2;
     36my $ps3;
     37my $ps4;
     38my $ps5;
     39my $ps6;
     40my $ps7;
     41
     42my $linkfiles;      # if set, put links to files in datapath in the Data Store
     43my $copyfiles;      # if set, copy files from this directory to the Data Store fileset
     44my $datapath;       # source for files required if $linkfiles or $copyfiles
     45
     46my $ds_dir;
    3147
    3248my $add;
    3349my $del;
    34 
    35 my $ds_dir;
    36 my $product;
    37 my $fileset;
    38 
    39 ### XXX: these aren't currently used
    40 ### fill in some bogus values here
    41 my $type = 'OBJECT';
    42 my $ra = '00:00:00.00';
    43 my $dec = '00:00:00.00';
    44 my $equinox = 2000;
    45 my $etime = 30.0;
    46 my $filter = 'z';
    47 my $airmass = 1.2;
    48 
    49 my $date;
     50my $remove;
     51
     52my $verbosity = 1;
     53
     54
     55
    5056
    5157#
     
    5359#
    5460
    55 # XXX: need to make argument parsing file type specific
    5661GetOptions(
    57     'add'               => \$add,
    58     'del'               => \$del,
    59     'dsdir|ds=s'        => \$ds_dir,
    60     'type|t=s'          => \$type,
    61     'ra|r=s'            => \$ra,
    62     'dec|d=s'           => \$dec,
    63     'equinox|eq=f'      => \$equinox,
    64     'etime|ex|e=f'      => \$etime,
    65     'filter|f=s'        => \$filter,
    66         'date=s'        => \$date,
    67     'airmass|a=f'       => \$airmass,
     62        'add'           =>      \$add,
     63        'del'           =>      \$del,
     64        'product=s'     =>      \$product,
     65        'fileset=s'     =>      \$fileset,
     66        'type=s'        =>      \$fstype,
     67        'datapath=s'    =>      \$datapath,
     68        'link'          =>      \$linkfiles,
     69        'copy'          =>      \$copyfiles,
     70        'rm'            =>      \$remove,
     71        'ps0=s'         =>      \$ps0,          # product specific columns 0 - 7
     72        'ps1=s'         =>      \$ps1,
     73        'ps2=s'         =>      \$ps2,
     74        'ps3=s'         =>      \$ps3,
     75        'ps4=s'         =>      \$ps4,
     76        'ps5=s'         =>      \$ps5,
     77        'ps6=s'         =>      \$ps6,
     78        'ps7=s'         =>      \$ps7
    6879) or pod2usage(2);
    6980
    7081my $err = "";
    7182
    72 $err .= "Must specify a product and a fileset.\n"
    73     unless @ARGV == 2;
     83$err .= "product and fileset are required\n" unless defined $product and $fileset;
    7484
    7585# will exit if neither or both -add and -del were specified
    7686$err .= "Must specify either --add or --del.\n"
    7787    unless $add xor $del;
     88
     89if ($add) {
     90    if (!$fstype) {
     91        $err .= "need to specify fileset type to add\n";
     92    }
     93
     94    if ($linkfiles and $copyfiles) {
     95        $err .= "only one of --link and --copy allowedn";
     96    }
     97    if (($linkfiles or $copyfiles) and !$datapath) {
     98        $err .= "need to specify datapath with --link or --copy\n";
     99    }
     100}
     101
     102
     103#
     104# lookup the location of the Data Store
     105#
    78106
    79107my $ipprc =  PS::IPP::Config->new(); # IPP Configuration
     
    82110    $ds_dir = metadataLookupStr($ipprc->{_siteConfig}, 'PSTAMP_DATA_STORE_ROOT');
    83111    if (!$ds_dir) {
    84         die("data store root not defined");
     112        die("Data Store root directory not set");
    85113    }
    86114}
     
    88116
    89117if (!stat("$ds_dir/index.txt")) {
    90     $err .= "Datastore not found at '$ds_dir'.\n"
     118    $err .= "Data Store not found at '$ds_dir'.\n"
    91119}
    92120
     
    95123    if ($err);
    96124
    97 $product = shift;
    98 
    99125show_usage("Invalid product '$product'.")
    100126    unless defined stat("$ds_dir/$product/index.txt");
    101 
    102 $fileset = shift;
    103 
    104 
    105 #
    106 # run
    107 #
    108127
    109128my $dbserver = metadataLookupStr($siteConfig, 'DBSERVER');
     
    117136my $dbh = DBI->connect($dsn, $dbuser, $dbpass) or die "Cannot connect to server\n";
    118137
    119 my $index_script_name = "$ds_dir/$product/$fileset/index.txt";
     138
     139
     140my $fileset_dir = "$ds_dir/$product/$fileset";
     141my $index_script_name = "$fileset_dir/index.txt";
    120142
    121143if ($del) {
     
    143165    }
    144166
    145     # zap the index script
    146     unlink("$index_script_name");
     167    if ($remove) {
     168        if (system "rm -r $fileset_dir") {
     169            die("failed to remove $fileset_dir");
     170        }
     171    } else  {
     172        # zap the index script
     173        unlink("$index_script_name");
     174    }
    147175
    148176    my $fileset_id = $fs_row->{fileset_id};
     
    170198} else {
    171199    #
    172     # adding a new fileset
     200    # add a new fileset
    173201    #
     202
     203    # make a string out of the product specifc column values provided
     204    my $prodcolstr = make_prodcol_str($ps0, $ps1, $ps2, $ps3, $ps4, $ps5, $ps6, $ps7);
     205
    174206    my $stmt = $dbh->prepare("SELECT prod_id FROM dsProduct WHERE prod_name = \'$product\'");
    175207    $stmt->execute();
     
    198230        my $filename;
    199231        my $filetype;
    200         my $type_col_0;
    201         if (/([A-Za-z0-9-_.]+)\s+([A-Za-z0-9-_.]+)\s+([A-Za-z0-9-_.]+)/) {
    202             $filename = $1;
    203             $filetype = $2;
    204             $type_col_0 = $3;
    205         } else {
    206             unless (/([A-Za-z0-9-_.]+)\s+([A-Za-z0-9-_.]+)\s+/) {
     232        my $ts_string = "";
     233
     234        chomp;
     235        my @fields = split /\|/;
     236        if (@fields < 2) {
    207237                print STDERR "Line $lineno: ignored malformed input line.\n";
    208238                next;
    209             }
    210             $filename = $1;
    211             $filetype = $2;
    212         }
    213 
    214         my @finfo = stat("$ds_dir/$product/$fileset/$filename");
     239        }
     240        $filename = shift @fields;
     241        $filetype = shift @fields;
     242
     243        #
     244        # save any type specific fields provided in the string to be added to the
     245        # VALUES list for this file
     246        my $nfields = @fields;
     247        my $i;
     248        for ($i=0; $i < $nfields; $i++) {
     249            $ts_string .= ", \'$fields[$i]\'";
     250        }
     251        for ($i=$nfields ; $i < 4; $i++) {
     252            $ts_string .= ", NULL";
     253        }
     254
     255        my $path = "$datapath/$filename";
     256        my @finfo = stat("$path");
    215257
    216258        unless (@finfo) {
    217259            die ("Line $lineno: referenced file "
    218                 ."($ds_dir/$product/$fileset/$1) does not exist.\n");
     260                ."($path does not exist.\n");
    219261        }
    220262       
    221263        # Get MD5 sum
    222         my $md5 = file_md5_hex("$ds_dir/$product/$fileset/$filename");
     264        my $md5 = file_md5_hex($path);
    223265
    224266        my $hashref = {
    225             'file' => $filename,
    226             'bytes' => $finfo[7],
     267            'file'      => $filename,
     268            'bytes'     => $finfo[7],
    227269            'md5sum'    => $md5,
    228270            'type'      => $filetype,
    229             'type_col_0'=> $type_col_0
     271            'ts_string'  => $ts_string
    230272        };
    231273
    232274        push @files, $hashref;
    233275    }
    234 
    235276
    236277    if (@files == 0) {
    237278        die("empty filelist");
    238279    }
    239 
    240     # create the cgi script index file by making a copy of its parent's
     280   
     281    #
     282    # Prepare the fileset directory
     283    if ($linkfiles or $copyfiles) {
     284            ## create the fileset directory
     285        if (! -e $fileset_dir) {
     286            if (!mkdir $fileset_dir) {
     287                die("failed trying to make fileset directory $fileset_dir");
     288            }
     289        }
     290        eval {
     291            ## then copy or symlink the files into place
     292            foreach my $ref (@files) {
     293                my $src = "$datapath/$ref->{file}";
     294                my $dest = "$fileset_dir/$ref->{file}";
     295
     296                if ($linkfiles) {
     297                    if (!  symlink $src, $dest) {
     298                        die("failed trying to link $src to $dest");
     299                    }
     300                } else {
     301                    if (!copy($src, $dest)) {
     302                        die("copy($src, $dest) failed");
     303                    }
     304                }
     305            }
     306        };
     307        if ($@) { # an error occured
     308            print STDERR "error preparing the fileset directory: $@\n";
     309
     310            if (system "rm -r $fileset_dir") {
     311                die("failed to remove $fileset_dir");
     312            }
     313           
     314            exit $PS_EXIT_UNKNOWN_ERROR;
     315        }
     316    }
     317
     318    # create the cgi script index.txt by making a copy of its parent's
    241319    if (!copy("$ds_dir/$product/index.txt", $index_script_name)) {
    242         die("failed to copy index script to fileset");
     320        die("failed to copy index script to file set");
    243321    }
    244322
     
    248326        $dbh->{AutoCommit} = 0;
    249327
    250         $count = $dbh->do("INSERT into dsFileset" .
    251                 " (prod_id, fileset_name, reg_time, type)" .
    252                 " VALUES($prod_id, \'$fileset\', UTC_TIMESTAMP(), 'PSRESULTS')");
     328        my $qstring = "INSERT into dsFileset" .
     329                " (prod_id, fileset_name, reg_time, type," .
     330                " prod_col_0, prod_col_1, prod_col_2, prod_col_3, prod_col_4, prod_col_5, " .
     331                " prod_col_6, prod_col_7)" .
     332                # note prodcolstr begins with a comma
     333                " VALUES($prod_id, \'$fileset\', UTC_TIMESTAMP(), \'$fstype\' $prodcolstr)";
     334        $count = $dbh->do($qstring);
    253335        if ($count == 0E0) {
    254336            die("failed to insert $fileset");
     
    260342
    261343        foreach my $ref (@files) {
    262             my $query;
    263             if ($ref->{type_col_0}) {
    264                 $query = "INSERT INTO dsFile" .
    265                     " (fileset_id, file_id, file_name, bytes, md5sum, type, type_col_0)" .
     344            # note: ts_string has a leading comma
     345            my $query = "INSERT INTO dsFile" .
     346
     347                    " (fileset_id, file_id, file_name, bytes, md5sum, type, " .
     348                    " type_col_0, type_col_1, type_col_2, type_col_3)" .
     349
    266350                    " VALUES($fileset_id, 0, \'$ref->{file}\', $ref->{bytes}," .
    267                              " \'$ref->{md5sum}\', \'$ref->{type}\', \'$ref->{type_col_0}\')";
    268             } else {
    269                 $query = "INSERT INTO dsFile" .
    270                     " (fileset_id, file_id, file_name, bytes, md5sum, type)" .
    271                     " VALUES($fileset_id, 0, \'$ref->{file}\', $ref->{bytes}," .
    272                              " \'$ref->{md5sum}\', \'$ref->{type}\')";
    273             }
     351                             " \'$ref->{md5sum}\', \'$ref->{type}\' $ref->{ts_string} )";
     352
    274353            $count = $dbh->do($query);
    275354
     
    301380}
    302381
     382
    303383sub show_usage {
    304384    my $str = shift;
     
    310390    pod2usage(
    311391        -msg =>
    312 "usage: $tmp[$#tmp] [--add|--del] product fileset [options]
     392"usage: $tmp[$#tmp] [--add|--del] --product prod_name --fileset fs_name --type fs_type [options]
    313393
    314394Commands:
    315395
    316     --del        Remove a fileset.
    317396    --add        Add a new fileset with the given metadata options.
    318397                File information will be read per-line from STDIN, in the form:
    319                     fileID type [chipname]
     398
     399                    fileID|type|ts0|ts1|ts2|ts3
     400
    320401                These entries are read until EOF is sent.
     402                (The type specific ts[0-3]fields are optional)
     403
     404    --del        Remove a fileset.
     405
    321406Options:
    322    
    323     --dsdir      Specify the path to the Datastore
     407    --link      Link files from datapath to Data Store
     408    --copy      Copy files from datapath to Data Store
     409    --datapath  path to source files
     410    --ps0 - ps7 Optional product specific data
     411    --rm        with --del remove the fileset directory from the Data Store
    324412   
    325413$str",
    326414        -exitval => 2
    327415    );
    328 
    329     if (0) {
    330      my $saveString = "(The following metadata is not used yet)
    331 
    332     --date       ISO8601 date string. (File timestamp used if not specified.)
    333     --type       Fileset type.
    334     --ra         Telescope pointing RA.
    335     --dec        Telescope pointing Dec.
    336     --equinox    Equinox.
    337     --etime      Exposure time.
    338     --filter     Filter used.
    339     --airmass    Air mass. ";   
    340     }
    341 }
    342 
    343 # get the current UTC time in iso8601 format
    344 # this is used if no time parameter is specified
    345 sub get_iso8601() {
    346     my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) =
    347         gmtime(time);
    348 
    349     return sprintf("%4d-%02d-%02dT%02d:%02d:%02dZ",
    350         $year+1900, $mon+1, $mday, $hour, $min, $sec);
    351 }
     416}
     417
     418sub make_prodcol_str {
     419
     420    my @list = @_;
     421    my $string = "";
     422
     423    foreach my $s (@list) {
     424        if ($s) {
     425            $string .= ", \'$s\'";
     426        } else {
     427            $string .= ", NULL";
     428        }
     429    }
     430
     431    return $string;
     432}
Note: See TracChangeset for help on using the changeset viewer.