diff --git a/xCAT-server/lib/xcat/plugins/anaconda.pm b/xCAT-server/lib/xcat/plugins/anaconda.pm index 02b67795f..f64d50fa8 100644 --- a/xCAT-server/lib/xcat/plugins/anaconda.pm +++ b/xCAT-server/lib/xcat/plugins/anaconda.pm @@ -24,7 +24,7 @@ use File::Copy; use File::Temp qw/mkdtemp/; use File::Find; use File::Basename; - +use Digest::MD5 qw(md5_hex); use Socket; use strict; @@ -1427,6 +1427,7 @@ sub copycd my $mntpath=undef; my $inspection=undef; my $noosimage=undef; + my $nonoverwrite=undef; @ARGV = @{$request->{arg}}; GetOptions( @@ -1436,6 +1437,7 @@ sub copycd 'm=s' => \$mntpath, 'i' => \$inspection, 'o' => \$noosimage, + 'w' => \$nonoverwrite, ); unless ($mntpath) { @@ -1575,6 +1577,56 @@ sub copycd $path=$defaultpath; } + #tranverse the directory structure of the os media and get the fingerprint + my @filelist=(); + find( + { + "wanted" => sub{s/$mntpath/\./;push(@filelist,$_);}, + "no_chdir" => 1, + "follow" => 0, + }, + $mntpath + ); + my @sortedfilelist=sort @filelist; + my $fingerprint=md5_hex(join("",@sortedfilelist)); + + #check whether the os media has already been copied in + my $disccopiedin=0; + my $osdistroname=$distname."-".$arch; + my $tabosdistro=xCAT::Table->new('osdistro',-create=>1); + if($tabosdistro) + { + my %keyhash=(); + $keyhash{osdistroname} = $osdistroname; + my $ref = undef; + $ref=$tabosdistro->getAttribs(\%keyhash, 'dirpaths'); + if ($ref and $ref->{dirpaths} ) + { + my @dirpaths=split(',',$ref->{dirpaths}); + foreach(@dirpaths) + { + if(0 == system("grep -E "."\"\\<$fingerprint\\>\""." $_"."/.fingerprint")) + { + $disccopiedin=1; + if($nonoverwrite) + { + $callback->( + { + info => + ["The disc iso has already been copied in!"]} + ); + $tabosdistro->close(); + return; + } + last; + } + } + } + } + $tabosdistro->close(); + + + $callback->({data => "Copying media to $path"}); my $omask = umask 0022; if(-l $path) @@ -1595,9 +1647,10 @@ sub copycd system("umount $mntpath"); } }; + my $KID; chdir $mntpath; - my $numFiles = `find . -print | wc -l`; + my $numFiles = scalar(@sortedfilelist); my $child = open($KID, "|-"); unless (defined $child) { @@ -1607,10 +1660,10 @@ sub copycd if ($child) { push @cpiopid, $child; - my @finddata = `find .`; - for (@finddata) + chdir("/"); + for (@sortedfilelist) { - print $KID $_; + print $KID $_."\n"; } close($KID); $rc = $?; @@ -1619,8 +1672,7 @@ sub copycd { nice 10; my $c = "nice -n 20 cpio -vdump $path"; - my $k2 = open(PIPE, "$c 2>&1 |") || - $callback->({error => "Media copy operation fork failure"}); + my $k2 = open(PIPE, "$c 2>&1 |") || exit(1); push @cpiopid, $k2; my $copied = 0; my ($percent, $fout); @@ -1631,13 +1683,32 @@ sub copycd $callback->({sinfo => "$fout"}); ++$copied; } - exit; - } - + if($copied == $numFiles) + { + #media copy success + exit(0); + } + else + { + #media copy failed + exit(1); + } +} #my $rc = system("cd $path; find . | nice -n 20 cpio -dump $installroot/$distname/$arch"); #my $rc = system("cd $path;rsync -a . $installroot/$distname/$arch/"); chmod 0755, "$path"; + #append the fingerprint to the .fingerprint file to indicate that the os media has been copied in + unless($disccopiedin) + { + my $ret=open(my $fpd,">>","$path/.fingerprint"); + if($ret){ + print $fpd "$fingerprint,"; + close($fpd); + } + } + + unless($path =~ /^($defaultpath)/) { mkpath($defaultpath); @@ -1661,17 +1732,15 @@ sub copycd } require xCAT::Yum; - - xCAT::Yum->localize_yumrepo($installroot, $distname, $arch); + xCAT::Yum->localize_yumrepo($installroot, $distname, $arch); - if ($rc != 0) + if ($rc != 0) { $callback->({error => "Media copy operation failed, status $rc"}); } else { $callback->({data => "Media copy operation successful"}); - my $osdistroname=$distname."-".$arch; my @ret=xCAT::SvrUtils->update_osdistro_table($distname,$arch,$path,$osdistroname); if ($ret[0] != 0) { $callback->({data => "Error when updating the osdistro tables: " . $ret[1]}); diff --git a/xCAT-server/lib/xcat/plugins/copycds.pm b/xCAT-server/lib/xcat/plugins/copycds.pm index 0d4e96f51..8f58a7b28 100644 --- a/xCAT-server/lib/xcat/plugins/copycds.pm +++ b/xCAT-server/lib/xcat/plugins/copycds.pm @@ -42,6 +42,7 @@ sub process_request { my $inspection=undef; my $path=undef; my $noosimage=undef; + my $nonoverwrite=undef; $identified=0; $::CDMOUNTPATH="/var/run/xcat/mountpoint"; @@ -56,10 +57,11 @@ sub process_request { 'h|help' => \$help, 'i|inspection' => \$inspection, 'p|path=s' => \$path, - 'o|noosimage' => \$noosimage, + 'o|noosimage' => \$noosimage, + 'w|nonoverwrite' => \$nonoverwrite, ); if ($help) { - $callback->({info=>"copycds [{-p|--path}=path] [{-n|--name|--osver}=distroname] [{-a|--arch}=architecture] [-i|--inspection] [{-o|--noosimage}] 1st.iso [2nd.iso ...]."}); + $callback->({info=>"copycds [{-p|--path}=path] [{-n|--name|--osver}=distroname] [{-a|--arch}=architecture] [-i|--inspection] [{-o|--noosimage}] [{-w|--nonoverwrite}]1st.iso [2nd.iso ...]."}); return; } if ($arch and $arch =~ /i.86/) { @@ -157,6 +159,10 @@ sub process_request { if ($noosimage) { push @{$newreq->{arg}},("-o"); } + + if ($nonoverwrite) { + push @{$newreq->{arg}},("-w"); + } $doreq->($newreq,\&take_answer); #$::CDMOUNTPATH=""; diff --git a/xCAT-server/lib/xcat/plugins/sles.pm b/xCAT-server/lib/xcat/plugins/sles.pm index 82973ee31..cee650f74 100644 --- a/xCAT-server/lib/xcat/plugins/sles.pm +++ b/xCAT-server/lib/xcat/plugins/sles.pm @@ -25,7 +25,7 @@ my $httpmethod = "http"; my $httpport = "80"; use File::Find; use File::Basename; - +use Digest::MD5 qw(md5_hex); use Socket; use strict; @@ -1120,7 +1120,7 @@ sub copycd my $mntpath=undef; my $inspection=undef; my $noosimage=undef; - + my $nonoverwrite=undef; $installroot = "/install"; #my $sitetab = xCAT::Table->new('site'); @@ -1143,7 +1143,8 @@ sub copycd 'i' => \$inspection, 'p=s' => \$path, 'o' => \$noosimage, - ); + 'w' => \$nonoverwrite, + ); unless ($mntpath) { @@ -1156,6 +1157,8 @@ sub copycd #If they say to call it something other than SLES or SUSE, give up? return; } + + #parse the disc info of the os media to get the distribution, arch of the os unless (-r $mntpath . "/content") { return; @@ -1239,12 +1242,10 @@ sub copycd unless ($distname and $discnumber) { - return; + #failed to parse the disc info + return; } - - - if ($darch and $darch =~ /i.86/) { $darch = "x86"; @@ -1284,9 +1285,6 @@ sub copycd } %{$request} = (); #clear request we've got it. - - - my $defaultpath="$installroot/$distname/$arch"; unless($path) { @@ -1294,7 +1292,57 @@ sub copycd } my $ospkgpath= "$path/$discnumber"; + + #tranverse the directory structure of the os media and get the fingerprint + my @filelist=(); + find( + { + "wanted" => sub{s/$mntpath/\./;push(@filelist,$_);}, + "no_chdir" => 1, + "follow" => 0, + }, + $mntpath + ); + my @sortedfilelist=sort @filelist; + my $fingerprint=md5_hex(join("",@sortedfilelist)); + + #check whether the os media has already been copied in + my $disccopiedin=0; + my $osdistroname=$distname."-".$arch; + my $tabosdistro=xCAT::Table->new('osdistro',-create=>1); + if($tabosdistro) + { + my %keyhash=(); + $keyhash{osdistroname} = $osdistroname; + my $ref = undef; + $ref=$tabosdistro->getAttribs(\%keyhash, 'dirpaths'); + if ($ref and $ref->{dirpaths} ) + { + my @dirpaths=split(',',$ref->{dirpaths}); + foreach(@dirpaths) + { + if(0 == system("grep -E "."\"\\<$fingerprint\\>\""." $_"."/.fingerprint")) + { + $disccopiedin=1; + if($nonoverwrite) + { + $callback->( + { + info => + ["The disc iso has already been copied in!"] + } + ); + $tabosdistro->close(); + return; + } + last; + } + } + } + } + $tabosdistro->close(); + #create the destination directory of the os media copying if(-l $ospkgpath) { unlink($ospkgpath); @@ -1312,6 +1360,7 @@ sub copycd my $rc; + #the intrupt handler of SIGINT and SIGTERM $SIG{INT} = $SIG{TERM} = sub { foreach(@cpiopid){ kill 15, $_; @@ -1329,9 +1378,10 @@ sub copycd exit; }; + #media copy process my $kid; chdir $mntpath; - my $numFiles = `find . -print | wc -l`; + my $numFiles = scalar(@sortedfilelist); my $child = open($kid,"|-"); unless (defined $child) { $callback->({error=>"Media copy operation fork failure"}); @@ -1339,17 +1389,15 @@ sub copycd } if ($child) { push @cpiopid,$child; - my @finddata = `find .`; chdir("/"); - for (@finddata) { - print $kid $_; + for (@sortedfilelist) { + print $kid $_."\n"; } close($kid); $rc = $?; } else { my $c = "nice -n 20 cpio -vdump $ospkgpath"; - my $k2 = open(PIPE, "$c 2>&1 |") || - $callback->({error => "Media copy operation fork failure"}); + my $k2 = open(PIPE, "$c 2>&1 |") || exit(1); chdir("/"); push @cpiopid, $k2; my $copied = 0; @@ -1361,7 +1409,16 @@ sub copycd $callback->({sinfo => "$fout"}); ++$copied; } - exit; + if($copied == $numFiles) + { + #media copy success + exit(0); + } + else + { + #media copy failed + exit(1); + } } # system( # "cd $path; find . | nice -n 20 cpio -dump $installroot/$distname/$arch/$discnumber/" @@ -1370,6 +1427,17 @@ sub copycd chmod 0755, "$ospkgpath"; + #append the fingerprint to the .fingerprint file to indicate that the os media has been copied in + unless($disccopiedin) + { + my $ret=open(my $fpd,">>","$path/.fingerprint"); + if($ret){ + print $fpd "$fingerprint,"; + close($fpd); + } + } + + #if the destination path is not the default, create a symlink named by the default path to the specified path unless($path =~ /^($defaultpath)/) { mkpath("$defaultpath/$discnumber"); @@ -1435,12 +1503,13 @@ sub copycd else { $callback->({data => "Media copy operation successful"}); - my $osdistroname=$distname."-".$arch; + my @ret=xCAT::SvrUtils->update_osdistro_table($distname,$arch,$path,$osdistroname); if ($ret[0] != 0) { $callback->({data => "Error when updating the osdistro tables: " . $ret[1]}); } - + + #if --noosimage option is not specified, create the relevant osimage and linuximage entris unless($noosimage){ my @ret=xCAT::SvrUtils->update_tables_with_templates($distname, $arch,$path,$osdistroname); if ($ret[0] != 0) {