2007-10-26 22:44:33 +00:00
# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html
package xCAT_plugin::copycds ;
2008-07-18 22:39:01 +00:00
use strict ;
use warnings ;
2007-10-26 22:44:33 +00:00
use Storable qw( dclone ) ;
use xCAT::Table ;
2008-07-28 18:32:22 +00:00
use Thread qw( yield ) ;
2007-10-26 22:44:33 +00:00
use Data::Dumper ;
use Getopt::Long ;
2008-06-03 15:49:45 +00:00
use File::Basename ;
2012-10-16 09:19:48 +00:00
use File::Spec ;
use Digest::MD5 qw( md5_hex ) ;
2008-07-11 20:19:20 +00:00
use Cwd ;
2007-10-26 22:44:33 +00:00
Getopt::Long:: Configure ( "bundling" ) ;
Getopt::Long:: Configure ( "pass_through" ) ;
my $ processed = 0 ;
my $ callback ;
sub handled_commands {
return {
copycds = > "copycds" ,
}
}
2008-04-29 17:39:28 +00:00
my $ identified ;
2007-10-26 22:44:33 +00:00
sub take_answer {
#TODO: Intelligently filter and decide things
my $ resp = shift ;
$ callback - > ( $ resp ) ;
2008-04-29 17:39:28 +00:00
$ identified = 1 ;
2007-10-26 22:44:33 +00:00
}
sub process_request {
my $ request = shift ;
$ callback = shift ;
my $ doreq = shift ;
my $ distname = undef ;
my $ arch = undef ;
2008-11-04 19:24:38 +00:00
my $ help = undef ;
2012-06-08 03:00:27 +00:00
my $ inspection = undef ;
2012-11-08 07:02:56 +00:00
my $ path = undef ;
my $ noosimage = undef ;
2013-01-07 08:39:52 +00:00
my $ nonoverwrite = undef ;
2014-03-21 14:56:20 +00:00
my $ specific = undef ;
2012-06-08 03:00:27 +00:00
2008-04-29 17:39:28 +00:00
$ identified = 0 ;
2012-11-14 07:23:16 +00:00
$ ::CDMOUNTPATH = "/var/run/xcat/mountpoint" ;
2008-07-11 20:19:20 +00:00
my $ existdir = getcwd ;
2007-10-26 22:44:33 +00:00
2008-07-31 21:07:18 +00:00
if ( $ request - > { arg } ) {
@ ARGV = @ { $ request - > { arg } } ;
}
2007-10-26 22:44:33 +00:00
GetOptions (
'n|name|osver=s' = > \ $ distname ,
2008-11-04 19:24:38 +00:00
'a|arch=s' = > \ $ arch ,
2012-06-08 03:00:27 +00:00
'h|help' = > \ $ help ,
'i|inspection' = > \ $ inspection ,
2012-11-08 07:02:56 +00:00
'p|path=s' = > \ $ path ,
2013-01-07 08:39:52 +00:00
'o|noosimage' = > \ $ noosimage ,
2014-03-21 14:56:20 +00:00
's|specific' = > \ $ specific ,
2013-01-07 08:39:52 +00:00
'w|nonoverwrite' = > \ $ nonoverwrite ,
2012-06-08 03:00:27 +00:00
) ;
2008-11-04 19:24:38 +00:00
if ( $ help ) {
2013-01-08 13:08:33 +00:00
$ callback - > ( { info = > "copycds [{-p|--path}=path] [{-n|--name|--osver}=distroname] [{-a|--arch}=architecture] [-i|--inspection] [{-o|--noosimage}] [{-w|--nonoverwrite}] 1st.iso [2nd.iso ...]." } ) ;
2012-06-08 03:00:27 +00:00
return ;
2008-11-04 19:24:38 +00:00
}
2007-10-26 22:44:33 +00:00
if ( $ arch and $ arch =~ /i.86/ ) {
2008-07-18 22:39:01 +00:00
$ arch = 'x86' ;
2007-10-26 22:44:33 +00:00
}
my @ args = @ ARGV ; #copy ARGV
unless ( $# args >= 0 ) {
2012-06-08 03:00:27 +00:00
$ callback - > ( { error = > "copycds needs at least one full path to ISO currently." , errorcode = > [ 1 ] } ) ;
return ;
2007-10-26 22:44:33 +00:00
}
2008-07-18 22:39:01 +00:00
my $ file ;
2007-10-26 22:44:33 +00:00
foreach ( @ args ) {
2012-06-08 03:00:27 +00:00
$ identified = 0 ;
2008-01-10 13:41:31 +00:00
unless ( /^\// ) { #If not an absolute path, concatenate with client specified cwd
2008-06-03 15:49:45 +00:00
s/^/$request->{cwd}->[0]\// ;
2008-01-10 13:41:31 +00:00
}
2008-06-03 15:49:45 +00:00
2008-06-27 15:25:42 +00:00
# /dev/cdrom is a symlink on some systems. We need to be able to determine
# if the arg points to a block device.
2008-06-03 15:49:45 +00:00
if ( - l $ _ ) {
my $ link = readlink ( $ _ ) ;
2008-06-27 15:25:42 +00:00
# Symlinks can be relative, i.e., "../../foo"
2008-06-03 15:49:45 +00:00
if ( $ link =~ m {^/} )
{ $ file = $ link ; }
else
2008-06-27 15:25:42 +00:00
{ $ file = dirname ( $ _ ) . "/" . $ link ; } # Unix can handle "/foo/../bar"
2008-06-03 15:49:45 +00:00
}
else { $ file = $ _ ; }
2013-06-30 03:56:29 +00:00
# handle the copycds for tar file
# if the source file is tar format, call the 'copytar' command to handle it.
# currently it's used for Xeon Phi (mic) support
if ( - r $ file ) {
my @ filestat = `file $file` ;
if ( grep /tar archive/ , @ filestat ) {
# this is a tar file, call the 'copytar' to generate the image
my $ newreq = dclone ( $ request ) ;
$ newreq - > { command } = [ 'copytar' ] ; #Note the singular, it's different
$ newreq - > { arg } = [ "-f" , $ file , "-n" , $ distname ] ;
$ doreq - > ( $ newreq , $ callback ) ;
return ;
}
}
2008-09-07 03:27:58 +00:00
my $ mntopts = "-t udf,iso9660" ; #Prefer udf formate to iso when media supports both, like MS media
2008-06-03 15:49:45 +00:00
if ( - r $ file and - b $ file ) # Block device?
2008-09-07 03:27:58 +00:00
{ $ mntopts . = " -o ro" ; }
2008-06-27 15:25:42 +00:00
elsif ( - r $ file and - f $ file ) # Assume ISO file
2008-09-07 03:27:58 +00:00
{ $ mntopts . = " -o ro,loop" ; }
2008-06-03 15:49:45 +00:00
else {
2012-06-08 03:00:27 +00:00
$ callback - > ( { error = > "The management server was unable to find/read $file. Ensure that file exists on the server at the specified location." , errorcode = > [ 1 ] } ) ;
return ;
2007-10-26 22:44:33 +00:00
}
2008-06-03 15:49:45 +00:00
2012-10-16 09:19:48 +00:00
#let the MD5 Digest of isofullpath as the default mount point of the iso
my $ isofullpath = File::Spec - > rel2abs ( $ file ) ;
my $ mntpath = File::Spec - > catpath ( "" , $ ::CDMOUNTPATH , md5_hex ( $ isofullpath ) ) ;
system ( "mkdir -p $mntpath" ) ;
system ( "umount $mntpath >/dev/null 2>&1" ) ;
2008-06-03 15:49:45 +00:00
2012-10-16 09:19:48 +00:00
if ( system ( "mount $mntopts '$file' $mntpath" ) ) {
eval { $ callback - > ( { error = > "copycds was unable to mount $file to $mntpath." , errorcode = > [ 1 ] } ) } ;
chdir ( "/" ) ;
2012-11-14 03:40:31 +00:00
system ( "umount $mntpath" ) ;
2012-06-08 03:00:27 +00:00
return ;
2007-10-26 22:44:33 +00:00
}
2012-09-10 18:58:03 +00:00
eval {
2007-10-26 22:44:33 +00:00
my $ newreq = dclone ( $ request ) ;
$ newreq - > { command } = [ 'copycd' ] ; #Note the singular, it's different
2012-10-16 09:19:48 +00:00
$ newreq - > { arg } = [ "-m" , $ mntpath ] ;
2012-06-08 03:00:27 +00:00
if ( $ path )
{
push @ { $ newreq - > { arg } } , ( "-p" , $ path ) ;
}
2014-03-21 14:56:20 +00:00
if ( $ specific )
{
push @ { $ newreq - > { arg } } , ( "-s" ) ;
}
2012-06-08 03:00:27 +00:00
if ( $ inspection )
{
push @ { $ newreq - > { arg } } , ( "-i" ) ;
$ callback - > ( { info = > "OS Image:" . $ _ } ) ;
2007-10-26 22:44:33 +00:00
}
2012-06-08 03:00:27 +00:00
if ( $ distname ) {
if ( $ inspection ) {
$ callback - > ( { warning = > "copycds: option --inspection specified, argument specified with option --name is ignored" } ) ;
}
else {
push @ { $ newreq - > { arg } } , ( "-n" , $ distname ) ;
}
}
2007-10-26 22:44:33 +00:00
if ( $ arch ) {
2012-06-08 03:00:27 +00:00
if ( $ inspection ) {
$ callback - > ( { warning = > "copycds: option --inspection specified, argument specified with option --arch is ignored" } ) ;
}
else {
2007-10-26 22:44:33 +00:00
push @ { $ newreq - > { arg } } , ( "-a" , $ arch ) ;
2012-06-08 03:00:27 +00:00
}
2012-08-20 13:48:24 +00:00
}
2012-11-08 07:02:56 +00:00
2012-08-20 13:48:24 +00:00
if ( ! - l $ file ) {
push @ { $ newreq - > { arg } } , ( "-f" , $ file ) ;
}
2012-06-08 03:00:27 +00:00
2012-11-08 07:02:56 +00:00
if ( $ noosimage ) {
push @ { $ newreq - > { arg } } , ( "-o" ) ;
}
2013-01-07 08:39:52 +00:00
if ( $ nonoverwrite ) {
push @ { $ newreq - > { arg } } , ( "-w" ) ;
}
2012-11-08 07:02:56 +00:00
2007-10-26 22:44:33 +00:00
$ doreq - > ( $ newreq , \ & take_answer ) ;
2012-10-16 09:19:48 +00:00
#$::CDMOUNTPATH="";
2007-10-26 22:44:33 +00:00
2008-07-11 20:19:20 +00:00
chdir ( $ existdir ) ;
2008-07-18 22:39:01 +00:00
while ( wait ( ) > 0 ) { yield ( ) ; } #Make sure all children exit before trying umount
2012-09-10 18:58:03 +00:00
} ;
2012-10-16 09:19:48 +00:00
chdir ( "/" ) ; ;
2012-11-14 03:40:31 +00:00
system ( "umount $mntpath" ) ;
2012-10-16 09:19:48 +00:00
system ( "rm -rf $mntpath" ) ;
2008-04-29 17:39:28 +00:00
unless ( $ identified ) {
$ callback - > ( { error = > [ "copycds could not identify the ISO supplied, you may wish to try -n <osver>" ] , errorcode = > [ 1 ] } ) ;
}
2007-10-26 22:44:33 +00:00
}
}
1 ;
2008-06-03 15:49:45 +00:00
# vim: set ts=2 sts=2 sw=2 et ai: