package RsyncContent; use strict; eval{require warnings;1;}; use bigint; use Logging; use Storage::FileStorage; use vars qw|@ISA|; sub new { my $self = {}; bless( $self, shift ); $self->_init(@_); return $self; } sub _init { my $self = shift; my $storage = shift; my $packer = shift; my %options = @_; $self->{storage} = $storage; $self->{packer} = $packer; $self->{options} = {%options}; Logging::info("Rsync content transport has been initialized"); } ### Public routines ### # addAdminContent,addResellerContent,addClientContent,addDomainContent,addDomainMailListContent,addPhostingContent,\ # addSubDomainContent,addSubDomainPhostingContent,addMailnameContent,addDbContent,addSubdomainDbContent sub addAdminContent{ my $self = shift; my $cid_type = shift; my $id = shift; my $file = shift; if($cid_type eq 'sb5-server' or $cid_type eq 'sapp-distrib' or $cid_type eq 'drilldowns-config' or $cid_type eq 'key' ) { return $self->_addTar($cid_type, $self->{packer}->getAdminBackupPath( $file ) , @_); } $self->_addContent($cid_type, $id, $file, @_); } sub addResellerContent{ _addContent(@_); } sub addClientContent{ _addContent(@_); } sub addDomainContent{ my $self = shift; my $cid_type = shift; my $id = shift; my $file = shift; if($cid_type eq 'sb5-site' or $cid_type eq 'sb-dump') { return $self->_addTar( $cid_type, $self->{packer}->getDomainsBackupPath($id, $file ), @_); } $self->_addContent($cid_type, $id, $file, @_); } sub addDomainMailListContent{ my $self = shift; my $cid_type = shift; my $id = shift; return if $self->_isDomainMlParentContent($id); _addContent($self, $cid_type, $id, @_); } sub addPhostingContent{ my $self = shift; my $cid_type = shift; my $id = shift; my $referralId = shift; my $file = shift; if ($cid_type eq 'sapp-apsc') { return $self->_addTar( $cid_type, $self->{packer}->getPhostingBackupPath($id, $file ), @_); } return if $self->_isDomainPhParentContent( $self->{packer}->getPhostingParentId( $referralId ) ); _addContent($self, $cid_type, $id, $file, @_); } sub addSubDomainContent{ _addContent(@_); } sub addSubDomainPhostingContent{ my $self = shift; my $cid_type = shift; my $id = shift; my $webspaceId = shift; my $file = shift; if( $webspaceId ) { return if $self->_isDomainPhParentContent( $webspaceId ); } if ($cid_type eq 'sapp-apsc') { return $self->_addTar( $cid_type, $self->{packer}->getSubdomainsBackupPath($id, $file ), @_); } return if $self->_isDomainPhParentContent( $self->{packer}->getSubdomainParentId( $id ) ); _addContent($self, $cid_type, $id, $file, @_); } sub addMailnameContent{ my $self = shift; my $cid_type = shift; my $id = shift; return if $self->_isDomainMailParentContent( $self->{packer}->getMailNameParentId( $id ) ); _addContent($self, $cid_type, $id, @_); } sub addDbContent { my $self = shift; my $cid_type = shift; my $id = shift; return $self->_addDb( $cid_type, $self->{packer}->getDatabasesBackupPath( $id, '' ), @_); } sub addSubdomainDbContent { my $self = shift; my $cid_type = shift; my $subdomainId = shift; my $id = shift; return $self->_addDb( $cid_type, $self->{packer}->getSubdomainsBackupPath( $subdomainId, "db$id" ), @_); } sub getContentTransportDescription { my $self = shift; my $descriptionNode = XmlNode->new( 'rsync' ); $descriptionNode->setAttribute( 'host', $self->{options}->{'host'} ); $descriptionNode->setAttribute( 'port', $self->{options}->{'port'} ) if exists ( $self->{options}->{'port'} ); $descriptionNode->setAttribute( 'login', $self->{options}->{'login'} ); $descriptionNode->setAttribute( 'password', $self->{options}->{'passwd'} ); return $descriptionNode; } ### Private routines ### # check full vhost content is dumped for domainId sub _isDomainPhParentContent{ my $self = shift; my $domainId = shift; return 1 if exists $self->{packer}->{domainVhost}->{$domainId}; } sub _isDomainMlParentContent{ my $self = shift; my $domainId = shift; return 1 if exists $self->{packer}->{domainMailListContent}->{$domainId}; } sub _isDomainMailParentContent{ my $self = shift; my $domainId = shift; return 1 if exists $self->{packer}->{domainMailContent}->{$domainId}; } sub _addContent{ my $self = shift; my $cid_type = shift; my $id = shift; my $file = shift; return $self->_addRsyncContent( $cid_type, @_); } sub _addRsyncContent { my $self = shift; my $cid_type = shift; my %options = @_; return if exists $self->{packer}->{skip_content}; if ( $options{'checkEmptyDir'} ) { return unless Storage::FileStorage::checkDirForArchive($options{'directory'}, $options{'exclude'}, $options{'include_hidden_files'}); } return $self->_makeCidRsyncNode( $cid_type, $options{'directory'}, $options{'include'}, $options{'exclude'}, $options{'no_recursion'} ); } sub _addDb { my $self = shift; my $cid_type = shift; my $dstFile = shift; return if exists $self->{packer}->{skip_content}; my $id = $self->{storage}->addDb( $dstFile, @_); return unless defined $id; return $self->_makeCidNode( $id, $cid_type); } sub _addTar { my $self = shift; my $cid_type = shift; my $dstFile = shift; return if exists $self->{packer}->{skip_content}; my $id = $self->{storage}->addTar( $dstFile, @_); return unless defined $id; return $self->_makeCidNode( $id, $cid_type ); } sub _makeCidNode{ my ($self, $id, $cid_type ) = @_; my $cid = XmlNode->new( 'cid' ); $cid->setAttribute( 'type', $cid_type ); $cid->setAttribute( 'unpacksize', $self->{storage}->getFilesUnpackSizeFromId($id) ); $cid->setAttribute( 'path', $self->{storage}->getFilePathFromId( $id ) ); my $files = $self->{storage}->getFilesFromId( $id ); foreach my $filedata( @{$files} ){ $cid->addChild( XmlNode->new( 'content-file', 'content' => $filedata->[0], 'attributes' => {'size' => $filedata->[1] } ) ); } return $cid; } sub _makeCidRsyncNode{ my ($self, $cid_type, $directory, $include, $exclude, $no_recursion) = @_; # '$include' could contain filename inside '$directory'. # Note we does not process 'exclude' statement yet. return unless(-d $directory); my $cid = XmlNode->new( 'cid-rsync' ); $cid->setAttribute( 'type', $cid_type ); my $path = $directory; if ( defined $include ) { my @includes = @{$include}; my $subpath = $includes[0]; if ($subpath ne '.') { $path .= '/' if $path and substr( $path, -1, 1 ) ne '/'; $path .= $subpath; } } my $cmd = "du -sb"; if ( defined $no_recursion ) { $cmd .= " -S"; } $cmd .= " $path"; my $sizes = `$cmd`; my $unpacksize = 0; for(split /[\r\n]+/,$sizes) { my ($number, $file) = split /\t/; $unpacksize += $number; } if ( -d $path and substr( $path, -1, 1 ) ne '/') { $path .= '/'; } $cid->setAttribute( 'unpacksize', $unpacksize ); $cid->setAttribute( 'path', $path ); return $cid; } 1;