IPP Software Navigation Tools IPP Links Communication Pan-STARRS Links

Ignore:
Timestamp:
May 26, 2009, 1:59:32 PM (17 years ago)
Author:
beaumont
Message:

merged with trunk

Location:
branches/cnb_branches/cnb_branch_20090301
Files:
1 deleted
24 edited
3 copied

Legend:

Unmodified
Added
Removed
  • branches/cnb_branches/cnb_branch_20090301

  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server

  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/Build.PL

    r20157 r24244  
    1515        'DBI'                   => '1.53',
    1616        'Digest::SHA1'          => 0,
     17        'File::Basename'        => 0,
    1718        'File::ExtAttr'         => '1.03',
    1819        'File::Mountpoint'      => '0.01',
    1920        'File::Path'            => '1.08',
    2021        'File::Spec'            => 0,
    21         'Filesys::Df'           => '0.92',
    2222        'File::Spec::Functions' => 0,
    2323        'File::Temp'            => 0,
     24        'Filesys::Df'           => '0.92',
     25        'Log::Dispatch::Email::MailSend' => 0,
    2426        'Log::Log4perl'         => '0.48',
    2527        'Net::Server::Daemonize'=> '0.05',
    2628        'Params::Validate'      => '0.73',
    2729        'SOAP::Lite'            => '0.69',
     30        'SQL::Interp'           => '1.06',
    2831        'URI'                   => '1.30',
    29         'SQL::Interp'           => '1.06',
    3032    },
    3133    build_requires      => {
    3234        'Test::More'            => '0.49',
    3335        'Test::URI'             => '1.06',
     36        'Test::DBUnit'          => '0.20',
    3437    },
    3538    recommends          => {
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/Changes

    r23594 r24244  
    330.17
    44    - retry database transactions when a deadlock is detected
    5 
     5    - add log4perl logging to nebdiskd
     6    - base the on disk directory hashing of files only on the dirname()
     7      component of keys
     8    - add email logging of events to nebdiskd
     9    - attempt to optimize _is_valid_object_key() by eliminating an unused join
     10    - rename Nebulous::Keys class -> Nebulous::Key
     11    - select neb db to use by hashing only the directory component of the key
     12    - disallow Nebulous::Server->rename_object() when it would cause the db
     13      hash of a key to change
     14    - create a pseduo directory structure on key creation
     15    - Nebulous::Key parsing and testing improvements
     16    - change 'log_level' param to 'trace'
     17    - refactor ->find_objects() functionality
     18     
    6190.16
    720    - add so_id/name idxs to storage_object_xattr table
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/MANIFEST

    r23352 r24244  
    44MANIFEST
    55README
    6 Todo
    76bin/neb-admin
    87bin/neb-fsck
     
    1918examples/uri_test.pl
    2019init.d/nebdiskd
    21 lib/Nebulous/Keys.pm
     20lib/Nebulous/Key.pm
    2221lib/Nebulous/Server.pm
    2322lib/Nebulous/Server.pod
     
    3332t/00_distribution.t
    3433t/01_load.t
     34t/02_config.t
    3535t/02_server_setup.t
    3636t/03_server_create_object.t
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/bin/neb-admin

    r23594 r24244  
    174174        # if the copies xattr is unset and the object has 2 or more instances, we
    175175        # will assume a target of 2 copies
     176       
     177        # XXX change this: there should be no default value or we will
     178        # have a race condition.  user.copies should never get set by
     179        # any client until AFTER a file is no longer in use.
    176180        my $copies = $obj->{copies} || 2;
    177181
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/bin/nebdiskd

    r20206 r24244  
    1616use File::Spec;
    1717use Filesys::Df;
     18use Log::Log4perl;
    1819use Nebulous::Server::SQL;
    1920use Net::Server::Daemonize qw( daemonize unlink_pid_file );
     
    8586    unless $db && $dbuser && $dbpass;
    8687
     88# start up logging
     89my $conf = '
     90    log4perl.category.nebdiskd = WARN, Screen, SERVERLOGFILE, Mailer
     91
     92    log4perl.appender.Screen        = Log::Log4perl::Appender::Screen
     93    log4perl.appender.Screen.stderr = 1
     94    log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
     95    log4perl.appender.Screen.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} | %H | %p | %M - %m%n
     96
     97    log4perl.appender.SERVERLOGFILE           = Log::Log4perl::Appender::File
     98    log4perl.appender.SERVERLOGFILE.filename  = /tmp/nebdiskd.log
     99    log4perl.appender.SERVERLOGFILE.mode      = append
     100    log4perl.appender.SERVERLOGFILE.layout    = Log::Log4perl::Layout::PatternLayout
     101    log4perl.appender.SERVERLOGFILE.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} | %H | %p | %M - %m%n
     102
     103    log4perl.filter.MatchWarn  = Log::Log4perl::Filter::LevelMatch
     104    log4perl.filter.MatchWarn.LevelToMatch  = WARN
     105    log4perl.filter.MatchWarn.AcceptOnMatch = off
     106
     107    log4perl.appender.Mailer         = Log::Dispatch::Email::MailSend
     108    log4perl.appender.Mailer.to      = ps-ipp-ops@ifa.hawaii.edu
     109    log4perl.appender.Mailer.subject = nebdiskd alert
     110    log4perl.appender.AppError.Filter= MatchWarn
     111    log4perl.appender.Mailer.layout = Log::Log4perl::Layout::PatternLayout
     112    log4perl.appender.Mailer.layout.ConversionPattern = %d{yyyy-MM-dd HH:mm:ss} | %H | %p | %M - %m%n
     113';
     114Log::Log4perl::init(\$conf);
     115my $log = Log::Log4perl::get_logger("nebdiskd");
     116$log->level('WARN');
     117$log->level('DEBUG') if $debug;
     118
    87119daemonize(
    88120    $user,     # User
     
    104136                poll_interval   => $poll_interval,
    105137                debug           => $debug,
    106         ) or die "poll_mounts() should not have returned";
     138        );
    107139    };
    108     if ($!) {
    109         warn $@;
     140    if ($@) {
     141        $log->warn($@);
    110142    }
    111143
     
    113145}
    114146
    115 die "poll loop exited -- THIS SHOULD NOT HAPPEN";
     147$log->logdie("poll loop exited -- THIS SHOULD NOT HAPPEN");
    116148
    117149
     
    141173        # determine valid mountpoints
    142174        foreach my $mnt (@$mounts) {
    143             print "checking $mnt\n" if $debug;
     175            $log->debug("checking $mnt");
    144176            # this /SHOULD/ fail if the mount point is handled by the
    145177            # automounter and it fails to mount
    146178            eval {
    147179                unless (is_mountpoint($mnt)) {
    148                     die "$mnt is not a valid mountpoint\n";
     180                    $log->warn("$mnt is not a valid mountpoint");
    149181                }
    150182            };
    151183            if ($@) {
    152                 print $@ if $debug;
     184                $log->warn($@);
    153185                $d_query->execute($mnt);
    154186                next;
     
    160192            my $dev_info = df($mnt, 1024);
    161193            unless (defined $dev_info) {
    162                 print "can't find device info for $mnt\n" if $debug;
     194                $log->error("can't find device info for $mnt");
    163195                next;
    164196            }
    165197
    166198            $r_query->execute($mnt, @$dev_info{qw( blocks used )});
    167             print "adding $mnt to db\n" if $debug;
     199            $log->debug("adding $mnt to db");
    168200
    169201        }
     
    172204
    173205        $dbh->commit;
    174         print "commited to database\n" if $debug;
     206        $log->debug("commited to database");
    175207    };
    176208    if ($@) {
    177209        $dbh->rollback;
    178         print "rolledback transaction\n" if $debug;
    179         warn $@;
     210        $log->debug("rolledback transaction");
     211        $log->logdie($@);
    180212    }
    181213}
     
    188220
    189221    if (!-f $rcfile) {
    190         open(my $fh, '>', $rcfile) or die "can't open file: $!";
    191         close($fh) or die "can't close file:$!";
     222        open(my $fh, '>', $rcfile) or $log->logdie("can't open file: $!");
     223        close($fh) or $log->logdie("can't close file:$!");
    192224    }
    193225
     
    226258    };
    227259    if ($@) {
    228         $db->rollback;
    229         die $@;
     260        $dbh->rollback;
     261        $log->logdie($@);
    230262    }
    231263
     
    242274    foreach my $path (@$mounts) {
    243275        if (stat File::Spec->canonpath($path)) {
    244             print "stated $path\n" if $debug;
     276            $log->debug("stated $path");
    245277        } else {
    246             warn "can not stat path: $path";
     278            $log->warn("can not stat path: $path");
    247279        }
    248280    }
     
    263295  ### get the currently listed pid
    264296  if( ! open(_PID,$pid_file) ){
    265     die "Couldn't open existant pid_file \"$pid_file\" [$!]\n";
     297    $log->logdie("Couldn't open existant pid_file \"$pid_file\" [$!]");
    266298  }
    267299  my $_current_pid = <_PID>;
    268300  close _PID;
    269   my $current_pid = $_current_pid =~ /^(\d{1,10})/ ? $1 : die "Couldn't find pid in existing pid_file";
     301  my $current_pid = $_current_pid =~ /^(\d{1,10})/ ? $1 : $log->logdie("Couldn't find pid in existing pid_file");
    270302
    271303  my $exists = undef;
     
    289321
    290322        if( $current_pid == $$ ){
    291             warn "Pid_file created by this same process. Doing nothing.\n";
     323            $log->warn("Pid_file created by this same process. Doing nothing.");
    292324            return 1;
    293325        }else{
    294326            kill 'TERM', $current_pid
    295                 or die "Failed to signal process ($current_pid)";
    296             unlink $pid_file || die "Couldn't remove pid_file \"$pid_file\" [$!]\n";
     327                or $log->logdie("Failed to signal process ($current_pid)");
     328            unlink $pid_file || $log->logdie("Couldn't remove pid_file \"$pid_file\" [$!]");
    297329        }
    298330    }
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/docs/install.txt

    r23352 r24244  
    5656
    5757    neb-initdb
    58     neb-addvol --name ipp000.0 --uri file:///data/ipp000.0/nebulous
    59     neb-addvol --name ipp000.1 --uri file:///data/ipp000.1/nebulous
    60     neb-addvol --name ipp002.0 --uri file:///data/ipp002.0/nebulous
    61     neb-addvol --name ipp003.0 --uri file:///data/ipp003.0/nebulous
    62 
    63 #    perl -e 'for (1..24) { $i = sprintf "po%02d", $_ ; system "neb-addvol --name $i --uri file:/$i/nebulous" }'
     58
     59    neb-voladd --vhost ipp000 --vname ipp000.0 --uri file:///data/ipp000.0/nebulous
     60    neb-voladd --vhost ipp001 --vname ipp000.1 --uri file:///data/ipp000.1/nebulous
     61    neb-voladd --vhost ipp002 --vname ipp002.0 --uri file:///data/ipp002.0/nebulous
     62    neb-voladd --vhost ipp003 --vname ipp003.0 --uri file:///data/ipp003.0/nebulous
     63    neb-voladd --vhost ipp022 --vname ipp022.0 --uri file:///data/ipp022.0/nebulous
     64
     65    # or in bulk:
     66   
     67    for i in ipp005 ipp006 ipp007 ipp009 ipp010 ipp011 ipp012 ipp013 ipp014 ipp015 ipp016 ipp017 ipp018 ipp020 ipp021 ipp022 ipp023 ipp024 ipp025 ipp026 ipp027 ipp028 ipp029 ipp030 ipp031 ipp032 ipp033 ipp034 ipp035
     68    do
     69        /usr/bin/neb-voladd --vname ${i}.0 --vhost $i --uri file:///data/${i}.0/nebulous_beta
     70    done
     71
     72#    perl -e 'for (1..24) { $i = sprintf "po%02d", $_ ; system "neb-voladd
     73#    --vname $i --vhost $i --uri file:/$i/nebulous" }'
    6474    .
    6575    .
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server.pm

    r23594 r24244  
    99no warnings qw( uninitialized );
    1010
    11 our $VERSION = '0.15';
     11our $VERSION = '0.17';
    1212
    1313use base qw( Class::Accessor::Fast );
     
    1515use DBI;
    1616use Digest::SHA1 qw( sha1_hex );
     17use File::Basename qw( basename dirname fileparse );
    1718use File::ExtAttr qw( setfattr );
    1819use File::Path;
    1920use File::Spec;
    20 use Log::Log4perl;
     21use Log::Log4perl qw( :levels );
     22use Nebulous::Key qw( parse_neb_key parse_neb_volume );
    2123use Nebulous::Server::Config;
    2224use Nebulous::Server::Log;
    2325use Nebulous::Server::SQL;
    24 use Nebulous::Keys qw( parse_neb_key parse_neb_volume );
    25 use Params::Validate qw( validate_pos SCALAR SCALARREF UNDEF );
     26use Params::Validate qw( validate validate_pos SCALAR SCALARREF UNDEF BOOLEAN );
    2627use URI::file;
    2728
     
    3637
    3738    # let Nebulous::Server::Config validate our params
    38     my $config = Nebulous::Server::Config->init( @_ );
     39    my $config = Nebulous::Server::Config->new( @_ );
     40
     41    return $class->new_from_config($config);
     42}
     43
     44
     45sub new_from_config
     46{
     47    my ($class, $config) = @_;
    3948
    4049    # log4perl is not avaliable until we call init()
    4150    Nebulous::Server::Log->init($config);
    4251    my $log = Log::Log4perl::get_logger( "Nebulous::Server" );
     52    $log->level($config->trace);
    4353
    4454    my $sql = Nebulous::Server::SQL->new;
     
    5161    $self->config($config);
    5262
    53     # ask for the db handle as a means of validating the database parameters
    54     $self->db;
    55 
    5663    $log->debug( "leaving" );
    57    
     64
    5865    return $self;
    5966}
    6067
    61 
    62 sub db
    63 {
    64     my $self = shift;
    65 
    66     if (@_) {
    67         $self->{db} = $_[0];
    68         return $self;
    69     }
     68# EAM : In the 'distributed' version of Nebulous, there is a collection of N databases
     69# the db_index uniquely defines the db used by a given key
     70sub _db_index_for_key
     71{
     72    my ($self, $key) = @_;
     73
     74    my $config  = $self->config;
     75
     76    my $db_index = 0;
     77    die "key not defined" unless defined $key;
     78
     79    # hash the key to select the correct database instance
     80    # only use the first 8 hex chars... have to be careful to avoid an int
     81    # overflow here
     82
     83    # hash only the directory component of the path and not the filename
     84    my $path = dirname($key->path);
     85    $db_index = unpack("h8", sha1_hex($path)) % $config->n_db;
     86
     87    return $db_index;
     88}
     89
     90sub _db_for_index
     91{
     92    my ($self, $db_index) = @_;
    7093
    7194    my $log     = $self->log;
     
    7396    my $config  = $self->config;
    7497
     98    # lookup to see if we have a stored dbh for this database
     99    my $dbh = $self->{dbs}[$db_index];
    75100    # if the dbh is still alive, return it
    76     if (defined $self->{db} and $self->{db}->ping) {
     101    if (defined $dbh and $dbh->ping) {
    77102        $log->debug("db handle is still alive");
    78         return $self->{db};
     103        return $dbh;
    79104    }
    80105    # otherwise create a new connection
    81106    $log->debug("db handle is dead/unopened");
     107
     108    # lookup database info
     109    my $db_config = $config->db($db_index);
     110    die "can't find database configuration info for database # $db_index"
     111        unless $db_config;
    82112
    83113    # if we're running under mod_perl & Apache::DBI is loaded we want to
     
    86116    # processes and the database might have gone away on us.  Apache::DBI will
    87117    # take care of getting a valid dbh back.
    88     my $db;
    89118    eval {
    90         $db = DBI->connect_cached(
    91             $config->dsn,
    92             $config->dbuser,
    93             $config->dbpasswd,
     119        $dbh = DBI->connect_cached(
     120            $db_config->dsn,
     121            $db_config->dbuser,
     122            $db_config->dbpasswd,
    94123            {
    95124                RaiseError => 1,
     
    99128        );
    100129
    101         $db->do( $sql->set_transaction_model );
    102         $log->debug( "connected to database: ", sub { $db->data_sources; } );
    103         $db->commit;
     130        $dbh->do( $sql->set_transaction_model );
     131        $log->debug( "connected to database: ", sub { $dbh->data_sources; } );
     132        $dbh->commit;
    104133        $log->debug("commit");
    105134    };
    106135    if ( $@ ) {
    107         $db->rollback if $db;
     136        $dbh->rollback if $dbh;
    108137        $log->debug("rollback");
    109138        $log->logdie( "database error: $@" );
    110139    }
    111140
    112     $self->{db} = $db;
    113 
    114     return $db;
    115 }
    116 
     141    $self->{dbs}[$db_index] = $dbh;
     142
     143    return $dbh;
     144}
     145
     146sub db
     147{
     148    my $self = shift;
     149
     150    my ($key) = validate_pos(@_,
     151        {
     152            isa => 'Nebulous::Key',
     153        },
     154    );
     155
     156    my $log     = $self->log;
     157    my $sql     = $self->sql;
     158    my $config  = $self->config;
     159
     160    die "key not defined" unless defined $key;
     161    my $db_index = $self->_db_index_for_key($key);
     162
     163    my $dbh = $self->_db_for_index($db_index);
     164    return $dbh;
     165}
    117166
    118167sub create_object
     
    137186    );
    138187
    139     my $log = $self->log;
    140     my $sql = $self->sql;
    141     my $db  =$self->db;
    142 
    143     $log->debug( "entered - @_" );
    144 
    145188    # vol_name overrides the key implied volume
    146189    $key = parse_neb_key($key, $vol_name);
    147190    $vol_name = $key->volume;
    148191
     192    my $log = $self->log;
     193    my $sql = $self->sql;
     194    my $db  = $self->db($key);
     195
     196    $log->debug( "entered - @_" );
     197
    149198    # the key's volume can't be validiated on input for this method so we have
    150199    # to check it after parsing the key
    151200    if (defined $vol_name
    152         and not $self->_is_valid_volume_name($key->volume)) {
     201        and not $self->_is_valid_volume_name($key, $key->volume)) {
    153202        if ($key->soft_volume) {
    154203            $log->warn( "$vol_name is not a known volume name" );
     
    160209       
    161210    my ($vol_id, $vol_host, $vol_path, $vol_xattr)
    162         = $self->_get_storage_volume($vol_name, $key->soft_volume);
     211        = $self->_get_storage_volume($key, $vol_name, $key->soft_volume);
     212
     213    my $parent_id = $self->_resolve_dir_parent_id(key => $key, create => 1);
    163214
    164215    my $uri;
     
    168219                # create storage_object
    169220                my $query = $db->prepare_cached( $sql->new_object );
    170                 $query->execute('NULL', $key->path);
     221                $query->execute('NULL', $key->path, basename($key->path), $parent_id);
    171222            }
    172223
     
    214265
    215266            # TODO add some stuff here to retry if unsucessful
    216             $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr);
     267            $uri = $self->_create_empty_instance_file($key, $so_id, $ins_id, $vol_path, $vol_xattr);
    217268            $log->debug("created $uri on volume ID: $vol_id");
    218269
     
    246297
    247298
     299sub _resolve_dir_parent_id
     300{
     301    my $self = shift;
     302
     303    my %p = validate(@_,
     304        {
     305            key     => {
     306                isa         => 'Nebulous::Key',
     307            },
     308            create  => {
     309                type        => BOOLEAN,
     310                optional    => 1,
     311                default     => undef,
     312            },
     313            # return dir_id instead of parent_id
     314            dir_id  => {
     315                type        => BOOLEAN,
     316                optional    => 1,
     317                default     => undef,
     318            },
     319        }
     320    );
     321
     322    my $key = $p{key};
     323
     324    my $log = $self->log;
     325    my $sql = $self->sql;
     326    my $db  = $self->db($key);
     327
     328    $log->debug( "entered - @_" );
     329
     330    # no path means '/', which has a dir_id & parent_id of 1
     331    return 1 if $key->path eq '';
     332
     333    # resolve parent directory
     334    my @dirs;
     335
     336    # File::Spec->splitpath was causing ->splitdir to always an extra dir
     337    # named "" because of a trailing /
     338    unless ($p{dir_id}) {
     339        @dirs = File::Spec->splitdir(dirname($key->path));
     340    } else {
     341        @dirs = File::Spec->splitdir($key->path);
     342    }
     343    # dirname returns "." if there is no dir component to the path, we have
     344    # to filter this out
     345    @dirs = grep(!/^\.$/, @dirs);
     346
     347    $log->debug("looking for dirs - ", join(" : ", @dirs), "\n");
     348
     349    # start at the root dir; '/' == 1
     350    my $parent_id = 1;
     351    my $dir_id;
     352TRANS: while (1) {
     353        eval {
     354            foreach my $dir (@dirs) {
     355                $dir_id = undef;
     356                {
     357                    my $query = $db->prepare_cached($sql->get_directory);
     358                    $query->execute($parent_id, $dir);
     359                    if ($query->rows) {
     360                        $dir_id = $query->fetchrow_hashref->{'dir_id'};
     361                        $log->debug("resolved $dir to dir_id: $dir_id");
     362                    }
     363                    $query->finish;
     364                }
     365
     366                # if we found a dir_id, a row for this directory already exists
     367                if (defined $dir_id) {
     368                    $parent_id = $dir_id;
     369                    # note that you can't exit an eval {} with next
     370                    next;
     371                }
     372
     373                # else dir doesn't exist
     374                unless ($p{create}) {
     375                    # resolution failed
     376                    $parent_id = undef;
     377                    last;
     378                }
     379
     380                {
     381                    # dir doesn't exist, create it
     382                    my $query = $db->prepare_cached($sql->new_directory);
     383                    $query->execute($dir, $parent_id);
     384                }
     385
     386                # get the dir_id of the new directory entry
     387                {
     388                    my $query = $db->prepare_cached($sql->last_insert_id);
     389                    $query->execute();
     390
     391                    # the new dir_id will be the parent_id of the next
     392                    # descendent directory
     393                    ($parent_id) = $query->fetchrow_array;
     394                    $query->finish;
     395                }
     396                $log->logdie("failed to get LAST_INSERT_ID()")
     397                    unless $parent_id;
     398
     399                $db->commit;
     400            }
     401        };
     402        if ($@) {
     403            $db->rollback;
     404            $log->debug("rollback");
     405            if ($@ =~ /Deadlock found/) {
     406                $log->warn("database deadlock retrying transaction: $@");
     407                redo TRANS;
     408            }
     409            $log->logdie("error: $@");
     410        }
     411        last;
     412    }
     413
     414    $log->debug("leaving");
     415
     416    return $p{dir_id} ? $dir_id : $parent_id;
     417}
     418
     419
    248420sub rename_object
    249421{
     
    265437        },
    266438    );
    267 
    268     my $log = $self->log;
    269     my $sql = $self->sql;
    270     my $db  =$self->db;
    271 
    272     $log->debug("entered - @_");
    273439
    274440    # ignore volumes
    275441    $key    = parse_neb_key($key);
    276442    $newkey = parse_neb_key($newkey);
     443
     444    my $log = $self->log;
     445    my $sql = $self->sql;
     446    my $db  = $self->db($key);
     447
     448    $log->debug("entered - @_");
     449
     450    # XXX this may require database migration in the future
     451    unless ($self->_db_index_for_key($key)
     452         == $self->_db_index_for_key($newkey)) {
     453        $log->logdie("can not rename objects across distributed database boundaries");
     454    }
    277455
    278456TRANS: while (1) {
     
    281459            my $query = $db->prepare_cached($sql->rename_object);
    282460            # this SQL statment takes the new key name as the first param
    283             my $rows = $query->execute($newkey->path, $key->path);
     461            my $rows = $query->execute($newkey->path, basename($newkey->path), $self->_resolve_dir_parent_id(key => $newkey, create => 1), $key->path);
    284462
    285463            # if we affected more then one row something very bad has happened.
     
    309487}
    310488
    311 
    312489sub swap_objects
    313490{
     
    328505        },
    329506    );
    330 
    331     my $log = $self->log;
    332     my $sql = $self->sql;
    333     my $db  =$self->db;
    334 
    335     $log->debug("entered - @_");
    336507
    337508    # ignore volumes
     
    339510    $key2 = parse_neb_key($key2);
    340511
    341     # order of operations for the swap:
     512    my $log = $self->log;
     513    my $sql = $self->sql;
     514
     515    my $dbidx1 = $self->_db_index_for_key($key1);
     516    my $dbidx2 = $self->_db_index_for_key($key2);
     517    die "cannot swap keys not stored on the same database" unless ($dbidx1 == $dbidx2);
     518
     519    my $dbh1 = $self->_db_for_index($dbidx1);
     520    my $dbh2 = $self->_db_for_index($dbidx2);
     521    die "different db handles for the same db?" unless ($dbh1 == $dbh2);
     522
     523    $log->debug("entered - @_");
     524
     525    # order of operations for the swap with a single db is:
    342526    # key1 -> key1.swap
    343527    # key2 -> key1
    344528    # key1.swap -> key2
    345529
    346 TRANS: while (1) {
     530    my $db = $dbh1;
     531  TRANS: while (1) {
    347532        eval {
    348533            {
    349                 # key1 -> key1.swap
    350                 my $query = $db->prepare_cached($sql->rename_object);
    351                 # this SQL statment takes the new key name as the first param
    352                 my $rows = $query->execute($key1->path . ".swap", $key1->path);
    353 
    354                 # if we affected more then one row something very bad has happened.
    355                 unless ($rows == 1) {
    356                     $query->finish;
    357                     $log->logdie("affected row count is $rows instead of 1");
    358                 }
    359             }
    360 
    361             {
    362                 # key2 -> key1
    363                 my $query = $db->prepare_cached($sql->rename_object);
    364                 # this SQL statment takes the new key name as the first param
    365                 my $rows = $query->execute($key1->path, $key2->path);
    366 
    367                 # if we affected more then one row something very bad has happened.
    368                 unless ($rows == 1) {
    369                     $query->finish;
    370                     $log->logdie("affected row count is $rows instead of 1");
    371                 }
    372             }
    373 
    374             {
    375                 # key1.swap -> key2
    376                 my $query = $db->prepare_cached($sql->rename_object);
    377                 # this SQL statment takes the new key name as the first param
    378                 my $rows = $query->execute($key2->path, $key1->path . ".swap");
    379 
    380                 # if we affected more then one row something very bad has happened.
    381                 unless ($rows == 1) {
    382                     $query->finish;
    383                     $log->logdie("affected row count is $rows instead of 1");
    384                 }
    385             }
     534              # key1 -> key1.swap
     535              my $query = $db->prepare_cached($sql->rename_object);
     536              # this SQL statment takes the new key name as the first param
     537              # XXX currently using a bogus dir_id -- this may cause a problem
     538              # someday but it's unlikley as it's contained entirely in the
     539              # transaction
     540              my $rows = $query->execute($key1->path . ".swap", basename($key1->path) . ".swap", 1, $key1->path);
     541
     542              # if we affected more then one row something very bad has happened.
     543              unless ($rows == 1) {
     544                  $query->finish;
     545                  $log->logdie("affected row count is $rows instead of 1");
     546              }
     547          }
     548
     549          {
     550              # key2 -> key1
     551              my $query = $db->prepare_cached($sql->rename_object);
     552              # this SQL statment takes the new key name as the first param
     553              my $rows = $query->execute($key1->path, basename($key1->path), $self->_resolve_dir_parent_id(key => $key1, create => 1), $key2->path);
     554
     555              # if we affected more then one row something very bad has happened.
     556              unless ($rows == 1) {
     557                  $query->finish;
     558                  $log->logdie("affected row count is $rows instead of 1");
     559              }
     560          }
     561
     562          {
     563              # key1.swap -> key2
     564              my $query = $db->prepare_cached($sql->rename_object);
     565              # this SQL statment takes the new key name as the first param
     566              my $rows = $query->execute($key2->path, basename($key2->path), $self->_resolve_dir_parent_id(key => $key2, create => 1), $key1->path . ".swap");
     567
     568              # if we affected more then one row something very bad has happened.
     569              unless ($rows == 1) {
     570                  $query->finish;
     571                  $log->logdie("affected row count is $rows instead of 1");
     572              }
     573          }
    386574
    387575            $db->commit;
     
    397585            $log->logdie("database error: $@");
    398586        }
    399         last;
    400     }
     587      last;
     588  }
    401589
    402590    $log->debug("leaving");
     
    405593}
    406594
     595# EAM : from JH, below is a possible option to swap instances across
     596# dbs.  I recommend that this action be disallowed, and instead such
     597# operations be implemented only as a combination of copy and delete
     598
     599# order of operations for the swap between two dbs is:
     600# key1 start transaction
     601# key1 -> read all instances
     602# key1 -> remove all instances
     603# key2 start transaction
     604# key2 -> read all instances
     605# key2 -> remove all instances
     606# key1 -> insert key 2 instances
     607# key2 -> insert key 1 instances
     608# key1,2 commit
    407609
    408610sub replicate_object
     
    439641    # then we should throw an error
    440642
    441     my $log = $self->log;
    442     my $sql = $self->sql;
    443     my $db  =$self->db;
    444 
    445     $log->debug("entered - @_");
    446 
    447643    # vol_name overrides the key implied volume
    448644    $key = parse_neb_key($key, $vol_name);
    449645    $vol_name = $key->volume;
    450646
     647    my $log = $self->log;
     648    my $sql = $self->sql;
     649    my $db  = $self->db($key);
     650
     651    $log->debug("entered - @_");
     652
    451653    if (defined $vol_name
    452         and not $self->_is_valid_volume_name($key->volume)) {
     654        and not $self->_is_valid_volume_name($key, $key->volume)) {
    453655        if ($key->soft_volume) {
    454656            $log->warn( "$vol_name is not a known volume name" );
     
    462664    if (defined $vol_name) {
    463665        ($vol_id, $vol_host, $vol_path, $vol_xattr)
    464             = $self->_get_storage_volume($vol_name);
     666            = $self->_get_storage_volume($key, $vol_name);
    465667    } else {
    466668        ($vol_id, $vol_host, $vol_path, $vol_xattr)
     
    507709
    508710            # TODO add some stuff here to retry if unsucessful
    509             $uri = $self->_create_empty_instance_file($key->path, $so_id, $ins_id, $vol_path, $vol_xattr);
     711            # XXX if this fails, it should try to generate the
     712            # instance on another volume (unless !$soft_volume)
     713            $uri = $self->_create_empty_instance_file($key, $so_id, $ins_id, $vol_path, $vol_xattr);
    510714
    511715            {
     
    560764    );
    561765
    562     my $log = $self->log;
    563     my $sql = $self->sql;
    564     my $db  =$self->db;
    565 
    566     $log->debug( "entered - @_" );
    567 
    568766    # ignore volume
    569767    $key = parse_neb_key($key);
     768
     769    my $log = $self->log;
     770    my $sql = $self->sql;
     771    my $db  = $self->db($key);
     772
     773    $log->debug( "entered - @_" );
    570774
    571775    my $so_id;
     
    670874    );
    671875
    672     my $log = $self->log;
    673     my $sql = $self->sql;
    674     my $db  =$self->db;
    675 
    676     $log->debug( "entered - @_" );
    677 
    678876    # ignore volume
    679877    $key = parse_neb_key($key);
     878
     879    my $log = $self->log;
     880    my $sql = $self->sql;
     881    my $db  = $self->db($key);
     882
     883    $log->debug( "entered - @_" );
    680884
    681885    my $so_id;
     
    789993    );
    790994
    791     my $log = $self->log;
    792     my $sql = $self->sql;
    793     my $db  =$self->db;
    794 
    795     $log->debug("entered - @_");
    796 
    797995    # ignore volume
    798996    $key = parse_neb_key($key);
     997
     998    my $log = $self->log;
     999    my $sql = $self->sql;
     1000    my $db  = $self->db($key);
     1001
     1002    $log->debug("entered - @_");
    7991003
    8001004TRANS: while (1) {
     
    8631067    );
    8641068
    865     my $log = $self->log;
    866     my $sql = $self->sql;
    867     my $db  =$self->db;
    868 
    869     $log->debug("entered - @_");
    870 
    8711069    # ignore volume
    8721070    $key = parse_neb_key($key);
     1071
     1072    my $log = $self->log;
     1073    my $sql = $self->sql;
     1074    my $db  = $self->db($key);
     1075
     1076    $log->debug("entered - @_");
    8731077
    8741078    my $value;
     
    9161120    );
    9171121
    918     my $log = $self->log;
    919     my $sql = $self->sql;
    920     my $db  =$self->db;
    921 
    922     $log->debug("entered - @_");
    923 
    9241122    # ignore volume
    9251123    $key = parse_neb_key($key);
     1124
     1125    my $log = $self->log;
     1126    my $sql = $self->sql;
     1127    my $db  = $self->db($key);
     1128
     1129    $log->debug("entered - @_");
    9261130
    9271131    my @xattrs;
     
    9591163    );
    9601164
    961     my $log = $self->log;
    962     my $sql = $self->sql;
    963     my $db  =$self->db;
    964 
    965     $log->debug("entered - @_");
    966 
    9671165    # ignore volume
    9681166    $key = parse_neb_key($key);
     1167
     1168    my $log = $self->log;
     1169    my $sql = $self->sql;
     1170    my $db  = $self->db($key);
     1171
     1172    $log->debug("entered - @_");
    9691173
    9701174TRANS: while (1) {
     
    10001204}
    10011205
    1002 
     1206# loop over all db_index values, passing db_index to each call
    10031207sub find_objects
    10041208{
    10051209    my $self = shift;
    10061210
    1007     my ( $pattern ) = validate_pos( @_,
     1211    my ($pattern) = validate_pos( @_,
    10081212        {
    10091213            type        => SCALAR,
     
    10121216    );
    10131217
    1014     my $log = $self->log;
    1015     my $sql = $self->sql;
    1016     my $db  =$self->db;
     1218    $pattern = parse_neb_key($pattern);
     1219
     1220    my $log = $self->log;
    10171221
    10181222    $log->debug( "entered - @_" );
    10191223
    1020     unless ($pattern) {
     1224    unless (defined $pattern) {
    10211225        $log->debug( "leaving" );
    10221226        $log->logdie("no keys found");
    10231227    }
    10241228
    1025     # attempt to strip off neb:// if it exists
    1026     $pattern =~ s|^neb:||;
    1027 
     1229    my @keys = ();
     1230    my $n_dbs = $self->config->n_db();
     1231    for (my $index = 0; $index < $n_dbs; $index ++) {
     1232        my $newkeys = $self->_find_objects_for_index($index, $pattern);
     1233        push @keys, @$newkeys;
     1234    }
     1235    $log->logdie("no keys found") unless ( scalar @keys );
     1236
     1237    $log->debug( "leaving" );
     1238
     1239    return \@keys;
     1240}
     1241
     1242# find matching objects from the given server
     1243sub _find_objects_for_index
     1244{
     1245
     1246    my $self    = shift;
     1247    my $index   = shift;
     1248    my $key     = shift;
     1249
     1250    my $log = $self->log;
     1251    my $sql = $self->sql;
     1252    my $db  = $self->_db_for_index($index);
     1253
     1254    $log->debug( "entered - @_" );
     1255
     1256    # first check to see if the key is an exact match
    10281257    my @keys;
    10291258    eval {
    1030         my $query = $db->prepare_cached( $sql->find_objects );
    1031         $query->execute( $pattern );
     1259        $log->debug("trying for an exact key match with $key");
     1260        my $query = $db->prepare_cached( $sql->find_object_by_ext_id );
     1261        $query->execute( $key->path );
     1262        if ($query->rows) {
     1263            my $ext_id = $query->fetchrow_hashref->{'ext_id'};
     1264            $log->debug( "pattern has an exact match" );
     1265            push @keys, $ext_id;
     1266        } else {
     1267            $log->debug("no exact match for key");
     1268        }
     1269        $query->finish;
     1270    };
     1271    if ($@) {
     1272        $db->rollback;
     1273        $log->logdie("database error: $@");
     1274    }
     1275
     1276    if (scalar @keys) {
     1277        # it was an exact match, so stop here
     1278        $log->debug("leaving");
     1279
     1280        return \@keys;
     1281    }
     1282
     1283    # else, assume it's a directory
     1284    my $dir_id = $self->_resolve_dir_parent_id(key => $key, dir_id => 1);
     1285    unless (defined $dir_id) {
     1286        $log->logdie("pattern $key does not match any key or directory");
     1287    }
     1288
     1289    eval {
     1290        $log->debug("trying for a directory match under dir: $dir_id");
     1291        my $query = $db->prepare_cached( $sql->find_object_by_dir_id );
     1292        $query->execute( $dir_id );
    10321293
    10331294        while ( my $row = $query->fetchrow_hashref ) {
    10341295            my $key = $row->{ 'ext_id' };
    10351296            push @keys, $key if $key;
     1297            $log->debug( "matched $key" ) if $key;
    10361298        }
    10371299    };
    10381300    $log->logdie("database error: $@") if $@;
    1039 
    1040     $log->logdie("no keys found") unless ( scalar @keys );
    10411301
    10421302    $log->debug( "leaving" );
     
    10701330    );
    10711331
    1072     my $log = $self->log;
    1073     my $sql = $self->sql;
    1074     my $db  =$self->db;
    1075 
    1076     $log->debug("entered - @_");
    1077 
    10781332    # vol_name overrides the key implied volume
    10791333    $key = parse_neb_key($key, $vol_name);
    10801334    $vol_name = $key->volume;
    10811335
     1336    my $log = $self->log;
     1337    my $sql = $self->sql;
     1338    my $db  = $self->db($key);
     1339
     1340    $log->debug("entered - @_");
     1341
    10821342    # the key's volume can't be validiated on input for this method so we have
    10831343    # to check it after parsing the key
    10841344    if (defined $vol_name
    1085         and not $self->_is_valid_volume_name($key->volume)) {
     1345        and not $self->_is_valid_volume_name($key, $key->volume)) {
    10861346        if ($key->soft_volume) {
    10871347            $log->warn( "$vol_name is not a known volume name" );
     
    11431403    my $self = shift;
    11441404
    1145     my ( $uri ) = validate_pos( @_,
     1405    my ($key, $uri) = validate_pos( @_,
     1406        {
     1407            type        => SCALAR,
     1408            callbacks   => {
     1409                'is valid object key' => sub { $self->_is_valid_object_key($_[0]) },
     1410            },
     1411        },
    11461412        {
    11471413            type => SCALAR|SCALARREF,
     
    11491415    );
    11501416
    1151     my $log = $self->log;
    1152     my $sql = $self->sql;
    1153     my $db  =$self->db;
     1417    # ignore volume
     1418    $key = parse_neb_key($key);
     1419
     1420    my $log = $self->log;
     1421    my $sql = $self->sql;
     1422    my $db  = $self->db($key);
    11541423
    11551424    $log->debug( "entered - @_" );
     
    12431512    );
    12441513
    1245     my $log = $self->log;
    1246     my $sql = $self->sql;
    1247     my $db  =$self->db;
    1248 
    1249     $log->debug("entered - @_");
    1250 
    12511514    # ignore volume
    12521515    $key = parse_neb_key($key);
     1516
     1517    my $log = $self->log;
     1518    my $sql = $self->sql;
     1519    my $db  = $self->db($key);
     1520
     1521    $log->debug("entered - @_");
    12531522
    12541523    my $stat;
     
    12711540}
    12721541
    1273 
     1542# this should have a 'db_index' as an argument
    12741543sub mounts
    12751544{
     1545    # XXX: this will only pull the mounts from one db
     1546    # XXX: loop over db_index and generate a single unique list
     1547    # XXX: or report mount info for each db server
    12761548    my $self = shift;
    12771549
     
    12801552    my $log = $self->log;
    12811553    my $sql = $self->sql;
    1282     my $db  =$self->db;
     1554    my $db  = $self->_db_for_index(0); # XXX fix as above
    12831555
    12841556    $log->debug("entered - @_");
     
    13091581    my $self = shift;
    13101582
    1311     my $log = $self->log;
    1312     my $sql = $self->sql;
    1313     my $db  = $self->db;
     1583    my ($key, $name, $soft_volume) = @_;
     1584
     1585    my $log = $self->log;
     1586    my $sql = $self->sql;
     1587    my $db  = $self->db($key);
    13141588
    13151589    no warnings qw( uninitialized );
    13161590    $log->debug( "entered - @_" );
    13171591    use warnings;
    1318 
    1319     my ($name, $soft_volume) = @_;
    13201592
    13211593    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    13341606                # find it, fall back to any volume
    13351607                if ($soft_volume) {
    1336                     ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume;
     1608                    ($vol_id, $vol_host, $vol_path, $xattr) = $self->_get_storage_volume($key);
    13371609                    return; # this just returns out of the eval not from the subroutine
    13381610                }
     
    13741646    my $self = shift;
    13751647
    1376     my $log = $self->log;
    1377     my $sql = $self->sql;
    1378     my $db  =$self->db;
     1648    my $key = shift;
     1649
     1650    my $log = $self->log;
     1651    my $sql = $self->sql;
     1652    my $db  = $self->db($key);
    13791653
    13801654    no warnings qw( uninitialized );
    13811655    $log->debug( "entered - @_" );
    13821656    use warnings;
    1383 
    1384     my $key = shift;
    1385 
    1386     $key = parse_neb_key($key);
    13871657
    13881658    my ($vol_id, $vol_host, $vol_path, $xattr);
     
    14221692    my ($self, $key) = @_;
    14231693
    1424     my $log = $self->log;
    1425     my $sql = $self->sql;
    1426     my $db  =$self->db;
    1427 
    14281694    $key = parse_neb_key($key);
     1695
     1696    my $log = $self->log;
     1697    my $sql = $self->sql;
     1698    my $db  = $self->db($key);
    14291699
    14301700    my $ext_id;
    14311701    eval {
    1432         my $query = $db->prepare_cached( $sql->get_object );
     1702        my $query = $db->prepare_cached( $sql->check_object_name );
    14331703        $query->execute($key->path);
    14341704        ($ext_id) = $query->fetchrow_array;
     
    14511721sub _is_valid_volume_name
    14521722{
    1453     my ($self, $vol_name) = @_;
    1454 
    1455     my $log = $self->log;
    1456     my $sql = $self->sql;
    1457     my $db  =$self->db;
    1458 
     1723    my ($self, $key, $vol_name) = @_;
     1724
     1725    $key = parse_neb_key($key);
    14591726    my $volume_info = parse_neb_volume($vol_name);
     1727
     1728    my $log = $self->log;
     1729    my $sql = $self->sql;
     1730    my $db  = $self->db($key);
    14601731
    14611732    $vol_name = $volume_info->{volume};
     
    14921763    my $log = $self->log;
    14931764    my $sql = $self->sql;
    1494     my $db  = $self->db;
     1765    my $db  = $self->db($key);
    14951766
    14961767    my $uri;
    14971768    eval {
    1498         my $storage_path = $self->_generate_storage_path($key, $vol_path);
    1499         my $storage_filename = $self->_generate_storage_filename($key, $ins_id);
     1769        my $storage_path = $self->_generate_storage_path($key->path, $vol_path);
     1770        my $storage_filename = $self->_generate_storage_filename($key->path, $ins_id);
    15001771        unless (-d $storage_path) {
    15011772            _retry(sub { mkpath(@_) }, $storage_path, 0, 0775)
     
    15061777        my $mode = [_retry(sub { stat($storage_path) } )]->[2] & 07777;
    15071778        unless ($mode == 0775) {
    1508             $log->error("$storage_path has the wrong permissions of: %04o", $mode);
     1779            $log->error("$storage_path has the wrong permissions of: %04x", $mode);
    15091780            _retry(sub { chmod(0775, $storage_path) }) or die "can't chmod $storage_path: $!";
    15101781        }
     
    15221793        my $path = $uri->file;
    15231794        die "can not set xattr on $path: $!"
    1524             unless (setfattr($path, 'user.nebulous_key', $key));
     1795            unless (setfattr($path, 'user.nebulous_key', $key->path));
    15251796    }
    15261797
     
    16211892    my $log = $self->log;
    16221893    my $sql = $self->sql;
    1623     my $db  =$self->db;
     1894#    my $db  = $self->db;
    16241895
    16251896    $log->debug( "entered" );
    16261897
    1627     $self->db->disconnect;       
    1628 
    1629     $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
     1898# XXX do we need to loop over db_index?
     1899#    $self->db->disconnect;       
     1900
     1901#    $log->debug( "disconnected from database: ", sub { $db->data_sources; } );
    16301902
    16311903    $log->debug( "leaving" );
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server.pod

    r20092 r24244  
    2626    Nebulous::Server->find_objects( $pattern );
    2727    Nebulous::Server->find_instances( $key, $volume );
    28     Nebulous::Server->delete_instance( $uri );
     28    Nebulous::Server->delete_instance( $key, $uri );
    2929    Nebulous::Server->stat_object( $key );
    3030    Nebulous::Server->mounts();
     
    160160Throws an exception on error.
    161161
    162 =item * delete_instance( $uri );
    163 
    164 Accepts 1 parameters, it is mandatory.  Returns Boolean true.  Throws an
    165 exception on error.
     162=item * delete_instance( $key, $uri );
     163
     164Accepts 2 parameters, both mandatory.  Returns Boolean true.  C<<$uri>> must be
     165an instance of C<<$key>>.  Throws an exception on error.
    166166
    167167=item * swap_objects( $key1, $key2 );
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/Config.pm

    r20990 r24244  
    88use warnings FATAL => qw( all );
    99
    10 our $VERSION = 0.02;
     10our $VERSION = 0.03;
    1111
    1212use base qw( Class::Accessor::Fast );
    1313
    1414use Log::Log4perl qw( :levels );
    15 use Params::Validate qw( validate SCALAR );
     15use Params::Validate qw( validate validate_pos SCALAR );
    1616
    1717our %LEVELS = (
     
    2525);
    2626
    27 my $new_validate = {
     27my $db_validate = {
     28    dbindex       => {
     29        type => SCALAR,
     30        regex => qr/^\d+$/,
     31    },
    2832    dsn         => { type => SCALAR },
    2933    dbuser      => { type => SCALAR },
    3034    dbpasswd    => { type => SCALAR },
    31     log_level   => {
     35};
     36
     37my $new_validate = {
     38    trace       => {
    3239        type        => SCALAR,
    3340        optional    => 1,
    34         default     => 'all',
     41        default     => 'fatal',
    3542        callbacks   => {
    3643            'is valid level' => sub {
     
    3946        },
    4047    },
     48    dsn         => { type => SCALAR, optional => 1 },
     49    dbuser      => { type => SCALAR, optional => 1 },
     50    dbpasswd    => { type => SCALAR, optional => 1 },
    4151};
    4252
    4353__PACKAGE__->mk_ro_accessors( keys %$new_validate );
    4454
    45 sub init {
     55
     56sub new
     57{
    4658    my $class = shift;
    4759
     
    4961
    5062    # normalize log levels to lower-case
    51     $p{ log_level } = lc $p{ log_level };
    52 
    53     my $self = \%p;
     63    my $self = { trace => $LEVELS{lc($p{trace})} };
    5464
    5565    bless $self, $class || ref $class;
     66
     67    my @dbs;
     68    $self->{dbs} = \@dbs;
     69
     70    if (defined $p{dsn} or defined $p{dbuser} or defined $p{dbpasswd}) {
     71        $self->add_db(
     72            dbindex     => 0,
     73            dsn         => $p{dsn},
     74            dbuser      => $p{dbuser},
     75            dbpasswd    => $p{dbpasswd},
     76        );
     77    }
    5678
    5779    return $self;
    5880}
    5981
     82
     83sub add_db
     84{
     85    my $self = shift;
     86   
     87    my %p = validate( @_, $db_validate );
     88
     89    my $config_db = Nebulous::Server::Config::DB->new({
     90        dsn         => $p{dsn},
     91        dbuser      => $p{dbuser},
     92        dbpasswd    => $p{dbpasswd},
     93    });
     94
     95    $self->{dbs}->[$p{dbindex}] = $config_db;
     96
     97    return $self;
     98}
     99
     100
     101sub db
     102{
     103    my $self = shift;
     104
     105    my ($db_index) = validate_pos( @_, { type => SCALAR, optional => 1, });
     106
     107    # default to 0
     108    $db_index ||= 0;
     109
     110    return $self->{dbs}->[$db_index];
     111}
     112
     113
     114sub n_db
     115{
     116    my $self = shift;
     117
     118    return scalar @{ $self->{dbs} };
     119}
     120
     121
     122package Nebulous::Server::Config::DB;
     123
     124use strict;
     125use warnings FATAL => qw( all );
     126
     127our $VERSION = 0.01;
     128
     129use base qw( Class::Accessor::Fast );
     130
     131__PACKAGE__->mk_ro_accessors(qw( dsn dbuser dbpasswd ));
     132
    601331;
    61134
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/Log.pm

    r20990 r24244  
    1616    my ($self, $config) = @_;
    1717
    18     my $dsn         = $config->dsn;
    19     my $dbuser      = $config->dbuser;
    20     my $dbpasswd    = $config->dbpasswd;
     18#    my $dsn         = $config->db->dsn;
     19#    my $dbuser      = $config->db->dbuser;
     20#    my $dbpasswd    = $config->db->dbpasswd;
    2121
    2222    my $conf = <<END;
     
    3030#   date | hostname | priority | method/sub - message\n
    3131
    32     log4perl.appender.SQLLOG            = Log::Log4perl::Appender::DBI
    33     log4perl.appender.SQLLOG.datasource = $dsn
    34     log4perl.appender.SQLLOG.username   = $dbuser
    35     log4perl.appender.SQLLOG.password   = $dbpasswd
    36     log4perl.appender.SQLLOG.sql        = \
     32#    log4perl.appender.SQLLOG            = Log::Log4perl::Appender::DBI
     33#    log4perl.appender.SQLLOG.sql        = \
     34#    log4perl.appender.SQLLOG.datasource =
     35#    log4perl.appender.SQLLOG.username   =
     36#    log4perl.appender.SQLLOG.password   =
    3737    INSERT INTO log (timestamp, hostname, level, sub, message) \
    3838    VALUES          (%d,        %H,       %p,    %M,  %m)
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/SOAP.pm

    r20990 r24244  
    11# Copyright (c) 2004  Joshua Hoblitt
    22#
    3 # $Id: SOAP.pm,v 1.6 2008-12-14 22:54:25 eugene Exp $
     3# $Id: SOAP.pm,v 1.4.32.1 2008-12-14 22:52:37 eugene Exp $
    44
    55package Nebulous::Server::SOAP;
     
    1717our $AUTOLOAD;
    1818
    19 our @args;
     19our $config;
    2020our $neb;
    2121
    22 sub new_on_init {
     22
     23sub new_on_init
     24{
    2325    my $self = shift;
    2426
     
    2729    require Apache2::ServerUtil;
    2830
    29     @args = @_;
     31    $config = shift;
    3032
    3133    my $s = Apache2::ServerUtil->server;
     
    3537}
    3638
    37 sub init {
     39
     40sub init
     41{
    3842    my $self = shift;
    3943
    40     $neb = Nebulous::Server->new(@args);       
     44    $neb = Nebulous::Server->new_from_config($config);       
    4145
    4246    return Apache2::Const::OK;
    4347}
    4448
    45 sub AUTOLOAD {
     49
     50sub AUTOLOAD
     51{
    4652    my $self = shift;
    4753
     
    7682}
    7783
     84
    78851;
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/SQL.pm

    r20990 r24244  
    88use warnings FATAL => qw( all );
    99
    10 our $VERSION = '0.02';
     10our $VERSION = '0.04';
    1111
    1212use base qw( Class::Accessor::Fast );
     
    2626    new_object          => qq{
    2727        INSERT INTO storage_object
    28         (so_id, ext_id, type)
    29         VALUES (?, ?, 'REG_FILE')
     28        (so_id, ext_id, ext_id_basename, type, dir_id)
     29        VALUES (?, ?, ?, 'REG_FILE', ?)
    3030    },
    3131    new_object_attr  => qq{
     
    5959        JOIN storage_object_attr
    6060        USING (so_id)
     61        WHERE ext_id = ?
     62    },
     63    get_directory       => qq{
     64        SELECT
     65            dir_id
     66        FROM directory
     67        WHERE parent_id = ?
     68            AND dirname = ?
     69    },
     70    new_directory       => qq{
     71        INSERT INTO directory
     72        (dirname, parent_id)
     73        VALUES (?, ?)
     74    },
     75    check_object_name => qq{
     76        SELECT
     77            so_id,
     78            ext_id
     79        FROM storage_object
    6180        WHERE ext_id = ?
    6281    },
     
    290309            USING(vol_id)
    291310    },
    292     find_objects => qq{
    293         SELECT *
    294         FROM storage_object
    295         WHERE ext_id REGEXP ?
     311    find_object_by_ext_id => qq{
     312        SELECT ext_id, ext_id_basename
     313        FROM storage_object
     314        WHERE ext_id = ?
     315    },
     316    find_object_by_dir_id => qq{
     317        SELECT ext_id, ext_id_basename
     318        FROM storage_object
     319        WHERE dir_id = ?
    296320    },
    297321    rename_object => qq{
    298322        UPDATE storage_object
    299         SET ext_id = ?
     323        SET ext_id = ?, ext_id_basename = ?, dir_id = ?
    300324        WHERE ext_id = ?
    301325    },
     
    323347        GROUP BY so_id
    324348        HAVING available_instances < instances OR instances < copies
     349    },
     350    find_objects_with_extra_instances_by_xattr => qq{
     351        SELECT
     352            so.so_id,
     353            so.ext_id,
     354            count(ins_id) as instances,
     355            mv.name as volume_name,
     356            mv.host as volume_host,
     357            count(mv.vol_id) as available_instances,
     358            xattr.value as copies
     359        FROM storage_object AS so
     360        JOIN storage_object_xattr as xattr
     361            ON so.so_id = xattr.so_id
     362            AND xattr.name = 'user.copies'
     363        JOIN instance AS i
     364            ON so.so_id = i.so_id
     365        JOIN mountedvol AS mv
     366            USING(vol_id)
     367        WHERE
     368            mv.available = 1
     369        GROUP BY so_id
     370        HAVING available_instances > copies
     371        limit 5;
    325372    },
    326373    find_objects_with_extra_instances => qq{
     
    380427DROP TABLE IF EXISTS log;
    381428DROP TABLE IF EXISTS mountedvol;
     429DROP TABLE IF EXISTS directory;
    382430DROP PROCEDURE IF EXISTS getmountedvol;
    383431SET FOREIGN_KEY_CHECKS=1
     
    401449
    402450__DATA__
     451CREATE TABLE directory (
     452    dir_id BIGINT NOT NULL AUTO_INCREMENT,
     453    dirname CHAR(255) NOT NULL,
     454    parent_id BIGINT NOT NULL,
     455    FOREIGN KEY(parent_id) REFERENCES directory(dir_id),
     456    PRIMARY KEY(dir_id),
     457    KEY(parent_id)
     458) ENGINE=innodb DEFAULT CHARSET=latin1;
     459
     460###
     461
     462INSERT INTO directory (dir_id, dirname, parent_id) VALUES (1, '/', 1);
     463
     464###
     465
    403466CREATE TABLE storage_object (
    404467    so_id BIGINT NOT NULL AUTO_INCREMENT,
    405468    ext_id VARCHAR(255) NOT NULL UNIQUE,
     469    ext_id_basename VARCHAR(255) NOT NULL,
     470    dir_id BIGINT NOT NULL,
     471    FOREIGN KEY(dir_id) REFERENCES directory(dir_id),
    406472    type enum('REG_FILE'),
    407473    PRIMARY KEY(so_id),
    408     KEY(ext_id(64)),
     474    KEY(dir_id),
    409475    KEY(type)
    410476) ENGINE=innodb DEFAULT CHARSET=latin1;
     
    441507    type ENUM( 'read', 'write' ) NOT NULL,
    442508    epoch TIMESTAMP,
    443     KEY(so_ID)
     509    KEY(so_id)
    444510) ENGINE=innodb DEFAULT CHARSET=latin1;
    445511
     
    455521    xattr BOOLEAN DEFAULT FALSE,
    456522    PRIMARY KEY(vol_id),
    457     KEY(name(16)),
    458523    KEY(host(16)),
    459524    KEY(path(255)),
     
    470535    vol_id INT NOT NULL,
    471536    FOREIGN KEY(vol_id) REFERENCES volume(vol_id),
    472     uri VARCHAR(255) NOT NULL UNIQUE,
     537    uri VARCHAR(255) NOT NULL,
    473538    epoch TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    474539    mtime TIMESTAMP,
     
    476541    KEY(so_id),
    477542    KEY(vol_id),
    478     KEY(uri(64))
     543    KEY(uri(40))
    479544) ENGINE=innodb DEFAULT CHARSET=latin1;
    480545
     
    515580    available BOOLEAN DEFAULT FALSE,
    516581    xattr BOOLEAN DEFAULT FALSE,
     582    PRIMARY KEY(mountpoint),
    517583    KEY(vol_id),
     584    KEY(name),
     585    KEY(host),
     586    KEY(path),
    518587    KEY(allocate),
    519     KEY(available)
     588    KEY(available),
     589    KEY(xattr)
    520590) ENGINE=innodb DEFAULT CHARSET=latin1;
    521591
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/01_load.t

    r17076 r24244  
    1212use Test::More tests => 5;
    1313
    14 BEGIN { use_ok( 'Nebulous::Keys' ); }
     14BEGIN { use_ok( 'Nebulous::Key' ); }
    1515BEGIN { use_ok( 'Nebulous::Server' ); }
    1616BEGIN { use_ok( 'Nebulous::Server::Log' ); }
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/02_config.t

    r20965 r24244  
    33# Copryight (C) 2004-2005  Joshua Hoblitt
    44#
    5 # $Id: 02_config.t,v 1.1 2008-12-12 21:13:41 jhoblitt Exp $
     5# $Id: 02_config.t,v 1.1.2.2 2008-12-14 22:52:37 eugene Exp $
    66
    77use strict;
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/02_server_setup.t

    r20990 r24244  
    88use warnings;
    99
    10 use Test::More tests => 2;
     10use Test::More tests => 6;
    1111
    1212use lib qw( ./t ./lib );
     
    1717Test::Nebulous->setup;
    1818
    19 isa_ok(
    20     Nebulous::Server->new(
    21         dsn         => $NEB_DB,
    22         dbuser      => $NEB_USER,
    23         dbpasswd    => $NEB_PASS,
    24     ),
    25     "Nebulous::Server"
    26 );
     19isa_ok(Nebulous::Server->new(), "Nebulous::Server");
    2720
    2821Test::Nebulous->setup;
    2922
    30 eval {
    31     Nebulous::Server->new(
     23# ->new()
     24{
     25    my $neb = Nebulous::Server->new( trace => 'off' );
     26
     27    ok($neb, "set log level");
     28}
     29
     30Test::Nebulous->setup;
     31
     32{
     33    my $neb = Nebulous::Server->new(
    3234        dsn         => "DBI:mysql:database=foobar:host=localhost",
    3335        dbuser      => "baz",
    3436        dbpasswd    =>"boo",
    3537    );
    36 };
    37 like( $@, qr/DBI connect.*? failed/, "bad dsn/user/pass" );
     38
     39    ok($neb, "set database");
     40}
     41
     42Test::Nebulous->setup;
     43
     44# add dbs after ->new()
     45{
     46    my $neb = Nebulous::Server->new;
     47
     48    ok($neb->config->add_db(
     49        dbindex    => 0,
     50        dsn         => "DBI:mysql:database=foobar:host=localhost",
     51        dbuser      => "baz",
     52        dbpasswd    =>"boo",
     53    ), "add db");
     54   
     55    ok($neb->config->add_db(
     56        dbindex    => 1,
     57        dsn         => "DBI:mysql:database=foobar:host=localhost",
     58        dbuser      => "baz",
     59        dbpasswd    =>"boo",
     60    ), "add dbs");
     61
     62    is($neb->config->n_db, 2, "n dbs")
     63}
    3864
    3965Test::Nebulous->cleanup;
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/03_server_create_object.t

    r19493 r24244  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 89;
     10use Test::More tests => 99;
    1111
    1212use lib qw( ./t ./lib );
    1313
     14use File::Basename qw( basename );
    1415use File::ExtAttr qw( getfattr );
    1516use Nebulous::Server;
     
    2627);
    2728
     29use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
     30
    2831Test::Nebulous->setup;
    2932
     
    334337}
    335338
     339# test for properly row creation in the directories table
     340
     341Test::Nebulous->setup;
     342
     343{
     344    my $key = "foo";
     345    $neb->create_object($key);
     346
     347    expected_dataset_ok(
     348        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     349        storage_object  => [so_id => 1, ext_id => $key, dir_id => 1],
     350    );
     351}
     352
     353Test::Nebulous->setup;
     354
     355{
     356    my $key = "a/foo";
     357    $neb->create_object($key);
     358
     359    expected_dataset_ok(
     360        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     361        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     362        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 2],
     363    );
     364
     365}
     366
     367Test::Nebulous->setup;
     368
     369{
     370    my $key = "a/b/foo";
     371    $neb->create_object($key);
     372
     373    expected_dataset_ok(
     374        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     375        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     376        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     377        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 3],
     378    );
     379}
     380
     381Test::Nebulous->setup;
     382
     383{
     384    my $key = "a/b/c/foo";
     385    $neb->create_object($key);
     386
     387    expected_dataset_ok(
     388        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     389        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     390        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     391        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     392        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 4],
     393    );
     394}
     395
     396Test::Nebulous->setup;
     397
     398{
     399    my $key1 = "a/b/c/foo";
     400    my $key2 = "foo";
     401    $neb->create_object($key1);
     402    $neb->create_object($key2);
     403
     404    expected_dataset_ok(
     405        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     406        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 1],
     407        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     408        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     409        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     410        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
     411    );
     412}
     413
     414Test::Nebulous->setup;
     415
     416{
     417    my $key1 = "a/b/c/foo";
     418    my $key2 = "a/foo";
     419    $neb->create_object($key1);
     420    $neb->create_object($key2);
     421
     422    expected_dataset_ok(
     423        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     424        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     425        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 2],
     426        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     427        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     428        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
     429    );
     430}
     431
     432Test::Nebulous->setup;
     433
     434{
     435    my $key1 = "a/b/c/foo";
     436    my $key2 = "d/foo";
     437    $neb->create_object($key1);
     438    $neb->create_object($key2);
     439
     440    expected_dataset_ok(
     441        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     442        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     443        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     444        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     445        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
     446        directory       => [dir_id => 5, dirname => 'd', parent_id => 1],
     447        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 5],
     448    );
     449}
     450
     451Test::Nebulous->setup;
     452
     453{
     454    my $key1 = "a/b/c/foo";
     455    my $key2 = "a/d/foo";
     456    $neb->create_object($key1);
     457    $neb->create_object($key2);
     458
     459    expected_dataset_ok(
     460        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     461        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     462        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     463        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     464        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
     465        directory       => [dir_id => 5, dirname => 'd', parent_id => 2],
     466        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 5],
     467    );
     468}
     469
     470Test::Nebulous->setup;
     471
     472{
     473    my $key1 = "a/b/c/foo";
     474    my $key2 = "d/a/foo";
     475    $neb->create_object($key1);
     476    $neb->create_object($key2);
     477
     478    expected_dataset_ok(
     479        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     480        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     481        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     482        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     483        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
     484        directory       => [dir_id => 5, dirname => 'd', parent_id => 1],
     485        directory       => [dir_id => 6, dirname => 'a', parent_id => 5],
     486        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 6],
     487    );
     488}
     489
     490Test::Nebulous->setup;
     491
     492{
     493    my $key1 = "a/b/c/foo";
     494    my $key2 = "a/b/c/d/foo";
     495    $neb->create_object($key1);
     496    $neb->create_object($key2);
     497
     498    expected_dataset_ok(
     499        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     500        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     501        directory       => [dir_id => 3, dirname => 'b', parent_id => 2],
     502        directory       => [dir_id => 4, dirname => 'c', parent_id => 3],
     503        storage_object  => [so_id => 1, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 4],
     504        directory       => [dir_id => 5, dirname => 'd', parent_id => 4],
     505        storage_object  => [so_id => 2, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 5],
     506    );
     507}
     508
    336509Test::Nebulous->setup;
    337510
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/08_server_delete_instance.t

    r20990 r24244  
    33# Copryight (C) 2004-2005  Joshua Hoblitt
    44#
    5 # $Id: 08_server_delete_instance.t,v 1.12 2008-12-14 22:54:25 eugene Exp $
     5# $Id: 08_server_delete_instance.t,v 1.10.22.1 2008-12-14 22:52:37 eugene Exp $
    66
    77use strict;
     
    2424
    2525{
    26     my $uri = $neb->create_object("foo");
     26    my $key = "foo";
     27    my $uri = $neb->create_object($key);
    2728
    28     ok($neb->delete_instance($uri), "delete instance");
     29    ok($neb->delete_instance($key, $uri), "delete instance");
    2930}
    3031
     
    3233
    3334{
    34     my $uri1 = $neb->create_object("foo");
    35     my $uri2 = $neb->replicate_object("foo");
     35    my $key = "foo";
     36    my $uri1 = $neb->create_object($key);
     37    my $uri2 = $neb->replicate_object($key);
    3638
    37     ok($neb->delete_instance($uri1), "delete instance");
     39    ok($neb->delete_instance($key, $uri1), "delete instance");
    3840
    39     my $locations = $neb->find_instances("foo");
     41    my $locations = $neb->find_instances($key);
    4042
    4143    is($locations->[0], $uri2, "instance remains");
    4244
    43     ok($neb->delete_instance( $uri2 ), "delete instance");
     45    ok($neb->delete_instance($key, $uri2), "delete instance");
    4446
    4547    eval {
    46         $neb->find_instances("foo");
     48        $neb->find_instances($key);
    4749    };
    4850    like($@, qr/is valid object key/, "storage object was deleted");
     
    5254
    5355eval {
    54     $neb->delete_instance("file:/foo");
     56    my $key = "foo";
     57    my $uri1 = $neb->create_object($key);
     58
     59    $neb->delete_instance($key, "file:/foo");
    5560};
    5661like($@, qr/no instance is associated with uri/, "uri does not exist");
     
    6166    $neb->delete_instance();
    6267};
    63 like($@, qr/1 was expected/, "no params");
     68like($@, qr/2 were expected/, "no params");
    6469
    6570Test::Nebulous->setup;
    6671
    6772eval {
    68     $neb->delete_instance("foo", 2);
     73    my $key = "foo";
     74    my $uri1 = $neb->create_object($key);
     75
     76    $neb->delete_instance("foo", 2, 3);
    6977};
    70 like($@, qr/1 was expected/, "too many params");
     78like($@, qr/2 were expected/, "too many params");
    7179
    7280Test::Nebulous->cleanup;
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/10_server_is_valid_volume_name.t

    r20990 r24244  
    2323Test::Nebulous->setup;
    2424
    25 ok($neb->_is_valid_volume_name('node01'), "valid volume name");
     25ok($neb->_is_valid_volume_name('foo', 'node01'), "valid volume name");
    2626
    2727Test::Nebulous->setup;
    2828
    29 ok($neb->_is_valid_volume_name('node02'), "valid volume name");
     29ok($neb->_is_valid_volume_name('foo', 'node02'), "valid volume name");
    3030
    3131Test::Nebulous->setup;
    3232
    33 is($neb->_is_valid_volume_name('node99'), undef, "invalid volume name");
     33is($neb->_is_valid_volume_name('foo', 'node99'), undef, "invalid volume name");
    3434
    3535Test::Nebulous->cleanup;
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/12_server_find_objects.t

    r17717 r24244  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 6;
     10use Test::More tests => 28;
    1111
    1212use lib qw( ./t ./lib );
     
    2525# search for a regex of '' should match nothing
    2626eval {
    27     # key
    28     my $uri = $neb->create_object("foo");
     27    $neb->create_object("foo");
    2928
    3029    my $keys = $neb->find_objects();
     
    3534
    3635{
    37     # key
    38     my $uri = $neb->create_object("foo");
     36    $neb->create_object("foo");
    3937
    4038    my $keys = $neb->find_objects("foo");
     
    4846{
    4947    # key
    50     my $uri1 = $neb->create_object("foo");
    51     my $uri2 = $neb->replicate_object("foo");
     48    $neb->create_object("foo");
     49    $neb->replicate_object("foo");
    5250
    5351    my $keys = $neb->find_objects("foo");
     
    5553    is(scalar @$keys, 1, 'number of keys found');
    5654    is($keys->[0], "foo", "key name");
     55}
     56
     57Test::Nebulous->setup;
     58
     59{
     60    # key
     61    $neb->create_object("foo");
     62    $neb->create_object("bar");
     63
     64    my $keys = $neb->find_objects("foo");
     65
     66    is(scalar @$keys, 1, 'number of keys found');
     67    is($keys->[0], "foo", "key name");
     68}
     69
     70# test recursive dir searching
     71Test::Nebulous->setup;
     72
     73{
     74    $neb->create_object("a/foo");
     75
     76    my $keys = $neb->find_objects("a");
     77
     78    is(scalar @$keys, 1, 'number of keys found');
     79    is($keys->[0], "a/foo", "key name");
     80}
     81
     82Test::Nebulous->setup;
     83
     84{
     85    $neb->create_object("a/foo");
     86    $neb->create_object("b/foo");
     87
     88    my $keys = $neb->find_objects("a");
     89
     90    is(scalar @$keys, 1, 'number of keys found');
     91    is($keys->[0], "a/foo", "key name");
     92}
     93
     94Test::Nebulous->setup;
     95
     96{
     97    $neb->create_object("a/foo");
     98    $neb->create_object("a/b/foo");
     99
     100    my $keys = $neb->find_objects("a");
     101
     102    is(scalar @$keys, 1, 'number of keys found');
     103    is($keys->[0], "a/foo", "key name");
     104}
     105
     106Test::Nebulous->setup;
     107
     108{
     109    $neb->create_object("a/foo");
     110    $neb->create_object("a/bar");
     111
     112    my $keys = $neb->find_objects("a");
     113
     114    is(scalar @$keys, 2, 'number of keys found');
     115    is($keys->[0], "a/foo", "key name");
     116    is($keys->[1], "a/bar", "key name");
     117}
     118
     119Test::Nebulous->setup;
     120
     121{
     122    $neb->create_object("a/foo");
     123    $neb->create_object("bar");
     124
     125    my $keys = $neb->find_objects("a");
     126
     127    is(scalar @$keys, 1, 'number of keys found');
     128    is($keys->[0], "a/foo", "key name");
     129}
     130
     131Test::Nebulous->setup;
     132
     133{
     134    $neb->create_object("a/foo");
     135    $neb->create_object("foo");
     136    $neb->create_object("bar");
     137
     138    my $keys = $neb->find_objects("/");
     139
     140    is(scalar @$keys, 2, 'number of keys found');
     141    is($keys->[0], "foo", "key name");
     142    is($keys->[1], "bar", "key name");
     143}
     144
     145Test::Nebulous->setup;
     146
     147{
     148    $neb->create_object("a/foo");
     149    $neb->create_object("foo");
     150    $neb->create_object("bar");
     151
     152    my $keys = $neb->find_objects(".");
     153
     154    is(scalar @$keys, 2, 'number of keys found');
     155    is($keys->[0], "foo", "key name");
     156    is($keys->[1], "bar", "key name");
     157}
     158
     159Test::Nebulous->setup;
     160
     161{
     162    $neb->create_object("a/foo");
     163    $neb->create_object("foo");
     164    $neb->create_object("bar");
     165
     166    my $keys = $neb->find_objects("..");
     167
     168    is(scalar @$keys, 2, 'number of keys found');
     169    is($keys->[0], "foo", "key name");
     170    is($keys->[1], "bar", "key name");
    57171}
    58172
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/13_server_rename_object.t

    r17717 r24244  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 6;
     10use Test::More tests => 8;
    1111
    1212use lib qw( ./t ./lib );
    1313
     14use File::Basename qw( basename );
    1415use Nebulous::Server;
    1516use Test::Nebulous;
     
    2122);
    2223
     24use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
     25
    2326Test::Nebulous->setup;
    2427
    2528{
     29    my $key = "bar";
    2630    my $uri = $neb->create_object("foo");
    2731
    28     $neb->rename_object("foo", "bar");
     32    $neb->rename_object("foo", $key);
    2933
    30     eval {
    31         $neb->find_objects('^foo$');
    32     };
    33     like($@, qr/no keys found/, "old key name");
     34    expected_dataset_ok(
     35        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     36        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 1],
     37    );
     38}
    3439
    35     my $keys = $neb->find_objects('^bar$');
    36     is(scalar @$keys, 1, 'number of keys found');
     40Test::Nebulous->setup;
     41
     42{
     43    my $key = "a/bar";
     44    my $uri = $neb->create_object("foo");
     45
     46    $neb->rename_object("foo", $key);
     47
     48    expected_dataset_ok(
     49        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     50        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     51        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 2],
     52    );
     53}
     54
     55Test::Nebulous->setup;
     56
     57{
     58    my $key = "bar";
     59    my $uri = $neb->create_object("a/foo");
     60
     61    $neb->rename_object("a/foo", $key);
     62
     63    expected_dataset_ok(
     64        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     65        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     66        storage_object  => [so_id => 1, ext_id => $key, ext_id_basename => basename($key), dir_id => 1],
     67    );
    3768}
    3869
     
    73104like($@, qr/2 were expected/, "too many params");
    74105
     106# test attempting to rename a key in such a way to cause the distributed
     107# storage db to change
     108# this must be the last test as we're messing with the $neb object
     109eval {
     110    $neb->config->add_db(
     111        dbindex     => 1,
     112        dsn         => $NEB_DB,
     113        dbuser      => $NEB_USER,
     114        dbpasswd    => $NEB_PASS,
     115    );
     116
     117    $neb->create_object("a/foo");
     118    $neb->rename_object("a/foo", "g/bar");
     119};
     120like($@, qr/rename objects across distributed database boundaries/, "rename between databases");
     121
    75122Test::Nebulous->cleanup;
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/16_server_swap_objects.t

    r20091 r24244  
    88use warnings FATAL => qw( all );
    99
    10 use Test::More tests => 8;
     10use Test::More tests => 13;
    1111
    1212use lib qw( ./t ./lib );
    1313
     14use File::Basename qw( basename );
    1415use Nebulous::Server;
    1516use Test::Nebulous;
     
    2122);
    2223
     24use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS;
     25
    2326Test::Nebulous->setup;
    2427
    2528{
    26     my $uri1 = $neb->create_object("foo1");
    27     my $uri2 = $neb->create_object("foo2");
     29    my $key1 = "foo1";
     30    my $key2 = "foo2";
     31    my $uri1 = $neb->create_object($key1);
     32    my $uri2 = $neb->create_object($key2);
    2833
    29     ok($neb->swap_objects("foo1", "foo2"), "swap succeeded");
     34    ok($neb->swap_objects($key1, $key2), "swap succeeded");
    3035
    31     my $new_uri1 = ($neb->find_instances("foo1"))->[0];
    32     my $new_uri2 = ($neb->find_instances("foo2"))->[0];
     36    my $new_uri1 = ($neb->find_instances($key1))->[0];
     37    my $new_uri2 = ($neb->find_instances($key2))->[0];
     38
     39    expected_dataset_ok(
     40        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     41        storage_object  => [so_id => 1, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 1],
     42        storage_object  => [so_id => 2, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 1],
     43    );
     44
     45    is($uri1, $new_uri2, "key1 -> key2");
     46    is($uri2, $new_uri1, "key2 -> key1");
     47}
     48
     49Test::Nebulous->setup;
     50
     51{
     52    my $key1 = "foo1";
     53    my $key2 = "a/foo2";
     54    my $uri1 = $neb->create_object($key1);
     55    my $uri2 = $neb->create_object($key2);
     56
     57    ok($neb->swap_objects($key1, $key2), "swap succeeded");
     58
     59    my $new_uri1 = ($neb->find_instances($key1))->[0];
     60    my $new_uri2 = ($neb->find_instances($key2))->[0];
     61
     62    expected_dataset_ok(
     63        directory       => [dir_id => 1, dirname => '/', parent_id => 1],
     64        directory       => [dir_id => 2, dirname => 'a', parent_id => 1],
     65        storage_object  => [so_id => 1, ext_id => $key2, ext_id_basename => basename($key2), dir_id => 2],
     66        storage_object  => [so_id => 2, ext_id => $key1, ext_id_basename => basename($key1), dir_id => 1],
     67    );
    3368
    3469    is($uri1, $new_uri2, "key1 -> key2");
  • branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/75_parse_neb_key.t

    r19431 r24244  
    1010use Test::More;
    1111
    12 plan tests => 80;
     12plan tests => 99;
    1313
    1414use lib qw( ./t ./lib );
    1515
    16 use Nebulous::Keys qw( parse_neb_key );
     16use Nebulous::Key qw( parse_neb_key );
    1717use Test::Nebulous;
    1818
     
    224224}
    225225
     226# root volume references
     227{
     228    my $key = parse_neb_key('neb:///');
     229
     230    is($key->path, '', 'path');
     231    is($key->volume, undef, 'volume name');
     232    is($key->soft_volume, undef, 'soft volume name');
     233}
     234
     235{
     236    my $key = parse_neb_key('neb:///.');
     237
     238    is($key->path, '', 'path');
     239    is($key->volume, undef, 'volume name');
     240    is($key->soft_volume, undef, 'soft volume name');
     241}
     242
     243{
     244    my $key = parse_neb_key('neb:///..');
     245
     246    is($key->path, '', 'path');
     247    is($key->volume, undef, 'volume name');
     248    is($key->soft_volume, undef, 'soft volume name');
     249}
     250
     251{
     252    my $key = parse_neb_key('/');
     253
     254    is($key->path, '', 'path');
     255    is($key->volume, undef, 'volume name');
     256    is($key->soft_volume, undef, 'soft volume name');
     257}
     258
     259{
     260    my $key = parse_neb_key('.');
     261
     262    is($key->path, '', 'path');
     263    is($key->volume, undef, 'volume name');
     264    is($key->soft_volume, undef, 'soft volume name');
     265}
     266
     267{
     268    my $key = parse_neb_key('..');
     269
     270    is($key->path, '', 'path');
     271    is($key->volume, undef, 'volume name');
     272    is($key->soft_volume, undef, 'soft volume name');
     273}
     274
    226275# key w/ whitespace
    227276eval {
     
    267316};
    268317like( $@, qr/requires a leading slash/, "leading slash" );
     318
     319# URI w/ volume but w/o path
     320eval {
     321    my $key = parse_neb_key('neb://foo');
     322};
     323like( $@, qr/requires a path/, "no path" );
Note: See TracChangeset for help on using the changeset viewer.