- Timestamp:
- May 26, 2009, 1:59:32 PM (17 years ago)
- Location:
- branches/cnb_branches/cnb_branch_20090301
- Files:
-
- 1 deleted
- 24 edited
- 3 copied
-
. (modified) (1 prop)
-
Nebulous-Server (modified) (1 prop)
-
Nebulous-Server/Build.PL (modified) (1 diff)
-
Nebulous-Server/Changes (modified) (1 diff)
-
Nebulous-Server/MANIFEST (modified) (3 diffs)
-
Nebulous-Server/bin/neb-admin (modified) (1 diff)
-
Nebulous-Server/bin/nebdiskd (modified) (12 diffs)
-
Nebulous-Server/docs/apache2-mod_perl-startup.pl (copied) (copied from trunk/Nebulous-Server/docs/apache2-mod_perl-startup.pl )
-
Nebulous-Server/docs/install.txt (modified) (1 diff)
-
Nebulous-Server/lib/Nebulous/Key.pm (copied) (copied from trunk/Nebulous-Server/lib/Nebulous/Key.pm )
-
Nebulous-Server/lib/Nebulous/Keys.pm (deleted)
-
Nebulous-Server/lib/Nebulous/Server.pm (modified) (45 diffs)
-
Nebulous-Server/lib/Nebulous/Server.pod (modified) (2 diffs)
-
Nebulous-Server/lib/Nebulous/Server/Config.pm (modified) (4 diffs)
-
Nebulous-Server/lib/Nebulous/Server/Log.pm (modified) (2 diffs)
-
Nebulous-Server/lib/Nebulous/Server/SOAP.pm (modified) (5 diffs)
-
Nebulous-Server/lib/Nebulous/Server/SQL.pm (modified) (12 diffs)
-
Nebulous-Server/scripts/dirize.pl (copied) (copied from trunk/Nebulous-Server/scripts/dirize.pl )
-
Nebulous-Server/t/01_load.t (modified) (1 diff)
-
Nebulous-Server/t/02_config.t (modified) (1 diff)
-
Nebulous-Server/t/02_server_setup.t (modified) (2 diffs)
-
Nebulous-Server/t/03_server_create_object.t (modified) (3 diffs)
-
Nebulous-Server/t/08_server_delete_instance.t (modified) (5 diffs)
-
Nebulous-Server/t/10_server_is_valid_volume_name.t (modified) (1 diff)
-
Nebulous-Server/t/12_server_find_objects.t (modified) (5 diffs)
-
Nebulous-Server/t/13_server_rename_object.t (modified) (3 diffs)
-
Nebulous-Server/t/16_server_swap_objects.t (modified) (2 diffs)
-
Nebulous-Server/t/75_parse_neb_key.t (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
branches/cnb_branches/cnb_branch_20090301
- Property svn:mergeinfo changed
-
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server
-
Property svn:mergeinfo
set to (toggle deleted branches)
/branches/neb_distrib_20081210/Nebulous-Server merged eligible /trunk/Nebulous-Server merged eligible /branches/eam_branches/eam_branch_20090303/Nebulous-Server 23158-23228 /branches/pap_magic/Nebulous-Server 24120-24173
-
Property svn:mergeinfo
set to (toggle deleted branches)
-
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/Build.PL
r20157 r24244 15 15 'DBI' => '1.53', 16 16 'Digest::SHA1' => 0, 17 'File::Basename' => 0, 17 18 'File::ExtAttr' => '1.03', 18 19 'File::Mountpoint' => '0.01', 19 20 'File::Path' => '1.08', 20 21 'File::Spec' => 0, 21 'Filesys::Df' => '0.92',22 22 'File::Spec::Functions' => 0, 23 23 'File::Temp' => 0, 24 'Filesys::Df' => '0.92', 25 'Log::Dispatch::Email::MailSend' => 0, 24 26 'Log::Log4perl' => '0.48', 25 27 'Net::Server::Daemonize'=> '0.05', 26 28 'Params::Validate' => '0.73', 27 29 'SOAP::Lite' => '0.69', 30 'SQL::Interp' => '1.06', 28 31 'URI' => '1.30', 29 'SQL::Interp' => '1.06',30 32 }, 31 33 build_requires => { 32 34 'Test::More' => '0.49', 33 35 'Test::URI' => '1.06', 36 'Test::DBUnit' => '0.20', 34 37 }, 35 38 recommends => { -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/Changes
r23594 r24244 3 3 0.17 4 4 - 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 6 19 0.16 7 20 - add so_id/name idxs to storage_object_xattr table -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/MANIFEST
r23352 r24244 4 4 MANIFEST 5 5 README 6 Todo7 6 bin/neb-admin 8 7 bin/neb-fsck … … 19 18 examples/uri_test.pl 20 19 init.d/nebdiskd 21 lib/Nebulous/Key s.pm20 lib/Nebulous/Key.pm 22 21 lib/Nebulous/Server.pm 23 22 lib/Nebulous/Server.pod … … 33 32 t/00_distribution.t 34 33 t/01_load.t 34 t/02_config.t 35 35 t/02_server_setup.t 36 36 t/03_server_create_object.t -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/bin/neb-admin
r23594 r24244 174 174 # if the copies xattr is unset and the object has 2 or more instances, we 175 175 # 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. 176 180 my $copies = $obj->{copies} || 2; 177 181 -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/bin/nebdiskd
r20206 r24244 16 16 use File::Spec; 17 17 use Filesys::Df; 18 use Log::Log4perl; 18 19 use Nebulous::Server::SQL; 19 20 use Net::Server::Daemonize qw( daemonize unlink_pid_file ); … … 85 86 unless $db && $dbuser && $dbpass; 86 87 88 # start up logging 89 my $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 '; 114 Log::Log4perl::init(\$conf); 115 my $log = Log::Log4perl::get_logger("nebdiskd"); 116 $log->level('WARN'); 117 $log->level('DEBUG') if $debug; 118 87 119 daemonize( 88 120 $user, # User … … 104 136 poll_interval => $poll_interval, 105 137 debug => $debug, 106 ) or die "poll_mounts() should not have returned";138 ); 107 139 }; 108 if ($ !) {109 warn $@;140 if ($@) { 141 $log->warn($@); 110 142 } 111 143 … … 113 145 } 114 146 115 die "poll loop exited -- THIS SHOULD NOT HAPPEN";147 $log->logdie("poll loop exited -- THIS SHOULD NOT HAPPEN"); 116 148 117 149 … … 141 173 # determine valid mountpoints 142 174 foreach my $mnt (@$mounts) { 143 print "checking $mnt\n" if $debug;175 $log->debug("checking $mnt"); 144 176 # this /SHOULD/ fail if the mount point is handled by the 145 177 # automounter and it fails to mount 146 178 eval { 147 179 unless (is_mountpoint($mnt)) { 148 die "$mnt is not a valid mountpoint\n";180 $log->warn("$mnt is not a valid mountpoint"); 149 181 } 150 182 }; 151 183 if ($@) { 152 print $@ if $debug;184 $log->warn($@); 153 185 $d_query->execute($mnt); 154 186 next; … … 160 192 my $dev_info = df($mnt, 1024); 161 193 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"); 163 195 next; 164 196 } 165 197 166 198 $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"); 168 200 169 201 } … … 172 204 173 205 $dbh->commit; 174 print "commited to database\n" if $debug;206 $log->debug("commited to database"); 175 207 }; 176 208 if ($@) { 177 209 $dbh->rollback; 178 print "rolledback transaction\n" if $debug;179 warn $@;210 $log->debug("rolledback transaction"); 211 $log->logdie($@); 180 212 } 181 213 } … … 188 220 189 221 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:$!"); 192 224 } 193 225 … … 226 258 }; 227 259 if ($@) { 228 $db ->rollback;229 die $@;260 $dbh->rollback; 261 $log->logdie($@); 230 262 } 231 263 … … 242 274 foreach my $path (@$mounts) { 243 275 if (stat File::Spec->canonpath($path)) { 244 print "stated $path\n" if $debug;276 $log->debug("stated $path"); 245 277 } else { 246 warn "can not stat path: $path";278 $log->warn("can not stat path: $path"); 247 279 } 248 280 } … … 263 295 ### get the currently listed pid 264 296 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\" [$!]"); 266 298 } 267 299 my $_current_pid = <_PID>; 268 300 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"); 270 302 271 303 my $exists = undef; … … 289 321 290 322 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."); 292 324 return 1; 293 325 }else{ 294 326 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\" [$!]"); 297 329 } 298 330 } -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/docs/install.txt
r23352 r24244 56 56 57 57 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" }' 64 74 . 65 75 . -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server.pm
r23594 r24244 9 9 no warnings qw( uninitialized ); 10 10 11 our $VERSION = '0.1 5';11 our $VERSION = '0.17'; 12 12 13 13 use base qw( Class::Accessor::Fast ); … … 15 15 use DBI; 16 16 use Digest::SHA1 qw( sha1_hex ); 17 use File::Basename qw( basename dirname fileparse ); 17 18 use File::ExtAttr qw( setfattr ); 18 19 use File::Path; 19 20 use File::Spec; 20 use Log::Log4perl; 21 use Log::Log4perl qw( :levels ); 22 use Nebulous::Key qw( parse_neb_key parse_neb_volume ); 21 23 use Nebulous::Server::Config; 22 24 use Nebulous::Server::Log; 23 25 use Nebulous::Server::SQL; 24 use Nebulous::Keys qw( parse_neb_key parse_neb_volume ); 25 use Params::Validate qw( validate_pos SCALAR SCALARREF UNDEF ); 26 use Params::Validate qw( validate validate_pos SCALAR SCALARREF UNDEF BOOLEAN ); 26 27 use URI::file; 27 28 … … 36 37 37 38 # 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 45 sub new_from_config 46 { 47 my ($class, $config) = @_; 39 48 40 49 # log4perl is not avaliable until we call init() 41 50 Nebulous::Server::Log->init($config); 42 51 my $log = Log::Log4perl::get_logger( "Nebulous::Server" ); 52 $log->level($config->trace); 43 53 44 54 my $sql = Nebulous::Server::SQL->new; … … 51 61 $self->config($config); 52 62 53 # ask for the db handle as a means of validating the database parameters54 $self->db;55 56 63 $log->debug( "leaving" ); 57 64 58 65 return $self; 59 66 } 60 67 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 70 sub _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 90 sub _db_for_index 91 { 92 my ($self, $db_index) = @_; 70 93 71 94 my $log = $self->log; … … 73 96 my $config = $self->config; 74 97 98 # lookup to see if we have a stored dbh for this database 99 my $dbh = $self->{dbs}[$db_index]; 75 100 # if the dbh is still alive, return it 76 if (defined $ self->{db} and $self->{db}->ping) {101 if (defined $dbh and $dbh->ping) { 77 102 $log->debug("db handle is still alive"); 78 return $ self->{db};103 return $dbh; 79 104 } 80 105 # otherwise create a new connection 81 106 $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; 82 112 83 113 # if we're running under mod_perl & Apache::DBI is loaded we want to … … 86 116 # processes and the database might have gone away on us. Apache::DBI will 87 117 # take care of getting a valid dbh back. 88 my $db;89 118 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, 94 123 { 95 124 RaiseError => 1, … … 99 128 ); 100 129 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; 104 133 $log->debug("commit"); 105 134 }; 106 135 if ( $@ ) { 107 $db ->rollback if $db;136 $dbh->rollback if $dbh; 108 137 $log->debug("rollback"); 109 138 $log->logdie( "database error: $@" ); 110 139 } 111 140 112 $self->{db} = $db; 113 114 return $db; 115 } 116 141 $self->{dbs}[$db_index] = $dbh; 142 143 return $dbh; 144 } 145 146 sub 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 } 117 166 118 167 sub create_object … … 137 186 ); 138 187 139 my $log = $self->log;140 my $sql = $self->sql;141 my $db =$self->db;142 143 $log->debug( "entered - @_" );144 145 188 # vol_name overrides the key implied volume 146 189 $key = parse_neb_key($key, $vol_name); 147 190 $vol_name = $key->volume; 148 191 192 my $log = $self->log; 193 my $sql = $self->sql; 194 my $db = $self->db($key); 195 196 $log->debug( "entered - @_" ); 197 149 198 # the key's volume can't be validiated on input for this method so we have 150 199 # to check it after parsing the key 151 200 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)) { 153 202 if ($key->soft_volume) { 154 203 $log->warn( "$vol_name is not a known volume name" ); … … 160 209 161 210 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); 163 214 164 215 my $uri; … … 168 219 # create storage_object 169 220 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); 171 222 } 172 223 … … 214 265 215 266 # 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); 217 268 $log->debug("created $uri on volume ID: $vol_id"); 218 269 … … 246 297 247 298 299 sub _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; 352 TRANS: 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 248 420 sub rename_object 249 421 { … … 265 437 }, 266 438 ); 267 268 my $log = $self->log;269 my $sql = $self->sql;270 my $db =$self->db;271 272 $log->debug("entered - @_");273 439 274 440 # ignore volumes 275 441 $key = parse_neb_key($key); 276 442 $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 } 277 455 278 456 TRANS: while (1) { … … 281 459 my $query = $db->prepare_cached($sql->rename_object); 282 460 # 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); 284 462 285 463 # if we affected more then one row something very bad has happened. … … 309 487 } 310 488 311 312 489 sub swap_objects 313 490 { … … 328 505 }, 329 506 ); 330 331 my $log = $self->log;332 my $sql = $self->sql;333 my $db =$self->db;334 335 $log->debug("entered - @_");336 507 337 508 # ignore volumes … … 339 510 $key2 = parse_neb_key($key2); 340 511 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: 342 526 # key1 -> key1.swap 343 527 # key2 -> key1 344 528 # key1.swap -> key2 345 529 346 TRANS: while (1) { 530 my $db = $dbh1; 531 TRANS: while (1) { 347 532 eval { 348 533 { 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 } 386 574 387 575 $db->commit; … … 397 585 $log->logdie("database error: $@"); 398 586 } 399 last;400 }587 last; 588 } 401 589 402 590 $log->debug("leaving"); … … 405 593 } 406 594 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 407 609 408 610 sub replicate_object … … 439 641 # then we should throw an error 440 642 441 my $log = $self->log;442 my $sql = $self->sql;443 my $db =$self->db;444 445 $log->debug("entered - @_");446 447 643 # vol_name overrides the key implied volume 448 644 $key = parse_neb_key($key, $vol_name); 449 645 $vol_name = $key->volume; 450 646 647 my $log = $self->log; 648 my $sql = $self->sql; 649 my $db = $self->db($key); 650 651 $log->debug("entered - @_"); 652 451 653 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)) { 453 655 if ($key->soft_volume) { 454 656 $log->warn( "$vol_name is not a known volume name" ); … … 462 664 if (defined $vol_name) { 463 665 ($vol_id, $vol_host, $vol_path, $vol_xattr) 464 = $self->_get_storage_volume($ vol_name);666 = $self->_get_storage_volume($key, $vol_name); 465 667 } else { 466 668 ($vol_id, $vol_host, $vol_path, $vol_xattr) … … 507 709 508 710 # 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); 510 714 511 715 { … … 560 764 ); 561 765 562 my $log = $self->log;563 my $sql = $self->sql;564 my $db =$self->db;565 566 $log->debug( "entered - @_" );567 568 766 # ignore volume 569 767 $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 - @_" ); 570 774 571 775 my $so_id; … … 670 874 ); 671 875 672 my $log = $self->log;673 my $sql = $self->sql;674 my $db =$self->db;675 676 $log->debug( "entered - @_" );677 678 876 # ignore volume 679 877 $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 - @_" ); 680 884 681 885 my $so_id; … … 789 993 ); 790 994 791 my $log = $self->log;792 my $sql = $self->sql;793 my $db =$self->db;794 795 $log->debug("entered - @_");796 797 995 # ignore volume 798 996 $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 - @_"); 799 1003 800 1004 TRANS: while (1) { … … 863 1067 ); 864 1068 865 my $log = $self->log;866 my $sql = $self->sql;867 my $db =$self->db;868 869 $log->debug("entered - @_");870 871 1069 # ignore volume 872 1070 $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 - @_"); 873 1077 874 1078 my $value; … … 916 1120 ); 917 1121 918 my $log = $self->log;919 my $sql = $self->sql;920 my $db =$self->db;921 922 $log->debug("entered - @_");923 924 1122 # ignore volume 925 1123 $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 - @_"); 926 1130 927 1131 my @xattrs; … … 959 1163 ); 960 1164 961 my $log = $self->log;962 my $sql = $self->sql;963 my $db =$self->db;964 965 $log->debug("entered - @_");966 967 1165 # ignore volume 968 1166 $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 - @_"); 969 1173 970 1174 TRANS: while (1) { … … 1000 1204 } 1001 1205 1002 1206 # loop over all db_index values, passing db_index to each call 1003 1207 sub find_objects 1004 1208 { 1005 1209 my $self = shift; 1006 1210 1007 my ( $pattern) = validate_pos( @_,1211 my ($pattern) = validate_pos( @_, 1008 1212 { 1009 1213 type => SCALAR, … … 1012 1216 ); 1013 1217 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; 1017 1221 1018 1222 $log->debug( "entered - @_" ); 1019 1223 1020 unless ( $pattern) {1224 unless (defined $pattern) { 1021 1225 $log->debug( "leaving" ); 1022 1226 $log->logdie("no keys found"); 1023 1227 } 1024 1228 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 1243 sub _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 1028 1257 my @keys; 1029 1258 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 ); 1032 1293 1033 1294 while ( my $row = $query->fetchrow_hashref ) { 1034 1295 my $key = $row->{ 'ext_id' }; 1035 1296 push @keys, $key if $key; 1297 $log->debug( "matched $key" ) if $key; 1036 1298 } 1037 1299 }; 1038 1300 $log->logdie("database error: $@") if $@; 1039 1040 $log->logdie("no keys found") unless ( scalar @keys );1041 1301 1042 1302 $log->debug( "leaving" ); … … 1070 1330 ); 1071 1331 1072 my $log = $self->log;1073 my $sql = $self->sql;1074 my $db =$self->db;1075 1076 $log->debug("entered - @_");1077 1078 1332 # vol_name overrides the key implied volume 1079 1333 $key = parse_neb_key($key, $vol_name); 1080 1334 $vol_name = $key->volume; 1081 1335 1336 my $log = $self->log; 1337 my $sql = $self->sql; 1338 my $db = $self->db($key); 1339 1340 $log->debug("entered - @_"); 1341 1082 1342 # the key's volume can't be validiated on input for this method so we have 1083 1343 # to check it after parsing the key 1084 1344 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)) { 1086 1346 if ($key->soft_volume) { 1087 1347 $log->warn( "$vol_name is not a known volume name" ); … … 1143 1403 my $self = shift; 1144 1404 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 }, 1146 1412 { 1147 1413 type => SCALAR|SCALARREF, … … 1149 1415 ); 1150 1416 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); 1154 1423 1155 1424 $log->debug( "entered - @_" ); … … 1243 1512 ); 1244 1513 1245 my $log = $self->log;1246 my $sql = $self->sql;1247 my $db =$self->db;1248 1249 $log->debug("entered - @_");1250 1251 1514 # ignore volume 1252 1515 $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 - @_"); 1253 1522 1254 1523 my $stat; … … 1271 1540 } 1272 1541 1273 1542 # this should have a 'db_index' as an argument 1274 1543 sub mounts 1275 1544 { 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 1276 1548 my $self = shift; 1277 1549 … … 1280 1552 my $log = $self->log; 1281 1553 my $sql = $self->sql; 1282 my $db = $self->db;1554 my $db = $self->_db_for_index(0); # XXX fix as above 1283 1555 1284 1556 $log->debug("entered - @_"); … … 1309 1581 my $self = shift; 1310 1582 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); 1314 1588 1315 1589 no warnings qw( uninitialized ); 1316 1590 $log->debug( "entered - @_" ); 1317 1591 use warnings; 1318 1319 my ($name, $soft_volume) = @_;1320 1592 1321 1593 my ($vol_id, $vol_host, $vol_path, $xattr); … … 1334 1606 # find it, fall back to any volume 1335 1607 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); 1337 1609 return; # this just returns out of the eval not from the subroutine 1338 1610 } … … 1374 1646 my $self = shift; 1375 1647 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); 1379 1653 1380 1654 no warnings qw( uninitialized ); 1381 1655 $log->debug( "entered - @_" ); 1382 1656 use warnings; 1383 1384 my $key = shift;1385 1386 $key = parse_neb_key($key);1387 1657 1388 1658 my ($vol_id, $vol_host, $vol_path, $xattr); … … 1422 1692 my ($self, $key) = @_; 1423 1693 1424 my $log = $self->log;1425 my $sql = $self->sql;1426 my $db =$self->db;1427 1428 1694 $key = parse_neb_key($key); 1695 1696 my $log = $self->log; 1697 my $sql = $self->sql; 1698 my $db = $self->db($key); 1429 1699 1430 1700 my $ext_id; 1431 1701 eval { 1432 my $query = $db->prepare_cached( $sql-> get_object);1702 my $query = $db->prepare_cached( $sql->check_object_name ); 1433 1703 $query->execute($key->path); 1434 1704 ($ext_id) = $query->fetchrow_array; … … 1451 1721 sub _is_valid_volume_name 1452 1722 { 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); 1459 1726 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); 1460 1731 1461 1732 $vol_name = $volume_info->{volume}; … … 1492 1763 my $log = $self->log; 1493 1764 my $sql = $self->sql; 1494 my $db = $self->db ;1765 my $db = $self->db($key); 1495 1766 1496 1767 my $uri; 1497 1768 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); 1500 1771 unless (-d $storage_path) { 1501 1772 _retry(sub { mkpath(@_) }, $storage_path, 0, 0775) … … 1506 1777 my $mode = [_retry(sub { stat($storage_path) } )]->[2] & 07777; 1507 1778 unless ($mode == 0775) { 1508 $log->error("$storage_path has the wrong permissions of: %04 o", $mode);1779 $log->error("$storage_path has the wrong permissions of: %04x", $mode); 1509 1780 _retry(sub { chmod(0775, $storage_path) }) or die "can't chmod $storage_path: $!"; 1510 1781 } … … 1522 1793 my $path = $uri->file; 1523 1794 die "can not set xattr on $path: $!" 1524 unless (setfattr($path, 'user.nebulous_key', $key ));1795 unless (setfattr($path, 'user.nebulous_key', $key->path)); 1525 1796 } 1526 1797 … … 1621 1892 my $log = $self->log; 1622 1893 my $sql = $self->sql; 1623 my $db =$self->db;1894 # my $db = $self->db; 1624 1895 1625 1896 $log->debug( "entered" ); 1626 1897 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; } ); 1630 1902 1631 1903 $log->debug( "leaving" ); -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server.pod
r20092 r24244 26 26 Nebulous::Server->find_objects( $pattern ); 27 27 Nebulous::Server->find_instances( $key, $volume ); 28 Nebulous::Server->delete_instance( $ uri );28 Nebulous::Server->delete_instance( $key, $uri ); 29 29 Nebulous::Server->stat_object( $key ); 30 30 Nebulous::Server->mounts(); … … 160 160 Throws an exception on error. 161 161 162 =item * delete_instance( $ uri );163 164 Accepts 1 parameters, it is mandatory. Returns Boolean true. Throws an165 exception on error.162 =item * delete_instance( $key, $uri ); 163 164 Accepts 2 parameters, both mandatory. Returns Boolean true. C<<$uri>> must be 165 an instance of C<<$key>>. Throws an exception on error. 166 166 167 167 =item * swap_objects( $key1, $key2 ); -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/Config.pm
r20990 r24244 8 8 use warnings FATAL => qw( all ); 9 9 10 our $VERSION = 0.0 2;10 our $VERSION = 0.03; 11 11 12 12 use base qw( Class::Accessor::Fast ); 13 13 14 14 use Log::Log4perl qw( :levels ); 15 use Params::Validate qw( validate SCALAR );15 use Params::Validate qw( validate validate_pos SCALAR ); 16 16 17 17 our %LEVELS = ( … … 25 25 ); 26 26 27 my $new_validate = { 27 my $db_validate = { 28 dbindex => { 29 type => SCALAR, 30 regex => qr/^\d+$/, 31 }, 28 32 dsn => { type => SCALAR }, 29 33 dbuser => { type => SCALAR }, 30 34 dbpasswd => { type => SCALAR }, 31 log_level => { 35 }; 36 37 my $new_validate = { 38 trace => { 32 39 type => SCALAR, 33 40 optional => 1, 34 default => ' all',41 default => 'fatal', 35 42 callbacks => { 36 43 'is valid level' => sub { … … 39 46 }, 40 47 }, 48 dsn => { type => SCALAR, optional => 1 }, 49 dbuser => { type => SCALAR, optional => 1 }, 50 dbpasswd => { type => SCALAR, optional => 1 }, 41 51 }; 42 52 43 53 __PACKAGE__->mk_ro_accessors( keys %$new_validate ); 44 54 45 sub init { 55 56 sub new 57 { 46 58 my $class = shift; 47 59 … … 49 61 50 62 # 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})} }; 54 64 55 65 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 } 56 78 57 79 return $self; 58 80 } 59 81 82 83 sub 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 101 sub 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 114 sub n_db 115 { 116 my $self = shift; 117 118 return scalar @{ $self->{dbs} }; 119 } 120 121 122 package Nebulous::Server::Config::DB; 123 124 use strict; 125 use warnings FATAL => qw( all ); 126 127 our $VERSION = 0.01; 128 129 use base qw( Class::Accessor::Fast ); 130 131 __PACKAGE__->mk_ro_accessors(qw( dsn dbuser dbpasswd )); 132 60 133 1; 61 134 -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/Log.pm
r20990 r24244 16 16 my ($self, $config) = @_; 17 17 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; 21 21 22 22 my $conf = <<END; … … 30 30 # date | hostname | priority | method/sub - message\n 31 31 32 log4perl.appender.SQLLOG = Log::Log4perl::Appender::DBI33 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 = 37 37 INSERT INTO log (timestamp, hostname, level, sub, message) \ 38 38 VALUES (%d, %H, %p, %M, %m) -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/SOAP.pm
r20990 r24244 1 1 # Copyright (c) 2004 Joshua Hoblitt 2 2 # 3 # $Id: SOAP.pm,v 1. 6 2008-12-14 22:54:25eugene Exp $3 # $Id: SOAP.pm,v 1.4.32.1 2008-12-14 22:52:37 eugene Exp $ 4 4 5 5 package Nebulous::Server::SOAP; … … 17 17 our $AUTOLOAD; 18 18 19 our @args;19 our $config; 20 20 our $neb; 21 21 22 sub new_on_init { 22 23 sub new_on_init 24 { 23 25 my $self = shift; 24 26 … … 27 29 require Apache2::ServerUtil; 28 30 29 @args = @_;31 $config = shift; 30 32 31 33 my $s = Apache2::ServerUtil->server; … … 35 37 } 36 38 37 sub init { 39 40 sub init 41 { 38 42 my $self = shift; 39 43 40 $neb = Nebulous::Server->new (@args);44 $neb = Nebulous::Server->new_from_config($config); 41 45 42 46 return Apache2::Const::OK; 43 47 } 44 48 45 sub AUTOLOAD { 49 50 sub AUTOLOAD 51 { 46 52 my $self = shift; 47 53 … … 76 82 } 77 83 84 78 85 1; -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/lib/Nebulous/Server/SQL.pm
r20990 r24244 8 8 use warnings FATAL => qw( all ); 9 9 10 our $VERSION = '0.0 2';10 our $VERSION = '0.04'; 11 11 12 12 use base qw( Class::Accessor::Fast ); … … 26 26 new_object => qq{ 27 27 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', ?) 30 30 }, 31 31 new_object_attr => qq{ … … 59 59 JOIN storage_object_attr 60 60 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 61 80 WHERE ext_id = ? 62 81 }, … … 290 309 USING(vol_id) 291 310 }, 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 = ? 296 320 }, 297 321 rename_object => qq{ 298 322 UPDATE storage_object 299 SET ext_id = ? 323 SET ext_id = ?, ext_id_basename = ?, dir_id = ? 300 324 WHERE ext_id = ? 301 325 }, … … 323 347 GROUP BY so_id 324 348 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; 325 372 }, 326 373 find_objects_with_extra_instances => qq{ … … 380 427 DROP TABLE IF EXISTS log; 381 428 DROP TABLE IF EXISTS mountedvol; 429 DROP TABLE IF EXISTS directory; 382 430 DROP PROCEDURE IF EXISTS getmountedvol; 383 431 SET FOREIGN_KEY_CHECKS=1 … … 401 449 402 450 __DATA__ 451 CREATE 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 462 INSERT INTO directory (dir_id, dirname, parent_id) VALUES (1, '/', 1); 463 464 ### 465 403 466 CREATE TABLE storage_object ( 404 467 so_id BIGINT NOT NULL AUTO_INCREMENT, 405 468 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), 406 472 type enum('REG_FILE'), 407 473 PRIMARY KEY(so_id), 408 KEY( ext_id(64)),474 KEY(dir_id), 409 475 KEY(type) 410 476 ) ENGINE=innodb DEFAULT CHARSET=latin1; … … 441 507 type ENUM( 'read', 'write' ) NOT NULL, 442 508 epoch TIMESTAMP, 443 KEY(so_ ID)509 KEY(so_id) 444 510 ) ENGINE=innodb DEFAULT CHARSET=latin1; 445 511 … … 455 521 xattr BOOLEAN DEFAULT FALSE, 456 522 PRIMARY KEY(vol_id), 457 KEY(name(16)),458 523 KEY(host(16)), 459 524 KEY(path(255)), … … 470 535 vol_id INT NOT NULL, 471 536 FOREIGN KEY(vol_id) REFERENCES volume(vol_id), 472 uri VARCHAR(255) NOT NULL UNIQUE,537 uri VARCHAR(255) NOT NULL, 473 538 epoch TIMESTAMP DEFAULT CURRENT_TIMESTAMP, 474 539 mtime TIMESTAMP, … … 476 541 KEY(so_id), 477 542 KEY(vol_id), 478 KEY(uri( 64))543 KEY(uri(40)) 479 544 ) ENGINE=innodb DEFAULT CHARSET=latin1; 480 545 … … 515 580 available BOOLEAN DEFAULT FALSE, 516 581 xattr BOOLEAN DEFAULT FALSE, 582 PRIMARY KEY(mountpoint), 517 583 KEY(vol_id), 584 KEY(name), 585 KEY(host), 586 KEY(path), 518 587 KEY(allocate), 519 KEY(available) 588 KEY(available), 589 KEY(xattr) 520 590 ) ENGINE=innodb DEFAULT CHARSET=latin1; 521 591 -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/01_load.t
r17076 r24244 12 12 use Test::More tests => 5; 13 13 14 BEGIN { use_ok( 'Nebulous::Key s' ); }14 BEGIN { use_ok( 'Nebulous::Key' ); } 15 15 BEGIN { use_ok( 'Nebulous::Server' ); } 16 16 BEGIN { use_ok( 'Nebulous::Server::Log' ); } -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/02_config.t
r20965 r24244 3 3 # Copryight (C) 2004-2005 Joshua Hoblitt 4 4 # 5 # $Id: 02_config.t,v 1.1 2008-12-12 21:13:41 jhoblittExp $5 # $Id: 02_config.t,v 1.1.2.2 2008-12-14 22:52:37 eugene Exp $ 6 6 7 7 use strict; -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/02_server_setup.t
r20990 r24244 8 8 use warnings; 9 9 10 use Test::More tests => 2;10 use Test::More tests => 6; 11 11 12 12 use lib qw( ./t ./lib ); … … 17 17 Test::Nebulous->setup; 18 18 19 isa_ok( 20 Nebulous::Server->new( 21 dsn => $NEB_DB, 22 dbuser => $NEB_USER, 23 dbpasswd => $NEB_PASS, 24 ), 25 "Nebulous::Server" 26 ); 19 isa_ok(Nebulous::Server->new(), "Nebulous::Server"); 27 20 28 21 Test::Nebulous->setup; 29 22 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 30 Test::Nebulous->setup; 31 32 { 33 my $neb = Nebulous::Server->new( 32 34 dsn => "DBI:mysql:database=foobar:host=localhost", 33 35 dbuser => "baz", 34 36 dbpasswd =>"boo", 35 37 ); 36 }; 37 like( $@, qr/DBI connect.*? failed/, "bad dsn/user/pass" ); 38 39 ok($neb, "set database"); 40 } 41 42 Test::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 } 38 64 39 65 Test::Nebulous->cleanup; -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/03_server_create_object.t
r19493 r24244 8 8 use warnings FATAL => qw( all ); 9 9 10 use Test::More tests => 89;10 use Test::More tests => 99; 11 11 12 12 use lib qw( ./t ./lib ); 13 13 14 use File::Basename qw( basename ); 14 15 use File::ExtAttr qw( getfattr ); 15 16 use Nebulous::Server; … … 26 27 ); 27 28 29 use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS; 30 28 31 Test::Nebulous->setup; 29 32 … … 334 337 } 335 338 339 # test for properly row creation in the directories table 340 341 Test::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 353 Test::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 367 Test::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 381 Test::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 396 Test::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 414 Test::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 432 Test::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 451 Test::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 470 Test::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 490 Test::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 336 509 Test::Nebulous->setup; 337 510 -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/08_server_delete_instance.t
r20990 r24244 3 3 # Copryight (C) 2004-2005 Joshua Hoblitt 4 4 # 5 # $Id: 08_server_delete_instance.t,v 1.1 2 2008-12-14 22:54:25eugene Exp $5 # $Id: 08_server_delete_instance.t,v 1.10.22.1 2008-12-14 22:52:37 eugene Exp $ 6 6 7 7 use strict; … … 24 24 25 25 { 26 my $uri = $neb->create_object("foo"); 26 my $key = "foo"; 27 my $uri = $neb->create_object($key); 27 28 28 ok($neb->delete_instance($ uri), "delete instance");29 ok($neb->delete_instance($key, $uri), "delete instance"); 29 30 } 30 31 … … 32 33 33 34 { 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); 36 38 37 ok($neb->delete_instance($ uri1), "delete instance");39 ok($neb->delete_instance($key, $uri1), "delete instance"); 38 40 39 my $locations = $neb->find_instances( "foo");41 my $locations = $neb->find_instances($key); 40 42 41 43 is($locations->[0], $uri2, "instance remains"); 42 44 43 ok($neb->delete_instance( $uri2), "delete instance");45 ok($neb->delete_instance($key, $uri2), "delete instance"); 44 46 45 47 eval { 46 $neb->find_instances( "foo");48 $neb->find_instances($key); 47 49 }; 48 50 like($@, qr/is valid object key/, "storage object was deleted"); … … 52 54 53 55 eval { 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"); 55 60 }; 56 61 like($@, qr/no instance is associated with uri/, "uri does not exist"); … … 61 66 $neb->delete_instance(); 62 67 }; 63 like($@, qr/ 1 wasexpected/, "no params");68 like($@, qr/2 were expected/, "no params"); 64 69 65 70 Test::Nebulous->setup; 66 71 67 72 eval { 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); 69 77 }; 70 like($@, qr/ 1 wasexpected/, "too many params");78 like($@, qr/2 were expected/, "too many params"); 71 79 72 80 Test::Nebulous->cleanup; -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/10_server_is_valid_volume_name.t
r20990 r24244 23 23 Test::Nebulous->setup; 24 24 25 ok($neb->_is_valid_volume_name(' node01'), "valid volume name");25 ok($neb->_is_valid_volume_name('foo', 'node01'), "valid volume name"); 26 26 27 27 Test::Nebulous->setup; 28 28 29 ok($neb->_is_valid_volume_name(' node02'), "valid volume name");29 ok($neb->_is_valid_volume_name('foo', 'node02'), "valid volume name"); 30 30 31 31 Test::Nebulous->setup; 32 32 33 is($neb->_is_valid_volume_name(' node99'), undef, "invalid volume name");33 is($neb->_is_valid_volume_name('foo', 'node99'), undef, "invalid volume name"); 34 34 35 35 Test::Nebulous->cleanup; -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/12_server_find_objects.t
r17717 r24244 8 8 use warnings FATAL => qw( all ); 9 9 10 use Test::More tests => 6;10 use Test::More tests => 28; 11 11 12 12 use lib qw( ./t ./lib ); … … 25 25 # search for a regex of '' should match nothing 26 26 eval { 27 # key 28 my $uri = $neb->create_object("foo"); 27 $neb->create_object("foo"); 29 28 30 29 my $keys = $neb->find_objects(); … … 35 34 36 35 { 37 # key 38 my $uri = $neb->create_object("foo"); 36 $neb->create_object("foo"); 39 37 40 38 my $keys = $neb->find_objects("foo"); … … 48 46 { 49 47 # 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"); 52 50 53 51 my $keys = $neb->find_objects("foo"); … … 55 53 is(scalar @$keys, 1, 'number of keys found'); 56 54 is($keys->[0], "foo", "key name"); 55 } 56 57 Test::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 71 Test::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 82 Test::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 94 Test::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 106 Test::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 119 Test::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 131 Test::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 145 Test::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 159 Test::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"); 57 171 } 58 172 -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/13_server_rename_object.t
r17717 r24244 8 8 use warnings FATAL => qw( all ); 9 9 10 use Test::More tests => 6;10 use Test::More tests => 8; 11 11 12 12 use lib qw( ./t ./lib ); 13 13 14 use File::Basename qw( basename ); 14 15 use Nebulous::Server; 15 16 use Test::Nebulous; … … 21 22 ); 22 23 24 use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS; 25 23 26 Test::Nebulous->setup; 24 27 25 28 { 29 my $key = "bar"; 26 30 my $uri = $neb->create_object("foo"); 27 31 28 $neb->rename_object("foo", "bar");32 $neb->rename_object("foo", $key); 29 33 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 } 34 39 35 my $keys = $neb->find_objects('^bar$'); 36 is(scalar @$keys, 1, 'number of keys found'); 40 Test::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 55 Test::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 ); 37 68 } 38 69 … … 73 104 like($@, qr/2 were expected/, "too many params"); 74 105 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 109 eval { 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 }; 120 like($@, qr/rename objects across distributed database boundaries/, "rename between databases"); 121 75 122 Test::Nebulous->cleanup; -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/16_server_swap_objects.t
r20091 r24244 8 8 use warnings FATAL => qw( all ); 9 9 10 use Test::More tests => 8;10 use Test::More tests => 13; 11 11 12 12 use lib qw( ./t ./lib ); 13 13 14 use File::Basename qw( basename ); 14 15 use Nebulous::Server; 15 16 use Test::Nebulous; … … 21 22 ); 22 23 24 use Test::DBUnit dsn => $NEB_DB, username => $NEB_USER, password => $NEB_PASS; 25 23 26 Test::Nebulous->setup; 24 27 25 28 { 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); 28 33 29 ok($neb->swap_objects( "foo1", "foo2"), "swap succeeded");34 ok($neb->swap_objects($key1, $key2), "swap succeeded"); 30 35 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 49 Test::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 ); 33 68 34 69 is($uri1, $new_uri2, "key1 -> key2"); -
branches/cnb_branches/cnb_branch_20090301/Nebulous-Server/t/75_parse_neb_key.t
r19431 r24244 10 10 use Test::More; 11 11 12 plan tests => 80;12 plan tests => 99; 13 13 14 14 use lib qw( ./t ./lib ); 15 15 16 use Nebulous::Key sqw( parse_neb_key );16 use Nebulous::Key qw( parse_neb_key ); 17 17 use Test::Nebulous; 18 18 … … 224 224 } 225 225 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 226 275 # key w/ whitespace 227 276 eval { … … 267 316 }; 268 317 like( $@, qr/requires a leading slash/, "leading slash" ); 318 319 # URI w/ volume but w/o path 320 eval { 321 my $key = parse_neb_key('neb://foo'); 322 }; 323 like( $@, qr/requires a path/, "no path" );
Note:
See TracChangeset
for help on using the changeset viewer.
