Merge branch 'master' of git.rot13.org:/git/cloudstore
authorDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 11 Apr 2012 16:54:22 +0000 (18:54 +0200)
committerDobrica Pavlinusic <dpavlin@rot13.org>
Wed, 11 Apr 2012 17:09:54 +0000 (19:09 +0200)
Conflicts:
t/API.t

1  2 
lib/CloudStore/API.pm
t/API.t

diff --combined lib/CloudStore/API.pm
@@@ -9,46 -9,35 +9,46 @@@ use base qw(CloudStore::Gearman CloudSt
  use File::Path qw(make_path remove_tree);
  use File::Find;
  use Data::Dump qw(dump);
 -use Carp qw(confess);
 +use Carp qw(confess cluck);
  
  sub new {
        my ($class,$slice) = @_;
  
 -      my ( undef, $dir, $port, undef ) = getgrnam($slice);
 -      die "can't find group $slice: $!" unless $dir && $port;
 +      cluck "DEPRICIATED $slice specified" if $slice;
 +
        my $self = {
                passwd => '/var/lib/extrausers/passwd',
 -              PORT => $port,
 -              SLICE => $dir,
        };
        bless $self, $class;
  
        $self->{md5} = $self->user_info("md5") || die "can't find user md5";
 +=for removed
        $self->{md5}->{dir} = "$dir/md5";
        if ( ! -e $self->{md5}->{dir} ) {
                make_path $self->{md5}->{dir}, { uid => $self->{md5}->{uid}, gid => $self->{md5}->{gid} };
                warn "## CREATED md5pool $self->{md5}->{dir}\n";
        }
 -
 -      my $name = $self->{SLICE};
 -      $name =~ s/\W+/_/g;
 -      $name =~ s/^_+//;
 -      $self->{quota} = $name . '_quota';
 +=cut
  
        return $self;
  }
  
 +sub slice_dir_port {
 +      my ($self,$slice) = @_;
 +      my ( undef, $dir, $port, undef ) = getgrnam($slice);
 +      warn "# slice_dir_port $slice = $dir $port\n";
 +      return ( $dir, $port );
 +}
 +
 +sub dir2gearman {
 +      my $self = shift;
 +      my $dir  = shift;
 +      $dir =~ s/\W+/_/g;
 +      $dir =~ s/^_+//;
 +      $dir =~ s{_\d+$}{};
 +      return join('_', $dir, @_);
 +}
 +
  sub user_info {
        my ($self,$login) = @_;
  
@@@ -76,20 -65,17 +76,20 @@@ sub create_user 
        }
        close($fh);
  
 +      my $slice = $ENV{SLICE} || 's1';
 +      my ( $dir, $port ) = $self->slice_dir_port( $slice );
 +
        if ( ! $found ) {
                $max_uid++;
 -              my $dir = "$self->{SLICE}/$max_uid";
 -              warn "# create_user $new_email $new_quota = $max_uid $dir";
 +              $dir .= "/$max_uid";
 +              warn "# create_user $slice $new_email $new_quota = $max_uid $dir";
                open(my $fh, '>>', $self->{passwd});
 -              print $fh "u$max_uid:$new_passwd:$max_uid:$self->{PORT}:$new_email:$dir:/bin/true\n";
 +              print $fh "u$max_uid:$new_passwd:$max_uid:$port:$new_email:$dir:/bin/true\n";
                close($fh);
                $found = $max_uid;
  
                mkdir $dir;
 -              chown $max_uid, $self->{PORT}, $dir;
 +              chown $max_uid, $port, $dir;
  
                my $path = "$dir/.meta/secrets";
                $self->mkbasepath($path);
@@@ -99,7 -85,7 +99,7 @@@
        }
  
        # FIXME update quota only on create?
 -      $self->gearman_do( "$self->{quota}_set" => "$found $new_quota" );
 +      $self->gearman_do( $self->dir2gearman( $dir, 'quota', 'set' ) => "$found $new_quota" );
  
        return $found;
  }
@@@ -165,7 -151,7 +165,7 @@@ sub usage 
                $sum->{_usage}  += $v[1];
        }
        my ( $usage, $quota ) = split(/ /,
 -              $self->gearman_do( "$self->{quota}_get" => $user->{uid} )
 +              $self->gearman_do( $self->dir2gearman( $user->{dir}, 'quota', 'get' ) => $user->{uid} )
        );
        $sum->{_usage} += $usage;
        $sum->{_quota} = $quota;
@@@ -177,7 -163,7 +177,7 @@@ sub send_file 
        my ( $self, $f_uid,$f_path, $t_uid,$t_path ) = @_;
  
        my $f = $self->user_info($f_uid);
 -      die "FIXME not on current slice" if $f->{dir} !~ m/^$self->{SLICE}/;
 +      die "FIXME not on current slice" if $f->{dir} !~ m/^$ENV{SLICE}/;
        my $t = $self->user_info($t_uid);
  
        my $f_full = "$f->{dir}/$f_path";
  
        $self->delete( $t, $t_path ) if -e $t_full;
  
-       my $ok = link $f_full, $t_full; 
-       $self->append( $t, 'recv', -s $t_full, $f->{uid}, $t_path );
-       $ok = -s $t_full if $ok; # replace true with file size
+       my $size = -s $f_full;
        my $md5;
-       if ( $f->{uid} == $self->{md5}->{uid} ) {
-               $md5 = $f_path; # we don't have local md5sum db for md5 user!
+       my $ok;
+       {
+               no autodie qw(link);
+               $ok = link $f_full, $t_full
+       };
+       if ( ! $ok || $! =~ m/cross-link/ ) {
+               $ok = symlink $f_full, $t_full;
        } else {
-               $md5 = $self->md5_get($f_full);
-       }
-       if ( ! $md5 ) {
-               warn "ERROR: no md5 for $f_path";
-               return $ok;
+               $size = -s $t_full;
+               if ( $f->{uid} == $self->{md5}->{uid} ) {
+                       $md5 = $f_path; # we don't have local md5sum db for md5 user!
+               } else {
+                       $md5 = $self->md5_get($f_full);
+               }
        }
  
-       $self->append_meta('md5sum', $t, $md5 => $t_path ); # md5sum for received files!
+       if ( $ok ) {
+               $self->append( $t, 'recv', $size, $f->{uid}, $t_path );
+               $self->append_meta('md5sum', $t, $md5 => $t_path ) if $md5; # md5sum for received files! FIXME -- cross-slice md5
+       }
  
-       return $ok;
+       return $size;
  }
  
  sub rename_file {
diff --combined t/API.t
+++ b/t/API.t
@@@ -2,7 -2,7 +2,7 @@@
  use strict;
  use warnings;
  
- use Test::More tests => 25;
 -use Test::More tests => 27;
++use Test::More tests => 26;
  use Data::Dump qw(dump);
  
  use lib 'lib';
@@@ -11,6 -11,8 +11,6 @@@ use_ok 'CloudStore::API'
  
  ok my $o = CloudStore::API->new('s1'), 'new';
  
 -ok exists $o->{SLICE}, 'SLICE';
 -
  cmp_ok $o->create_user('md5@example.com','md5sum',0), '==', 2000, 'create_user md5';
  
  ok my $info = $o->user_info( 'md5' ), 'user_info';
@@@ -49,6 -51,8 +49,8 @@@ ok $o->send_file( $uid2 => 'dir1/dir2/b
  usage $uid;
  usage $uid2;
  
+ ok $o->send_file( $uid2 => 'dir1/dir2/bar.txt', 2004 => 'bar.txt' ), 'send_file cross-slice';
  ok $o->delete( $uid, 'foo.txt' );
  usage $uid;