From 47725c06ae17bf844a730e80f74ebb83e390127c Mon Sep 17 00:00:00 2001 From: WangXiaoPeng Date: Thu, 14 May 2015 02:33:20 -0400 Subject: [PATCH 01/26] restapi, fix the issue that cannot set attribute which name is password --- xCAT-server/xCAT-wsapi/xcatws.cgi | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/xCAT-server/xCAT-wsapi/xcatws.cgi b/xCAT-server/xCAT-wsapi/xcatws.cgi index 6bbeafebe..112de13b7 100755 --- a/xCAT-server/xCAT-wsapi/xcatws.cgi +++ b/xCAT-server/xCAT-wsapi/xcatws.cgi @@ -2908,12 +2908,13 @@ sub fetchParameters { if (ref($phash) ne 'HASH') { error("put or post data must be a json object (hash/dict).", $STATUS_BAD_REQUEST); } # if any general parms are in the put/post data, move them to genparms - foreach my $k (keys %$phash) { - if (grep(/^$k$/, @generalparamlist)) { - $genparms->{$k} = $phash->{$k}; - delete($phash->{$k}); - } - } + # Do not think this is neccessary and it caused the issue that set any 'password' key would fail. + # foreach my $k (keys %$phash) { + # if (grep(/^$k$/, @generalparamlist)) { + # $genparms->{$k} = $phash->{$k}; + # delete($phash->{$k}); + # } + # } } else { $phash = {}; } From 8f7633c9b55520f7b5cf88eedd4d523c01c6ec6c Mon Sep 17 00:00:00 2001 From: ligc Date: Thu, 14 May 2015 03:55:42 -0400 Subject: [PATCH 02/26] remove the install/netboot/statelite from the usage statements of nodeset, imgcapture, genimage and packimgage --- perl-xCAT/xCAT/Usage.pm | 568 -------------- xCAT-client/bin/genimage | 460 ----------- xCAT-server/lib/xcat/plugins/imgcapture.pm | 846 --------------------- xCAT-server/lib/xcat/plugins/packimage.pm | 629 --------------- 4 files changed, 2503 deletions(-) mode change 100644 => 100755 perl-xCAT/xCAT/Usage.pm mode change 100644 => 100755 xCAT-server/lib/xcat/plugins/imgcapture.pm mode change 100644 => 100755 xCAT-server/lib/xcat/plugins/packimage.pm diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm old mode 100644 new mode 100755 index 16815a68c..e69de29bb --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -1,568 +0,0 @@ -#!/usr/bin/perl -# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html - -package xCAT::Usage; -use Getopt::Long; -use xCAT::Utils; - -#------------------------------------------------------------------------------- -=head1 xCAT::Usage -=head2 Package Description - xCAT usage module. Some commands such as rpower have different implementations - for different hardware. This module holds the usage string for these kind - of commands so that the usage can be referenced from different modules. -=cut -#------------------------------------------------------------------------------- - - -my %usage = ( - "rnetboot" => -"Usage: rnetboot [-s net|hd] [-F] [-f] [-V|--verbose] [-m table.colum==expectedstatus] [-m table.colum==expectedstatus...] [-r ] [-t ] - rnetboot [-h|--help|-v|--version] - zVM specific: - rnetboot [ipl= address]", - "rpower" => -"Usage: rpower [--nodeps] [on|onstandby|off|suspend|reset|stat|state|boot] [-V|--verbose] [-m table.colum==expectedstatus][-m table.colum==expectedstatus...] [-r ] [-t ] - rpower [-h|--help|-v|--version] - KVM Virtualization specific: - rpower [boot] [ -c ] - PPC (with IVM or HMC) specific: - rpower [--nodeps] [of] [-V|--verbose] - CEC (with HMC) specific: - rpower [on|off|reset|boot|onstandby] - LPAR(with HMC) specific: - rpower [on|off|reset|stat|state|boot|of|sms|softoff] - CEC(using Direct FSP Management) specific: - rpower [on|onstandby|off|stat|state|resetsp] - Frame(using Direct FSP Management) specific: - rpower [stat|state|rackstandby|exit_rackstandby|resetsp] - LPAR(using Direct FSP Management) specific: - rpower [on|off|reset|stat|state|boot|of|sms] - Blade(using Direct FSP Management) specific: - rpower [on|onstandby|off|cycle|state|sms] - Blade(using AMM) specific: - rpower [cycle|softoff] [-V|--verbose] - zVM specific: - rpower noderange [on|off|reset|stat|softoff] - MIC specific: - rpower noderange [stat|state|on|off|reset|boot] -", - "rbeacon" => -"Usage: rbeacon [on|off|stat] [-V|--verbose] - rbeacon [-h|--help|-v|--version]", - "rvitals" => -"Usage: - Common: - rvitals [-h|--help|-v|--version] - FSP/LPAR (with HMC) specific: - rvitals noderange {temp|voltage|lcds|all} - CEC/LPAR/Frame (using Direct FSP Management)specific: - rvitals noderange {rackenv|lcds|all} - MPA specific: - rvitals noderange {temp|voltage|wattage|fanspeed|power|leds|summary|all} - Blade specific: - rvitals noderange {temp|wattage|fanspeed|leds|summary|all} - BMC specific: - rvitals noderange {temp|voltage|wattage|fanspeed|power|leds|lcds|summary|all} - MIC specific: - rvitals noderange {thermal|all}", - "reventlog" => -"Usage: reventlog [all [-s]|clear| [-s]] [-V|--verbose] - reventlog [-h|--help|-v|--version]", - "rinv" => -"Usage: - Common: - rinv [all|model|serial] [-V|--verbose] - rinv [-h|--help|-v|--version] - BMC specific: - rinv [mprom|deviceid|uuid|guid|vpd [-t]|all [-t]] - MPA specific: - rinv [firm|bios|diag|mprom|sprom|mparom|mac|mtm [-t]] - PPC specific(with HMC): - rinv [all|bus|config|serial|model|firm [-t]] - PPC specific(using Direct FSP Management): - rinv [firm] - rinv [deconfig [-x]] - Blade specific: - rinv [all|serial|mac|bios|diag|mprom|mparom|firm|mtm [-t]] - IBM Flex System Compute Node specific: - rinv [firm] - VMware specific: - rinv - zVM specific: - rinv noderange [all|config] - MIC specific: - rinv noderange [system|ver|board|core|gddr|all]", - "rsetboot" => -"Usage: rsetboot [net|hd|cd|floppy|def|stat] [-V|--verbose] - rsetboot [-h|--help|-v|--version]", - "rbootseq" => -"Usage: - Common: - rbootseq [-h|--help|-v|--version|-V|--verbose] - Blade specific: - rbootseq [hd0|hd1|hd2|hd3|net|iscsi|usbflash|floppy|none],... - PPC (using Direct FSP Management) specific: - rbootseq [hfi|net]", - "rscan" => -"Usage: rscan [-u][-w][-x|-z] [-V|--verbose] - rscan [-h|--help|-v|--version]", - "rspconfig" => -"Usage: - Common: - rspconfig [-h|--help|-v|--version|-V|--verbose] - BMC/MPA Common: - rspconfig [snmpdest|alert|community] [-V|--verbose] - rspconfig [snmpdest=|alert=|community=] - BMC specific: - rspconfig [ip|netmask|gateway|backupgateway|garp] - rspconfig [garp=] - iDataplex specific: - rspconfig [thermprofile] - rspconfig [thermprofile=] - MPA specific: - rspconfig [sshcfg|snmpcfg|pd1|pd2|network|swnet|ntp|textid|frame] - rspconfig [textid=name] - rspconfig [frame=number] - rspconfig [USERID=passwd] [updateBMC=] - rspconfig [sshcfg=| - snmpcfg=| - pd1=| - pd2=| - network=<*|[ip],[host],[gateway],[netmask]>| - swnet=<[ip],[gateway],[netmask]>| - textid=<*>| - frame=<*>| - ntp=<[ntp],[ip],[frequency],[v3]> - FSP/CEC (using ASM Interface) Specific: - rspconfig [autopower|iocap|decfg|memdecfg|procdecfg|time|date|spdump|sysdump|network|hostname] - rspconfig autopower=| - iocap=| - decfg=:,...| - memdecfg=::::id,...| - procdecfg=::id,...| - date=| - time=| - network=<*|[ip],[host],[gateway],[netmask]>| - HMC_passwd=| - admin_passwd=| - general_passwd=| - *_passwd=| - hostname=<*|hostname> - FSP/CEC (using Direct FSP Management) Specific: - rspconfig HMC_passwd= - rspconfig admin_passwd= - rspconfig general_passwd= - rspconfig *_passwd= - rspconfig [sysname] - rspconfig [sysname=<*|name>] - rspconfig [pending_power_on_side] - rspconfig [pending_power_on_side=] - rspconfig [cec_off_policy] - rspconfig [cec_off_policy=] - rspconfig [huge_page] - rspconfig [huge_page=] - rspconfig [BSR] - rspconfig [setup_failover] - rspconfig [setup_failover=] - rspconfig [force_failover] - rspconfig --resetnet - BPA/Frame (using Direct FSP Management)specific: - rspconfig HMC_passwd= - rspconfig admin_passwd= - rspconfig general_passwd= - rspconfig *_passwd= - rspconfig [frame] - rspconfig frame=<*|frame> - rspconfig [sysname] - rspconfig [sysname=<*|name>] - rspconfig [pending_power_on_side] - rspconfig [pending_power_on_side=] - rspconfig --resetnet - HMC specific: - rspconfig [sshcfg] - rspconfig [sshcfg=] - CEC|Frame(using ASM)Specific: - rspconfig [dev|celogin1] - rspconfig [dev=]| - rspconfig [celogin1=] - ", - "getmacs" => -"Usage: - Common: - getmacs [-h|--help|-v|--version] - PPC specific: - getmacs [-F filter] - getmacs [-M] - getmacs [-V| --verbose] [-f] [-d] [--arp] | [-D {[-o] [-S server] [-G gateway] [-C client] | [--noping]}] - blade specific: - getmacs [-V| --verbose] [-d] [--arp] [-i ethN|enN] -", - "mkvm" => -"Usage: - Common: - mkvm [-h|--help|-v|--version] - For PPC(with HMC) specific: - mkvm noderange -i id -l singlenode [-V|--verbose] - mkvm noderange -c destcec -p profile [-V|--verbose] - mkvm noderange --full [-V|--verbose] - PPC (using Direct FSP Management) specific: - mkvm noderange [--full] - mkvm noderange [vmcpus=min/req/max] [vmmemory=min/req/max] - [vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N] - [vmnics=vlan1,vlan2] [vmstorage=] [--vios] - For KVM - mkvm noderange -m|--master mastername -s|--size disksize -f|--force - For zVM - mkvm noderange directory_entry_file_path - mkvm noderange source_virtual_machine pool=disk_pool pw=multi_password", - "lsvm" => -"Usage: - Common: - lsvm [-V|--verbose] - lsvm [-h|--help|-v|--version] - PPC (with HMC) specific: - lsvm [-a|--all] - PPC (using Direct FSP Management) specific: - lsvm [-l|--long] --p775 - lsvm - zVM specific: - lsvm noderange - lsvm noderange --getnetworknames - lsvm noderange --getnetwork network_name - lsvm noderange --diskpoolnames - lsvm noderange --diskpool pool_name", - "chvm" => -"Usage: - Common: - chvm [-h|--help|-v|--version] - PPC (with HMC) specific: - chvm [-p profile][-V|--verbose] - chvm = [=...] - PPC (using Direct FSP Management) specific: - chvm --p775 [-p ] - chvm --p775 -i [-m ] -r - chvm [lparname=<*|name>] - chvm [vmcpus=min/req/max] [vmmemory=min/req/max] - [vmothersetting=hugepage:N,bsr:N] - [add_physlots=drc_index1,drc_index2...] - [add_vmnics=vlan1,vlan2] [add_vmstorage=] [--vios] - chvm [del_physlots=drc_index1,drc_index2...] - chvm [del_vadapter=slotid] - VMware specific: - chvm [-a size][-d disk][-p disk][--resize disk=size][--cpus count][--mem memory] - zVM specific: - chvm noderange [--add3390 disk_pool device_address cylinders mode read_password write_password multi_password] - chvm noderange [--add3390active device_address mode] - chvm noderange [--add9336 disk_pool virtual_device block_size mode blocks read_password write_password multi_password] - chvm noderange [--adddisk2pool function region volume group] - chvm noderange [--addnic address type device_count] - chvm noderange [--addprocessor address] - chvm noderange [--addprocessoractive address type] - chvm noderange [--addvdisk userID] device_address size] - chvm noderange [--connectnic2guestlan address lan owner] - chvm noderange [--connectnic2vswitch address vswitch] - chvm noderange [--copydisk target_address source_node source_address] - chvm noderange [--dedicatedevice virtual_device real_device mode] - chvm noderange [--deleteipl] - chvm noderange [--formatdisk disk_address multi_password] - chvm noderange [--disconnectnic address] - chvm noderange [--grantvswitch VSwitch] - chvm noderange [--removedisk virtual_device] - chvm noderange [--resetsmapi] - chvm noderange [--removediskfrompool function region group] - chvm noderange [--removenic address] - chvm noderange [--removeprocessor address] - chvm noderange [--replacevs directory_entry] - chvm noderange [--setipl ipl_target load_parms parms] - chvm noderange [--setpassword password]", - "rmvm" => -"Usage: rmvm [--service][-V|--verbose] - rmvm [-h|--help|-v|--version], - rmvm [-p] [-f] - PPC (using Direct FSP Management) specific: - rmvm ", - "lsslp" => -"Usage: lsslp [-h|--help|-v|--version] - lsslp [][-V|--verbose][-i ip[,ip..]][-w][-r|-x|-z][-n][-I][-s FRAME|CEC|MM|IVM|RSA|HMC|CMM|IMM2|FSP] - [-u] [--range IPranges][-t tries][--vpdtable][-C counts][-T timeout]", - "switchdiscover" => -"Usage: switchdiscover [-h|--help|-v|--version] - switchdiscover [][-V|--verbose][-i adpt[,adpt..]][-w][-r|-x|-z][-n][-s scan_methods]", - "rflash" => -"Usage: - rflash [ -h|--help|-v|--version] - PPC (with HMC) specific: - rflash -p [--activate concurrent | disruptive][-V|--verbose] - rflash [--commit | --recover] [-V|--verbose] - PPC (using Direct FSP Management) specific: - rflash -p --activate [-d ] - rflash [--commit | --recover] [-V|--verbose] - rflash [--bpa_acdl]", - "mkhwconn" => -"Usage: - mkhwconn [-h|--help] - - PPC (with HMC) specific: - mkhwconn noderange -t [--bind] [-V|--verbose] - mkhwconn noderange -p single_hmc [-P HMC passwd] [-V|--verbose] - - PPC (using Direct FSP Management) specific: - mkhwconn noderange -t [-T tooltype] [--port port_value] - mkhwconn noderange -s [hmcnode] [-P HMC passwd] [-V|--verbose]", - "rmhwconn" => -"Usage: - rmhwconn [-h|--help] - - PPC (with HMC) specific: - rmhwconn noderange [-V|--verbose] - - PPC (using Direct FSP Management) specific: - rmhwconn noderange [-T tooltype] - rmhwconn noderange -s", - "lshwconn" => -"Usage: - lshwconn [-h|--help] - - PPC (with HMC) specific: - lshwconn noderange [-V|--verbose] - - PPC (using Direct FSP Management) specific: - lshwconn noderange [-T tooltype] - lshwconn noderange -s", - "renergy" => -"Usage: - renergy [-h | --help] - renergy [-v | --version] - - Power 6 server specific : - renergy noderange [-V] { all | { [savingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] } } - renergy noderange [-V] { {savingstatus}={on | off} | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage } - - Power 7 server specific : - renergy noderange [-V] { all | { [savingstatus] [dsavingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue] } } - renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} | {fsavingstatus}={on | off} | {ffovalue}=MHZ | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage } - - Power 8 server specific : - renergy noderange [-V] { all | [savingstatus] [dsavingstatus] [averageAC] [averageAChistory] [averageDC] [averageDChistory] [ambienttemp] [ambienttemphistory] [exhausttemp] [exhausttemphistory] [fanspeed] [fanspeedhistory] [CPUspeed] [CPUspeedhistory] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue]} - renergy noderange [-V] { savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} | fsavingstatus={on | off} | ffovalue=MHZ } - - BladeCenter specific : - For Management Modules: - renergy noderange [-V] { all | pd1all | pd2all | [pd1status] [pd2status] [pd1policy] [pd2policy] [pd1powermodule1] [pd1powermodule2] [pd2powermodule1] [pd2powermodule2] [pd1avaiablepower] [pd2avaiablepower] [pd1reservedpower] [pd2reservedpower] [pd1remainpower] [pd2remainpower] [pd1inusedpower] [pd2inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] } - For a blade server nodes: - renergy noderange [-V] { all | [averageDC] [capability] [cappingvalue] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] } - renergy noderange [-V] { savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} } - - Flex specific : - For Flex Management Modules: - renergy noderange [-V] { all | [powerstatus] [powerpolicy] [powermodule] [avaiablepower] [reservedpower] [remainpower] [inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] } - - For Flex node (power and x86): - renergy noderange [-V] { all | [averageDC] [capability] [cappingvalue] [cappingmaxmin] [cappingmax] [cappingmin] [cappingGmin] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] } - renergy noderange [-V] { cappingstatus={on | off} | cappingwatt=watt | cappingperc=percentage | savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} } - - iDataPlex specific : - renergy noderange [-V] [ { cappingmaxmin | cappingmax | cappingmin } ] [cappingstatus] [cappingvalue] [relhistogram] - renergy noderange [-V] { cappingstatus={on | enable | off | disable} | {cappingwatt|cappingvalue}=watt }", - "updatenode" => -"Usage: - updatenode [-h|--help|-v|--version | -g|--genmypost] - or - updatenode [-V|--verbose] [-k|--security] [-s|--sn] [-t ] - or - updatenode [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t ] - [-P|--scripts [script1,script2,...]] [-s|--sn] - [-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir] - [attr=val [attr=val...]] - or - updatenode [-V|--verbose] [script1,script2,...] - -Options: - A list of nodes or groups. - - [-k|--security] Update the security keys and certificates for the - target nodes. - - [-F|--sync] Perform File Syncing. - - [--fanout] Allows you to assign the fanout value for the command. - See xdsh/xdcp fanout parameter in the man page. - - [-f|--snsync] Performs File Syncing to the service nodes that service - the nodes in the noderange. - - [-g|--genmypost] Will generate a new mypostscript file for the - the nodes in the noderange, if site precreatemypostscripts is 1 or YES. - - [-l|--user] User name to run the updatenode command. It overrides the - current user which is the default. - - [-S|--sw] Perform Software Maintenance. - - [-P|--scripts] Execute postscripts listed in the postscripts table or - parameters. - - [-c|--cmdlineonly] Only use AIX software maintenance information - provided on the command line. (AIX only) - - [-s|--sn] Set the server information stored on the nodes. - - [-t|--timeout] Time out in seconds to allow the command to run. Default is no timeout, - except for updatenode -k which has a 10 second default timeout. - - [-A|--updateallsw] Install or update all software contained in the source - directory. (AIX only) - - [-d ] Used to indicate a source directory other than - the standard lpp_source directory specified in the xCAT osimage - definition. (AIX only) - - [script1,script2,...] A comma separated list of postscript names. - If omitted, all the post scripts defined for the nodes will be run. - - [attr=val [attr=val...]] Specifies one or more 'attribute equals value' - pairs, separated by spaces. (AIX only)", - "lsflexnode" => -"Usage: - lsflexnode [-h|--help|-v|--version] - lsflexnode ", - "mkflexnode" => -"Usage: - mkflexnode [-h|--help|-v|--version] - mkflexnode ", - "nodeset" => -"Usage: - Common: - nodeset [-h|--help|-v|--version] - nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage[=]|statelite|offline]", - "rmflexnode" => -"Usage: - rmflexnode [-h|--help|-v|--version] - rmflexnode ", - "lsve" => -"Usage: - lsve [-t type] [-m manager] [-o object] - -t: dc - 'Data Center', cl - 'Cluster', sd - 'Storage Domain', nw - 'Network', tpl -'Template' - -m: FQDN (Fully Qualified Domain Name) of the rhev manager - -o: Target object to display", - "cfgve" => -"Usage: - cfgve -t dc -m manager -o object [-c -k nfs|localfs | -r] - cfgve -t cl -m manager -o object [-c -p cpu type | -r -f] - cfgve -t sd -m manager -o object [-c | -g | -s | -a | -b | -r -f] - -t: sd - 'Storage Domain', nw - 'Network', tpl -'Template' - -m: FQDN (Fully Qualified Domain Name) of the rhev manager - -o: Target object to configure - cfgve -t nw -m manager -o object [-c -d data center -n vlan ID | -a -l cluster| -b | -r] - cfgve -t tpl -m manager -o object [-r]", - "chhypervisor" => -"Usage: - chhypervisor noderange [-a | -n | -p | -e | -d | -h]", - "rmhypervisor" => -"Usage: - rmhypervisor noderange [-f | -h]", - "clonevm" => -"Usage: - clonevm noderange [-t createmaster -f | -b basemaster -d | -h]", -); -my $vers = xCAT::Utils->Version(); -my %version = ( - "rnetboot" => "$vers", - "rpower" => "$vers", - "rbeacon" => "$vers", - "rvitals" => "$vers", - "reventlog" => "$vers", - "rinv" => "$vers", - "rsetboot" => "$vers", - "rbootseq" => "$vers", - "rscan" => "$vers", - "rspconfig" => "$vers", - "getmacs" => "$vers", - "mkvm" => "$vers", - "lsvm" => "$vers", - "chvm" => "$vers", - "rmvm" => "$vers", - "lsslp" => "$vers", - "switchdiscover" => "$vers", - "rflash" => "$vers", - "renergy" => "$vers", - "lsflexnode" => "$vers", - "mkflexnode" => "$vers", - "rmflexnode" => "$vers", - "nodeset" => "$vers", - "lsve" => "$vers", - "cfgve" => "$vers", - "chhypervisor" => "$vers", - "rmhypervisor" => "$vers", - "clonevm" => "$vers", -); - -#-------------------------------------------------------------------------------- -=head3 getUsage - It returns the usage string for the given command. - Arguments: - command - Returns: - the usage string for the command. -=cut -#------------------------------------------------------------------------------- -sub getUsage { - my ($class, $command)=@_; - if (exists($usage{$command})) { return $usage{$command};} - else { return "Usage for command $command cannot be found\n"; } -} - -#-------------------------------------------------------------------------------- -=head3 getVersion - It returns the version string for the given command. - Arguments: - command - Returns: - the version string for the command. -=cut -#------------------------------------------------------------------------------- -sub getVersion { - my ($class, $command)=@_; - if (exists($version{$command})) { return $version{$command};} - else { return "Version string for command $command cannot be found\n"; } -} - -#-------------------------------------------------------------------------------- -=head3 parseCommand - This function parses the given command to see if the usage or version string - need to be returned. - Arguments: - command - arguments - Returns: - the usage or the version string for the command. The caller need to display the - string and then exit. - none, if no usage or version strings are needed. The caller can keep going. -=cut -#------------------------------------------------------------------------------- -sub parseCommand { - my $command=shift; - if ($command =~ /xCAT::Usage/) { $command=shift; } - my @exargs=@_; - - @ARGV=@exargs; - - #print "command=$command, args=@exargs, ARGV=@ARGV\n"; - - Getopt::Long::Configure('pass_through','no_ignore_case'); - - # parse the options - if(!GetOptions( - 'h|help' => \$::HELP, - 'v|version' => \$::VERSION)) { - - return ""; - } - - if ($::HELP) { return xCAT::Usage->getUsage($command); } - if ($::VERSION) { return xCAT::Usage->getVersion($command); } - - return ""; -} - diff --git a/xCAT-client/bin/genimage b/xCAT-client/bin/genimage index 2e00040b0..e69de29bb 100755 --- a/xCAT-client/bin/genimage +++ b/xCAT-client/bin/genimage @@ -1,460 +0,0 @@ -#!/usr/bin/perl -BEGIN -{ - $::XCATROOT = - $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} - : -d '/opt/xcat' ? '/opt/xcat' - : '/usr'; -} -use lib "$::XCATROOT/lib/perl"; -use strict; - -use Getopt::Long; -require xCAT::MsgUtils; -require xCAT::DSHCLI; -require xCAT::Client; - -use xCAT::Utils; -use xCAT::TableUtils; -use File::Basename; - -$::XCATROOT = "/opt/xcat"; -my $os = ""; -my $profile = ""; -my $interface = ""; -my $version; -my $drivers = ""; -my $otherInterfaces = ""; -my $kernel = ""; -my @oses; # available OSes. -my @profiles; # available profiles -my $profDir; # root where you do ./genimage from -my $help; -my $match = 0; -my $imagename; -my $arch; -my $permission; -my $rootlimit; -my $tmplimit; -my $krpmver; -my $kerneldir; -my $mode; -my $interactive; -my $onlyinitrd; -my $dryrun; -my $ignorekernelchk; -my $noupdate; -#----------------------------------------------------------------------------- - -=head3 print_usage - usage message - -=cut - -#----------------------------------------------------------------------------- -sub print_usage -{ - print "Usage:\n"; - print " genimage\n\n"; - print " genimage --dryrun\n\n"; - print ' genimage -o [-a ] -p -i -n [--onlyinitrd] [-r ] [-k ] [-g ] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission ] [--interactive] [--dryrun] [--noupdate]'."\n\n"; - print ' genimage [-o ] [-a ] [-p ] [-i ] [-n ] [--onlyinitrd] [-r ] [-k ] [-g ] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission ] [--interactive] [--dryrun] [--noupdate] '."\n\n"; - print " --permission is used for statelite only\n"; - print " -g is used for SLES only\n\n"; - print " -m is used for urbuntu, debian and fedora12 only\n\n"; - print "Examples:\n"; - print " genimage\n"; - print " genimage --interactive\n"; - print " genimage -i eth0 -n tg3 -o sles11 -p compute\n"; - print " genimage -i eth0 -n tg3 -o sles11 -p compute --onlyinitrd\n"; - print " genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute --interactive\n"; - print " genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute --dryrun\n"; - print " genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777\n"; - print " genimage -i eth0 -n tg3 --interactive myimagename\n"; - print " genimage myimagename\n"; -} - -if (!GetOptions( - 'a=s' => \$arch, - 'p=s' => \$profile, - 'o=s' => \$os, - 'n=s' => \$drivers, - 'i=s' => \$interface, - 'r=s' => \$otherInterfaces, - 'l=s' => \$rootlimit, - 't=s' => \$tmplimit, - 'k=s' => \$kernel, - 'g=s' => \$krpmver, - 'm=s' => \$mode, - 'permission=s' => \$permission, - 'kerneldir=s' => \$kerneldir, - 'interactive' => \$interactive, - 'onlyinitrd' => \$onlyinitrd, - 'dryrun' => \$dryrun, - 'ignorekernelchk' => \$ignorekernelchk, - 'noupdate' => \$noupdate, - 'h|help' => \$help, - 'v|version' => \$version, -)) { - &print_usage; - exit 1; -} - -if($help){ - &print_usage; - exit 0; -} - -if ($version){ - my $version = xCAT::Utils->Version(); - xCAT::MsgUtils->message("N", $version); - exit 0; - -} -if (@ARGV > 0) { - $imagename=$ARGV[0]; -} - -if ((!$imagename) && (!$profile) && (!$os) && (!$arch)) { - my $tmpimgs=`lsdef -t osimage -w provmethod=~'/statelite|netboot/' |cut -d' ' -f1`; - if ($? == 0) { - if (($tmpimgs) && ($tmpimgs !~ /^Could/)) { #Could is returned when the osimage table is empty - my @images=split('\n', $tmpimgs); - print "Do you want to re-generate an existing image from the osimage table? "; - print "[y/n] "; - my $conf = ; - chomp($conf); - if($conf ne "" && $conf !~/N|n|[Nn][Oo]/) { - $match = 0; - while(1){ - print "Available images: \n"; - foreach(sort @images){ - print " $_\n"; - } - # default is the first image - print "Which image do you want to re-generate? ["; - print $images[0]; - print "] "; - - my $img = ; - chomp($img); - if($img eq ""){ - $imagename = $images[0]; - last; - } - foreach(@images){ - if($img eq $_){ - $imagename=$img; - $match = 1; - } - } - if ($match) { - last; - } else { - print "$img is not found in the osimage table.\n"; - } - } - } - } - } -} - - -# get the install directory -my @entries = xCAT::TableUtils->get_site_attribute("installdir"); -my $installdir = $entries[0]; -chomp($installdir); -# lots of error checking to make sure it exists. -if($installdir eq ''){ - print "Could not get install directory from site table. Assuming your OSes are stored in '/install'\n"; - $installdir = "/install"; -} - -unless(-d $installdir){ - print "The directory where your OS distributions resides: $installdir does not exist. Please check site table\n"; - exit 1; -} - -if ((!$imagename) && (!$os)){ - my @dircontents = `ls $installdir`; - chomp(@dircontents); - foreach (@dircontents) { - # SL matches Scientific Linux, sl matches sles amd sled - if($_ =~ /(rhel|fedora|SL|centos|sl|suse)/){ - push @oses,$_; - } - } - - if($#oses eq -1){ - print "There are no OS repositories in $installdir. Please run copycds for the OS first.\n"; - exit 1; - } - - # now they have the OSes, make sure they select one that is available - $match = 0; - while(1){ - print "Available OSes: \n"; - foreach(@oses){ - print " $_\n"; - } - # default is the first OS cause in many cases, they'll only have 1. - print "Which OS do you want to build a image for? ["; - print $oses[0] ; - print "] "; - - $os = ; - chomp($os); - if($os eq ""){ - $os = $oses[0]; - last; - } - foreach(@oses){ - if($os eq $_){ - $match = 1; - } - } - - if($match){ - last; - }else{ - print "$os is not found in '$installdir'\n"; - } - } - - chomp($os); -} -if ($os) { print " OS: $os\n"; } - - - -### Get the Profile #### -my $osfamily = $os; -$osfamily =~ s/\d+//g; -$osfamily =~ s/\.//g; -if($osfamily =~ /rh/){ - $osfamily = "rh"; -} - -# OS version on s390x can contain 'sp', e.g. sles11sp1 -# If the $osfamily contains 'sles' and 'sp', the $osfamily = sles -if ($osfamily =~ /sles/ && $osfamily =~ /sp/) { - $osfamily = "sles"; -} - -#print "OSfamily: $osfamily\n"; -$profDir = "$::XCATROOT/share/xcat/netboot/$osfamily"; -unless(-d $profDir){ - print "Unable to find genimage script in $profDir\n"; - exit 1; -} - -if ((!$imagename) && (!$profile)){ - my $profDir2 = "$installdir/custom/netboot/$osfamily"; - my @proList = `ls $profDir/*.pkglist`; - if (-d $profDir2) { - @proList = (@proList, `ls $profDir2/*.pkglist`); - } - my %seen = (); - foreach (@proList) { - my $f = basename($_); - $f =~ s/([^\.]*).*/$1/; - chomp($f); - $seen{$f}++; - } - @profiles = sort keys %seen; - if($#profiles eq -1){ - print "There are no profiles in $::XCATROOT/share/xcat/netboot/$osfamily.\n"; - exit 1; - } - $match = 0; - while(1){ - print "Available Profiles for $os: \n"; - foreach(@profiles){ - print " $_\n"; - } - # default is the first OS cause in many cases, they'll only have 1. - print "Which profile do you want to use for $os? ["; - print "$profiles[0] "; - print "] "; - - $profile = ; - chomp($profile); - if($profile eq ""){ - $profile = $profiles[0]; - last; - } - foreach(@profiles){ - if($profile eq $_){ - $match = 1; - } - } - if($match eq 1){ - last; - } - } -} -if ($profile) { print " Profile: $profile\n"; } - -# get the interface -if ((!$imagename) && (!$interface)){ - while(1){ - print "OPTIONAL: Which specific network interface will the image boot from? []"; - $interface = ; - chomp($interface); - if($interface eq ""){ - last; - }else{ - print "You want your stateless machines to boot off of "; - print "$interface"; - print "? "; - print "[Y/n] "; - my $conf = ; - chomp($conf); - if($conf eq ""){ - last; - } - if($conf =~ /Y|y|[Yy][Ee][Ss]/){ - last; - } - } - } - if ($interface) { print " Interface: $interface\n"; } - else { print " No interface specified. The interface will be determined at network boot time.\n"; } -} - - - -print "Generating image: \n"; -my @arg; -if ($imagename) { - push @arg, "$imagename"; -} - -if ($interface) { - push @arg, "-i"; - push @arg, "$interface"; -} -if ($drivers) { - push @arg, "-n"; - push @arg, "$drivers"; -} -if ($os) { - push @arg, "-o"; - push @arg, "$os"; -} -if ($profile) { - push @arg, "-p"; - push @arg, "$profile"; -} -if ($arch) { - push @arg, "-a"; - push @arg, "$arch"; -} - -if ($kernel) { - push @arg, "-k"; - push @arg, "$kernel"; -} - -if($otherInterfaces){ - push @arg, "-r"; - push @arg, "$otherInterfaces"; -} - -if ($permission) { - push @arg, "--permission"; - push @arg, "$permission"; -} - -if ($rootlimit) { - push @arg, "-l"; - push @arg, "$rootlimit"; -} - -if($tmplimit) { - push @arg, "-t"; - push @arg, "$tmplimit"; -} - -if ($krpmver) { - push @arg, "-g"; - push @arg, "$krpmver"; -} - -if ($mode) { - push @arg, "-m"; - push @arg, "$mode"; -} - -if ($kerneldir) { - push @arg, "--kerneldir"; - push @arg, "$kerneldir"; -} - -my $tempfile="/tmp/xcat_genimage.$$"; -push @arg, "--tempfile"; #this is the file that contains the output -push @arg, "$tempfile"; - -if ($interactive) { - push @arg, "--interactive"; -} - - -if ($onlyinitrd) { - push @arg, "--onlyinitrd"; -} - -if ($dryrun) { - push @arg, "--dryrun"; -} - -if ($ignorekernelchk) { - push @arg, "--ignorekernelchk"; -} - -if ($noupdate) { - push @arg, "--noupdate"; -} - -my $cmdref; -push (@{$cmdref->{arg}}, @arg); -$cmdref->{command}->[0] = "genimage"; - -if (!$interactive) { - xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response); - exit $xCAT::Client::EXITCODE; -} else { - if ($dryrun) { exit 0; } - #when in interactive mode, first call genimage.pm get info from DB, - xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response); - - #then call the specific genimage under /opt/xcat/share... - if (-f $tempfile) { - my $cmdname; - #read the command name - open(FILE1, "<$tempfile"); - my @output = ; - if (@output >0) { - $cmdname=$output[0]; - } else { - close FILE1; - return 1; - } - close FILE1; - - # run the specific genimage command - #print "cmdname=$cmdname\n"; - system("$cmdname"); - - #then call genimage.pm to save the DB - my @arg1; - push @arg1, $tempfile; - my $request; - push (@{$request->{arg}}, @arg1); - $request->{command}->[0] = "saveimgdata"; - xCAT::Client::submit_request($request, \&xCAT::Client::handle_response); - exit $xCAT::Client::EXITCODE; - } else { - exit 1; - } -} - diff --git a/xCAT-server/lib/xcat/plugins/imgcapture.pm b/xCAT-server/lib/xcat/plugins/imgcapture.pm old mode 100644 new mode 100755 index 5a2ff9946..e69de29bb --- a/xCAT-server/lib/xcat/plugins/imgcapture.pm +++ b/xCAT-server/lib/xcat/plugins/imgcapture.pm @@ -1,846 +0,0 @@ -#!/usr/bin/perl -# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html - -package xCAT_plugin::imgcapture; - -BEGIN -{ - $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; -} - -use lib "$::XCATROOT/lib/perl"; - -use strict; - -use Data::Dumper; # for debug purpose -use Getopt::Long; -use xCAT::MsgUtils; -use xCAT::Utils; -use xCAT::TableUtils; -use xCAT::SvrUtils; -use xCAT::Table; -use File::Path qw(mkpath); - -Getopt::Long::Configure("bundling"); -Getopt::Long::Configure("pass_through"); - -my $verbose = 0; -my $installroot = "/install"; -my $sysclone_home = $installroot . "/sysclone"; - -sub handled_commands { - return { "imgcapture" => "imgcapture" }; -} - -sub process_request { - my $request = shift; - my $callback = shift; - my $doreq = shift; - - my $node; - if (exists $request->{node}) { - $node = $request->{node}->[0]; - } - - $installroot = xCAT::TableUtils->getInstallDir(); - @ARGV = @{$request->{arg}} if (defined $request->{arg}); - my $argc = scalar @ARGV; - - my $usage = "Usage: imgcapture -t|--type diskless [-p | --profile ] [-o|--osimage ] [-i ] [-n ] [-d | --device ] [-V | --verbose] \n imgcapture -t|--type sysclone -o|--osimage [-V | --verbose] \n imgcapture [-h|--help] \n imgcapture [-v|--version]"; - - my $os; - my $arch; - my $device; - my $profile; - my $bootif; - my $netdriver; - my $osimg; - my $help; - my $version; - my $type; - - GetOptions( - "profile|p=s" => \$profile, - "i=s" => \$bootif, - 'n=s' => \$netdriver, - 'osimage|o=s' => \$osimg, - "device|d=s" => \$device, - "help|h" => \$help, - "version|v" => \$version, - "verbose|V" => \$verbose, - "type|t=s" => \$type - ); - - if ( defined( $ARGV[0] )) { - my $rsp = {}; - $rsp->{data}->[0] = "Invalid Argument: $ARGV[0]"; - $rsp->{data}->[1] = $usage; - xCAT::MsgUtils->message("D", $rsp, $callback); - return 0; - } - - if($version) { - my $version = xCAT::Utils->Version(); - my $rsp = {}; - $rsp->{data}->[0] = $version; - xCAT::MsgUtils->message("D", $rsp, $callback); - return 0; - } - - if($help) { - my $rsp = {}; - $rsp->{data}->[0] = $usage; - xCAT::MsgUtils->message("D", $rsp, $callback); - return 0; - } - - if( ! $node ) { - my $rsp = {}; - $rsp->{data}->[0] = $usage; - xCAT::MsgUtils->message("D", $rsp, $callback); - return 0; - } - - if(($type =~ /sysclone/) && (!$osimg)){ - my $rsp = {}; - push @{$rsp->{data}}, "You must specify osimage name if you are using \"sysclone\"."; - push @{$rsp->{data}}, $usage; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - my $nodetypetab = xCAT::Table->new("nodetype"); - my $ref_nodetype = $nodetypetab->getNodeAttribs($node, ['os','arch','profile']); - $os = $ref_nodetype->{os}; - $arch = $ref_nodetype->{arch}; - unless($profile) { - $profile = $ref_nodetype->{profile}; - } - - # sysclone - unless($type =~ /diskless/) - { - # Handle image capture separately for s390x - if ($arch eq 's390x') { - eval { require xCAT_plugin::zvm; }; # Load z/VM plugin dynamically - xCAT_plugin::zvm->imageCapture($callback, $node, $os, $arch, $profile, $osimg, $device); - return; - } - - my $shortname = xCAT::InstUtils->myxCATname(); - - my $rc; - $rc = sysclone_configserver($shortname, $osimg, $callback, $doreq); - if($rc){ - my $rsp = {}; - $rsp->{data}->[0] = qq{Can not configure Imager Server on $shortname.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - $rc = sysclone_prepclient($node, $shortname, $osimg, $callback, $doreq); - if($rc){ - my $rsp = {}; - $rsp->{data}->[0] = qq{Can not prepare Golden Client on $node.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - $rc = sysclone_getimg($node, $shortname, $osimg, $callback, $doreq); - if($rc){ - my $rsp = {}; - $rsp->{data}->[0] = qq{Can not get image $osimg from $node.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - $rc = sysclone_createosimgdef($node, $shortname, $osimg, $callback, $doreq); - if($rc){ - my $rsp = {}; - $rsp->{data}->[0] = qq{Can not create osimage definition for $osimg on $shortname.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - return; - } - - # -i flag is required with sles genimage - if (!$bootif && $os =~ /^sles/) { - $bootif = "eth0"; - } - - # check whether the osimage exists or not - if($osimg) { - my $osimgtab=xCAT::Table->new('osimage', -create=>1); - unless($osimgtab) { - # the osimage table doesn't exist - my $rsp = {}; - $rsp->{data}->[0] = qq{Cannot open the osimage table}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - my $linuximgtab = xCAT::Table->new('linuximage', -create=>1); - unless($linuximgtab) { - # the linuximage table doesn't exist - my $rsp = {}; - $rsp->{data}->[0] = qq{Cannot open the linuximage table}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - my ($ref) = $osimgtab->getAttribs({imagename => $osimg}, 'osvers', 'osarch', 'profile'); - unless($ref) { - my $rsp = {}; - $rsp->{data}->[0] = qq{Cannot find $osimg from the osimage table.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - my ($ref1) = $linuximgtab->getAttribs({imagename => $osimg}, 'imagename'); - unless($ref1) { - my $rsp = {}; - $rsp->{data}->[0] = qq{Cannot find $osimg from the linuximage table}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - # make sure the "osvers" and "osarch" attributes match the node's attribute - unless($os eq $ref->{'osvers'} and $arch eq $ref->{'osarch'}) { - my $rsp = {}; - $rsp->{data}->[0] = qq{The 'osvers' or 'osarch' attribute of the "$osimg" table doesn't match the node's attribute}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - } - - imgcapture($node, $os, $arch, $profile, $osimg, $bootif, $netdriver, $callback, $doreq); -} - -sub imgcapture { - my ($node, $os, $arch, $profile, $osimg, $bootif, $netdriver, $callback, $subreq) = @_; - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = "nodename is $node; os is $os; arch is $arch; profile is $profile"; - $rsp->{data}->[1] = "bootif is $bootif; netdriver is $netdriver"; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - # make sure the "/" partion is on the disk, - my $output = xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg =>["stat / -f |grep Type"]}, $subreq, -1, 1); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{the output of "stat / -f |grep Type" on $node is:}; - foreach my $o (@$output) { - push @{$rsp->{data}}, $o; - } - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC) { #failed - my $rsp = {}; - $rsp->{data}->[0] = qq{The "xdsh" command fails to run on the $node}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - # parse the output of "stat / -f |grep Type", - $output->[0] =~ m/Type:\s+(.*)$/; - my $fstype = $1; - if ($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{The file type is $fstype}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - # make sure the rootfs type is not nfs or tmpfs - if($fstype eq "nfs" or $fstype eq "tmpfs") { - my $rsp = {}; - $rsp->{data}->[0] = qq{This node might not be diskful Linux node, please check it.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - my $distname = $os; - while ( $distname and ( ! -r "$::XCATROOT/share/xcat/netboot/$distname/") ) { - chop($distname); - } - - unless($distname) { - $callback->({error=>["Unable to find $::XCATROOT/share/xcat/netboot directory for $os"], errorcode => [1]}); - return; - } - - my $exlistloc = xCAT::SvrUtils->get_imgcapture_exlist_file_name("$installroot/custom/netboot/$distname", $profile, $os, $arch); - unless ($exlistloc) { - $exlistloc = xCAT::SvrUtils->get_imgcapture_exlist_file_name("$::XCATROOT/share/xcat/netboot/$distname", $profile, $os, $arch); - } - - my $xcat_imgcapture_tmpfile = "/tmp/xcat_imgcapture.$$"; - - my $excludestr = "cd /; find ."; - - if($exlistloc) { - my $exlist; - open $exlist, "<", $exlistloc; - - while(<$exlist>) { - $_ =~ s/^\s+//; - chomp $_; - unless($_ =~ m{^#}) { - $excludestr .= qq{ ! -path "$_"}; - } - } - - close $exlist; - } else { - # the following directories must be exluded when capturing the image - my @default_exlist = ("./tmp/*", "./proc/*", "./sys/*", "./dev/*", "./xcatpost/*", "./install/*"); - foreach my $item (@default_exlist) { - $excludestr .= qq{ ! -path "$item"}; - } - } - - $excludestr .= " |cpio -H newc -o |gzip -c - >$xcat_imgcapture_tmpfile"; - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{The excludestr is "$excludestr"}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - # run the command via "xdsh" - - xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg => ["echo -n >$xcat_imgcapture_tmpfile"]}, $subreq, -1, 1); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{running "echo -n > $xcat_imgcapture_tmpfile" on $node}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC) { # the xdsh command fails - my $rsp = {}; - $rsp->{data}->[0] = qq{The "xdsh" command fails to run "echo -n > $xcat_imgcapture_tmpfile" on $node}; - xCAT:MsgUtils->message("E", $rsp, $callback); - return; - } - - my $rsp = {}; - $rsp->{data}->[0] = qq{Capturing image on $node...}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{running "$excludestr" on $node via the "xdsh" command}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg => [$excludestr]}, $subreq, -1, 1); - - if($::RUNCMD_RC) { # the xdsh command fails - my $rsp = {}; - $rsp->{data}->[0] = qq{The "xdsh" command fails to run "$excludestr" on $node}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - $rsp = {}; - $rsp->{data}->[0] = qq{Transfering the image captured on $node back...}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - # copy the image captured on $node back via the "scp" command - xCAT::Utils->runcmd("scp $node:$xcat_imgcapture_tmpfile $xcat_imgcapture_tmpfile"); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{Running "scp $node:$xcat_imgcapture_tmpfile $xcat_imgcapture_tmpfile"}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC) { - my $rsp ={}; - $rsp->{data}->[0] = qq{The scp command fails}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - xCAT::Utils->runxcmd({command => ["xdsh" ], node => [$node], arg => ["rm -f $xcat_imgcapture_tmpfile"]}, $subreq, -1, 1); - - # extract the $xcat_imgcapture_tmpfile file to /install/netboot/$os/$arch/$profile/rootimg - my $rootimgdir = "$installroot/netboot/$os/$arch/$profile/rootimg"; - - # empty the rootimg directory before extracting the image captured on the diskful Linux node - if( -d $rootimgdir ) { - unlink $rootimgdir; - } - mkpath($rootimgdir); - - xCAT::Utils->runcmd("cd $rootimgdir; gzip -cd $xcat_imgcapture_tmpfile|cpio -idum"); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{Extracting the image to $rootimgdir}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - if($::RUNCMD_RC) { - my $rsp = {}; - $rsp->{data}->[0] = qq{fails to run the "gzip -cd xx |cpio -idum" command}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{Creating the spots exluded when capturing on $node...}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - # the next step is to call "genimage" - my $platform = getplatform($os); - if( -e "$::XCATROOT/share/xcat/netboot/$platform/genimage" ) { - my $cmd; - - if( $osimg ) { - $cmd = "$::XCATROOT/bin/genimage $osimg "; - } else { - $cmd = "$::XCATROOT/share/xcat/netboot/$platform/genimage -o $os -a $arch -p $profile "; - } - - if($bootif) { - $cmd .= "-i $bootif "; - } - if($netdriver) { - $cmd .= "-n $netdriver"; - } - - my $rsp = {}; - $rsp->{data}->[0] = qq{Generating kernel and initial ramdisks...}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{"The genimage command is: $cmd"}; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - my @cmdoutput = xCAT::Utils->runcmd($cmd, 0); - if($::RUNCMD_RC) { - my $rsp = {}; - foreach (@cmdoutput) { - push @{$rsp->{data}}, $_; - } - xCAT::MsgUtils->message("E", $rsp, $callback); - unlink $xcat_imgcapture_tmpfile; - return; - } - } else { - my $rsp = {}; - $rsp->{data}->[0] = qq{Can't run the "genimage" command for $os}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return; - } - - my $rsp = {}; - $rsp->{data}->[0] = qq{Done.}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - unlink $xcat_imgcapture_tmpfile; - - return 0; -} - -sub getplatform { - my $os = shift; - my $platform; - if ($os =~ m/rh.*/) { - $platform = "rh"; - } elsif ($os =~ m/centos.*/) { - $platform = "centos"; - } elsif ($os =~ m/fedora.*/) { - $platform = "fedora"; - } elsif ($os =~ m/SL.*/) { - $platform = "SL"; - } elsif ($os =~ m/sles.*/) { - $platform = "sles"; - } elsif ($os =~ m/suse.*/) { - $platform = "suse"; - } - - return $platform; -} - -sub sysclone_configserver{ - my ($server, $osimage, $callback, $subreq) = @_; - - # check if systemimager is installed on the imager server - my $rsp = {}; - $rsp->{data}->[0] = qq{Checking if systemimager packages are installed on $server.}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - my $cmd = "rpm -qa|grep systemimager-server"; - my $output = xCAT::Utils->runcmd("$cmd", -1); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{the output of $cmd on $server is:}; - push @{$rsp->{data}}, $output; - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC != 0) { #failed - my $rsp = {}; - $rsp->{data}->[0] = qq{systemimager-server is not installed on the $server.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - # update /etc/systemimager/systemimager.conf - my $rc = `sed -i "s/\\/var\\/lib\\/systemimager/\\/install\\/sysclone/g" /etc/systemimager/systemimager.conf`; - if (!(-e $sysclone_home)) - { - mkpath($sysclone_home); - } - - my $sysclone_images = $sysclone_home . "/images"; - if (!(-e $sysclone_images)) - { - mkpath($sysclone_images); - } - - my $sysclone_scripts = $sysclone_home . "/scripts"; - if (!(-e $sysclone_scripts)) - { - mkpath($sysclone_scripts); - } - - my $sysclone_overrides = $sysclone_home . "/overrides"; - if (!(-e $sysclone_overrides)) - { - mkpath($sysclone_overrides); - } - - my $imagedir; - my $osimgtab = xCAT::Table->new('osimage'); - my $entry = ($osimgtab->getAllAttribsWhere("imagename = '$osimage'", 'ALL' ))[0]; - if(!$entry){ - $imagedir = $sysclone_home . "/images/" . $osimage; - }else{ - my $osimagetab = xCAT::Table->new('linuximage'); - my $osimageentry = $osimagetab->getAttribs({imagename => $osimage}, 'rootimgdir'); - if($osimageentry){ - $imagedir = $osimageentry->{rootimgdir}; - if (!(-e $imagedir)){ - mkpath($imagedir); - } - }else{ - $imagedir = $sysclone_home . "/images/" . $osimage; - $cmd = "chdef -t osimage $osimage rootimgdir=$imagedir"; - $rc = `$cmd`; - } - } - - $imagedir =~ s/^(\/.*)\/.+\/?$/$1/; - $imagedir =~ s/\//\\\\\//g; - $imagedir = "DEFAULT_IMAGE_DIR = ".$imagedir; - - my $olddir = `more /etc/systemimager/systemimager.conf |grep DEFAULT_IMAGE_DIR`; - $olddir =~ s/\//\\\\\//g; - chomp($olddir); - - $cmd= "sed -i \"s/$olddir/$imagedir/\" /etc/systemimager/systemimager.conf"; - $rc = `$cmd`; - - # update /etc/systemimager/rsync_stubs/10header to generate new /etc/systemimager/rsyncd.conf - $rc = `sed -i "s/\\/var\\/lib\\/systemimager/\\/install\\/sysclone/g" /etc/systemimager/rsync_stubs/10header`; - $rc = `export PERL5LIB=/usr/lib/perl5/site_perl/;LANG=C si_mkrsyncd_conf`; - - return 0; -} - -sub sysclone_prepclient { - my ($node, $server, $osimage, $callback, $subreq) = @_; - - # check if systemimager is installed on the golden client - my $rsp = {}; - $rsp->{data}->[0] = qq{Checking if systemimager packages are installed on $node.}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - my $cmd = "rpm -qa|grep systemimager-client"; - my $output = xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg =>[$cmd]}, $subreq, 0, 1); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{the output of $cmd on $node is:}; - foreach my $o (@$output) { - push @{$rsp->{data}}, $o; - } - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC != 0) { #failed - my $rsp = {}; - $rsp->{data}->[0] = qq{systemimager-client is not installed on the $node.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - # prepare golden client - my $rsp = {}; - $rsp->{data}->[0] = qq{Preparing osimage $osimage on $node.}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - my $cmd = "export PERL5LIB=/usr/lib/perl5/site_perl/;LANG=C si_prepareclient --server $server --no-uyok --yes"; - my $output = xCAT::Utils->runxcmd( - { - command => ["xdsh"], - node => [$node], - arg =>["-s", $cmd] - }, - $subreq, 0, 1); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{the output of $cmd on $node is:}; - foreach my $o (@$output) { - push @{$rsp->{data}}, $o; - } - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC != 0) { #failed - my $rsp = {}; - $rsp->{data}->[0] = qq{$cmd failed on the $node.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - # fix systemimager bug - $cmd = qq{sed -i 's/p_name=\"(v1)\"/p_name=\"-\"/' /etc/systemimager/autoinstallscript.conf}; - $output = xCAT::Utils->runxcmd( - { - command => ["xdsh"], - node => [$node], - arg =>[$cmd] - }, - $subreq, 0, 1); - - my @nodes = ($node); - my $nodetypetab = xCAT::Table->new("nodetype"); - my $nthash = $nodetypetab->getNodesAttribs(\@nodes, ['arch']); - my $tmp = $nthash->{$node}->[0]->{arch}; - if ( $tmp eq 'ppc64'){ - $cmd = qq(if ! cat /etc/systemimager/autoinstallscript.conf |grep 'part num=\\\"1\\\"' |grep 'id=' >/dev/null ;then sed -i 's:\\(.*\\):\\1 id=\\\"41\\\" \\2:' /etc/systemimager/autoinstallscript.conf;fi); - $output = xCAT::Utils->runxcmd( - { - command => ["xdsh"], - node => [$node], - arg =>[$cmd] - }, - $subreq, 0, 1); - } - - return 0; -} - -sub sysclone_getimg{ - my ($node, $server, $osimage, $callback, $subreq) = @_; - - my $rsp = {}; - $rsp->{data}->[0] = qq{Getting osimage "$osimage" from $node to $server.}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - my $cmd = "export PERL5LIB=/usr/lib/perl5/site_perl/;"; - $cmd .= "LANG=C si_getimage -golden-client $node -image $osimage -ip-assignment dhcp -post-install reboot -quiet -update-script YES"; - my $output = xCAT::Utils->runcmd($cmd, -1); - if($verbose) { - my $rsp = {}; - $rsp->{data}->[0] = qq{the output of $cmd on $server is:}; - if(ref $output){ - foreach my $o (@$output) { - push @{$rsp->{data}}, $o; - } - } else { - @{$rsp->{data}} = ($output); - } - xCAT::MsgUtils->message("D", $rsp, $callback); - } - - if($::RUNCMD_RC != 0) { #failed - my $rsp = {}; - $rsp->{data}->[0] = qq{$cmd failed on the $server.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - # use reboot in genesis - my $masterscript = $sysclone_home . "/scripts" . "/$osimage.master"; - my $rc = `sed -i "s/shutdown -r now/reboot -f/g" $masterscript`; - - #on redhat5 and centos5, the fs inode size must be 128 - my $node_osver = getOsVersion($node); - if ( $node_osver =~ /rh.*5.*/ || $node_osver =~ /centos5.*/ ) { - `sed -i "s/mke2fs/mke2fs -I 128/g" $masterscript` - } - return 0; -} - -sub sysclone_createosimgdef{ - my ($node, $server, $osimage, $callback, $subreq) = @_; - my $createnew = 0; - my %osimgdef; - - my $osimgtab = xCAT::Table->new('osimage'); - my $entry = ($osimgtab->getAllAttribsWhere("imagename = '$osimage'", 'ALL' ))[0]; - if($entry){ - my $rsp = {}; - $rsp->{data}->[0] = qq{Using the existing osimage "$osimage" defined on $server.}; - xCAT::MsgUtils->message("I", $rsp, $callback); - return 0; - } - - # try to see if we can get the osimage def from golden client. - my $nttab = xCAT::Table->new('nodetype'); - if (!$nttab){ - my $rsp = {}; - $rsp->{data}->[0] = qq{Can not open nodebype table.}; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - my @nodes = ($node); - my $nthash = $nttab->getNodesAttribs(\@nodes, ['node', 'provmethod']); - my $tmp = $nthash->{$node}->[0]; - if (($tmp) && ($tmp->{provmethod})){ - - my %objtype; - my $oldimg = $tmp->{provmethod}; - - # see if osimage exists - $objtype{$oldimg} = 'osimage'; - my %imagedef = xCAT::DBobjUtils->getobjdefs(\%objtype, $callback); - if (!($imagedef{$oldimg}{osvers})){ # just select one attribute for test - # create new one - $createnew = 1; - }else{ - # based on the existing one - $osimgdef{$osimage} = $imagedef{$oldimg}; - - # only update a few attributes which are meanless for sysclone - $osimgdef{$osimage}{provmethod} = "sysclone"; - $osimgdef{$osimage}{template} = ""; - $osimgdef{$osimage}{otherpkglist} = ""; - $osimgdef{$osimage}{pkglist} = ""; - - if(!($imagedef{$oldimg}{rootimgdir})){ - $imagedef{$oldimg}{rootimgdir} = $sysclone_home . "/images/" . $osimage; - - my $imagedir = $imagedef{$oldimg}{rootimgdir}; - $imagedir =~ s/^(\/.*)\/.+\/?$/$1/; - $imagedir =~ s/\//\\\\\//g; - $imagedir = "DEFAULT_IMAGE_DIR = ".$imagedir; - - my $olddir = `more /etc/systemimager/systemimager.conf |grep DEFAULT_IMAGE_DIR`; - $olddir =~ s/\//\\\\\//g; - chomp($olddir); - - my $cmd= "sed -i \"s/$olddir/$imagedir/\" /etc/systemimager/systemimager.conf"; - my $rc = `$cmd`; - } - } - } else { - $createnew = 1; - } - - if($createnew){ - my $file = $sysclone_home . "/images/" . $osimage. "/etc/systemimager/boot/ARCH"; - my $cmd = "cat $file"; - my $output = xCAT::Utils->runcmd($cmd, -1); - chomp $output; - my $arch = $output; - my $osver = getOsVersion($node); - my $platform = getplatform($osver); - - # create a baic one - $osimgdef{$osimage}{objtype} = "osimage"; - $osimgdef{$osimage}{provmethod} = "sysclone"; - $osimgdef{$osimage}{profile} = "compute"; # use compute? - $osimgdef{$osimage}{imagetype} = "Linux"; - $osimgdef{$osimage}{osarch} = $arch; - $osimgdef{$osimage}{osname} = "Linux"; - $osimgdef{$osimage}{osvers} = $osver; - $osimgdef{$osimage}{osdistroname} = "$osver-$arch"; - - $osimgdef{$osimage}{rootimgdir} = $sysclone_home . "/images/" . $osimage; - my $imagedir = $osimgdef{$osimage}{rootimgdir}; - $imagedir =~ s/^(\/.*)\/.+\/?$/$1/; - $imagedir =~ s/\//\\\\\//g; - $imagedir = "DEFAULT_IMAGE_DIR = ".$imagedir; - my $olddir = `more /etc/systemimager/systemimager.conf |grep DEFAULT_IMAGE_DIR`; - $olddir =~ s/\//\\\\\//g; - chomp($olddir); - my $cmd= "sed -i \"s/$olddir/$imagedir/\" /etc/systemimager/systemimager.conf"; - my $rc = `$cmd`; - - #$osimgdef{$osimage}{pkgdir} = "/install/$osver/$arch"; - #$osimgdef{$osimage}{otherpkgdir} = "/install/post/otherpkgs/$osver/$arch"; - } - - if (xCAT::DBobjUtils->setobjdefs(\%osimgdef) != 0) - { - my $rsp; - $rsp->{data}->[0] = "Could not create xCAT definition for $osimage.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - my $rsp = {}; - $rsp->{data}->[0] = qq{The osimage definition for $osimage was created.}; - xCAT::MsgUtils->message("D", $rsp, $callback); - - return 0; -} - -sub getOsVersion { - my ($node) = @_; - - my $os = ''; - my $version = ''; - - # Get operating system - my $release = `ssh -o ConnectTimeout=2 $node "cat /etc/*release"`; - my @lines = split('\n', $release); - if (grep(/SLES|Enterprise Server/, @lines)) { - $os = 'sles'; - $version = $lines[0]; - $version =~ tr/\.//; - $version =~ s/[^0-9]*([0-9]+).*/$1/; - $os = $os . $version; - - # Append service level - $version = `echo "$release" | grep "LEVEL"`; - $version =~ tr/\.//; - $version =~ s/[^0-9]*([0-9]+).*/$1/; - $os = $os . 'sp' . $version; - } elsif (grep(/Red Hat/, @lines)) { - $os = "rh"; - $version = $lines[0]; - $version =~ s/[^0-9]*([0-9.]+).*/$1/; - if ($lines[0] =~ /AS/) { $os = 'rhas' } - elsif ($lines[0] =~ /ES/) { $os = 'rhes' } - elsif ($lines[0] =~ /WS/) { $os = 'rhws' } - elsif ($lines[0] =~ /Server/) { $os = 'rhels' } - elsif ($lines[0] =~ /Client/) { $os = 'rhel' } - #elsif (-f "/etc/fedora-release") { $os = 'rhfc' } - $os = $os . $version; - } - elsif (grep (/CentOS/, @lines)) { - $os = "centos"; - $version = $lines[0]; - $version =~ s/[^0-9]*([0-9.]+).*/$1/; - $os = $os . $version; - } - elsif (grep (/Fedora/, @lines)) { - $os = "fedora"; - $version = $lines[0]; - $version =~ s/[^0-9]*([0-9.]+).*/$1/; - $os = $os . $version; - } - - - return $os; -} -1; diff --git a/xCAT-server/lib/xcat/plugins/packimage.pm b/xCAT-server/lib/xcat/plugins/packimage.pm old mode 100644 new mode 100755 index 79e231270..e69de29bb --- a/xCAT-server/lib/xcat/plugins/packimage.pm +++ b/xCAT-server/lib/xcat/plugins/packimage.pm @@ -1,629 +0,0 @@ -package xCAT_plugin::packimage; -BEGIN -{ - $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; -} -use lib "$::XCATROOT/lib/perl"; -use Data::Dumper; -use xCAT::Table; -use Getopt::Long; -use File::Path; -use File::Copy; -use Cwd; -use File::Temp; -use File::Basename; -use File::Path; -#use xCAT::Utils qw(genpassword); -use xCAT::Utils; -use xCAT::TableUtils; -use xCAT::SvrUtils; -Getopt::Long::Configure("bundling"); -Getopt::Long::Configure("pass_through"); - - -my $verbose = 0; -#$verbose = 1; - -sub handled_commands { - return { - packimage => "packimage", - } -} - -sub process_request { - my $request = shift; - my $callback = shift; - my $doreq = shift; - my $installroot = xCAT::TableUtils->getInstallDir(); - - @ARGV = @{$request->{arg}}; - my $argc = scalar @ARGV; - if ($argc == 0) { - $callback->({info=>["packimage -h \npackimage -v \npackimage [-p profile] [-a architecture] [-o OS] [-m method]\npackimage imagename"]}); - return; - } - my $osver; - my $arch; - my $profile; - my $method='cpio'; - my $exlistloc; - my $syncfile; - my $rootimg_dir; - my $destdir; - my $imagename; - my $dotorrent; - - GetOptions( - "profile|p=s" => \$profile, - "arch|a=s" => \$arch, - "osver|o=s" => \$osver, - "method|m=s" => \$method, - "tracker=s" => \$dotorrent, - "help|h" => \$help, - "version|v" => \$version - ); - if ($version) { - my $version = xCAT::Utils->Version(); - $callback->({info=>[$version]}); - return; - } - if ($help) { - $callback->({info=>["packimage -h \npackimage -v \npackimage [-p profile] [-a architecture] [-o OS] [-m method]\npackimage imagename"]}); - return; - } - - if (@ARGV > 0) { - $imagename=$ARGV[0]; - if ($arch or $osver or $profile) { - $callback->({error=>["-o, -p and -a options are not allowed when a image name is specified."],errorcode=>[1]}); - return; - } - # load the module in memory - eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")}; - if ($@) { - $callback->({error=>[$@],errorcode=>[1]}); - return; - } - - # get the info from the osimage and linux - my $osimagetab=xCAT::Table->new('osimage', -create=>1); - unless ($osimagetab) { - $callback->({error=>["The osimage table cannot be opened."],errorcode=>[1]}); - return; - } - my $linuximagetab=xCAT::Table->new('linuximage', -create=>1); - unless ($linuximagetab) { - $callback->({error=>["The linuximage table cannot be opened."],errorcode=>[1]}); - return; - } - (my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod', 'synclists'); - unless ($ref) { - $callback->({error=>["Cannot find image \'$imagename\' from the osimage table."],errorcode=>[1]}); - return; - } - (my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'exlist', 'rootimgdir'); - unless ($ref1) { - $callback->({error=>["Cannot find $imagename from the linuximage table."],errorcode=>[1]}); - return; - } - - $osver=$ref->{'osvers'}; - $arch=$ref->{'osarch'}; - $profile=$ref->{'profile'}; - $syncfile=$ref->{'synclists'}; - my $provmethod=$ref->{'provmethod'}; - - unless ($osver and $arch and $profile and $provmethod) { - $callback->({error=>["osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database."],errorcode=>[1]}); - return; - } - - if ($provmethod ne 'netboot') { - $callback->({error=>["\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."],errorcode=>[1]}); - return; - } - - $exlistloc =$ref1->{'exlist'}; - $destdir=$ref1->{'rootimgdir'}; - } else { - $provmethod="netboot"; - unless ($osver) { - $callback->({error=>["Please specify a os version with the -o flag"],errorcode=>[1]}); - return; - } - unless ($arch) { - $arch = `uname -m`; - chomp($arch); - $arch = "x86" if ($arch =~ /i.86$/); - } - - unless ($profile) { - $callback->({error=>["Please specify a profile name with -p flag"],errorcode=>[1]}); - return; - } - } - - unless ($destdir) { - $destdir="$installroot/netboot/$osver/$arch/$profile"; - } - $rootimg_dir="$destdir/rootimg"; - - my $distname = $osver; - until (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) { - chop($distname); - } - unless ($distname) { - $callback->({error=>["Unable to find $::XCATROOT/share/xcat/netboot directory for $osver"],errorcode=>[1]}); - return; - } - unless ($installroot) { - $callback->({error=>["No installdir defined in site table"],errorcode=>[1]}); - return; - } - my $oldpath=cwd(); - unless ($imagename) { - $exlistloc=xCAT::SvrUtils->get_exlist_file_name("$installroot/custom/netboot/$distname", $profile, $osver, $arch); - unless ($exlistloc) { $exlistloc=xCAT::SvrUtils->get_exlist_file_name("$::XCATROOT/share/xcat/netboot/$distname", $profile, $osver, $arch); } - - #save the settings into DB, it will not update if the image already exist - my @ret = xCAT::SvrUtils->update_tables_with_diskless_image($osver, $arch, $profile, "netboot"); - unless ($ret[0] eq 0) { - $callback->({error=>["Error when updating the osimage tables: " . $ret[1]], errorcode=>[1]}); - return; - } - } - - #before generating rootimg.gz, copy $installroot/postscripts into the image at /xcatpost - if( -e "$rootimg_dir/xcatpost" ) { - system("rm -rf $rootimg_dir/xcatpost"); - } - - system("mkdir -p $rootimg_dir/xcatpost"); - system("cp -r $installroot/postscripts/* $rootimg_dir/xcatpost/"); - - #put the image name and timestamp into diskless image when it is packed. - `echo IMAGENAME="'$imagename'" > $rootimg_dir/opt/xcat/xcatinfo`; - - my $timestamp = `date`; - chomp $timestamp; - `echo TIMESTAMP="'$timestamp'" >> $rootimg_dir/opt/xcat/xcatinfo`; - - - # before generating rootimg.gz or rootimg.sfs, need to switch the rootimg to stateless mode if necessary - my $rootimg_status = 0; # 0 means stateless mode, while 1 means statelite mode - $rootimg_status = 1 if (-f "$rootimg_dir/.statelite/litefile.save"); - - my $ref_liteList; # get the litefile entries - - my @ret = xCAT::Utils->runcmd("ilitefile $osver-$arch-statelite-$profile" , 0, 1); - $ref_liteList = $ret[0]; - - my %liteHash; # create hash table for the entries in @listList - if (parseLiteFiles($ref_liteList, \%liteHash)) { - $callback->({error=>["Failed for parsing litefile table!"], errorcode=>[1]}); - return; - } - - $verbose && $callback->({data=>["rootimg_status = $rootimg_status at line " . __LINE__ ]}); - - if($rootimg_status) { - xCAT::Utils->runcmd("mkdir $rootimg_dir/.statebackup", 0, 1); - # read through the litefile table to decide which file/directory should be restore - my $defaultloc = "$rootimg_dir/.default"; - foreach my $entry (keys %liteHash) { - my @tmp = split /\s+/, $entry; - my $filename = $tmp[1]; - my $fileopt = $tmp[0]; - - if ($fileopt =~ m/link/) { - # backup them into .statebackup dirctory - # restore the files with "link" options - if ($filename =~ m/\/$/) { - chop $filename; - } - # create the parent directory if $filename's directory is not there, - my $parent = dirname $filename; - unless ( -d "$rootimg_dir/.statebackup$parent" ) { - unlink "$rootimg_dir/.statebackup$parent"; - $verbose && $callback->({data=>["mkdir -p $rootimg_dir/.statebackup$parent"]}); - xCAT::Utils->runcmd("mkdir -p $rootimg_dir/.statebackup$parent", 0, 1); - } - $verbose && $callback->({data=>["backing up the file $filename.. at line " . __LINE__ ]}); - $verbose && print "++ $defaultloc$filename ++ $rootimg_dir$filename ++ at " . __LINE__ . "\n"; - xCAT::Utils->runcmd("mv $rootimg_dir$filename $rootimg_dir/.statebackup$filename", 0, 1); - xCAT::Utils->runcmd("cp -r -a $defaultloc$filename $rootimg_dir$filename", 0, 1); - } - } - } - - # TODO: following the old genimage code, to update the stateles-only files/directories - # # another file should be /opt/xcat/xcatdsklspost, but it seems not necessary - xCAT::Utils->runcmd("mv $rootimg_dir/etc/init.d/statelite $rootimg_dir/.statebackup/statelite ", 0, 1) if ( -e "$rootimg_dir/etc/init.d/statelite"); - if ( -e "$rootimg_dir/usr/share/dracut" ) { - # currently only used for redhat families, not available for SuSE families - if ( -e "$rootimg_dir/etc/rc.sysinit.backup" ) { - xCAT::Utils->runcmd("mv $rootimg_dir/etc/rc.sysinit.backup $rootimg_dir/etc/rc.sysinit", 0, 1); - } - } - - #restore the install.netboot of xcat dracut module - if(-e "$rootimg_dir/usr/lib/dracut/modules.d/97xcat/install"){ - xCAT::Utils->runcmd("mv $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install $rootimg_dir/.statebackup/install", 0, 1); - } - xCAT::Utils->runcmd("cp /opt/xcat/share/xcat/netboot/rh/dracut_033/install.netboot $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install", 0, 1); - - - my $xcat_packimg_tmpfile = "/tmp/xcat_packimg.$$"; - my $excludestr = "find . -xdev "; - my $includestr; - if ($exlistloc) { - my @excludeslist = split ',', $exlistloc; - foreach my $exlistlocname ( @excludeslist ) { - my $exlist; - my $excludetext; - open($exlist,"<",$exlistlocname); - system("echo -n > $xcat_packimg_tmpfile"); - while (<$exlist>) { - $excludetext .= $_; - } - close($exlist); - - #handle the #INLCUDE# tag recursively - my $idir = dirname($exlistlocname); - my $doneincludes=0; - while (not $doneincludes) { - $doneincludes=1; - if ($excludetext =~ /#INCLUDE:[^#^\n]+#/) { - $doneincludes=0; - $excludetext =~ s/#INCLUDE:([^#^\n]+)#/include_file($1,$idir)/eg; - } - - } - - my @tmp=split("\n", $excludetext); - foreach (@tmp) { - chomp $_; - s/\s*#.*//; #-- remove comments - next if /^\s*$/; #-- skip empty lines - if (/^\+/) { - s/^\+//; #remove '+' - $includestr .= "-path '". $_ ."' -o "; - } else { - s/^\-//; #remove '-' if any - $excludestr .= "'!' -path '".$_."' -a "; - } - } - } - } - - # the files specified for statelite should be excluded - my @excludeStatelite = ("./etc/init.d/statelite", "./etc/rc.sysinit.backup", "./.statelite*", "./.default*", "./.statebackup*"); - foreach my $entry (@excludeStatelite) { - $excludestr .= "'!' -path '" . $entry . "' -a "; - } - - $excludestr =~ s/-a $//; - if ($includestr) { - $includestr =~ s/-o $//; - $includestr = "find . -xdev " . $includestr; - } - - print "\nexcludestr=$excludestr\n\n includestr=$includestr\n\n"; # debug - - # add the xCAT post scripts to the image - unless ( -d "$rootimg_dir") { - $callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"], errorcode=>[1]}); - return; - } - - # some rpms like atftp mount the rootimg/proc to /proc, we need to make sure rootimg/proc is free of junk - # before packaging the image - system("umount $rootimg_dir/proc"); - copybootscript($installroot, $rootimg_dir, $osver, $arch, $profile, $callback); - my $passtab = xCAT::Table->new('passwd'); - if ($passtab) { - my $pass = 'cluster'; - (my $pent) = $passtab->getAttribs({key=>'system',username=>'root'},'password'); - if ($pent and defined ($pent->{password})) { - $pass = $pent->{password}; - } - my $oldmask=umask(0077); - my $shadow; - open($shadow,"<","$rootimg_dir/etc/shadow"); - my @shadents = <$shadow>; - close($shadow); - open($shadow,">","$rootimg_dir/etc/shadow"); - # 1 - MD5, 5 - SHA256, 6 - SHA512 - unless (($pass =~ /^\$1\$/) || ($pass =~ /^\$5\$/) || ($pass =~ /^\$6\$/)) { - $pass = crypt($pass,'$1$'.xCAT::Utils::genpassword(8)); - } - print $shadow "root:$pass:13880:0:99999:7:::\n"; - foreach (@shadents) { - unless (/^root:/) { - print $shadow "$_"; - } - } - close($shadow); - umask($oldmask); - } - - # sync fils configured in the synclist to the rootimage - $syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot", $imagename); - if (defined ($syncfile) && -f $syncfile - && -d $rootimg_dir) { - print "sync files from $syncfile to the $rootimg_dir\n"; - system("$::XCATROOT/bin/xdcp -i $rootimg_dir -F $syncfile"); - } - - my $verb = "Packing"; - - my $temppath; - my $oldmask; - unless ( -d $rootimg_dir) { - $callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"]}); - return; - } - $callback->({data=>["$verb contents of $rootimg_dir"]}); - unlink("$destdir/rootimg.gz"); - unlink("$destdir/rootimg.sfs"); - if ($method =~ /cpio/) { - if ( ! $exlistloc ) { - $excludestr = "find . -xdev |cpio -H newc -o | gzip -c - > ../rootimg.gz"; - }else { - chdir("$rootimg_dir"); - system("$excludestr >> $xcat_packimg_tmpfile"); - if ($includestr) { - system("$includestr >> $xcat_packimg_tmpfile"); - } - #$excludestr =~ s!-a \z!|cpio -H newc -o | gzip -c - > ../rootimg.gz!; - $excludestr = "cat $xcat_packimg_tmpfile|cpio -H newc -o | gzip -c - > ../rootimg.gz"; - } - $oldmask = umask 0077; - } elsif ($method =~ /squashfs/) { - $temppath = mkdtemp("/tmp/packimage.$$.XXXXXXXX"); - chmod 0755,$temppath; - chdir("$rootimg_dir"); - system("$excludestr >> $xcat_packimg_tmpfile"); - if ($includestr) { - system("$includestr >> $xcat_packimg_tmpfile"); - } - $excludestr = "cat $xcat_packimg_tmpfile|cpio -dump $temppath"; - } else { - $callback->({error=>["Invalid method '$method' requested"],errorcode=>[1]}); - } - chdir("$rootimg_dir"); - `$excludestr`; - if ($method =~ /cpio/) { - chmod 0644,"$destdir/rootimg.gz"; - if ($dotorrent) { - my $currdir = getcwd; - chdir($destdir); - unlink("rootimg.gz.metainfo"); - system("ctorrent -t -u $dotorrent -l 1048576 -s rootimg.gz.metainfo rootimg.gz"); - chmod 0644, "rootimg.gz.metainfo"; - chdir($currdir); - } - umask $oldmask; - } elsif ($method =~ /squashfs/) { - my $flags; - if ($arch =~ /x86/) { - $flags="-le"; - } elsif ($arch =~ /ppc/) { - $flags="-be"; - } - - if( $osver =~ /rhels/ && $osver !~ /rhels5/) { - $flags=""; - } - - if (! -x "/sbin/mksquashfs" && ! -x "/usr/bin/mksquashfs" ) { - $callback->({error=>["mksquashfs not found, squashfs-tools rpm should be installed on the management node"],errorcode=>[1]}); - return; - } - my $rc = system("mksquashfs $temppath ../rootimg.sfs $flags"); - if ($rc) { - $callback->({error=>["mksquashfs could not be run successfully"],errorcode=>[1]}); - return; - } - $rc = system("rm -rf $temppath"); - if ($rc) { - $callback->({error=>["Failed to clean up temp space"],errorcode=>[1]}); - return; - } - chmod(0644,"../rootimg.sfs"); - } - system("rm -f $xcat_packimg_tmpfile"); - - # move the files in /.statebackup back to rootimg_dir - if ($rootimg_status) { # statelite mode - foreach my $entry (keys %liteHash) { - my @tmp = split /\s+/, $entry; - my $filename = $tmp[1]; - my $fileopt = $tmp[0]; - if ($fileopt =~ m/link/) { - chop $filename if ($filename =~ m/\/$/); - xCAT::Utils->runcmd("rm -rf $rootimg_dir$filename", 0, 1); - xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup$filename $rootimg_dir$filename", 0, 1); - } - } - - xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup/install $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install", 0, 1); - xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup/statelite $rootimg_dir/etc/init.d/statelite", 0, 1); - xCAT::Utils->runcmd("rm -rf $rootimg_dir/.statebackup", 0, 1); - } - - - chdir($oldpath); -} - -########################################################### -# -# copybootscript - copy the xCAT diskless init scripts to the image -# -############################################################# -sub copybootscript { - - my $installroot = shift; - my $rootimg_dir = shift; - my $osver = shift; - my $arch = shift; - my $profile = shift; - my $callback = shift; - my @timezone = xCAT::TableUtils->get_site_attribute("timezone"); - - if ( -f "$installroot/postscripts/xcatdsklspost") { - - # copy the xCAT diskless post script to the image - mkpath("$rootimg_dir/opt/xcat"); - - copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/xcatdsklspost"); - if($timezone[0]) { - copy ("$rootimg_dir/usr/share/zoneinfo/$timezone[0]", "$rootimg_dir/etc/localtime"); - } - - - chmod(0755,"$rootimg_dir/opt/xcat/xcatdsklspost"); - - } else { - - my $rsp; - push @{$rsp->{data}}, "Could not find the script $installroot/postscripts/xcatdsklspost.\n"; - xCAT::MsgUtils->message("E", $rsp, $callback); - return 1; - } - - - #if ( -f "$installroot/postscripts/xcatpostinit") { - # copy the linux diskless init script to the image - # - & set the permissions - #copy ("$installroot/postscripts/xcatpostinit","$rootimg_dir/etc/init.d/xcatpostinit"); - - #chmod(0755,"$rootimg_dir/etc/init.d/xcatpostinit"); - - # run chkconfig - #my $chkcmd = "chroot $rootimg_dir chkconfig --add xcatpostinit"; - #symlink "/etc/init.d/xcatpostinit","$rootimg_dir/etc/rc3.d/S84xcatpostinit"; - #symlink "/etc/init.d/xcatpostinit","$rootimg_dir/etc/rc4.d/S84xcatpostinit"; - #symlink "/etc/init.d/xcatpostinit","$rootimg_dir/etc/rc5.d/S84xcatpostinit"; - #my $rc = system($chkcmd); - #if ($rc) { - #my $rsp; - # push @{$rsp->{data}}, "Could not run the chkconfig command.\n"; - # xCAT::MsgUtils->message("E", $rsp, $callback); - # return 1; - # } - #} else { - #my $rsp; - # push @{$rsp->{data}}, "Could not find the script $installroot/postscripts/xcatpostinit.\n"; - # xCAT::MsgUtils->message("E", $rsp, $callback); - # return 1; - #} - return 0; -} - -sub include_file -{ - my $file = shift; - my $idir = shift; - my @text = (); - unless ($file =~ /^\//) { - $file = $idir."/".$file; - } - - open(INCLUDE,$file) || \ - return "#INCLUDEBAD:cannot open $file#"; - - while() { - chomp($_); - s/\s+$//; #remove trailing spaces - next if /^\s*$/; #-- skip empty lines - push(@text, $_); - } - - close(INCLUDE); - - return join("\n", @text); -} - -=head3 parseLiteFiles -In the liteentry table, one directory and its sub-items (including sub-directory and entries) can co-exist; -In order to handle such a scenario, one hash is generated to show the hirarachy relationship - -For example, one array with entry names is used as the input: -my @entries = ( - "imagename bind,persistent /var/", - "imagename bind /var/tmp/", - "imagename tmpfs,rw /root/", - "imagename tmpfs,rw /root/.bashrc", - "imagename tmpfs,rw /root/test/", - "imagename bind /etc/resolv.conf", - "imagename bind /var/run/" -); -Then, one hash will generated as: -%hashentries = { - 'bind,persistent /var/' => [ - 'bind /var/tmp/', - 'bind /var/run/' - ], - 'bind /etc/resolv.conf' => undef, - 'tmpfs,rw /root/' => [ - 'tmpfs,rw /root/.bashrc', - 'tmpfs,rw /root/test/' - ] - }; - -Arguments: - one array with entrynames, - one hash to hold the entries parsed - -Returns: - 0 if sucucess - 1 if fail - -=cut - - - -sub parseLiteFiles { - my ($flref, $dhref) = @_; - my @entries = @{$flref}; - - - foreach (@entries) { - my $entry = $_; - my @str = split /\s+/, $entry; - shift @str; - $entry = join "\t", @str; - my $file = $str[1]; - chop $file if ($file =~ m{/$}); - unless (exists $dhref->{"$entry"}) { - my $parent = dirname($file); - # to see whether $parent exists in @entries or not - unless ($parent =~ m/\/$/) { - $parent .= "/"; - } - my @res = grep {$_ =~ m/\Q$parent\E$/} @entries; - my $found = scalar @res; - - if($found eq 1) { # $parent is found in @entries - # handle $res[0]; - my @tmpresentry=split /\s+/, $res[0]; - shift @tmpresentry; - $res[0] = join "\t", @tmpresentry; - chop $parent; - my @keys = keys %{$dhref}; - my $kfound = grep {$_ =~ m/\Q$res[0]\E$/} @keys; - if($kfound eq 0) { - $dhref->{$res[0]} = []; - } - push @{$dhref->{"$res[0]"}}, $entry; - }else { - $dhref->{"$entry"} = (); - } - } - } - - return 0; -} - -1; From 2a107425ea9dc79fb76246b5f3657c626906b420 Mon Sep 17 00:00:00 2001 From: ligc Date: Thu, 14 May 2015 04:00:58 -0400 Subject: [PATCH 03/26] not sure what happended, fix the bad checkin 8f7633c9b55520f7b5cf88eedd4d523c01c6ec6c --- perl-xCAT/xCAT/Usage.pm | 568 ++++++++++++++ xCAT-client/bin/genimage | 454 +++++++++++ xCAT-server/lib/xcat/plugins/imgcapture.pm | 846 +++++++++++++++++++++ xCAT-server/lib/xcat/plugins/packimage.pm | 629 +++++++++++++++ 4 files changed, 2497 insertions(+) diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index e69de29bb..4314dfe36 100755 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -0,0 +1,568 @@ +#!/usr/bin/perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT::Usage; +use Getopt::Long; +use xCAT::Utils; + +#------------------------------------------------------------------------------- +=head1 xCAT::Usage +=head2 Package Description + xCAT usage module. Some commands such as rpower have different implementations + for different hardware. This module holds the usage string for these kind + of commands so that the usage can be referenced from different modules. +=cut +#------------------------------------------------------------------------------- + + +my %usage = ( + "rnetboot" => +"Usage: rnetboot [-s net|hd] [-F] [-f] [-V|--verbose] [-m table.colum==expectedstatus] [-m table.colum==expectedstatus...] [-r ] [-t ] + rnetboot [-h|--help|-v|--version] + zVM specific: + rnetboot [ipl= address]", + "rpower" => +"Usage: rpower [--nodeps] [on|onstandby|off|suspend|reset|stat|state|boot] [-V|--verbose] [-m table.colum==expectedstatus][-m table.colum==expectedstatus...] [-r ] [-t ] + rpower [-h|--help|-v|--version] + KVM Virtualization specific: + rpower [boot] [ -c ] + PPC (with IVM or HMC) specific: + rpower [--nodeps] [of] [-V|--verbose] + CEC (with HMC) specific: + rpower [on|off|reset|boot|onstandby] + LPAR(with HMC) specific: + rpower [on|off|reset|stat|state|boot|of|sms|softoff] + CEC(using Direct FSP Management) specific: + rpower [on|onstandby|off|stat|state|resetsp] + Frame(using Direct FSP Management) specific: + rpower [stat|state|rackstandby|exit_rackstandby|resetsp] + LPAR(using Direct FSP Management) specific: + rpower [on|off|reset|stat|state|boot|of|sms] + Blade(using Direct FSP Management) specific: + rpower [on|onstandby|off|cycle|state|sms] + Blade(using AMM) specific: + rpower [cycle|softoff] [-V|--verbose] + zVM specific: + rpower noderange [on|off|reset|stat|softoff] + MIC specific: + rpower noderange [stat|state|on|off|reset|boot] +", + "rbeacon" => +"Usage: rbeacon [on|off|stat] [-V|--verbose] + rbeacon [-h|--help|-v|--version]", + "rvitals" => +"Usage: + Common: + rvitals [-h|--help|-v|--version] + FSP/LPAR (with HMC) specific: + rvitals noderange {temp|voltage|lcds|all} + CEC/LPAR/Frame (using Direct FSP Management)specific: + rvitals noderange {rackenv|lcds|all} + MPA specific: + rvitals noderange {temp|voltage|wattage|fanspeed|power|leds|summary|all} + Blade specific: + rvitals noderange {temp|wattage|fanspeed|leds|summary|all} + BMC specific: + rvitals noderange {temp|voltage|wattage|fanspeed|power|leds|lcds|summary|all} + MIC specific: + rvitals noderange {thermal|all}", + "reventlog" => +"Usage: reventlog [all [-s]|clear| [-s]] [-V|--verbose] + reventlog [-h|--help|-v|--version]", + "rinv" => +"Usage: + Common: + rinv [all|model|serial] [-V|--verbose] + rinv [-h|--help|-v|--version] + BMC specific: + rinv [mprom|deviceid|uuid|guid|vpd [-t]|all [-t]] + MPA specific: + rinv [firm|bios|diag|mprom|sprom|mparom|mac|mtm [-t]] + PPC specific(with HMC): + rinv [all|bus|config|serial|model|firm [-t]] + PPC specific(using Direct FSP Management): + rinv [firm] + rinv [deconfig [-x]] + Blade specific: + rinv [all|serial|mac|bios|diag|mprom|mparom|firm|mtm [-t]] + IBM Flex System Compute Node specific: + rinv [firm] + VMware specific: + rinv + zVM specific: + rinv noderange [all|config] + MIC specific: + rinv noderange [system|ver|board|core|gddr|all]", + "rsetboot" => +"Usage: rsetboot [net|hd|cd|floppy|def|stat] [-V|--verbose] + rsetboot [-h|--help|-v|--version]", + "rbootseq" => +"Usage: + Common: + rbootseq [-h|--help|-v|--version|-V|--verbose] + Blade specific: + rbootseq [hd0|hd1|hd2|hd3|net|iscsi|usbflash|floppy|none],... + PPC (using Direct FSP Management) specific: + rbootseq [hfi|net]", + "rscan" => +"Usage: rscan [-u][-w][-x|-z] [-V|--verbose] + rscan [-h|--help|-v|--version]", + "rspconfig" => +"Usage: + Common: + rspconfig [-h|--help|-v|--version|-V|--verbose] + BMC/MPA Common: + rspconfig [snmpdest|alert|community] [-V|--verbose] + rspconfig [snmpdest=|alert=|community=] + BMC specific: + rspconfig [ip|netmask|gateway|backupgateway|garp] + rspconfig [garp=] + iDataplex specific: + rspconfig [thermprofile] + rspconfig [thermprofile=] + MPA specific: + rspconfig [sshcfg|snmpcfg|pd1|pd2|network|swnet|ntp|textid|frame] + rspconfig [textid=name] + rspconfig [frame=number] + rspconfig [USERID=passwd] [updateBMC=] + rspconfig [sshcfg=| + snmpcfg=| + pd1=| + pd2=| + network=<*|[ip],[host],[gateway],[netmask]>| + swnet=<[ip],[gateway],[netmask]>| + textid=<*>| + frame=<*>| + ntp=<[ntp],[ip],[frequency],[v3]> + FSP/CEC (using ASM Interface) Specific: + rspconfig [autopower|iocap|decfg|memdecfg|procdecfg|time|date|spdump|sysdump|network|hostname] + rspconfig autopower=| + iocap=| + decfg=:,...| + memdecfg=::::id,...| + procdecfg=::id,...| + date=| + time=| + network=<*|[ip],[host],[gateway],[netmask]>| + HMC_passwd=| + admin_passwd=| + general_passwd=| + *_passwd=| + hostname=<*|hostname> + FSP/CEC (using Direct FSP Management) Specific: + rspconfig HMC_passwd= + rspconfig admin_passwd= + rspconfig general_passwd= + rspconfig *_passwd= + rspconfig [sysname] + rspconfig [sysname=<*|name>] + rspconfig [pending_power_on_side] + rspconfig [pending_power_on_side=] + rspconfig [cec_off_policy] + rspconfig [cec_off_policy=] + rspconfig [huge_page] + rspconfig [huge_page=] + rspconfig [BSR] + rspconfig [setup_failover] + rspconfig [setup_failover=] + rspconfig [force_failover] + rspconfig --resetnet + BPA/Frame (using Direct FSP Management)specific: + rspconfig HMC_passwd= + rspconfig admin_passwd= + rspconfig general_passwd= + rspconfig *_passwd= + rspconfig [frame] + rspconfig frame=<*|frame> + rspconfig [sysname] + rspconfig [sysname=<*|name>] + rspconfig [pending_power_on_side] + rspconfig [pending_power_on_side=] + rspconfig --resetnet + HMC specific: + rspconfig [sshcfg] + rspconfig [sshcfg=] + CEC|Frame(using ASM)Specific: + rspconfig [dev|celogin1] + rspconfig [dev=]| + rspconfig [celogin1=] + ", + "getmacs" => +"Usage: + Common: + getmacs [-h|--help|-v|--version] + PPC specific: + getmacs [-F filter] + getmacs [-M] + getmacs [-V| --verbose] [-f] [-d] [--arp] | [-D {[-o] [-S server] [-G gateway] [-C client] | [--noping]}] + blade specific: + getmacs [-V| --verbose] [-d] [--arp] [-i ethN|enN] +", + "mkvm" => +"Usage: + Common: + mkvm [-h|--help|-v|--version] + For PPC(with HMC) specific: + mkvm noderange -i id -l singlenode [-V|--verbose] + mkvm noderange -c destcec -p profile [-V|--verbose] + mkvm noderange --full [-V|--verbose] + PPC (using Direct FSP Management) specific: + mkvm noderange [--full] + mkvm noderange [vmcpus=min/req/max] [vmmemory=min/req/max] + [vmphyslots=drc_index1,drc_index2...] [vmothersetting=hugepage:N,bsr:N] + [vmnics=vlan1,vlan2] [vmstorage=] [--vios] + For KVM + mkvm noderange -m|--master mastername -s|--size disksize -f|--force + For zVM + mkvm noderange directory_entry_file_path + mkvm noderange source_virtual_machine pool=disk_pool pw=multi_password", + "lsvm" => +"Usage: + Common: + lsvm [-V|--verbose] + lsvm [-h|--help|-v|--version] + PPC (with HMC) specific: + lsvm [-a|--all] + PPC (using Direct FSP Management) specific: + lsvm [-l|--long] --p775 + lsvm + zVM specific: + lsvm noderange + lsvm noderange --getnetworknames + lsvm noderange --getnetwork network_name + lsvm noderange --diskpoolnames + lsvm noderange --diskpool pool_name", + "chvm" => +"Usage: + Common: + chvm [-h|--help|-v|--version] + PPC (with HMC) specific: + chvm [-p profile][-V|--verbose] + chvm = [=...] + PPC (using Direct FSP Management) specific: + chvm --p775 [-p ] + chvm --p775 -i [-m ] -r + chvm [lparname=<*|name>] + chvm [vmcpus=min/req/max] [vmmemory=min/req/max] + [vmothersetting=hugepage:N,bsr:N] + [add_physlots=drc_index1,drc_index2...] + [add_vmnics=vlan1,vlan2] [add_vmstorage=] [--vios] + chvm [del_physlots=drc_index1,drc_index2...] + chvm [del_vadapter=slotid] + VMware specific: + chvm [-a size][-d disk][-p disk][--resize disk=size][--cpus count][--mem memory] + zVM specific: + chvm noderange [--add3390 disk_pool device_address cylinders mode read_password write_password multi_password] + chvm noderange [--add3390active device_address mode] + chvm noderange [--add9336 disk_pool virtual_device block_size mode blocks read_password write_password multi_password] + chvm noderange [--adddisk2pool function region volume group] + chvm noderange [--addnic address type device_count] + chvm noderange [--addprocessor address] + chvm noderange [--addprocessoractive address type] + chvm noderange [--addvdisk userID] device_address size] + chvm noderange [--connectnic2guestlan address lan owner] + chvm noderange [--connectnic2vswitch address vswitch] + chvm noderange [--copydisk target_address source_node source_address] + chvm noderange [--dedicatedevice virtual_device real_device mode] + chvm noderange [--deleteipl] + chvm noderange [--formatdisk disk_address multi_password] + chvm noderange [--disconnectnic address] + chvm noderange [--grantvswitch VSwitch] + chvm noderange [--removedisk virtual_device] + chvm noderange [--resetsmapi] + chvm noderange [--removediskfrompool function region group] + chvm noderange [--removenic address] + chvm noderange [--removeprocessor address] + chvm noderange [--replacevs directory_entry] + chvm noderange [--setipl ipl_target load_parms parms] + chvm noderange [--setpassword password]", + "rmvm" => +"Usage: rmvm [--service][-V|--verbose] + rmvm [-h|--help|-v|--version], + rmvm [-p] [-f] + PPC (using Direct FSP Management) specific: + rmvm ", + "lsslp" => +"Usage: lsslp [-h|--help|-v|--version] + lsslp [][-V|--verbose][-i ip[,ip..]][-w][-r|-x|-z][-n][-I][-s FRAME|CEC|MM|IVM|RSA|HMC|CMM|IMM2|FSP] + [-u] [--range IPranges][-t tries][--vpdtable][-C counts][-T timeout]", + "switchdiscover" => +"Usage: switchdiscover [-h|--help|-v|--version] + switchdiscover [][-V|--verbose][-i adpt[,adpt..]][-w][-r|-x|-z][-n][-s scan_methods]", + "rflash" => +"Usage: + rflash [ -h|--help|-v|--version] + PPC (with HMC) specific: + rflash -p [--activate concurrent | disruptive][-V|--verbose] + rflash [--commit | --recover] [-V|--verbose] + PPC (using Direct FSP Management) specific: + rflash -p --activate [-d ] + rflash [--commit | --recover] [-V|--verbose] + rflash [--bpa_acdl]", + "mkhwconn" => +"Usage: + mkhwconn [-h|--help] + + PPC (with HMC) specific: + mkhwconn noderange -t [--bind] [-V|--verbose] + mkhwconn noderange -p single_hmc [-P HMC passwd] [-V|--verbose] + + PPC (using Direct FSP Management) specific: + mkhwconn noderange -t [-T tooltype] [--port port_value] + mkhwconn noderange -s [hmcnode] [-P HMC passwd] [-V|--verbose]", + "rmhwconn" => +"Usage: + rmhwconn [-h|--help] + + PPC (with HMC) specific: + rmhwconn noderange [-V|--verbose] + + PPC (using Direct FSP Management) specific: + rmhwconn noderange [-T tooltype] + rmhwconn noderange -s", + "lshwconn" => +"Usage: + lshwconn [-h|--help] + + PPC (with HMC) specific: + lshwconn noderange [-V|--verbose] + + PPC (using Direct FSP Management) specific: + lshwconn noderange [-T tooltype] + lshwconn noderange -s", + "renergy" => +"Usage: + renergy [-h | --help] + renergy [-v | --version] + + Power 6 server specific : + renergy noderange [-V] { all | { [savingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] } } + renergy noderange [-V] { {savingstatus}={on | off} | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage } + + Power 7 server specific : + renergy noderange [-V] { all | { [savingstatus] [dsavingstatus] [cappingstatus] [cappingmaxmin] [cappingvalue] [cappingsoftmin] [averageAC] [averageDC] [ambienttemp] [exhausttemp] [CPUspeed] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue] } } + renergy noderange [-V] { {savingstatus}={on | off} | {dsavingstatus}={on-norm | on-maxp | off} | {fsavingstatus}={on | off} | {ffovalue}=MHZ | {cappingstatus}={on | off} | {cappingwatt}=watt | {cappingperc}=percentage } + + Power 8 server specific : + renergy noderange [-V] { all | [savingstatus] [dsavingstatus] [averageAC] [averageAChistory] [averageDC] [averageDChistory] [ambienttemp] [ambienttemphistory] [exhausttemp] [exhausttemphistory] [fanspeed] [fanspeedhistory] [CPUspeed] [CPUspeedhistory] [syssbpower] [sysIPLtime] [fsavingstatus] [ffoMin] [ffoVmin] [ffoTurbo] [ffoNorm] [ffovalue]} + renergy noderange [-V] { savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} | fsavingstatus={on | off} | ffovalue=MHZ } + + BladeCenter specific : + For Management Modules: + renergy noderange [-V] { all | pd1all | pd2all | [pd1status] [pd2status] [pd1policy] [pd2policy] [pd1powermodule1] [pd1powermodule2] [pd2powermodule1] [pd2powermodule2] [pd1avaiablepower] [pd2avaiablepower] [pd1reservedpower] [pd2reservedpower] [pd1remainpower] [pd2remainpower] [pd1inusedpower] [pd2inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] } + For a blade server nodes: + renergy noderange [-V] { all | [averageDC] [capability] [cappingvalue] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] } + renergy noderange [-V] { savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} } + + Flex specific : + For Flex Management Modules: + renergy noderange [-V] { all | [powerstatus] [powerpolicy] [powermodule] [avaiablepower] [reservedpower] [remainpower] [inusedpower] [availableDC] [averageAC] [thermaloutput] [ambienttemp] [mmtemp] } + + For Flex node (power and x86): + renergy noderange [-V] { all | [averageDC] [capability] [cappingvalue] [cappingmaxmin] [cappingmax] [cappingmin] [cappingGmin] [CPUspeed] [maxCPUspeed] [savingstatus] [dsavingstatus] } + renergy noderange [-V] { cappingstatus={on | off} | cappingwatt=watt | cappingperc=percentage | savingstatus={on | off} | dsavingstatus={on-norm | on-maxp | off} } + + iDataPlex specific : + renergy noderange [-V] [ { cappingmaxmin | cappingmax | cappingmin } ] [cappingstatus] [cappingvalue] [relhistogram] + renergy noderange [-V] { cappingstatus={on | enable | off | disable} | {cappingwatt|cappingvalue}=watt }", + "updatenode" => +"Usage: + updatenode [-h|--help|-v|--version | -g|--genmypost] + or + updatenode [-V|--verbose] [-k|--security] [-s|--sn] [-t ] + or + updatenode [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t ] + [-P|--scripts [script1,script2,...]] [-s|--sn] + [-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir] + [attr=val [attr=val...]] + or + updatenode [-V|--verbose] [script1,script2,...] + +Options: + A list of nodes or groups. + + [-k|--security] Update the security keys and certificates for the + target nodes. + + [-F|--sync] Perform File Syncing. + + [--fanout] Allows you to assign the fanout value for the command. + See xdsh/xdcp fanout parameter in the man page. + + [-f|--snsync] Performs File Syncing to the service nodes that service + the nodes in the noderange. + + [-g|--genmypost] Will generate a new mypostscript file for the + the nodes in the noderange, if site precreatemypostscripts is 1 or YES. + + [-l|--user] User name to run the updatenode command. It overrides the + current user which is the default. + + [-S|--sw] Perform Software Maintenance. + + [-P|--scripts] Execute postscripts listed in the postscripts table or + parameters. + + [-c|--cmdlineonly] Only use AIX software maintenance information + provided on the command line. (AIX only) + + [-s|--sn] Set the server information stored on the nodes. + + [-t|--timeout] Time out in seconds to allow the command to run. Default is no timeout, + except for updatenode -k which has a 10 second default timeout. + + [-A|--updateallsw] Install or update all software contained in the source + directory. (AIX only) + + [-d ] Used to indicate a source directory other than + the standard lpp_source directory specified in the xCAT osimage + definition. (AIX only) + + [script1,script2,...] A comma separated list of postscript names. + If omitted, all the post scripts defined for the nodes will be run. + + [attr=val [attr=val...]] Specifies one or more 'attribute equals value' + pairs, separated by spaces. (AIX only)", + "lsflexnode" => +"Usage: + lsflexnode [-h|--help|-v|--version] + lsflexnode ", + "mkflexnode" => +"Usage: + mkflexnode [-h|--help|-v|--version] + mkflexnode ", + "nodeset" => +"Usage: + Common: + nodeset [-h|--help|-v|--version] + nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline]", + "rmflexnode" => +"Usage: + rmflexnode [-h|--help|-v|--version] + rmflexnode ", + "lsve" => +"Usage: + lsve [-t type] [-m manager] [-o object] + -t: dc - 'Data Center', cl - 'Cluster', sd - 'Storage Domain', nw - 'Network', tpl -'Template' + -m: FQDN (Fully Qualified Domain Name) of the rhev manager + -o: Target object to display", + "cfgve" => +"Usage: + cfgve -t dc -m manager -o object [-c -k nfs|localfs | -r] + cfgve -t cl -m manager -o object [-c -p cpu type | -r -f] + cfgve -t sd -m manager -o object [-c | -g | -s | -a | -b | -r -f] + -t: sd - 'Storage Domain', nw - 'Network', tpl -'Template' + -m: FQDN (Fully Qualified Domain Name) of the rhev manager + -o: Target object to configure + cfgve -t nw -m manager -o object [-c -d data center -n vlan ID | -a -l cluster| -b | -r] + cfgve -t tpl -m manager -o object [-r]", + "chhypervisor" => +"Usage: + chhypervisor noderange [-a | -n | -p | -e | -d | -h]", + "rmhypervisor" => +"Usage: + rmhypervisor noderange [-f | -h]", + "clonevm" => +"Usage: + clonevm noderange [-t createmaster -f | -b basemaster -d | -h]", +); +my $vers = xCAT::Utils->Version(); +my %version = ( + "rnetboot" => "$vers", + "rpower" => "$vers", + "rbeacon" => "$vers", + "rvitals" => "$vers", + "reventlog" => "$vers", + "rinv" => "$vers", + "rsetboot" => "$vers", + "rbootseq" => "$vers", + "rscan" => "$vers", + "rspconfig" => "$vers", + "getmacs" => "$vers", + "mkvm" => "$vers", + "lsvm" => "$vers", + "chvm" => "$vers", + "rmvm" => "$vers", + "lsslp" => "$vers", + "switchdiscover" => "$vers", + "rflash" => "$vers", + "renergy" => "$vers", + "lsflexnode" => "$vers", + "mkflexnode" => "$vers", + "rmflexnode" => "$vers", + "nodeset" => "$vers", + "lsve" => "$vers", + "cfgve" => "$vers", + "chhypervisor" => "$vers", + "rmhypervisor" => "$vers", + "clonevm" => "$vers", +); + +#-------------------------------------------------------------------------------- +=head3 getUsage + It returns the usage string for the given command. + Arguments: + command + Returns: + the usage string for the command. +=cut +#------------------------------------------------------------------------------- +sub getUsage { + my ($class, $command)=@_; + if (exists($usage{$command})) { return $usage{$command};} + else { return "Usage for command $command cannot be found\n"; } +} + +#-------------------------------------------------------------------------------- +=head3 getVersion + It returns the version string for the given command. + Arguments: + command + Returns: + the version string for the command. +=cut +#------------------------------------------------------------------------------- +sub getVersion { + my ($class, $command)=@_; + if (exists($version{$command})) { return $version{$command};} + else { return "Version string for command $command cannot be found\n"; } +} + +#-------------------------------------------------------------------------------- +=head3 parseCommand + This function parses the given command to see if the usage or version string + need to be returned. + Arguments: + command + arguments + Returns: + the usage or the version string for the command. The caller need to display the + string and then exit. + none, if no usage or version strings are needed. The caller can keep going. +=cut +#------------------------------------------------------------------------------- +sub parseCommand { + my $command=shift; + if ($command =~ /xCAT::Usage/) { $command=shift; } + my @exargs=@_; + + @ARGV=@exargs; + + #print "command=$command, args=@exargs, ARGV=@ARGV\n"; + + Getopt::Long::Configure('pass_through','no_ignore_case'); + + # parse the options + if(!GetOptions( + 'h|help' => \$::HELP, + 'v|version' => \$::VERSION)) { + + return ""; + } + + if ($::HELP) { return xCAT::Usage->getUsage($command); } + if ($::VERSION) { return xCAT::Usage->getVersion($command); } + + return ""; +} + diff --git a/xCAT-client/bin/genimage b/xCAT-client/bin/genimage index e69de29bb..aa61089b9 100755 --- a/xCAT-client/bin/genimage +++ b/xCAT-client/bin/genimage @@ -0,0 +1,454 @@ +#!/usr/bin/perl +BEGIN +{ + $::XCATROOT = + $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} + : -d '/opt/xcat' ? '/opt/xcat' + : '/usr'; +} +use lib "$::XCATROOT/lib/perl"; +use strict; + +use Getopt::Long; +require xCAT::MsgUtils; +require xCAT::DSHCLI; +require xCAT::Client; + +use xCAT::Utils; +use xCAT::TableUtils; +use File::Basename; + +$::XCATROOT = "/opt/xcat"; +my $os = ""; +my $profile = ""; +my $interface = ""; +my $version; +my $drivers = ""; +my $otherInterfaces = ""; +my $kernel = ""; +my @oses; # available OSes. +my @profiles; # available profiles +my $profDir; # root where you do ./genimage from +my $help; +my $match = 0; +my $imagename; +my $arch; +my $permission; +my $rootlimit; +my $tmplimit; +my $krpmver; +my $kerneldir; +my $mode; +my $interactive; +my $onlyinitrd; +my $dryrun; +my $ignorekernelchk; +my $noupdate; +#----------------------------------------------------------------------------- + +=head3 print_usage - usage message + +=cut + +#----------------------------------------------------------------------------- +sub print_usage +{ + print "Usage:\n"; + print " genimage\n\n"; + print " genimage --dryrun\n\n"; + print ' genimage [-o ] [-a ] [-p ] [-i ] [-n ] [--onlyinitrd] [-r ] [-k ] [-g ] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission ] [--interactive] [--dryrun] [--noupdate] '."\n\n"; + print " --permission is used for statelite only\n"; + print " -g is used for SLES only\n\n"; + print " -m is used for urbuntu, debian and fedora12 only\n\n"; + print "Examples:\n"; + print " genimage\n"; + print " genimage --interactive\n"; + print " genimage -i eth0 -n tg3 --interactive myimagename\n"; + print " genimage myimagename\n"; +} + +if (!GetOptions( + 'a=s' => \$arch, + 'p=s' => \$profile, + 'o=s' => \$os, + 'n=s' => \$drivers, + 'i=s' => \$interface, + 'r=s' => \$otherInterfaces, + 'l=s' => \$rootlimit, + 't=s' => \$tmplimit, + 'k=s' => \$kernel, + 'g=s' => \$krpmver, + 'm=s' => \$mode, + 'permission=s' => \$permission, + 'kerneldir=s' => \$kerneldir, + 'interactive' => \$interactive, + 'onlyinitrd' => \$onlyinitrd, + 'dryrun' => \$dryrun, + 'ignorekernelchk' => \$ignorekernelchk, + 'noupdate' => \$noupdate, + 'h|help' => \$help, + 'v|version' => \$version, +)) { + &print_usage; + exit 1; +} + +if($help){ + &print_usage; + exit 0; +} + +if ($version){ + my $version = xCAT::Utils->Version(); + xCAT::MsgUtils->message("N", $version); + exit 0; + +} +if (@ARGV > 0) { + $imagename=$ARGV[0]; +} + +if ((!$imagename) && (!$profile) && (!$os) && (!$arch)) { + my $tmpimgs=`lsdef -t osimage -w provmethod=~'/statelite|netboot/' |cut -d' ' -f1`; + if ($? == 0) { + if (($tmpimgs) && ($tmpimgs !~ /^Could/)) { #Could is returned when the osimage table is empty + my @images=split('\n', $tmpimgs); + print "Do you want to re-generate an existing image from the osimage table? "; + print "[y/n] "; + my $conf = ; + chomp($conf); + if($conf ne "" && $conf !~/N|n|[Nn][Oo]/) { + $match = 0; + while(1){ + print "Available images: \n"; + foreach(sort @images){ + print " $_\n"; + } + # default is the first image + print "Which image do you want to re-generate? ["; + print $images[0]; + print "] "; + + my $img = ; + chomp($img); + if($img eq ""){ + $imagename = $images[0]; + last; + } + foreach(@images){ + if($img eq $_){ + $imagename=$img; + $match = 1; + } + } + if ($match) { + last; + } else { + print "$img is not found in the osimage table.\n"; + } + } + } + } + } +} + + +# get the install directory +my @entries = xCAT::TableUtils->get_site_attribute("installdir"); +my $installdir = $entries[0]; +chomp($installdir); +# lots of error checking to make sure it exists. +if($installdir eq ''){ + print "Could not get install directory from site table. Assuming your OSes are stored in '/install'\n"; + $installdir = "/install"; +} + +unless(-d $installdir){ + print "The directory where your OS distributions resides: $installdir does not exist. Please check site table\n"; + exit 1; +} + +if ((!$imagename) && (!$os)){ + my @dircontents = `ls $installdir`; + chomp(@dircontents); + foreach (@dircontents) { + # SL matches Scientific Linux, sl matches sles amd sled + if($_ =~ /(rhel|fedora|SL|centos|sl|suse)/){ + push @oses,$_; + } + } + + if($#oses eq -1){ + print "There are no OS repositories in $installdir. Please run copycds for the OS first.\n"; + exit 1; + } + + # now they have the OSes, make sure they select one that is available + $match = 0; + while(1){ + print "Available OSes: \n"; + foreach(@oses){ + print " $_\n"; + } + # default is the first OS cause in many cases, they'll only have 1. + print "Which OS do you want to build a image for? ["; + print $oses[0] ; + print "] "; + + $os = ; + chomp($os); + if($os eq ""){ + $os = $oses[0]; + last; + } + foreach(@oses){ + if($os eq $_){ + $match = 1; + } + } + + if($match){ + last; + }else{ + print "$os is not found in '$installdir'\n"; + } + } + + chomp($os); +} +if ($os) { print " OS: $os\n"; } + + + +### Get the Profile #### +my $osfamily = $os; +$osfamily =~ s/\d+//g; +$osfamily =~ s/\.//g; +if($osfamily =~ /rh/){ + $osfamily = "rh"; +} + +# OS version on s390x can contain 'sp', e.g. sles11sp1 +# If the $osfamily contains 'sles' and 'sp', the $osfamily = sles +if ($osfamily =~ /sles/ && $osfamily =~ /sp/) { + $osfamily = "sles"; +} + +#print "OSfamily: $osfamily\n"; +$profDir = "$::XCATROOT/share/xcat/netboot/$osfamily"; +unless(-d $profDir){ + print "Unable to find genimage script in $profDir\n"; + exit 1; +} + +if ((!$imagename) && (!$profile)){ + my $profDir2 = "$installdir/custom/netboot/$osfamily"; + my @proList = `ls $profDir/*.pkglist`; + if (-d $profDir2) { + @proList = (@proList, `ls $profDir2/*.pkglist`); + } + my %seen = (); + foreach (@proList) { + my $f = basename($_); + $f =~ s/([^\.]*).*/$1/; + chomp($f); + $seen{$f}++; + } + @profiles = sort keys %seen; + if($#profiles eq -1){ + print "There are no profiles in $::XCATROOT/share/xcat/netboot/$osfamily.\n"; + exit 1; + } + $match = 0; + while(1){ + print "Available Profiles for $os: \n"; + foreach(@profiles){ + print " $_\n"; + } + # default is the first OS cause in many cases, they'll only have 1. + print "Which profile do you want to use for $os? ["; + print "$profiles[0] "; + print "] "; + + $profile = ; + chomp($profile); + if($profile eq ""){ + $profile = $profiles[0]; + last; + } + foreach(@profiles){ + if($profile eq $_){ + $match = 1; + } + } + if($match eq 1){ + last; + } + } +} +if ($profile) { print " Profile: $profile\n"; } + +# get the interface +if ((!$imagename) && (!$interface)){ + while(1){ + print "OPTIONAL: Which specific network interface will the image boot from? []"; + $interface = ; + chomp($interface); + if($interface eq ""){ + last; + }else{ + print "You want your stateless machines to boot off of "; + print "$interface"; + print "? "; + print "[Y/n] "; + my $conf = ; + chomp($conf); + if($conf eq ""){ + last; + } + if($conf =~ /Y|y|[Yy][Ee][Ss]/){ + last; + } + } + } + if ($interface) { print " Interface: $interface\n"; } + else { print " No interface specified. The interface will be determined at network boot time.\n"; } +} + + + +print "Generating image: \n"; +my @arg; +if ($imagename) { + push @arg, "$imagename"; +} + +if ($interface) { + push @arg, "-i"; + push @arg, "$interface"; +} +if ($drivers) { + push @arg, "-n"; + push @arg, "$drivers"; +} +if ($os) { + push @arg, "-o"; + push @arg, "$os"; +} +if ($profile) { + push @arg, "-p"; + push @arg, "$profile"; +} +if ($arch) { + push @arg, "-a"; + push @arg, "$arch"; +} + +if ($kernel) { + push @arg, "-k"; + push @arg, "$kernel"; +} + +if($otherInterfaces){ + push @arg, "-r"; + push @arg, "$otherInterfaces"; +} + +if ($permission) { + push @arg, "--permission"; + push @arg, "$permission"; +} + +if ($rootlimit) { + push @arg, "-l"; + push @arg, "$rootlimit"; +} + +if($tmplimit) { + push @arg, "-t"; + push @arg, "$tmplimit"; +} + +if ($krpmver) { + push @arg, "-g"; + push @arg, "$krpmver"; +} + +if ($mode) { + push @arg, "-m"; + push @arg, "$mode"; +} + +if ($kerneldir) { + push @arg, "--kerneldir"; + push @arg, "$kerneldir"; +} + +my $tempfile="/tmp/xcat_genimage.$$"; +push @arg, "--tempfile"; #this is the file that contains the output +push @arg, "$tempfile"; + +if ($interactive) { + push @arg, "--interactive"; +} + + +if ($onlyinitrd) { + push @arg, "--onlyinitrd"; +} + +if ($dryrun) { + push @arg, "--dryrun"; +} + +if ($ignorekernelchk) { + push @arg, "--ignorekernelchk"; +} + +if ($noupdate) { + push @arg, "--noupdate"; +} + +my $cmdref; +push (@{$cmdref->{arg}}, @arg); +$cmdref->{command}->[0] = "genimage"; + +if (!$interactive) { + xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response); + exit $xCAT::Client::EXITCODE; +} else { + if ($dryrun) { exit 0; } + #when in interactive mode, first call genimage.pm get info from DB, + xCAT::Client::submit_request($cmdref, \&xCAT::Client::handle_response); + + #then call the specific genimage under /opt/xcat/share... + if (-f $tempfile) { + my $cmdname; + #read the command name + open(FILE1, "<$tempfile"); + my @output = ; + if (@output >0) { + $cmdname=$output[0]; + } else { + close FILE1; + return 1; + } + close FILE1; + + # run the specific genimage command + #print "cmdname=$cmdname\n"; + system("$cmdname"); + + #then call genimage.pm to save the DB + my @arg1; + push @arg1, $tempfile; + my $request; + push (@{$request->{arg}}, @arg1); + $request->{command}->[0] = "saveimgdata"; + xCAT::Client::submit_request($request, \&xCAT::Client::handle_response); + exit $xCAT::Client::EXITCODE; + } else { + exit 1; + } +} + diff --git a/xCAT-server/lib/xcat/plugins/imgcapture.pm b/xCAT-server/lib/xcat/plugins/imgcapture.pm index e69de29bb..6bb88b83e 100755 --- a/xCAT-server/lib/xcat/plugins/imgcapture.pm +++ b/xCAT-server/lib/xcat/plugins/imgcapture.pm @@ -0,0 +1,846 @@ +#!/usr/bin/perl +# IBM(c) 2007 EPL license http://www.eclipse.org/legal/epl-v10.html + +package xCAT_plugin::imgcapture; + +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} + +use lib "$::XCATROOT/lib/perl"; + +use strict; + +use Data::Dumper; # for debug purpose +use Getopt::Long; +use xCAT::MsgUtils; +use xCAT::Utils; +use xCAT::TableUtils; +use xCAT::SvrUtils; +use xCAT::Table; +use File::Path qw(mkpath); + +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + +my $verbose = 0; +my $installroot = "/install"; +my $sysclone_home = $installroot . "/sysclone"; + +sub handled_commands { + return { "imgcapture" => "imgcapture" }; +} + +sub process_request { + my $request = shift; + my $callback = shift; + my $doreq = shift; + + my $node; + if (exists $request->{node}) { + $node = $request->{node}->[0]; + } + + $installroot = xCAT::TableUtils->getInstallDir(); + @ARGV = @{$request->{arg}} if (defined $request->{arg}); + my $argc = scalar @ARGV; + + my $usage = "Usage:\n imgcapture -t|--type {diskless|sysclone} -o|--osimage [-V | --verbose] \n imgcapture [-h|--help] \n imgcapture [-v|--version]"; + + my $os; + my $arch; + my $device; + my $profile; + my $bootif; + my $netdriver; + my $osimg; + my $help; + my $version; + my $type; + + GetOptions( + "profile|p=s" => \$profile, + "i=s" => \$bootif, + 'n=s' => \$netdriver, + 'osimage|o=s' => \$osimg, + "device|d=s" => \$device, + "help|h" => \$help, + "version|v" => \$version, + "verbose|V" => \$verbose, + "type|t=s" => \$type + ); + + if ( defined( $ARGV[0] )) { + my $rsp = {}; + $rsp->{data}->[0] = "Invalid Argument: $ARGV[0]"; + $rsp->{data}->[1] = $usage; + xCAT::MsgUtils->message("D", $rsp, $callback); + return 0; + } + + if($version) { + my $version = xCAT::Utils->Version(); + my $rsp = {}; + $rsp->{data}->[0] = $version; + xCAT::MsgUtils->message("D", $rsp, $callback); + return 0; + } + + if($help) { + my $rsp = {}; + $rsp->{data}->[0] = $usage; + xCAT::MsgUtils->message("D", $rsp, $callback); + return 0; + } + + if( ! $node ) { + my $rsp = {}; + $rsp->{data}->[0] = $usage; + xCAT::MsgUtils->message("D", $rsp, $callback); + return 0; + } + + if(($type =~ /sysclone/) && (!$osimg)){ + my $rsp = {}; + push @{$rsp->{data}}, "You must specify osimage name if you are using \"sysclone\"."; + push @{$rsp->{data}}, $usage; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + my $nodetypetab = xCAT::Table->new("nodetype"); + my $ref_nodetype = $nodetypetab->getNodeAttribs($node, ['os','arch','profile']); + $os = $ref_nodetype->{os}; + $arch = $ref_nodetype->{arch}; + unless($profile) { + $profile = $ref_nodetype->{profile}; + } + + # sysclone + unless($type =~ /diskless/) + { + # Handle image capture separately for s390x + if ($arch eq 's390x') { + eval { require xCAT_plugin::zvm; }; # Load z/VM plugin dynamically + xCAT_plugin::zvm->imageCapture($callback, $node, $os, $arch, $profile, $osimg, $device); + return; + } + + my $shortname = xCAT::InstUtils->myxCATname(); + + my $rc; + $rc = sysclone_configserver($shortname, $osimg, $callback, $doreq); + if($rc){ + my $rsp = {}; + $rsp->{data}->[0] = qq{Can not configure Imager Server on $shortname.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + $rc = sysclone_prepclient($node, $shortname, $osimg, $callback, $doreq); + if($rc){ + my $rsp = {}; + $rsp->{data}->[0] = qq{Can not prepare Golden Client on $node.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + $rc = sysclone_getimg($node, $shortname, $osimg, $callback, $doreq); + if($rc){ + my $rsp = {}; + $rsp->{data}->[0] = qq{Can not get image $osimg from $node.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + $rc = sysclone_createosimgdef($node, $shortname, $osimg, $callback, $doreq); + if($rc){ + my $rsp = {}; + $rsp->{data}->[0] = qq{Can not create osimage definition for $osimg on $shortname.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + return; + } + + # -i flag is required with sles genimage + if (!$bootif && $os =~ /^sles/) { + $bootif = "eth0"; + } + + # check whether the osimage exists or not + if($osimg) { + my $osimgtab=xCAT::Table->new('osimage', -create=>1); + unless($osimgtab) { + # the osimage table doesn't exist + my $rsp = {}; + $rsp->{data}->[0] = qq{Cannot open the osimage table}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + my $linuximgtab = xCAT::Table->new('linuximage', -create=>1); + unless($linuximgtab) { + # the linuximage table doesn't exist + my $rsp = {}; + $rsp->{data}->[0] = qq{Cannot open the linuximage table}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + my ($ref) = $osimgtab->getAttribs({imagename => $osimg}, 'osvers', 'osarch', 'profile'); + unless($ref) { + my $rsp = {}; + $rsp->{data}->[0] = qq{Cannot find $osimg from the osimage table.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + my ($ref1) = $linuximgtab->getAttribs({imagename => $osimg}, 'imagename'); + unless($ref1) { + my $rsp = {}; + $rsp->{data}->[0] = qq{Cannot find $osimg from the linuximage table}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + # make sure the "osvers" and "osarch" attributes match the node's attribute + unless($os eq $ref->{'osvers'} and $arch eq $ref->{'osarch'}) { + my $rsp = {}; + $rsp->{data}->[0] = qq{The 'osvers' or 'osarch' attribute of the "$osimg" table doesn't match the node's attribute}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + } + + imgcapture($node, $os, $arch, $profile, $osimg, $bootif, $netdriver, $callback, $doreq); +} + +sub imgcapture { + my ($node, $os, $arch, $profile, $osimg, $bootif, $netdriver, $callback, $subreq) = @_; + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = "nodename is $node; os is $os; arch is $arch; profile is $profile"; + $rsp->{data}->[1] = "bootif is $bootif; netdriver is $netdriver"; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + # make sure the "/" partion is on the disk, + my $output = xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg =>["stat / -f |grep Type"]}, $subreq, -1, 1); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{the output of "stat / -f |grep Type" on $node is:}; + foreach my $o (@$output) { + push @{$rsp->{data}}, $o; + } + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC) { #failed + my $rsp = {}; + $rsp->{data}->[0] = qq{The "xdsh" command fails to run on the $node}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + # parse the output of "stat / -f |grep Type", + $output->[0] =~ m/Type:\s+(.*)$/; + my $fstype = $1; + if ($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{The file type is $fstype}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + # make sure the rootfs type is not nfs or tmpfs + if($fstype eq "nfs" or $fstype eq "tmpfs") { + my $rsp = {}; + $rsp->{data}->[0] = qq{This node might not be diskful Linux node, please check it.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + my $distname = $os; + while ( $distname and ( ! -r "$::XCATROOT/share/xcat/netboot/$distname/") ) { + chop($distname); + } + + unless($distname) { + $callback->({error=>["Unable to find $::XCATROOT/share/xcat/netboot directory for $os"], errorcode => [1]}); + return; + } + + my $exlistloc = xCAT::SvrUtils->get_imgcapture_exlist_file_name("$installroot/custom/netboot/$distname", $profile, $os, $arch); + unless ($exlistloc) { + $exlistloc = xCAT::SvrUtils->get_imgcapture_exlist_file_name("$::XCATROOT/share/xcat/netboot/$distname", $profile, $os, $arch); + } + + my $xcat_imgcapture_tmpfile = "/tmp/xcat_imgcapture.$$"; + + my $excludestr = "cd /; find ."; + + if($exlistloc) { + my $exlist; + open $exlist, "<", $exlistloc; + + while(<$exlist>) { + $_ =~ s/^\s+//; + chomp $_; + unless($_ =~ m{^#}) { + $excludestr .= qq{ ! -path "$_"}; + } + } + + close $exlist; + } else { + # the following directories must be exluded when capturing the image + my @default_exlist = ("./tmp/*", "./proc/*", "./sys/*", "./dev/*", "./xcatpost/*", "./install/*"); + foreach my $item (@default_exlist) { + $excludestr .= qq{ ! -path "$item"}; + } + } + + $excludestr .= " |cpio -H newc -o |gzip -c - >$xcat_imgcapture_tmpfile"; + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{The excludestr is "$excludestr"}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + # run the command via "xdsh" + + xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg => ["echo -n >$xcat_imgcapture_tmpfile"]}, $subreq, -1, 1); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{running "echo -n > $xcat_imgcapture_tmpfile" on $node}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC) { # the xdsh command fails + my $rsp = {}; + $rsp->{data}->[0] = qq{The "xdsh" command fails to run "echo -n > $xcat_imgcapture_tmpfile" on $node}; + xCAT:MsgUtils->message("E", $rsp, $callback); + return; + } + + my $rsp = {}; + $rsp->{data}->[0] = qq{Capturing image on $node...}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{running "$excludestr" on $node via the "xdsh" command}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg => [$excludestr]}, $subreq, -1, 1); + + if($::RUNCMD_RC) { # the xdsh command fails + my $rsp = {}; + $rsp->{data}->[0] = qq{The "xdsh" command fails to run "$excludestr" on $node}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + $rsp = {}; + $rsp->{data}->[0] = qq{Transfering the image captured on $node back...}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + # copy the image captured on $node back via the "scp" command + xCAT::Utils->runcmd("scp $node:$xcat_imgcapture_tmpfile $xcat_imgcapture_tmpfile"); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{Running "scp $node:$xcat_imgcapture_tmpfile $xcat_imgcapture_tmpfile"}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC) { + my $rsp ={}; + $rsp->{data}->[0] = qq{The scp command fails}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + xCAT::Utils->runxcmd({command => ["xdsh" ], node => [$node], arg => ["rm -f $xcat_imgcapture_tmpfile"]}, $subreq, -1, 1); + + # extract the $xcat_imgcapture_tmpfile file to /install/netboot/$os/$arch/$profile/rootimg + my $rootimgdir = "$installroot/netboot/$os/$arch/$profile/rootimg"; + + # empty the rootimg directory before extracting the image captured on the diskful Linux node + if( -d $rootimgdir ) { + unlink $rootimgdir; + } + mkpath($rootimgdir); + + xCAT::Utils->runcmd("cd $rootimgdir; gzip -cd $xcat_imgcapture_tmpfile|cpio -idum"); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{Extracting the image to $rootimgdir}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + if($::RUNCMD_RC) { + my $rsp = {}; + $rsp->{data}->[0] = qq{fails to run the "gzip -cd xx |cpio -idum" command}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{Creating the spots exluded when capturing on $node...}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + # the next step is to call "genimage" + my $platform = getplatform($os); + if( -e "$::XCATROOT/share/xcat/netboot/$platform/genimage" ) { + my $cmd; + + if( $osimg ) { + $cmd = "$::XCATROOT/bin/genimage $osimg "; + } else { + $cmd = "$::XCATROOT/share/xcat/netboot/$platform/genimage -o $os -a $arch -p $profile "; + } + + if($bootif) { + $cmd .= "-i $bootif "; + } + if($netdriver) { + $cmd .= "-n $netdriver"; + } + + my $rsp = {}; + $rsp->{data}->[0] = qq{Generating kernel and initial ramdisks...}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{"The genimage command is: $cmd"}; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + my @cmdoutput = xCAT::Utils->runcmd($cmd, 0); + if($::RUNCMD_RC) { + my $rsp = {}; + foreach (@cmdoutput) { + push @{$rsp->{data}}, $_; + } + xCAT::MsgUtils->message("E", $rsp, $callback); + unlink $xcat_imgcapture_tmpfile; + return; + } + } else { + my $rsp = {}; + $rsp->{data}->[0] = qq{Can't run the "genimage" command for $os}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return; + } + + my $rsp = {}; + $rsp->{data}->[0] = qq{Done.}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + unlink $xcat_imgcapture_tmpfile; + + return 0; +} + +sub getplatform { + my $os = shift; + my $platform; + if ($os =~ m/rh.*/) { + $platform = "rh"; + } elsif ($os =~ m/centos.*/) { + $platform = "centos"; + } elsif ($os =~ m/fedora.*/) { + $platform = "fedora"; + } elsif ($os =~ m/SL.*/) { + $platform = "SL"; + } elsif ($os =~ m/sles.*/) { + $platform = "sles"; + } elsif ($os =~ m/suse.*/) { + $platform = "suse"; + } + + return $platform; +} + +sub sysclone_configserver{ + my ($server, $osimage, $callback, $subreq) = @_; + + # check if systemimager is installed on the imager server + my $rsp = {}; + $rsp->{data}->[0] = qq{Checking if systemimager packages are installed on $server.}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + my $cmd = "rpm -qa|grep systemimager-server"; + my $output = xCAT::Utils->runcmd("$cmd", -1); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{the output of $cmd on $server is:}; + push @{$rsp->{data}}, $output; + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC != 0) { #failed + my $rsp = {}; + $rsp->{data}->[0] = qq{systemimager-server is not installed on the $server.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + # update /etc/systemimager/systemimager.conf + my $rc = `sed -i "s/\\/var\\/lib\\/systemimager/\\/install\\/sysclone/g" /etc/systemimager/systemimager.conf`; + if (!(-e $sysclone_home)) + { + mkpath($sysclone_home); + } + + my $sysclone_images = $sysclone_home . "/images"; + if (!(-e $sysclone_images)) + { + mkpath($sysclone_images); + } + + my $sysclone_scripts = $sysclone_home . "/scripts"; + if (!(-e $sysclone_scripts)) + { + mkpath($sysclone_scripts); + } + + my $sysclone_overrides = $sysclone_home . "/overrides"; + if (!(-e $sysclone_overrides)) + { + mkpath($sysclone_overrides); + } + + my $imagedir; + my $osimgtab = xCAT::Table->new('osimage'); + my $entry = ($osimgtab->getAllAttribsWhere("imagename = '$osimage'", 'ALL' ))[0]; + if(!$entry){ + $imagedir = $sysclone_home . "/images/" . $osimage; + }else{ + my $osimagetab = xCAT::Table->new('linuximage'); + my $osimageentry = $osimagetab->getAttribs({imagename => $osimage}, 'rootimgdir'); + if($osimageentry){ + $imagedir = $osimageentry->{rootimgdir}; + if (!(-e $imagedir)){ + mkpath($imagedir); + } + }else{ + $imagedir = $sysclone_home . "/images/" . $osimage; + $cmd = "chdef -t osimage $osimage rootimgdir=$imagedir"; + $rc = `$cmd`; + } + } + + $imagedir =~ s/^(\/.*)\/.+\/?$/$1/; + $imagedir =~ s/\//\\\\\//g; + $imagedir = "DEFAULT_IMAGE_DIR = ".$imagedir; + + my $olddir = `more /etc/systemimager/systemimager.conf |grep DEFAULT_IMAGE_DIR`; + $olddir =~ s/\//\\\\\//g; + chomp($olddir); + + $cmd= "sed -i \"s/$olddir/$imagedir/\" /etc/systemimager/systemimager.conf"; + $rc = `$cmd`; + + # update /etc/systemimager/rsync_stubs/10header to generate new /etc/systemimager/rsyncd.conf + $rc = `sed -i "s/\\/var\\/lib\\/systemimager/\\/install\\/sysclone/g" /etc/systemimager/rsync_stubs/10header`; + $rc = `export PERL5LIB=/usr/lib/perl5/site_perl/;LANG=C si_mkrsyncd_conf`; + + return 0; +} + +sub sysclone_prepclient { + my ($node, $server, $osimage, $callback, $subreq) = @_; + + # check if systemimager is installed on the golden client + my $rsp = {}; + $rsp->{data}->[0] = qq{Checking if systemimager packages are installed on $node.}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + my $cmd = "rpm -qa|grep systemimager-client"; + my $output = xCAT::Utils->runxcmd({command => ["xdsh"], node => [$node], arg =>[$cmd]}, $subreq, 0, 1); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{the output of $cmd on $node is:}; + foreach my $o (@$output) { + push @{$rsp->{data}}, $o; + } + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC != 0) { #failed + my $rsp = {}; + $rsp->{data}->[0] = qq{systemimager-client is not installed on the $node.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + # prepare golden client + my $rsp = {}; + $rsp->{data}->[0] = qq{Preparing osimage $osimage on $node.}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + my $cmd = "export PERL5LIB=/usr/lib/perl5/site_perl/;LANG=C si_prepareclient --server $server --no-uyok --yes"; + my $output = xCAT::Utils->runxcmd( + { + command => ["xdsh"], + node => [$node], + arg =>["-s", $cmd] + }, + $subreq, 0, 1); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{the output of $cmd on $node is:}; + foreach my $o (@$output) { + push @{$rsp->{data}}, $o; + } + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC != 0) { #failed + my $rsp = {}; + $rsp->{data}->[0] = qq{$cmd failed on the $node.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + # fix systemimager bug + $cmd = qq{sed -i 's/p_name=\"(v1)\"/p_name=\"-\"/' /etc/systemimager/autoinstallscript.conf}; + $output = xCAT::Utils->runxcmd( + { + command => ["xdsh"], + node => [$node], + arg =>[$cmd] + }, + $subreq, 0, 1); + + my @nodes = ($node); + my $nodetypetab = xCAT::Table->new("nodetype"); + my $nthash = $nodetypetab->getNodesAttribs(\@nodes, ['arch']); + my $tmp = $nthash->{$node}->[0]->{arch}; + if ( $tmp eq 'ppc64'){ + $cmd = qq(if ! cat /etc/systemimager/autoinstallscript.conf |grep 'part num=\\\"1\\\"' |grep 'id=' >/dev/null ;then sed -i 's:\\(.*\\):\\1 id=\\\"41\\\" \\2:' /etc/systemimager/autoinstallscript.conf;fi); + $output = xCAT::Utils->runxcmd( + { + command => ["xdsh"], + node => [$node], + arg =>[$cmd] + }, + $subreq, 0, 1); + } + + return 0; +} + +sub sysclone_getimg{ + my ($node, $server, $osimage, $callback, $subreq) = @_; + + my $rsp = {}; + $rsp->{data}->[0] = qq{Getting osimage "$osimage" from $node to $server.}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + my $cmd = "export PERL5LIB=/usr/lib/perl5/site_perl/;"; + $cmd .= "LANG=C si_getimage -golden-client $node -image $osimage -ip-assignment dhcp -post-install reboot -quiet -update-script YES"; + my $output = xCAT::Utils->runcmd($cmd, -1); + if($verbose) { + my $rsp = {}; + $rsp->{data}->[0] = qq{the output of $cmd on $server is:}; + if(ref $output){ + foreach my $o (@$output) { + push @{$rsp->{data}}, $o; + } + } else { + @{$rsp->{data}} = ($output); + } + xCAT::MsgUtils->message("D", $rsp, $callback); + } + + if($::RUNCMD_RC != 0) { #failed + my $rsp = {}; + $rsp->{data}->[0] = qq{$cmd failed on the $server.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + # use reboot in genesis + my $masterscript = $sysclone_home . "/scripts" . "/$osimage.master"; + my $rc = `sed -i "s/shutdown -r now/reboot -f/g" $masterscript`; + + #on redhat5 and centos5, the fs inode size must be 128 + my $node_osver = getOsVersion($node); + if ( $node_osver =~ /rh.*5.*/ || $node_osver =~ /centos5.*/ ) { + `sed -i "s/mke2fs/mke2fs -I 128/g" $masterscript` + } + return 0; +} + +sub sysclone_createosimgdef{ + my ($node, $server, $osimage, $callback, $subreq) = @_; + my $createnew = 0; + my %osimgdef; + + my $osimgtab = xCAT::Table->new('osimage'); + my $entry = ($osimgtab->getAllAttribsWhere("imagename = '$osimage'", 'ALL' ))[0]; + if($entry){ + my $rsp = {}; + $rsp->{data}->[0] = qq{Using the existing osimage "$osimage" defined on $server.}; + xCAT::MsgUtils->message("I", $rsp, $callback); + return 0; + } + + # try to see if we can get the osimage def from golden client. + my $nttab = xCAT::Table->new('nodetype'); + if (!$nttab){ + my $rsp = {}; + $rsp->{data}->[0] = qq{Can not open nodebype table.}; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + my @nodes = ($node); + my $nthash = $nttab->getNodesAttribs(\@nodes, ['node', 'provmethod']); + my $tmp = $nthash->{$node}->[0]; + if (($tmp) && ($tmp->{provmethod})){ + + my %objtype; + my $oldimg = $tmp->{provmethod}; + + # see if osimage exists + $objtype{$oldimg} = 'osimage'; + my %imagedef = xCAT::DBobjUtils->getobjdefs(\%objtype, $callback); + if (!($imagedef{$oldimg}{osvers})){ # just select one attribute for test + # create new one + $createnew = 1; + }else{ + # based on the existing one + $osimgdef{$osimage} = $imagedef{$oldimg}; + + # only update a few attributes which are meanless for sysclone + $osimgdef{$osimage}{provmethod} = "sysclone"; + $osimgdef{$osimage}{template} = ""; + $osimgdef{$osimage}{otherpkglist} = ""; + $osimgdef{$osimage}{pkglist} = ""; + + if(!($imagedef{$oldimg}{rootimgdir})){ + $imagedef{$oldimg}{rootimgdir} = $sysclone_home . "/images/" . $osimage; + + my $imagedir = $imagedef{$oldimg}{rootimgdir}; + $imagedir =~ s/^(\/.*)\/.+\/?$/$1/; + $imagedir =~ s/\//\\\\\//g; + $imagedir = "DEFAULT_IMAGE_DIR = ".$imagedir; + + my $olddir = `more /etc/systemimager/systemimager.conf |grep DEFAULT_IMAGE_DIR`; + $olddir =~ s/\//\\\\\//g; + chomp($olddir); + + my $cmd= "sed -i \"s/$olddir/$imagedir/\" /etc/systemimager/systemimager.conf"; + my $rc = `$cmd`; + } + } + } else { + $createnew = 1; + } + + if($createnew){ + my $file = $sysclone_home . "/images/" . $osimage. "/etc/systemimager/boot/ARCH"; + my $cmd = "cat $file"; + my $output = xCAT::Utils->runcmd($cmd, -1); + chomp $output; + my $arch = $output; + my $osver = getOsVersion($node); + my $platform = getplatform($osver); + + # create a baic one + $osimgdef{$osimage}{objtype} = "osimage"; + $osimgdef{$osimage}{provmethod} = "sysclone"; + $osimgdef{$osimage}{profile} = "compute"; # use compute? + $osimgdef{$osimage}{imagetype} = "Linux"; + $osimgdef{$osimage}{osarch} = $arch; + $osimgdef{$osimage}{osname} = "Linux"; + $osimgdef{$osimage}{osvers} = $osver; + $osimgdef{$osimage}{osdistroname} = "$osver-$arch"; + + $osimgdef{$osimage}{rootimgdir} = $sysclone_home . "/images/" . $osimage; + my $imagedir = $osimgdef{$osimage}{rootimgdir}; + $imagedir =~ s/^(\/.*)\/.+\/?$/$1/; + $imagedir =~ s/\//\\\\\//g; + $imagedir = "DEFAULT_IMAGE_DIR = ".$imagedir; + my $olddir = `more /etc/systemimager/systemimager.conf |grep DEFAULT_IMAGE_DIR`; + $olddir =~ s/\//\\\\\//g; + chomp($olddir); + my $cmd= "sed -i \"s/$olddir/$imagedir/\" /etc/systemimager/systemimager.conf"; + my $rc = `$cmd`; + + #$osimgdef{$osimage}{pkgdir} = "/install/$osver/$arch"; + #$osimgdef{$osimage}{otherpkgdir} = "/install/post/otherpkgs/$osver/$arch"; + } + + if (xCAT::DBobjUtils->setobjdefs(\%osimgdef) != 0) + { + my $rsp; + $rsp->{data}->[0] = "Could not create xCAT definition for $osimage.\n"; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + my $rsp = {}; + $rsp->{data}->[0] = qq{The osimage definition for $osimage was created.}; + xCAT::MsgUtils->message("D", $rsp, $callback); + + return 0; +} + +sub getOsVersion { + my ($node) = @_; + + my $os = ''; + my $version = ''; + + # Get operating system + my $release = `ssh -o ConnectTimeout=2 $node "cat /etc/*release"`; + my @lines = split('\n', $release); + if (grep(/SLES|Enterprise Server/, @lines)) { + $os = 'sles'; + $version = $lines[0]; + $version =~ tr/\.//; + $version =~ s/[^0-9]*([0-9]+).*/$1/; + $os = $os . $version; + + # Append service level + $version = `echo "$release" | grep "LEVEL"`; + $version =~ tr/\.//; + $version =~ s/[^0-9]*([0-9]+).*/$1/; + $os = $os . 'sp' . $version; + } elsif (grep(/Red Hat/, @lines)) { + $os = "rh"; + $version = $lines[0]; + $version =~ s/[^0-9]*([0-9.]+).*/$1/; + if ($lines[0] =~ /AS/) { $os = 'rhas' } + elsif ($lines[0] =~ /ES/) { $os = 'rhes' } + elsif ($lines[0] =~ /WS/) { $os = 'rhws' } + elsif ($lines[0] =~ /Server/) { $os = 'rhels' } + elsif ($lines[0] =~ /Client/) { $os = 'rhel' } + #elsif (-f "/etc/fedora-release") { $os = 'rhfc' } + $os = $os . $version; + } + elsif (grep (/CentOS/, @lines)) { + $os = "centos"; + $version = $lines[0]; + $version =~ s/[^0-9]*([0-9.]+).*/$1/; + $os = $os . $version; + } + elsif (grep (/Fedora/, @lines)) { + $os = "fedora"; + $version = $lines[0]; + $version =~ s/[^0-9]*([0-9.]+).*/$1/; + $os = $os . $version; + } + + + return $os; +} +1; diff --git a/xCAT-server/lib/xcat/plugins/packimage.pm b/xCAT-server/lib/xcat/plugins/packimage.pm index e69de29bb..02af3abc3 100755 --- a/xCAT-server/lib/xcat/plugins/packimage.pm +++ b/xCAT-server/lib/xcat/plugins/packimage.pm @@ -0,0 +1,629 @@ +package xCAT_plugin::packimage; +BEGIN +{ + $::XCATROOT = $ENV{'XCATROOT'} ? $ENV{'XCATROOT'} : '/opt/xcat'; +} +use lib "$::XCATROOT/lib/perl"; +use Data::Dumper; +use xCAT::Table; +use Getopt::Long; +use File::Path; +use File::Copy; +use Cwd; +use File::Temp; +use File::Basename; +use File::Path; +#use xCAT::Utils qw(genpassword); +use xCAT::Utils; +use xCAT::TableUtils; +use xCAT::SvrUtils; +Getopt::Long::Configure("bundling"); +Getopt::Long::Configure("pass_through"); + + +my $verbose = 0; +#$verbose = 1; + +sub handled_commands { + return { + packimage => "packimage", + } +} + +sub process_request { + my $request = shift; + my $callback = shift; + my $doreq = shift; + my $installroot = xCAT::TableUtils->getInstallDir(); + + @ARGV = @{$request->{arg}}; + my $argc = scalar @ARGV; + if ($argc == 0) { + $callback->({info=>["packimage -h \npackimage -v \npackimage imagename"]}); + return; + } + my $osver; + my $arch; + my $profile; + my $method='cpio'; + my $exlistloc; + my $syncfile; + my $rootimg_dir; + my $destdir; + my $imagename; + my $dotorrent; + + GetOptions( + "profile|p=s" => \$profile, + "arch|a=s" => \$arch, + "osver|o=s" => \$osver, + "method|m=s" => \$method, + "tracker=s" => \$dotorrent, + "help|h" => \$help, + "version|v" => \$version + ); + if ($version) { + my $version = xCAT::Utils->Version(); + $callback->({info=>[$version]}); + return; + } + if ($help) { + $callback->({info=>["packimage -h \npackimage -v \npackimage imagename"]}); + return; + } + + if (@ARGV > 0) { + $imagename=$ARGV[0]; + if ($arch or $osver or $profile) { + $callback->({error=>["-o, -p and -a options are not allowed when a image name is specified."],errorcode=>[1]}); + return; + } + # load the module in memory + eval {require("$::XCATROOT/lib/perl/xCAT/Table.pm")}; + if ($@) { + $callback->({error=>[$@],errorcode=>[1]}); + return; + } + + # get the info from the osimage and linux + my $osimagetab=xCAT::Table->new('osimage', -create=>1); + unless ($osimagetab) { + $callback->({error=>["The osimage table cannot be opened."],errorcode=>[1]}); + return; + } + my $linuximagetab=xCAT::Table->new('linuximage', -create=>1); + unless ($linuximagetab) { + $callback->({error=>["The linuximage table cannot be opened."],errorcode=>[1]}); + return; + } + (my $ref) = $osimagetab->getAttribs({imagename => $imagename}, 'osvers', 'osarch', 'profile', 'provmethod', 'synclists'); + unless ($ref) { + $callback->({error=>["Cannot find image \'$imagename\' from the osimage table."],errorcode=>[1]}); + return; + } + (my $ref1) = $linuximagetab->getAttribs({imagename => $imagename}, 'exlist', 'rootimgdir'); + unless ($ref1) { + $callback->({error=>["Cannot find $imagename from the linuximage table."],errorcode=>[1]}); + return; + } + + $osver=$ref->{'osvers'}; + $arch=$ref->{'osarch'}; + $profile=$ref->{'profile'}; + $syncfile=$ref->{'synclists'}; + my $provmethod=$ref->{'provmethod'}; + + unless ($osver and $arch and $profile and $provmethod) { + $callback->({error=>["osimage.osvers, osimage.osarch, osimage.profile and osimage.provmethod must be specified for the image $imagename in the database."],errorcode=>[1]}); + return; + } + + if ($provmethod ne 'netboot') { + $callback->({error=>["\'$imagename\' cannot be used to build diskless image. Make sure osimage.provmethod is 'netboot'."],errorcode=>[1]}); + return; + } + + $exlistloc =$ref1->{'exlist'}; + $destdir=$ref1->{'rootimgdir'}; + } else { + $provmethod="netboot"; + unless ($osver) { + $callback->({error=>["Please specify a os version with the -o flag"],errorcode=>[1]}); + return; + } + unless ($arch) { + $arch = `uname -m`; + chomp($arch); + $arch = "x86" if ($arch =~ /i.86$/); + } + + unless ($profile) { + $callback->({error=>["Please specify a profile name with -p flag"],errorcode=>[1]}); + return; + } + } + + unless ($destdir) { + $destdir="$installroot/netboot/$osver/$arch/$profile"; + } + $rootimg_dir="$destdir/rootimg"; + + my $distname = $osver; + until (-r "$::XCATROOT/share/xcat/netboot/$distname/" or not $distname) { + chop($distname); + } + unless ($distname) { + $callback->({error=>["Unable to find $::XCATROOT/share/xcat/netboot directory for $osver"],errorcode=>[1]}); + return; + } + unless ($installroot) { + $callback->({error=>["No installdir defined in site table"],errorcode=>[1]}); + return; + } + my $oldpath=cwd(); + unless ($imagename) { + $exlistloc=xCAT::SvrUtils->get_exlist_file_name("$installroot/custom/netboot/$distname", $profile, $osver, $arch); + unless ($exlistloc) { $exlistloc=xCAT::SvrUtils->get_exlist_file_name("$::XCATROOT/share/xcat/netboot/$distname", $profile, $osver, $arch); } + + #save the settings into DB, it will not update if the image already exist + my @ret = xCAT::SvrUtils->update_tables_with_diskless_image($osver, $arch, $profile, "netboot"); + unless ($ret[0] eq 0) { + $callback->({error=>["Error when updating the osimage tables: " . $ret[1]], errorcode=>[1]}); + return; + } + } + + #before generating rootimg.gz, copy $installroot/postscripts into the image at /xcatpost + if( -e "$rootimg_dir/xcatpost" ) { + system("rm -rf $rootimg_dir/xcatpost"); + } + + system("mkdir -p $rootimg_dir/xcatpost"); + system("cp -r $installroot/postscripts/* $rootimg_dir/xcatpost/"); + + #put the image name and timestamp into diskless image when it is packed. + `echo IMAGENAME="'$imagename'" > $rootimg_dir/opt/xcat/xcatinfo`; + + my $timestamp = `date`; + chomp $timestamp; + `echo TIMESTAMP="'$timestamp'" >> $rootimg_dir/opt/xcat/xcatinfo`; + + + # before generating rootimg.gz or rootimg.sfs, need to switch the rootimg to stateless mode if necessary + my $rootimg_status = 0; # 0 means stateless mode, while 1 means statelite mode + $rootimg_status = 1 if (-f "$rootimg_dir/.statelite/litefile.save"); + + my $ref_liteList; # get the litefile entries + + my @ret = xCAT::Utils->runcmd("ilitefile $osver-$arch-statelite-$profile" , 0, 1); + $ref_liteList = $ret[0]; + + my %liteHash; # create hash table for the entries in @listList + if (parseLiteFiles($ref_liteList, \%liteHash)) { + $callback->({error=>["Failed for parsing litefile table!"], errorcode=>[1]}); + return; + } + + $verbose && $callback->({data=>["rootimg_status = $rootimg_status at line " . __LINE__ ]}); + + if($rootimg_status) { + xCAT::Utils->runcmd("mkdir $rootimg_dir/.statebackup", 0, 1); + # read through the litefile table to decide which file/directory should be restore + my $defaultloc = "$rootimg_dir/.default"; + foreach my $entry (keys %liteHash) { + my @tmp = split /\s+/, $entry; + my $filename = $tmp[1]; + my $fileopt = $tmp[0]; + + if ($fileopt =~ m/link/) { + # backup them into .statebackup dirctory + # restore the files with "link" options + if ($filename =~ m/\/$/) { + chop $filename; + } + # create the parent directory if $filename's directory is not there, + my $parent = dirname $filename; + unless ( -d "$rootimg_dir/.statebackup$parent" ) { + unlink "$rootimg_dir/.statebackup$parent"; + $verbose && $callback->({data=>["mkdir -p $rootimg_dir/.statebackup$parent"]}); + xCAT::Utils->runcmd("mkdir -p $rootimg_dir/.statebackup$parent", 0, 1); + } + $verbose && $callback->({data=>["backing up the file $filename.. at line " . __LINE__ ]}); + $verbose && print "++ $defaultloc$filename ++ $rootimg_dir$filename ++ at " . __LINE__ . "\n"; + xCAT::Utils->runcmd("mv $rootimg_dir$filename $rootimg_dir/.statebackup$filename", 0, 1); + xCAT::Utils->runcmd("cp -r -a $defaultloc$filename $rootimg_dir$filename", 0, 1); + } + } + } + + # TODO: following the old genimage code, to update the stateles-only files/directories + # # another file should be /opt/xcat/xcatdsklspost, but it seems not necessary + xCAT::Utils->runcmd("mv $rootimg_dir/etc/init.d/statelite $rootimg_dir/.statebackup/statelite ", 0, 1) if ( -e "$rootimg_dir/etc/init.d/statelite"); + if ( -e "$rootimg_dir/usr/share/dracut" ) { + # currently only used for redhat families, not available for SuSE families + if ( -e "$rootimg_dir/etc/rc.sysinit.backup" ) { + xCAT::Utils->runcmd("mv $rootimg_dir/etc/rc.sysinit.backup $rootimg_dir/etc/rc.sysinit", 0, 1); + } + } + + #restore the install.netboot of xcat dracut module + if(-e "$rootimg_dir/usr/lib/dracut/modules.d/97xcat/install"){ + xCAT::Utils->runcmd("mv $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install $rootimg_dir/.statebackup/install", 0, 1); + } + xCAT::Utils->runcmd("cp /opt/xcat/share/xcat/netboot/rh/dracut_033/install.netboot $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install", 0, 1); + + + my $xcat_packimg_tmpfile = "/tmp/xcat_packimg.$$"; + my $excludestr = "find . -xdev "; + my $includestr; + if ($exlistloc) { + my @excludeslist = split ',', $exlistloc; + foreach my $exlistlocname ( @excludeslist ) { + my $exlist; + my $excludetext; + open($exlist,"<",$exlistlocname); + system("echo -n > $xcat_packimg_tmpfile"); + while (<$exlist>) { + $excludetext .= $_; + } + close($exlist); + + #handle the #INLCUDE# tag recursively + my $idir = dirname($exlistlocname); + my $doneincludes=0; + while (not $doneincludes) { + $doneincludes=1; + if ($excludetext =~ /#INCLUDE:[^#^\n]+#/) { + $doneincludes=0; + $excludetext =~ s/#INCLUDE:([^#^\n]+)#/include_file($1,$idir)/eg; + } + + } + + my @tmp=split("\n", $excludetext); + foreach (@tmp) { + chomp $_; + s/\s*#.*//; #-- remove comments + next if /^\s*$/; #-- skip empty lines + if (/^\+/) { + s/^\+//; #remove '+' + $includestr .= "-path '". $_ ."' -o "; + } else { + s/^\-//; #remove '-' if any + $excludestr .= "'!' -path '".$_."' -a "; + } + } + } + } + + # the files specified for statelite should be excluded + my @excludeStatelite = ("./etc/init.d/statelite", "./etc/rc.sysinit.backup", "./.statelite*", "./.default*", "./.statebackup*"); + foreach my $entry (@excludeStatelite) { + $excludestr .= "'!' -path '" . $entry . "' -a "; + } + + $excludestr =~ s/-a $//; + if ($includestr) { + $includestr =~ s/-o $//; + $includestr = "find . -xdev " . $includestr; + } + + print "\nexcludestr=$excludestr\n\n includestr=$includestr\n\n"; # debug + + # add the xCAT post scripts to the image + unless ( -d "$rootimg_dir") { + $callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"], errorcode=>[1]}); + return; + } + + # some rpms like atftp mount the rootimg/proc to /proc, we need to make sure rootimg/proc is free of junk + # before packaging the image + system("umount $rootimg_dir/proc"); + copybootscript($installroot, $rootimg_dir, $osver, $arch, $profile, $callback); + my $passtab = xCAT::Table->new('passwd'); + if ($passtab) { + my $pass = 'cluster'; + (my $pent) = $passtab->getAttribs({key=>'system',username=>'root'},'password'); + if ($pent and defined ($pent->{password})) { + $pass = $pent->{password}; + } + my $oldmask=umask(0077); + my $shadow; + open($shadow,"<","$rootimg_dir/etc/shadow"); + my @shadents = <$shadow>; + close($shadow); + open($shadow,">","$rootimg_dir/etc/shadow"); + # 1 - MD5, 5 - SHA256, 6 - SHA512 + unless (($pass =~ /^\$1\$/) || ($pass =~ /^\$5\$/) || ($pass =~ /^\$6\$/)) { + $pass = crypt($pass,'$1$'.xCAT::Utils::genpassword(8)); + } + print $shadow "root:$pass:13880:0:99999:7:::\n"; + foreach (@shadents) { + unless (/^root:/) { + print $shadow "$_"; + } + } + close($shadow); + umask($oldmask); + } + + # sync fils configured in the synclist to the rootimage + $syncfile = xCAT::SvrUtils->getsynclistfile(undef, $osver, $arch, $profile, "netboot", $imagename); + if (defined ($syncfile) && -f $syncfile + && -d $rootimg_dir) { + print "sync files from $syncfile to the $rootimg_dir\n"; + system("$::XCATROOT/bin/xdcp -i $rootimg_dir -F $syncfile"); + } + + my $verb = "Packing"; + + my $temppath; + my $oldmask; + unless ( -d $rootimg_dir) { + $callback->({error=>["$rootimg_dir does not exist, run genimage -o $osver -p $profile on a server with matching architecture"]}); + return; + } + $callback->({data=>["$verb contents of $rootimg_dir"]}); + unlink("$destdir/rootimg.gz"); + unlink("$destdir/rootimg.sfs"); + if ($method =~ /cpio/) { + if ( ! $exlistloc ) { + $excludestr = "find . -xdev |cpio -H newc -o | gzip -c - > ../rootimg.gz"; + }else { + chdir("$rootimg_dir"); + system("$excludestr >> $xcat_packimg_tmpfile"); + if ($includestr) { + system("$includestr >> $xcat_packimg_tmpfile"); + } + #$excludestr =~ s!-a \z!|cpio -H newc -o | gzip -c - > ../rootimg.gz!; + $excludestr = "cat $xcat_packimg_tmpfile|cpio -H newc -o | gzip -c - > ../rootimg.gz"; + } + $oldmask = umask 0077; + } elsif ($method =~ /squashfs/) { + $temppath = mkdtemp("/tmp/packimage.$$.XXXXXXXX"); + chmod 0755,$temppath; + chdir("$rootimg_dir"); + system("$excludestr >> $xcat_packimg_tmpfile"); + if ($includestr) { + system("$includestr >> $xcat_packimg_tmpfile"); + } + $excludestr = "cat $xcat_packimg_tmpfile|cpio -dump $temppath"; + } else { + $callback->({error=>["Invalid method '$method' requested"],errorcode=>[1]}); + } + chdir("$rootimg_dir"); + `$excludestr`; + if ($method =~ /cpio/) { + chmod 0644,"$destdir/rootimg.gz"; + if ($dotorrent) { + my $currdir = getcwd; + chdir($destdir); + unlink("rootimg.gz.metainfo"); + system("ctorrent -t -u $dotorrent -l 1048576 -s rootimg.gz.metainfo rootimg.gz"); + chmod 0644, "rootimg.gz.metainfo"; + chdir($currdir); + } + umask $oldmask; + } elsif ($method =~ /squashfs/) { + my $flags; + if ($arch =~ /x86/) { + $flags="-le"; + } elsif ($arch =~ /ppc/) { + $flags="-be"; + } + + if( $osver =~ /rhels/ && $osver !~ /rhels5/) { + $flags=""; + } + + if (! -x "/sbin/mksquashfs" && ! -x "/usr/bin/mksquashfs" ) { + $callback->({error=>["mksquashfs not found, squashfs-tools rpm should be installed on the management node"],errorcode=>[1]}); + return; + } + my $rc = system("mksquashfs $temppath ../rootimg.sfs $flags"); + if ($rc) { + $callback->({error=>["mksquashfs could not be run successfully"],errorcode=>[1]}); + return; + } + $rc = system("rm -rf $temppath"); + if ($rc) { + $callback->({error=>["Failed to clean up temp space"],errorcode=>[1]}); + return; + } + chmod(0644,"../rootimg.sfs"); + } + system("rm -f $xcat_packimg_tmpfile"); + + # move the files in /.statebackup back to rootimg_dir + if ($rootimg_status) { # statelite mode + foreach my $entry (keys %liteHash) { + my @tmp = split /\s+/, $entry; + my $filename = $tmp[1]; + my $fileopt = $tmp[0]; + if ($fileopt =~ m/link/) { + chop $filename if ($filename =~ m/\/$/); + xCAT::Utils->runcmd("rm -rf $rootimg_dir$filename", 0, 1); + xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup$filename $rootimg_dir$filename", 0, 1); + } + } + + xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup/install $rootimg_dir/usr/lib/dracut/modules.d/97xcat/install", 0, 1); + xCAT::Utils->runcmd("mv $rootimg_dir/.statebackup/statelite $rootimg_dir/etc/init.d/statelite", 0, 1); + xCAT::Utils->runcmd("rm -rf $rootimg_dir/.statebackup", 0, 1); + } + + + chdir($oldpath); +} + +########################################################### +# +# copybootscript - copy the xCAT diskless init scripts to the image +# +############################################################# +sub copybootscript { + + my $installroot = shift; + my $rootimg_dir = shift; + my $osver = shift; + my $arch = shift; + my $profile = shift; + my $callback = shift; + my @timezone = xCAT::TableUtils->get_site_attribute("timezone"); + + if ( -f "$installroot/postscripts/xcatdsklspost") { + + # copy the xCAT diskless post script to the image + mkpath("$rootimg_dir/opt/xcat"); + + copy ("$installroot/postscripts/xcatdsklspost", "$rootimg_dir/opt/xcat/xcatdsklspost"); + if($timezone[0]) { + copy ("$rootimg_dir/usr/share/zoneinfo/$timezone[0]", "$rootimg_dir/etc/localtime"); + } + + + chmod(0755,"$rootimg_dir/opt/xcat/xcatdsklspost"); + + } else { + + my $rsp; + push @{$rsp->{data}}, "Could not find the script $installroot/postscripts/xcatdsklspost.\n"; + xCAT::MsgUtils->message("E", $rsp, $callback); + return 1; + } + + + #if ( -f "$installroot/postscripts/xcatpostinit") { + # copy the linux diskless init script to the image + # - & set the permissions + #copy ("$installroot/postscripts/xcatpostinit","$rootimg_dir/etc/init.d/xcatpostinit"); + + #chmod(0755,"$rootimg_dir/etc/init.d/xcatpostinit"); + + # run chkconfig + #my $chkcmd = "chroot $rootimg_dir chkconfig --add xcatpostinit"; + #symlink "/etc/init.d/xcatpostinit","$rootimg_dir/etc/rc3.d/S84xcatpostinit"; + #symlink "/etc/init.d/xcatpostinit","$rootimg_dir/etc/rc4.d/S84xcatpostinit"; + #symlink "/etc/init.d/xcatpostinit","$rootimg_dir/etc/rc5.d/S84xcatpostinit"; + #my $rc = system($chkcmd); + #if ($rc) { + #my $rsp; + # push @{$rsp->{data}}, "Could not run the chkconfig command.\n"; + # xCAT::MsgUtils->message("E", $rsp, $callback); + # return 1; + # } + #} else { + #my $rsp; + # push @{$rsp->{data}}, "Could not find the script $installroot/postscripts/xcatpostinit.\n"; + # xCAT::MsgUtils->message("E", $rsp, $callback); + # return 1; + #} + return 0; +} + +sub include_file +{ + my $file = shift; + my $idir = shift; + my @text = (); + unless ($file =~ /^\//) { + $file = $idir."/".$file; + } + + open(INCLUDE,$file) || \ + return "#INCLUDEBAD:cannot open $file#"; + + while() { + chomp($_); + s/\s+$//; #remove trailing spaces + next if /^\s*$/; #-- skip empty lines + push(@text, $_); + } + + close(INCLUDE); + + return join("\n", @text); +} + +=head3 parseLiteFiles +In the liteentry table, one directory and its sub-items (including sub-directory and entries) can co-exist; +In order to handle such a scenario, one hash is generated to show the hirarachy relationship + +For example, one array with entry names is used as the input: +my @entries = ( + "imagename bind,persistent /var/", + "imagename bind /var/tmp/", + "imagename tmpfs,rw /root/", + "imagename tmpfs,rw /root/.bashrc", + "imagename tmpfs,rw /root/test/", + "imagename bind /etc/resolv.conf", + "imagename bind /var/run/" +); +Then, one hash will generated as: +%hashentries = { + 'bind,persistent /var/' => [ + 'bind /var/tmp/', + 'bind /var/run/' + ], + 'bind /etc/resolv.conf' => undef, + 'tmpfs,rw /root/' => [ + 'tmpfs,rw /root/.bashrc', + 'tmpfs,rw /root/test/' + ] + }; + +Arguments: + one array with entrynames, + one hash to hold the entries parsed + +Returns: + 0 if sucucess + 1 if fail + +=cut + + + +sub parseLiteFiles { + my ($flref, $dhref) = @_; + my @entries = @{$flref}; + + + foreach (@entries) { + my $entry = $_; + my @str = split /\s+/, $entry; + shift @str; + $entry = join "\t", @str; + my $file = $str[1]; + chop $file if ($file =~ m{/$}); + unless (exists $dhref->{"$entry"}) { + my $parent = dirname($file); + # to see whether $parent exists in @entries or not + unless ($parent =~ m/\/$/) { + $parent .= "/"; + } + my @res = grep {$_ =~ m/\Q$parent\E$/} @entries; + my $found = scalar @res; + + if($found eq 1) { # $parent is found in @entries + # handle $res[0]; + my @tmpresentry=split /\s+/, $res[0]; + shift @tmpresentry; + $res[0] = join "\t", @tmpresentry; + chop $parent; + my @keys = keys %{$dhref}; + my $kfound = grep {$_ =~ m/\Q$res[0]\E$/} @keys; + if($kfound eq 0) { + $dhref->{$res[0]} = []; + } + push @{$dhref->{"$res[0]"}}, $entry; + }else { + $dhref->{"$entry"} = (); + } + } + } + + return 0; +} + +1; From 4322c2b5531ea0fdfb6376df7c482b112d009e4b Mon Sep 17 00:00:00 2001 From: ligc Date: Thu, 14 May 2015 04:11:52 -0400 Subject: [PATCH 04/26] remove install|statelite|netboot from usage statements --- xCAT-server/lib/xcat/plugins/DBobjectdefs.pm | 12 ++++-------- xCAT-server/lib/xcat/plugins/grub2.pm | 2 +- xCAT-server/lib/xcat/plugins/pxe.pm | 2 +- xCAT-server/lib/xcat/plugins/xnba.pm | 2 +- xCAT-server/lib/xcat/plugins/yaboot.pm | 2 +- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm b/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm index 196806bde..ddd4a39f0 100755 --- a/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm +++ b/xCAT-server/lib/xcat/plugins/DBobjectdefs.pm @@ -4047,11 +4047,9 @@ sub defmk_usage " [-d | --dynamic] [-w attr==val [-w attr=~val] ...]"; $rsp->{data}->[4] = " [-f | --force] [noderange] [attr=val [attr=val...]]"; - $rsp->{data}->[5] = - " [-u provmethod= profile= [osvers=value] [osarch=value]]\n"; - $rsp->{data}->[6] = + $rsp->{data}->[5] = "\nThe following data object types are supported by xCAT.\n"; - my $n = 7; + my $n = 6; foreach my $t (sort(keys %{xCAT::Schema::defspec})) { @@ -4097,11 +4095,9 @@ sub defch_usage " [-z | --stanza] [-m | --minus] [-p | --plus]"; $rsp->{data}->[5] = " [-w attr==val [-w attr=~val] ... ] [noderange] [attr=val [attr=val...]]\n"; - $rsp->{data}->[6] = - " [-u [provmethod=]|[profile=]|[osvers=value]|[osarch=value]]"; - $rsp->{data}->[7] = + $rsp->{data}->[6] = "\nThe following data object types are supported by xCAT.\n"; - my $n = 8; + my $n = 7; foreach my $t (sort(keys %{xCAT::Schema::defspec})) { diff --git a/xCAT-server/lib/xcat/plugins/grub2.pm b/xCAT-server/lib/xcat/plugins/grub2.pm index c3b128b48..233a5ade4 100644 --- a/xCAT-server/lib/xcat/plugins/grub2.pm +++ b/xCAT-server/lib/xcat/plugins/grub2.pm @@ -23,7 +23,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir(); my %usage = ( - "nodeset" => "Usage: nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage[=]|offline]", + "nodeset" => "Usage: nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline]", ); sub handled_commands { # process noderes:netboot like "grub2-" diff --git a/xCAT-server/lib/xcat/plugins/pxe.pm b/xCAT-server/lib/xcat/plugins/pxe.pm index bdeb8034f..abc766aef 100644 --- a/xCAT-server/lib/xcat/plugins/pxe.pm +++ b/xCAT-server/lib/xcat/plugins/pxe.pm @@ -16,7 +16,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir(); #my $dhcpver = 3; my %usage = ( - "nodeset" => "Usage: nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage[=]|statelite|offline]", + "nodeset" => "Usage: nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline]", ); sub handled_commands { return { diff --git a/xCAT-server/lib/xcat/plugins/xnba.pm b/xCAT-server/lib/xcat/plugins/xnba.pm index 8ed6da148..084ae60ac 100644 --- a/xCAT-server/lib/xcat/plugins/xnba.pm +++ b/xCAT-server/lib/xcat/plugins/xnba.pm @@ -18,7 +18,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir(); #my $dhcpver = 3; my %usage = ( - "nodeset" => "Usage: nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage[=]|statelite|offline]", + "nodeset" => "Usage: nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline]", ); sub handled_commands { return { diff --git a/xCAT-server/lib/xcat/plugins/yaboot.pm b/xCAT-server/lib/xcat/plugins/yaboot.pm index 319d363bd..bed779b5b 100644 --- a/xCAT-server/lib/xcat/plugins/yaboot.pm +++ b/xCAT-server/lib/xcat/plugins/yaboot.pm @@ -20,7 +20,7 @@ my $globaltftpdir = xCAT::TableUtils->getTftpDir(); #my $dhcpver = 3; my %usage = ( - "nodeset" => "Usage: nodeset [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage[=]|offline]", + "nodeset" => "Usage: nodeset [shell|boot|runcmd=bmcsetup|iscsiboot|osimage[=]|offline]", ); sub handled_commands { return { From 74cb3470eb9d14ab4f3f778c90c3d9cbe0ca7f27 Mon Sep 17 00:00:00 2001 From: ligc Date: Thu, 14 May 2015 04:29:23 -0400 Subject: [PATCH 05/26] remove install/netboot/statelite from the manpages of genimage,packimage,nodeset and imgcapture --- xCAT-client/pods/man1/genimage.1.pod | 55 +------------------------- xCAT-client/pods/man1/imgcapture.1.pod | 22 ++--------- xCAT-client/pods/man1/packimage.1.pod | 11 ++---- xCAT-client/pods/man8/nodeset.8.pod | 20 +--------- 4 files changed, 9 insertions(+), 99 deletions(-) diff --git a/xCAT-client/pods/man1/genimage.1.pod b/xCAT-client/pods/man1/genimage.1.pod index 7f8f17f02..be5aa81c9 100644 --- a/xCAT-client/pods/man1/genimage.1.pod +++ b/xCAT-client/pods/man1/genimage.1.pod @@ -8,8 +8,6 @@ B B [B<-o> I] [B<-a> I] [B<-p> I] [B<-i> I] [B<-n> I] [B<--onlyinitrd>] [B<-r> I] [B<-k> I] [B<-g> I] [B<-m> I] [B<-l> I] [B<--permission> I] [B<--interactive>] [B<--dryrun>] [B<--ignorekernelchk>] [B<--noupdate>] I -B B<-o> I [B<-a> I] B<-p> I B<-i> I B<-n> I [B<--onlyinitrd>] [B<-r> I] [B<-k> I] [B<-g> I] [B<-m> I] [B<-l> I] [B<--permission> I] [B<--interactive>] [B<--dryrun>] [B<--noupdate>] - B [B<-h> | B<--help> | B<-v> | B<--version>] @@ -18,27 +16,7 @@ B [B<-h> | B<--help> | B<-v> | B<--version>] Generates a stateless and a statelite image that can be used to boot xCAT nodes in a diskless mode. -The I format of the command is recommended. When specified, genimage will use the osimage definition for information to generate this image. Additional options specified on the command line will override any corresponding previous osimage settings, and will be written back to the osimage definition. - -If I is not specified (old method): - - the default packages included (and excluded) in the image are specified by -/opt/xcat/share/xcat/netboot//[.][.].pkglist and - -/opt/xcat/share/xcat/netboot//[.][.].exlist. - - - Additional packages that are not from the os distro can be specified in a - -/opt/xcat/share/xcat/netboot//[.][.].otherpkgs.pkglist file. - - - Customized package list files will override these files and can be specified under /install/custom/netboot/ directory. - - The generated image will be put in /install/netboot/// directory. - - - osimage definitions will be created in the I and I tables. The newly generated image names will have the following format: - - for stateless: --netboot- - - for statelite: --statelite- - +genimage will use the osimage definition for information to generate this image. Additional options specified on the command line will override any corresponding previous osimage settings, and will be written back to the osimage definition. If B runs on the management node, both the I table and I table will be updated with the given values from the options. @@ -112,7 +90,6 @@ Regenerates the initrd for a stateless image to be used for a diskless install. Regenerates the initrd that is part of a stateless/statelite image that is used to boot xCAT nodes in a stateless/stateli te mode. -The generated initrd will be put in /install/netboot///. The B command will generate two initial ramdisks, one is B for B mode, the other one is B for B mode. @@ -205,36 +182,6 @@ To generate an image, replacing some values in the osimage definition: genimage -i eth0 -n tg3 myimagename -=item 6 -(old method) To generate a fedora8 image for a compute node architecture -x86_64 and place it in the -/install/netboot/fedora8/x86_64/compute/rootimg directory: - - genimage -i eth0 -o fedora8 -p compute - -=item 7 -(old method) - - genimage -i eth0 -r eth1,eth2 -n tg3,bnx2 -o centos5.1 -p compute - -=item 8 -(old method) - - genimage -i eth0 -n tg3,bnx2 -o sles11 -p compute --interactive - -=item 9 -(old method) - - genimage -i eth0 -n igb,e1000e,e1000,bnx2,tg3 -o centos5.4 -p nfsroot --permission 777 - -=item 10 -(old method) -To regenerate the initrd for a fedora8 image for a compute node architecture x86_64 and place it in the /install/netboot/fedora8/x86_64/compute/rootimg directory: - - cd /opt/xcat/share/xcat/netboot/fedora - ./genimage --onlyinitrd -i eth0 -n tg3,bnx2 -o fedora8 -p compute - - =back diff --git a/xCAT-client/pods/man1/imgcapture.1.pod b/xCAT-client/pods/man1/imgcapture.1.pod index d299d7832..ea9adb3c7 100644 --- a/xCAT-client/pods/man1/imgcapture.1.pod +++ b/xCAT-client/pods/man1/imgcapture.1.pod @@ -4,9 +4,7 @@ B - Captures an image from a Linux diskful node and create a diskles =head1 SYNOPSIS -B node B<-t>|B<--type> diskless [B<-p>|B<--profile> I] [B<-o>|B<--osimage> I] [B<-i> I] [B<-n> I] [B<-V>|B<--verbose>] - -B node B<-t>|B<--type> sysclone B<-o>|B<--osimage> I [B<-V>|B<--verbose>] +B node B<-t>|B<--type> {diskless|sysclone} B<-o>|B<--osimage> I [B<-V>|B<--verbose>] B [B<-h> | B<--help>] | [B<-v> | B<--version>] @@ -20,7 +18,7 @@ The B command supports two image types: B and B. The B type: -The I is pre-defined, the attributes of osimage will be used to capture and prepare the root image. The B, B and B attributes for the stateless/statelite image to be created are duplicated from the B's attribute. If the B<-p|--profile> I option is specified, the image will be created under "/>/netboot///>/rootimg". +The attributes of osimage will be used to capture and prepare the root image. The B, B and B attributes for the stateless/statelite image to be created are duplicated from the B's attribute. If the B<-p|--profile> I option is specified, the image will be created under "/>/netboot///>/rootimg". The default files/directories excluded in the image are specified by /opt/xcat/share/xcat/netboot//>...imgcapture.exlist; also, you can put your customized file (>...imgcapture.exlist) to /install/custom/netboot/. The directories in the default I<.imgcapture.exlist> file are necessary to capture image from the diskful Linux node managed by xCAT, please don't remove it. @@ -100,23 +98,11 @@ Verbose output. B is one diskful Linux node, which is managed by xCAT. -1. In order to capture and prepare the diskless root image, run the following command: - -imgcapture node1 -t diskless - -2. In order to capture and prepare the diskless root image with B as profile, run the command: - -imgcapture node1 -t diskless -p hpc - -3. In order to capture and prepare the diskless root image: its profile is B, and the network interface the diskless node will boot over is B, the driver modules for this network interface is B. - -imgcapture node1 -t diskless -p hpc -i eth0 -n e1000e - -4. There's one pre-defined I. In order to capture and prepare the diskless root image for I, run the command: +1. There's one pre-defined I. In order to capture and prepare the diskless root image for I, run the command: imgcapture node1 -t diskless -o osimage -5. In order to capture the diskful image from B and create the I B, run the command: +2. In order to capture the diskful image from B and create the I B, run the command: imgcapture node1 -t sysclone -o img1 diff --git a/xCAT-client/pods/man1/packimage.1.pod b/xCAT-client/pods/man1/packimage.1.pod index a0d42a340..9f4561e8a 100644 --- a/xCAT-client/pods/man1/packimage.1.pod +++ b/xCAT-client/pods/man1/packimage.1.pod @@ -8,9 +8,6 @@ I I - -I - I =head1 DESCRIPTION @@ -20,8 +17,7 @@ sent to the node for a diskless install. The install dir is setup by using "installdir" attribute set in the site table. The nodetype table "profile" attribute for the node should reflect the profile of the install image. -If no I is specified, this command uses the os image definition files from /install/custom/netboot/[os] directory first. If not found, it falls back to the default directory /opt/xcat/share/xcat/netboot/[os]. -If a I is specified, this command will get all the necessary os image definition files from the I and I tables. +This command will get all the necessary os image definition files from the I and I tables. =head1 Parameters @@ -51,11 +47,10 @@ B<-m> Method (default cpio) =head1 EXAMPLES -1. To pack a fedora8 image for a compute node architecture x86_64 and place it in the /install/netboot/fedora8/x86_64/compute/rootimg.gz file enter: +1. To pack the osimage rhels7.1-x86_64-netboot-compute: -I +I -This would use the package information from the /install/custom/netboot/fedora/compute* files first. If not found it uses /opt/xcat/share/xcat/netboot/fedora/compute* files. =head1 FILES diff --git a/xCAT-client/pods/man8/nodeset.8.pod b/xCAT-client/pods/man8/nodeset.8.pod index 2c8bd55cd..5c610996c 100644 --- a/xCAT-client/pods/man8/nodeset.8.pod +++ b/xCAT-client/pods/man8/nodeset.8.pod @@ -4,7 +4,7 @@ B - set the boot state for a noderange =head1 B -B [I] [I|I|I|I|I|I|I|I|I>]|I|I] +B [I] [I|I|I|I|I|I>]|I|I] B I I> [I<--noupdateinitrd>] [I<--ignorekernelchk>] @@ -43,24 +43,6 @@ A user can supply their own scripts to be run on the mn or on the service node ( Instruct network boot loader to be skipped, generally meaning boot to hard disk -=item B|B|B> - -Prepare server for installing a node according to the table configuration. This will -typically mean an unattended install file is created (i.e. kickstart or autoyast), -install resources will be verified in tftp and the bulk transfer method (http, ftp, or nfs for example), and the boot loader configuration file will be written. -Note: this option has been deprecated and will be removed in a future release. You should change to using the osimage option instead. - - -=item B|B|B> - -Prepare server for deploying diskless nodes. With the diskless solution, the os image will reside in the RAM of the node. -Note: this option has been deprecated and will be removed in a future release. You should change to using the osimage option instead. - -=item B|B|B> - -Prepare server for deploying statelite nodes. Statelite provides an efficient and flexible diskless solution because most of the OS image is NFS mounted read-only, but a configurable list of directories and files can be read-write. The read-write files can either be persistent across reboots, or volatile (restoring to pristine state after reboot). The configuration can be done through B, B and B tables. -Note: this option has been deprecated and will be removed in a future release. You should change to using the osimage option instead. - =item B Cleanup the current pxe/tftp boot configuration files for the nodes requested From c0f65b7ae79af002c4e60ac5a4fbaf504b347dcb Mon Sep 17 00:00:00 2001 From: ligc Date: Thu, 14 May 2015 04:57:44 -0400 Subject: [PATCH 06/26] remove install/netboot/statelite related flags from rmimage, liteimg and rinstall --- xCAT-server/lib/xcat/plugins/rinstall.pm | 13 ++++--------- xCAT-server/lib/xcat/plugins/rmimage.pm | 2 +- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/rinstall.pm b/xCAT-server/lib/xcat/plugins/rinstall.pm index 7799577f6..bb139d753 100644 --- a/xCAT-server/lib/xcat/plugins/rinstall.pm +++ b/xCAT-server/lib/xcat/plugins/rinstall.pm @@ -412,18 +412,13 @@ sub usage my $rsp = {}; $rsp->{data}->[0] = "$command usage:"; if ($command =~ /rinstall/) { - $rsp->{data}->[1] = " [-o|--osver] [-p|--profile] [-a|--arch] [-c|--console] "; - } else { # winstall - $rsp->{data}->[1] = " [-o|--osver] [-p|--profile] [-a|--arch] "; - } - if ($command =~ /rinstall/) { - $rsp->{data}->[2] = " [-O|--osimage] [-c|--console] "; + $rsp->{data}->[1] = " [-O|--osimage] [-c|--console] "; } else { # wininstall - $rsp->{data}->[2] = " [-O|--osimage] "; + $rsp->{data}->[1] = " [-O|--osimage] "; } - $rsp->{data}->[3] = " [-h|--help]"; - $rsp->{data}->[4] = " [-v|--version]"; + $rsp->{data}->[2] = " [-h|--help]"; + $rsp->{data}->[3] = " [-v|--version]"; xCAT::MsgUtils->message("I", $rsp, $callback); } diff --git a/xCAT-server/lib/xcat/plugins/rmimage.pm b/xCAT-server/lib/xcat/plugins/rmimage.pm index 3125cbc4c..bbfae5994 100644 --- a/xCAT-server/lib/xcat/plugins/rmimage.pm +++ b/xCAT-server/lib/xcat/plugins/rmimage.pm @@ -30,7 +30,7 @@ sub process_request { my $installroot = xCAT::TableUtils->getInstallDir(); my $tftproot = xCAT::TableUtils->getTftpDir(); - my $usage = "\nUsage:\n rmimage [-h | --help]\n rmimage [-V | --verbose] -o -a -p \n rmimage [-V | --verbose] imagename [--xcatde]"; + my $usage = "\nUsage:\n rmimage [-h | --help]\n rmimage [-V | --verbose] imagename [--xcatde]"; @ARGV = @{$request->{arg}}; From 7d5d1c9b730bb640bc6381ffd4b233ff90b2d1fe Mon Sep 17 00:00:00 2001 From: junxiawang Date: Thu, 14 May 2015 05:50:11 -0400 Subject: [PATCH 07/26] fix 4637 [FVT]:confignics -s does not work when there is no values in nics table --- xCAT/postscripts/confignics | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/xCAT/postscripts/confignics b/xCAT/postscripts/confignics index 7122d7749..2868a9a31 100755 --- a/xCAT/postscripts/confignics +++ b/xCAT/postscripts/confignics @@ -7,7 +7,7 @@ # # You can run the following commands on MN: # updatenode noderange confignics -# updatenode noderange "confignics -s" (this one configures the installation nic also) +# updatenode noderange "confignics -s" (configures the installation nic by default and no need to configure the install nic in nics table) # # #=cut @@ -209,11 +209,15 @@ fi bool_exit_flag=0 #check the required attributes if [ -z "$NICIPS" ];then - logger -t xcat -p local4.info "confignics: nicips attribute is not defined. " - echo "confignics on $NODE: nicips attribute is not defined. " - exit 0 + if [ $bool_cfg_inst_nic -eq 1 ];then + logger -t xcat -p local4.info "confignics: configure the install nic. " + echo "confignics on $NODE:configure the install nic. " + else + logger -t xcat -p local4.info "confignics: nicips attribute is not defined. " + echo "confignics on $NODE: nicips attribute is not defined. " + exit 0 + fi fi - splitconfig "$NICIPS" splitconfig "$NICCUSTOMSCRIPTS" From 1d7df6b238a53bc5c51863443504974bf0ff0ee3 Mon Sep 17 00:00:00 2001 From: linggao Date: Thu, 14 May 2015 11:27:38 -0400 Subject: [PATCH 08/26] more code for switchdiscover command --- perl-xCAT/xCAT/Usage.pm | 2 +- .../lib/xcat/plugins/switchdiscover.pm | 92 ++++++++++++++----- 2 files changed, 69 insertions(+), 25 deletions(-) diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 4314dfe36..9dfbc21a3 100755 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -288,7 +288,7 @@ my %usage = ( [-u] [--range IPranges][-t tries][--vpdtable][-C counts][-T timeout]", "switchdiscover" => "Usage: switchdiscover [-h|--help|-v|--version] - switchdiscover [][-V|--verbose][-i adpt[,adpt..]][-w][-r|-x|-z][-n][-s scan_methods]", + switchdiscover [|--range ipranges] [-s scan_methods] [-r|-x|-z][-n] [-w] [-V|--verbose]", "rflash" => "Usage: rflash [ -h|--help|-v|--version] diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm index 95e3a606b..4dca87c0d 100755 --- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm @@ -8,11 +8,13 @@ BEGIN } use lib "$::XCATROOT/lib/perl"; -use strict; use Getopt::Long; use xCAT::Usage; use xCAT::NodeRange; use xCAT::Utils; +use XML::Simple; +no strict; +use Data::Dumper; #global variables for this module my %globalopt; @@ -131,7 +133,7 @@ sub parse_args { # Process command-line flags ############################################# if (!GetOptions( \%opt, - qw(h|help V|Verbose v|version i=s x z w r n range=s s=s))) { + qw(h|help V|Verbose v|version x z w r n range=s s=s))) { return( usage() ); } @@ -146,6 +148,9 @@ sub parse_args { unless (@filternodes) { return(usage( "Invalid Argument: $ARGV[0]" )); } + if ( exists( $opt{range} )) { + return(usage( "--range flag cannot be used with noderange." )); + } } elsif ( scalar(@ARGV) > 1 ) { return(usage( "Invalid flag, please check and retry." )); } @@ -182,12 +187,10 @@ sub parse_args { } ############################################# - # Check the validation of -i option + # Check the --range ip range option ############################################# - if ( exists( $opt{i} )) { - foreach ( split /,/, $opt{i} ) { - } - $globalopt{i} = $opt{i}; + if ( exists( $opt{range} )) { + $globalopt{range} = $opt{range}; } ############################################# @@ -218,12 +221,6 @@ sub parse_args { $globalopt{z} = 1; } - ######################################################### - # only list the nodes that discovered for the first time - ######################################################### - if ( exists( $opt{n} )) { - $globalopt{n} = 1; - } ######################################################### # only list the nodes that discovered for the first time @@ -307,6 +304,7 @@ sub process_request { no strict; my $fn = $global_scan_type{$st}; my $result = &$fn(\%request, $callback); + print "switches=" . Dumper($result); } @@ -326,17 +324,61 @@ sub process_request { "1.2.3.5" =>{name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA"}, "1.2.4.6" =>{name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF"} } + returns 1 if there are errors occurred. =cut #-------------------------------------------------------------------------------- sub lldp_scan { my $request = shift; send_msg($request, 0, "Discovering switches using lldpd..."); - my %switches = ( - "1.2.3.5" => { name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA" }, - "1.2.4.6" => { name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF" } - ); - return %switches + + # get the PID of the currently running lldpd if it is running. + # If it is not running start it up. + my $pid; + chomp($pid= `ps -ef | grep lldpd | grep -v grep | awk '{print \$2}'`); + unless($pid){ + my $dcmd = "lldpd -c -s -e -f"; + my $outref = xCAT::Utils->runcmd($dcmd, 0); + if ($::RUNCMD_RC != 0) + { + send_msg($request, 1, "Could not start lldpd process. The command was: $dcmd" ); + return 1; + } + # TODO: how to determin if the lldpd has done all the scanning or not? + xCAT::Utils->runcmd("sleep 30"); + } + + #now run the lldpcli to collect the data + my $ccmd = "lldpcli show neighbors -f xml"; + my $result = xCAT::Utils->runcmd($ccmd, 0); + if ($::RUNCMD_RC != 0) + { + send_msg($request, 1, "Could not start lldpd process. The command was: $ccmd" ); + return 1; + } + send_msg($request, 0, $result); + my $result_ref = XMLin($result, KeyAttr => 'interface', ForceArray => 1); + my $switches; + if ($result_ref) { + if (exists($result_ref->{interface})) { + my $ref1 = $result_ref->{interface}; + foreach my $interface (@$ref1) { + if (exists($interface->{chassis})) { + my $chassis = $interface->{chassis}->[0]; + my $ip = $chassis->{'mgmt-ip'}->[0]->{content}; + if ($ip) { + my $name = $chassis->{name}->[0]->{content}; + my $id = $chassis->{id}->[0]->{content}; + my $desc = $chassis->{descr}->[0]->{content}; + $switches->{$ip}->{name} = $name; + $switches->{$ip}->{mac} = $id; + $switches->{$ip}->{vendor} = $desc; + } + } + } + } + } + return $switches } @@ -352,17 +394,18 @@ sub lldp_scan { "1.2.3.5" =>{name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA"}, "1.2.4.6" =>{name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF"} } + returns 1 if there are errors occurred. =cut #-------------------------------------------------------------------------------- sub nmap_scan { my $request = shift; send_msg($request, 0, "Discovering switches using nmap..."); - my %switches = ( + my $switches = { "1.2.3.5" => { name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA" }, "1.2.4.6" => { name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF" } - ); - return %switches + }; + return $switches } @@ -379,17 +422,18 @@ sub nmap_scan { "1.2.3.5" =>{name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA"}, "1.2.4.6" =>{name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF"} } + returns 1 if there are errors occurred. =cut #-------------------------------------------------------------------------------- sub snmp_scan { my $request = shift; send_msg($request, 0, "Discovering switches using snmp..."); - my %switches = ( + my $switches = { "1.2.3.5" => { name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA" }, "1.2.4.6" => { name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF" } - ); - return %switches + }; + return $switches } 1; From 7c5d90271054abb208f609cb348f281341c393af Mon Sep 17 00:00:00 2001 From: GONG Jie Date: Fri, 15 May 2015 16:29:34 +0800 Subject: [PATCH 09/26] Rename pre.rh.rhel7 -> pre.rh.rhels7 --- .../share/xcat/install/scripts/{pre.rh.rhel7 => pre.rh.rhels7} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename xCAT-server/share/xcat/install/scripts/{pre.rh.rhel7 => pre.rh.rhels7} (100%) diff --git a/xCAT-server/share/xcat/install/scripts/pre.rh.rhel7 b/xCAT-server/share/xcat/install/scripts/pre.rh.rhels7 similarity index 100% rename from xCAT-server/share/xcat/install/scripts/pre.rh.rhel7 rename to xCAT-server/share/xcat/install/scripts/pre.rh.rhels7 From 9400eff3ed39f0288c018bd9c7f80057e9b9e225 Mon Sep 17 00:00:00 2001 From: immarvin Date: Fri, 15 May 2015 04:32:41 -0400 Subject: [PATCH 10/26] all the ubuntu xcat-dep packages should be uploaded to on GSA, this script can grab them and finish the packaging --- build-ubunturepo | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/build-ubunturepo b/build-ubunturepo index a6cfe25de..eb1f37fa7 100755 --- a/build-ubunturepo +++ b/build-ubunturepo @@ -29,9 +29,12 @@ # UP=0 or UP=1 - override the default upload behavior # LOG= - provide an LOG file option to redirect some output into log file # -# For the dependency packages 1. please run the build-debs-all in xcat-dep svn first( there is usage detail in that script) +# For the dependency packages 1. All the xcat dependency deb packages should be uploaded to +# "pokgsa/projects/x/xcat/build/ubuntu/xcat-dep/debs/" on GSA # 2. run ./build-ubunturepo -d # +# 3. the built xcat-dep deb packages tarball can be found in "../../xcat-dep" +# related to the path of this script ############################ printusage() { @@ -87,6 +90,8 @@ if [ "$c_flag" -a "$d_flag" ];then exit 2 fi + + uploader="litingt" # Find where this script is located to set some build variables old_pwd=`pwd` @@ -378,6 +383,21 @@ then echo "# Creating xcat-dep repository #" echo "################################" + + #the path of ubuntu xcat-dep deb packages on GSA + GSA="/gsa/pokgsa/projects/x/xcat/build/ubuntu/xcat-dep" + + + if [ ! -d $GSA ]; then + echo "build-ubunturepo: It appears that you do not have gsa installed to access the xcat-dep pkgs." + exit 1; + fi + + # Sync from the GSA master copy of the dep rpms + echo "Syncing RPMs from $GSA/ to $local_dep_repo_path/../ ..." + rsync -ilrtpu --delete $GSA/ $local_dep_repo_path/../ + + #clean all old files if [ -e $local_dep_repo_path ];then rm -rf $local_dep_repo_path @@ -386,6 +406,7 @@ then cd $local_dep_repo_path mkdir conf + #create the conf/distributions file for dist in $dists; do if [ "$dist" = "trusty" ] || [ "$dist" = "utopic" ]; then From 7c52ddc29ce3e2aa436aa41e2f2ddd01ab12b078 Mon Sep 17 00:00:00 2001 From: junxiawang Date: Fri, 15 May 2015 04:52:36 -0400 Subject: [PATCH 11/26] add cuda installation testcase --- .../ubuntu_diskless_installation_cudafull | 39 +++++++++++++++++++ .../ubuntu_diskless_installation_cudaruntime | 39 +++++++++++++++++++ .../ubuntu_full_installation_cudafull | 35 +++++++++++++++++ .../ubuntu_full_installation_cudaruntime | 38 ++++++++++++++++++ 4 files changed, 151 insertions(+) create mode 100644 xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudafull create mode 100644 xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudaruntime create mode 100644 xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudafull create mode 100644 xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudaruntime diff --git a/xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudafull b/xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudafull new file mode 100644 index 000000000..b9335eeb7 --- /dev/null +++ b/xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudafull @@ -0,0 +1,39 @@ +start:Ubuntu_diskless_installation_p8le_vm_cudafull +os:Linux +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;echo "deb http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__ /" >> /etc/apt/sources.list +cmd:makedns -n +check:rc==0 +cmd:makeconservercf $$CN +check:rc==0 +cmd:makedhcp -n +check:rc==0 +cmd:makedhcp -a +check:rc==0 +cmd:if [ ! -d /install/custom/netboot/ubuntu ]; then mkdir -p /install/custom/netboot/ubuntu; fi +check:rc==0 +cmd:if [ ! -e /install/custom/netboot/ubuntu/compute.synclist ]; then echo "/etc/resolv.conf -> /etc/resolv.conf" > /install/custom/netboot/ubuntu/compute.synclist; fi +check:rc==0 +cmd:chdef -t osimage -o __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute -p pkgdir="http://ports.ubuntu.com/ubuntu-ports trusty main,http://ports.ubuntu.com/ubuntu-ports trusty-updates main" +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;chdef -t osimage -o __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute otherpkgdir="http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__ /" otherpkglist="/opt/xcat/share/xcat/netboot/ubuntu/cudafull.otherpkgs.pkglist" pkglist="/opt/xcat/share/xcat/netboot/ubuntu/cudafull.__GETNODEATTR($$CN,os)__.__GETNODEATTR($$CN,arch)__-.pkglist" rootimgdir="/install/netboot/ __GETNODEATTR($$CN,os)__/__GETNODEATTR($$CN,arch)__/cudafull" +cmd:apt-get install -y acpid +check:rc==0 +cmd:rm -rf /install/netboot/__GETNODEATTR($$CN,os)__/x86_64/compute +check:rc==0 +cmd:genimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute +check:rc==0 +cmd:packimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute +check:rc==0 +cmd:nodeset $$CN osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute +check:rc==0 +cmd:rpower $$CN reset +check:rc==0 +cmd:sleep 200 +cmd:lsdef -l $$CN | grep status +check:output=~booted +cmd:xdsh $$CN date +check:rc==0 +check:output=~\d\d:\d\d:\d\d +cmd:xdsh $$CN dpkg -l |grep cuda +check:rc==0 +check:output=~cuda +end diff --git a/xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudaruntime b/xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudaruntime new file mode 100644 index 000000000..777916ec6 --- /dev/null +++ b/xCAT-test/autotest/testcase/installation/ubuntu_diskless_installation_cudaruntime @@ -0,0 +1,39 @@ +start:Ubuntu_diskless_installation_vm_cudaruntime +os:Linux +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;echo "deb http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__ /" >> /etc/apt/sources.list +cmd:makedns -n +check:rc==0 +cmd:makeconservercf $$CN +check:rc==0 +cmd:makedhcp -n +check:rc==0 +cmd:makedhcp -a +check:rc==0 +cmd:if [ ! -d /install/custom/netboot/ubuntu ]; then mkdir -p /install/custom/netboot/ubuntu; fi +check:rc==0 +cmd:if [ ! -e /install/custom/netboot/ubuntu/compute.synclist ]; then echo "/etc/resolv.conf -> /etc/resolv.conf" > /install/custom/netboot/ubuntu/compute.synclist; fi +check:rc==0 +cmd:chdef -t osimage -o __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute -p pkgdir="http://ports.ubuntu.com/ubuntu-ports trusty main,http://ports.ubuntu.com/ubuntu-ports trusty-updates main " +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;chdef -t osimage -o __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute otherpkgdir="http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__ /" otherpkglist="/opt/xcat/share/xcat/netboot/ubuntu/cudaruntime.otherpkgs.pkglist" pkglist="/opt/xcat/share/xcat/netboot/ubuntu/cudaruntime.__GETNODEATTR($$CN,os)__.__GETNODEATTR($$CN,arch)__-.pkglist" rootimgdir="/install/netboot/ __GETNODEATTR($$CN,os)__/__GETNODEATTR($$CN,arch)__/cudaruntime" +cmd:apt-get install -y acpid +check:rc==0 +cmd:rm -rf /install/netboot/__GETNODEATTR($$CN,os)__/x86_64/compute +check:rc==0 +cmd:genimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute +check:rc==0 +cmd:packimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute +check:rc==0 +cmd:nodeset $$CN osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-netboot-compute +check:rc==0 +cmd:rpower $$CN reset +check:rc==0 +cmd:sleep 200 +cmd:lsdef -l $$CN | grep status +check:output=~booted +cmd:xdsh $$CN date +check:rc==0 +check:output=~\d\d:\d\d:\d\d +cmd:xdsh $$CN dpkg -l |grep cuda +check:rc==0 +check:output=~cuda +end diff --git a/xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudafull b/xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudafull new file mode 100644 index 000000000..24f9b4827 --- /dev/null +++ b/xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudafull @@ -0,0 +1,35 @@ +start:Ubuntu_full_installation_flat_cudafull +os:Linux +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;echo "deb http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__ /" >> /etc/apt/sources.list +cmd:makedns -n +check:rc==0 +cmd:makeconservercf $$CN +check:rc==0 +cmd:cat /etc/conserver.cf | grep $$CN +check:output=~$$CN +cmd:sleep 60 +cmd:makedhcp -n +check:rc==0 +cmd:makedhcp -a +check:rc==0 +cmd:copycds $$ISO +check:rc==0 +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;chdef -t osimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute -p pkgdir="http://ports.ubuntu.com/ubuntu-ports trusty main,http://ports.ubuntu.com/ubuntu-ports trusty-updates main,http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__/ /" +cmd:chdef -t osimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute pkglist="/opt/xcat/share/xcat/install/ubuntu/cudafull.__GETNODEATTR($$CN,os)__.__GETNODEATTR($$CN,arch)__.pkglist" +cmd:chdef -t osimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute template="/opt/xcat/share/xcat/install/ubuntu/cudafull.tmpl" +cmd:nodeset $$CN osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute +check:rc==0 +cmd:rpower $$CN reset +check:rc==0 +cmd:sleep 2000 +cmd:ping $$CN -c 3 +check:output=~64 bytes from $$CN +cmd:lsdef -l $$CN | grep status +check:output=~booted +cmd:xdsh $$CN date +check:rc==0 +check:output=~\d\d:\d\d:\d\d +cmd:xdsh $$CN dpkg -l |grep cuda +check:rc==0 +check:output=~cuda +end diff --git a/xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudaruntime b/xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudaruntime new file mode 100644 index 000000000..1695429e1 --- /dev/null +++ b/xCAT-test/autotest/testcase/installation/ubuntu_full_installation_cudaruntime @@ -0,0 +1,38 @@ +start:Ubuntu_full_installation_flat_cudaruntime +os:Linux +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;echo "deb http://developer.download.nvidia.com/compute/cuda/repos/$ver/__GETNODEATTR($$CN,arch)__ /" >> /etc/apt/sources.list +cmd:makedns -n +check:rc==0 +cmd:makeconservercf $$CN +check:rc==0 +cmd:cat /etc/conserver.cf | grep $$CN +check:output=~$$CN +cmd:sleep 60 +cmd:makedhcp -n +check:rc==0 +cmd:makedhcp -a +check:rc==0 +cmd:copycds $$ISO +check:rc==0 +cmd:if [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.04" ]];then ver=ubuntu1404;elif [[ "__GETNODEATTR($$CN,os)__" =~ "ubuntu14.10" ]];then ver=ubuntu1410; fi;chdef -t osimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute -p pkgdir="/install/__GETNODEATTR($$CN,os)__/ppc64el,http://ports.ubuntu.com/ubuntu-ports trusty main,http://ports.ubuntu.com/ubuntu-ports trusty-updates main, http://developer.download.nvidia.com/compute/cuda/repos/__GETNODEATTR($$CN,os)__/$ver /" +cmd:chdef -t osimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute pkglist="/opt/xcat/share/xcat/install/ubuntu/cudaruntime.__GETNODEATTR($$CN,os)__.__GETNODEATTR($$CN,arch)__.pkglist" +cmd:chdef -t osimage __GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute template="/opt/xcat/share/xcat/install/ubuntu/cudaruntime.tmpl" +cmd:nodeset $$CN osimage=__GETNODEATTR($$CN,os)__-__GETNODEATTR($$CN,arch)__-install-compute +check:rc==0 +cmd:rpower $$CN reset +check:rc==0 +cmd:sleep 2000 +cmd:ping $$CN -c 3 +check:output=~64 bytes from $$CN +cmd:lsdef -l $$CN | grep status +check:output=~booted +cmd:xdsh $$CN date +check:rc==0 +check:output=~\d\d:\d\d:\d\d +cmd:xdsh $$CN dpkg -l |grep cuda +check:rc==0 +check:output=~cuda +cmd:xdsh $$CN dpkg -l |grep cuda +check:rc==0 +check:output=~cuda +end From 6280270cd9642e812e888d38d1005f2de175f07f Mon Sep 17 00:00:00 2001 From: ertaozh Date: Fri, 15 May 2015 05:24:32 -0400 Subject: [PATCH 12/26] support to add/modify user/password for BMC with rspconfig --- xCAT-server/lib/xcat/plugins/ipmi.pm | 163 ++++++++++++++++++++++----- 1 file changed, 137 insertions(+), 26 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm b/xCAT-server/lib/xcat/plugins/ipmi.pm index ae863b24f..d2c5fd4ab 100644 --- a/xCAT-server/lib/xcat/plugins/ipmi.pm +++ b/xCAT-server/lib/xcat/plugins/ipmi.pm @@ -509,16 +509,20 @@ sub on_bmc_connect { } elsif($command eq "rsetboot") { return setboot($sessdata); } elsif($command eq "rspconfig") { - shift @{$sessdata->{extraargs}}; + shift @{$sessdata->{extraargs}}; + + # set username or/and password for specified userid # + if ($sessdata->{subcommand} =~ /userid|username|password/) { + setpassword($sessdata); + } else { if ($sessdata->{subcommand} =~ /=/) { - if ($sessdata->{subcommand} =~ /password/) { - setpassword($sessdata); - } else { - setnetinfo($sessdata); - } + setnetinfo($sessdata); } else { getnetinfo($sessdata); } + } + + } elsif($command eq "rvitals") { vitals($sessdata); } elsif($command eq "rinv") { @@ -642,26 +646,97 @@ sub resetedbmc { sub setpassword { my $sessdata = shift; - my $subcommand = $sessdata->{subcommand}; - my $argument; - ($subcommand, $argument) = split(/=/, $subcommand); + my $subcmd = $sessdata->{subcommand}; my $netfun = 0x06; - my $command = 0x47; - my @data = (); - @data = unpack("C*", $argument); - if ($#data > 19 or $#data < 0) { - xCAT::SvrUtils::sendmsg([1, "The new password is invalid"],$callback,$sessdata->{node},%allerrornodes); - return(1,"The new password is invalid."); + my $command = undef; + my ($subcommand, $argument) = split(/=/, $subcmd); + if ($subcommand eq "userid") { + if ($argument !~ /^\d+$/) { + return(1,"The value for $subcommand is invalid"); + } + $sessdata->{onuserid} = $argument; + $sessdata->{subcommand} = shift @{$sessdata->{extraargs}}; + if ($sessdata->{subcommand} and $sessdata->{subcommand} ne '') { + setpassword($sessdata); + } + } elsif ($subcommand eq "username") { + unless($sessdata->{onuserid}) { + my @cmdargv = @{$sessdata->{extraargs}}; + if (grep /userid/,@cmdargv) { + foreach my $opt (@cmdargv) { + if ($opt =~ m/userid=\s*(\d+)/) { + $sessdata->{onuserid} = $1; + last; + } else { + return(1,"The value for $subcommand is invalid"); + } + } + } else { + $sessdata->{onuserid} = '1';# User ID 1 is permanently associated with User 1, the null user name + } + } + my @data = (); + $command = 0x45; + @data = unpack("C*", $argument); + if ($#data > 15 or $#data < 0) { + xCAT::SvrUtils::sendmsg([1, "The username is invalid"],$callback,$sessdata->{node},%allerrornodes); + return(1,"The username is invalid."); + } + $sessdata->{newusername}=$argument; + my $index = $#data; + while($index < 15) { # Username must be padded with 0 to 16 bytes for IPMI 2.0 + push @data, 0; + $index += 1; + } + unshift @data, $sessdata->{onuserid} - '0'; # byte 1, userID, User ID 1 is permanently associated with User 1, the null user name + unless (exists($sessdata->{setuseraccess})) { + $sessdata->{setuseraccess} = 1; + } + $sessdata->{ipmisession}->subcmd(netfn=>$netfun,command=>$command,data=>\@data,callback=>\&password_set,callback_args=>$sessdata); + } elsif ($subcommand eq "password") { + unless($sessdata->{onuserid}) { + my @cmdargv = @{$sessdata->{extraargs}}; + if (grep /userid/,@cmdargv) { + foreach my $opt (@cmdargv) { + if ($opt =~ m/userid=\s*(\d+)/) { + $sessdata->{onuserid} = $1; + last; + } else { + return(1,"The value for $subcommand is invalid"); + } + } + } else { + $sessdata->{onuserid} = '1'; + } + } + $command = 0x47; + my @data = (); + @data = unpack("C*", $argument); + if ($#data > 15 or $#data < 0) { + xCAT::SvrUtils::sendmsg([1, "The new password is invalid"],$callback,$sessdata->{node},%allerrornodes); + return(1,"The new password is invalid."); + } + $sessdata->{newpassword}=$argument; + my $index = $#data; + while($index < 15) { # Password must be padded with 0 to 20 bytes for IPMI 2.0 + push @data, 0; + $index += 1; + } + unless(exists($sessdata->{enableuserdone})) { + unshift @data, 0x01; # byte 2, operation: 0x00 disable user, 0x01 enable user, 0x02 set password, 0x03 test password + unshift @data, ($sessdata->{onuserid} - '0'); # byte 1, userID, User ID 1 is permanently associated with User 1, the null user name + $sessdata->{enableuserdone} = 1; + $sessdata->{ipmisession}->subcmd(netfn=>$netfun,command=>$command,data=>\@data,callback=>\&password_set,callback_args=>$sessdata); + } else { + unshift @data, 0x02; # byte 2, operation: 0x00 disable user, 0x01 enable user, 0x02 set password, 0x03 test password + unshift @data, ($sessdata->{onuserid} - '0'); # byte 1, userID, User ID 1 is permanently associated with User 1, the null user name + unless (exists($sessdata->{setuseraccess})) { + $sessdata->{setuseraccess} = 1; + } + $sessdata->{ipmisession}->subcmd(netfn=>$netfun,command=>$command,data=>\@data,callback=>\&password_set,callback_args=>$sessdata); + } } - $sessdata->{newpassword}=$argument; - my $index = $#data; - while($index < 19) { # Password must be padded with 0 to 20 bytes for IPMI 2.0 - push @data, 0; - $index += 1; - } - unshift @data, 0x02; # byte 2, operation: 0x00 disable user, 0x01 enable user, 0x02 set password, 0x03 test password - unshift @data, 0x01; # byte 1, userID, User ID 1 is permanently associated with User 1, the null user name - $sessdata->{ipmisession}->subcmd(netfn=>$netfun,command=>$command,data=>\@data,callback=>\&password_set,callback_args=>$sessdata); + return; } sub password_set { @@ -679,16 +754,52 @@ sub password_set { } return; } + if ($sessdata->{setuseraccess}) { + setuseraccess($sessdata); + return; + } + if ($sessdata->{enableuserdone}) { + $sessdata->{enableuserdone} = 0; + setpassword($sessdata); + return; + } + my $ipmitab = xCAT::Table->new('ipmi'); if (!$ipmitab) { xCAT::SvrUtils::sendmsg([1, "Failed to update ipmi table."],$callback,$sessdata->{node},%allerrornodes); } else { - $ipmitab->setNodeAttribs($sessdata->{node}, {'password'=>$sessdata->{newpassword}}); - xCAT::SvrUtils::sendmsg("Done",$callback,$sessdata->{node},%allerrornodes); + if ($sessdata->{subcommand} =~ m/username/) { + $ipmitab->setNodeAttribs($sessdata->{node}, {'username'=>$sessdata->{newusername}}); + xCAT::SvrUtils::sendmsg("set username Done",$callback,$sessdata->{node},%allerrornodes); + } elsif ($sessdata->{subcommand} =~ m/password/) { + $ipmitab->setNodeAttribs($sessdata->{node}, {'password'=>$sessdata->{newpassword}}); + xCAT::SvrUtils::sendmsg("set password Done",$callback,$sessdata->{node},%allerrornodes); + } + } + $sessdata->{subcommand} = shift @{$sessdata->{extraargs}}; + if ($sessdata->{subcommand} and $sessdata->{subcommand} ne '') { + setpassword($sessdata); } return; } +sub setuseraccess { + my $sessdata = shift; + my $channel_number = $sessdata->{ipmisession}->{currentchannel}; + unless($sessdata->{onuserid}) { + return; + } + $sessdata->{setuseraccess} = 0; + my @data = (); + push @data, (0xc0 | $channel_number); + push @data, ($sessdata->{onuserid} - '0'); + push @data, 0x04; + push @data, 0; + + $sessdata->{ipmisession}->subcmd(netfn=>0x06,command=>0x43,data=>\@data,callback=>\&password_set,callback_args=>$sessdata); + return; +} + sub setnetinfo { my $sessdata = shift; my $subcommand = $sessdata->{subcommand}; From 91cc4b2c65d5e0494a30b6735215d72dbfcc72a2 Mon Sep 17 00:00:00 2001 From: ertaozh Date: Fri, 15 May 2015 05:40:25 -0400 Subject: [PATCH 13/26] add usage for supporting to add/modify user/password for BMC with rspconfig --- perl-xCAT/xCAT/Usage.pm | 1 + 1 file changed, 1 insertion(+) diff --git a/perl-xCAT/xCAT/Usage.pm b/perl-xCAT/xCAT/Usage.pm index 9dfbc21a3..d30b9edd2 100755 --- a/perl-xCAT/xCAT/Usage.pm +++ b/perl-xCAT/xCAT/Usage.pm @@ -117,6 +117,7 @@ my %usage = ( BMC specific: rspconfig [ip|netmask|gateway|backupgateway|garp] rspconfig [garp=] + rspconfig [userid= username= password=] iDataplex specific: rspconfig [thermprofile] rspconfig [thermprofile=] From 6041cea62161305fd11c832adaa8035b3580e8c3 Mon Sep 17 00:00:00 2001 From: ertaozh Date: Fri, 15 May 2015 06:40:27 -0400 Subject: [PATCH 14/26] the RESTAPI for supporting to add/modify user/password for BMC with rspconfig --- xCAT-server/xCAT-wsapi/xcatws.cgi | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/xCAT-server/xCAT-wsapi/xcatws.cgi b/xCAT-server/xCAT-wsapi/xcatws.cgi index 112de13b7..f47de980b 100755 --- a/xCAT-server/xCAT-wsapi/xcatws.cgi +++ b/xCAT-server/xCAT-wsapi/xcatws.cgi @@ -1883,6 +1883,13 @@ sub actionhdl { } elsif ($paramhash->{'value'}) { push @args, $urilayers[3]."=".$paramhash->{'value'}; } + if (defined($urilayers[3]) and $urilayers[3] =~ /^account/) { + foreach my $key (keys %$paramhash) { + if (($key ne '') and (exists($paramhash->{$key}))) { + push @args, $key."=".$paramhash->{$key}; + } + } + } } elsif ($params->{'resourcename'} eq "eventlog") { if (isGET()) { push @args, 'all'; From 20bf9f90f636c178fc21d1006c59b7bafb43a470 Mon Sep 17 00:00:00 2001 From: linggao Date: Fri, 15 May 2015 13:31:21 -0400 Subject: [PATCH 15/26] added output display for switchdiscover command --- .../lib/xcat/plugins/switchdiscover.pm | 62 ++++++++++++++++++- 1 file changed, 59 insertions(+), 3 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm index 4dca87c0d..55cde2c22 100755 --- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm @@ -300,14 +300,65 @@ sub process_request { if (exists($globalopt{scan_types})) { @scan_types = @{$globalopt{scan_types}}; } + + my $all_result; foreach my $st (@scan_types) { no strict; my $fn = $global_scan_type{$st}; - my $result = &$fn(\%request, $callback); - print "switches=" . Dumper($result); + my $tmp_result = &$fn(\%request, $callback); + $all_result->{$st} = $tmp_result; + } + + #consolidate the results by merging the swithes with the same ip + my $result; + foreach my $st (keys %$all_result) { + my $tmp_result = $all_result->{$st}; + foreach my $key (keys %$tmp_result) { + if (! exists($result->{$key})) { + $result->{$key} = $tmp_result->{$key}; + } else { + if (exists($tmp_result->{$key}->{name})) { + $result->{$key}->{name} = $tmp_result->{$key}->{name}; + } + if (exists($tmp_result->{$key}->{mac})) { + $result->{$key}->{mac} = $tmp_result->{$key}->{mac}; + } + if (exists($tmp_result->{$key}->{vendor})) { + $result->{$key}->{vendor} .= $tmp_result->{$key}->{vendor}; + } + } + } } + #display header + $format = "%-12s\t%-12s\t%-20.20s\t%-12s"; + $header = sprintf $format, "ip", "name","vendor", "mac"; + send_msg(\%request, 0, $header); + my $sep = "------------"; + send_msg(\%request, 0, sprintf($format, $sep, $sep, $sep, $sep )); + #display switches one by one + foreach my $key (keys(%$result)) { + my $name=" "; + my $mac = " "; + my $vendor = " "; + if (exists($result->{$key}->{name})) { + $name = $result->{$key}->{name}; + } + if (exists($result->{$key}->{mac})) { + $mac = $result->{$key}->{mac}; + } + if (exists($result->{$key}->{vendor})) { + $vendor = $result->{$key}->{vendor}; + } + my $msg = sprintf $format, $key, $name, $vendor, $mac; + send_msg(\%request, 0, $msg); + } + + # writes the data into xCAT db + if (exists($globalopt{w})) { + send_msg(\%request, 0, "Writing the data into xCAT DB...."); + } return; } @@ -356,7 +407,12 @@ sub lldp_scan { send_msg($request, 1, "Could not start lldpd process. The command was: $ccmd" ); return 1; } - send_msg($request, 0, $result); + + #display the raw output + if (exists($globalopt{r})) { + send_msg($request, 0, "$result\n\n"); + } + my $result_ref = XMLin($result, KeyAttr => 'interface', ForceArray => 1); my $switches; if ($result_ref) { From 686e79211f1cf4ce7e4c601c71288c280afd82d7 Mon Sep 17 00:00:00 2001 From: Casandra Qiu Date: Fri, 15 May 2015 15:54:31 -0400 Subject: [PATCH 16/26] nmap scan support for switchdiscover --- .../lib/xcat/plugins/switchdiscover.pm | 54 ++++++++++++++++--- 1 file changed, 48 insertions(+), 6 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm index 55cde2c22..0301fcacf 100755 --- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm @@ -19,6 +19,7 @@ use Data::Dumper; #global variables for this module my %globalopt; my @filternodes; +my @iprange; my %global_scan_type = ( lldp => "lldp_scan", nmap => "nmap_scan", @@ -191,6 +192,10 @@ sub parse_args { ############################################# if ( exists( $opt{range} )) { $globalopt{range} = $opt{range}; + my @ips = split /,/, $opt{range}; + foreach (@ips) { + push @iprange, $_; + } } ############################################# @@ -456,12 +461,49 @@ sub lldp_scan { sub nmap_scan { my $request = shift; - send_msg($request, 0, "Discovering switches using nmap..."); - my $switches = { - "1.2.3.5" => { name=>"switch1", vendor=>"ibm", mac=>"AABBCCDDEEFA" }, - "1.2.4.6" => { name=>"switch2", vendor=>"cisco", mac=>"AABBCCDDEEFF" } - }; - return $switches + my $ccmd; + + send_msg($request, 0, "Discovering switches using nmap..."); + + if ( scalar(@filternodes) eq 0) + { + $ccmd = "/usr/bin/nmap -sn -oX - @iprange"; + } else { + $ccmd = "/usr/bin/nmap -sn -oX - @filternodes"; + } + print $ccmd; + my $result = xCAT::Utils->runcmd($ccmd, 0); + if ($::RUNCMD_RC != 0) + { + send_msg($request, 1, "Could not process this command: $ccmd" ); + return 1; + } + my $result_ref = XMLin($result, ForceArray => 1); + my $switches; + if ($result_ref) { + if (exists($result_ref->{host})) { + my $host_ref = $result_ref->{host}; + foreach my $host ( @$host_ref ) { + my $ip; + if (exists($host->{address})) { + my $addr_ref = $host->{address}; + foreach my $addr ( @$addr_ref ) { + my $type = $addr->{addrtype}; + if ( $type ne "mac" ) { + $ip = $addr->{addr}; + } + if ($addr->{vendor}) { + $switches->{$ip}->{mac} = $addr->{addr}; + $switches->{$ip}->{vendor} = $addr->{vendor}; + $switches->{$ip}->{name} = $host->{hostname}; + } + } #end for each address + } + } #end for each host + } + } + + return $switches } From 31be446db81f591f60c928625a01a2c74e71945c Mon Sep 17 00:00:00 2001 From: Casandra Qiu Date: Fri, 15 May 2015 16:09:25 -0400 Subject: [PATCH 17/26] remove -i options from switchdiscover man page --- xCAT-client/pods/man1/switchdiscover.1.pod | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/xCAT-client/pods/man1/switchdiscover.1.pod b/xCAT-client/pods/man1/switchdiscover.1.pod index b756b2b47..af17fd3e1 100755 --- a/xCAT-client/pods/man1/switchdiscover.1.pod +++ b/xCAT-client/pods/man1/switchdiscover.1.pod @@ -11,7 +11,7 @@ I I -I +I @@ -30,15 +30,13 @@ B The switches which the user want to discover. switches will be defined in /etc/hosts file. This command will fill the switch attributes for the switches defined. -B<-i> adapter(s) the command will search through (defaults to all available adapters). - B<-h> Display usage message. B<-n> Only display and write the newly discovered switches. B<--range> Specify one or more IP ranges. It accepts multiple formats. For example, 192.168.1.1/24, 40-41.1-2.3-4.1-100. - If the range is huge, for example, 192.168.1.1/8, lsslp may take a very long + If the range is huge, for example, 192.168.1.1/8, switchdiscover may take a very long time for node scan. So the range should be exactly specified. B<-r> Display Raw response. From 91bd44955f5aac6131e6b22a3a9a7da04c7dbd0a Mon Sep 17 00:00:00 2001 From: linggao Date: Fri, 15 May 2015 17:07:28 -0400 Subject: [PATCH 18/26] more code for switchdiscover --- .../lib/xcat/plugins/switchdiscover.pm | 78 +++++++++++++------ 1 file changed, 53 insertions(+), 25 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/switchdiscover.pm b/xCAT-server/lib/xcat/plugins/switchdiscover.pm index 0301fcacf..37152b921 100755 --- a/xCAT-server/lib/xcat/plugins/switchdiscover.pm +++ b/xCAT-server/lib/xcat/plugins/switchdiscover.pm @@ -335,37 +335,53 @@ sub process_request { } } - #display header - $format = "%-12s\t%-12s\t%-20.20s\t%-12s"; - $header = sprintf $format, "ip", "name","vendor", "mac"; - send_msg(\%request, 0, $header); - my $sep = "------------"; - send_msg(\%request, 0, sprintf($format, $sep, $sep, $sep, $sep )); - - #display switches one by one - foreach my $key (keys(%$result)) { - my $name=" "; - my $mac = " "; - my $vendor = " "; - if (exists($result->{$key}->{name})) { - $name = $result->{$key}->{name}; - } - if (exists($result->{$key}->{mac})) { - $mac = $result->{$key}->{mac}; - } - if (exists($result->{$key}->{vendor})) { - $vendor = $result->{$key}->{vendor}; - } - my $msg = sprintf $format, $key, $name, $vendor, $mac; - send_msg(\%request, 0, $msg); + my $display_done = 0; + if (exists($globalopt{r})) { + #do nothing since is done by the scan functions. + $display_done = 1; } + + if (exists($globalopt{x})) { + $display_done = 1; + } + + if (exists($globalopt{z})) { + $display_done = 1; + } + + if (!$display_done) { + #display header + $format = "%-12s\t%-12s\t%-20.20s\t%-12s"; + $header = sprintf $format, "ip", "name","vendor", "mac"; + send_msg(\%request, 0, $header); + my $sep = "------------"; + send_msg(\%request, 0, sprintf($format, $sep, $sep, $sep, $sep )); + + #display switches one by one + foreach my $key (keys(%$result)) { + my $name=" "; + my $mac = " "; + my $vendor = " "; + if (exists($result->{$key}->{name})) { + $name = $result->{$key}->{name}; + } + if (exists($result->{$key}->{mac})) { + $mac = $result->{$key}->{mac}; + } + if (exists($result->{$key}->{vendor})) { + $vendor = $result->{$key}->{vendor}; + } + my $msg = sprintf $format, $key, $name, $vendor, $mac; + send_msg(\%request, 0, $msg); + } + } + # writes the data into xCAT db if (exists($globalopt{w})) { send_msg(\%request, 0, "Writing the data into xCAT DB...."); } return; - } #-------------------------------------------------------------------------------- @@ -415,7 +431,12 @@ sub lldp_scan { #display the raw output if (exists($globalopt{r})) { - send_msg($request, 0, "$result\n\n"); + my $ccmd = "lldpcli show neighbors"; + my $raw_result = xCAT::Utils->runcmd($ccmd, 0); + if ($::RUNCMD_RC == 0) + { + send_msg($request, 0, "$raw_result\n\n"); + } } my $result_ref = XMLin($result, KeyAttr => 'interface', ForceArray => 1); @@ -478,6 +499,13 @@ sub nmap_scan { send_msg($request, 1, "Could not process this command: $ccmd" ); return 1; } + + #display the raw output + if (exists($globalopt{r})) { + send_msg($request, 0, "$result\n" ); + } + + #compose the switch hash my $result_ref = XMLin($result, ForceArray => 1); my $switches; if ($result_ref) { From 889d0d1a8c6af9698b513a9e0f5af4ec069e0461 Mon Sep 17 00:00:00 2001 From: ligc Date: Sun, 17 May 2015 21:49:33 -0400 Subject: [PATCH 19/26] update manpages of rmimage,liteimg and rinstall to remove the non-osimage flags and examples --- xCAT-client/pods/man1/liteimg.1.pod | 15 ++------------- xCAT-client/pods/man1/rmimage.1.pod | 20 ++------------------ xCAT-client/pods/man8/rinstall.8.pod | 19 ------------------- 3 files changed, 4 insertions(+), 50 deletions(-) diff --git a/xCAT-client/pods/man1/liteimg.1.pod b/xCAT-client/pods/man1/liteimg.1.pod index 741a4c031..f28130dec 100644 --- a/xCAT-client/pods/man1/liteimg.1.pod +++ b/xCAT-client/pods/man1/liteimg.1.pod @@ -8,8 +8,6 @@ I I -I - I =head1 DESCRIPTION @@ -53,15 +51,6 @@ B<-h> Display usage message. B<-v> Command Version. -B<-o> Operating system (fedora8, rhel5, sles10,etc) - -B<-p> Profile (compute,service) - -B<-a> Architecture (ppc64,x86_64,etc) - -B<-t> The type of rootfs for the image (nfs, ramdisk). It is optional, nfs is used to be the rootfs type when B<-t> is not specified. - - =head1 RETURN VALUE 0 The command completed successfully. @@ -70,9 +59,9 @@ B<-t> The type of rootfs for the image (nfs, ramdisk). It is optional, =head1 EXAMPLES -1. To lite a fedora8 image for a compute node architecture x86_64 enter: +1. To lite a RHEL 6.6 statelite image for a compute node architecture x86_64 enter: -I +I =head1 FILES diff --git a/xCAT-client/pods/man1/rmimage.1.pod b/xCAT-client/pods/man1/rmimage.1.pod index b3556c4fa..ae9a1259c 100644 --- a/xCAT-client/pods/man1/rmimage.1.pod +++ b/xCAT-client/pods/man1/rmimage.1.pod @@ -7,8 +7,6 @@ B - Removes the Linux stateless or statelite image from the file system I -I I<-o > I<-a > I<-p > - I =head1 DESCRIPTION @@ -40,12 +38,6 @@ B<-h | --help> Display usage message. B<-V | --verbose> Verbose mode. -B<-o> Operating system (fedora9,rhels5.5,sles11,etc) - -B<-p> Profile (compute,service,etc) - -B<-a> Architecture (ppc64,x86_64,etc) - B<--xcatdef> Remove the xCAT osimage definition @@ -57,22 +49,14 @@ B<--xcatdef> Remove the xCAT osimage definition =head1 EXAMPLES -1. To remove a fedora9 stateless image for a compute node architecture x86_64, enter: +1. To remove a RHEL 7.1 stateless image for a compute node architecture x86_64, enter: -I - -or - -I +I 2. To remove a rhels5.5 statelite image for a compute node architecture ppc64 and the osimage definition, enter: I -or - -I - =head1 FILES /opt/xcat/sbin/rmimage diff --git a/xCAT-client/pods/man8/rinstall.8.pod b/xCAT-client/pods/man8/rinstall.8.pod index 1923a8f9f..62696dc88 100644 --- a/xCAT-client/pods/man8/rinstall.8.pod +++ b/xCAT-client/pods/man8/rinstall.8.pod @@ -4,8 +4,6 @@ B - Begin OS provision on a noderange =head1 B -B [I<-o>|I<--osver>] [I<-p>|I<--profile>] [I<-a>|I<--arch>] [I<-c>|I<--console>] [I] - B [I<-O>|I<--osimage>] [I<-c>|I<--console>] [I] =head1 B @@ -28,19 +26,6 @@ Display usage message. Display version. -=item B<-o>|B<--osver> - -Specifies which os version to provision. If unspecified, the current node os setting is used. Will be ignored if [I<-O>|I<--osimage>] is specified or nodetype.provmethod=I. - -=item B<-p>|B<--profile> - -Specifies what profile should be used of the operating system. If not specified the current node profile setting is used. Will be ignored if [I<-O>|I<--osimage>] is specified or nodetype.provmethod=I. - - -=item B<-a>|B<--arch> - -Specifies what architecture of the OS to provision. Typically this is unneeded, but if provisioning between x86_64 and x86 frequently, this may be a useful flag. Will be ignored if [I<-O>|I<--osimage>] is specified or nodetype.provmethod=I. - =item B<-O>|B<--osimage> Specifies the osimage to provision. @@ -58,10 +43,6 @@ B I Provison nodes 1 through 20, using their current configuration. -B I -o rhels5.1 -p compute - -Provision nodes 1 through 20, forcing rhels5.1 and compute profile. - B I -O rhels6.4-ppc64-netboot-compute Provision nodes 1 through 20 with the osimage rhels6.4-ppc64-netboot-compute. From 8cdde379022b2cebe324d91fb9931884c70820f7 Mon Sep 17 00:00:00 2001 From: ertaozh Date: Mon, 18 May 2015 01:49:26 -0400 Subject: [PATCH 20/26] fix bug that REST will return error message if no objection defined --- xCAT-server/xCAT-wsapi/xcatws.cgi | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/xCAT-server/xCAT-wsapi/xcatws.cgi b/xCAT-server/xCAT-wsapi/xcatws.cgi index f47de980b..7c31f6a35 100755 --- a/xCAT-server/xCAT-wsapi/xcatws.cgi +++ b/xCAT-server/xCAT-wsapi/xcatws.cgi @@ -1470,6 +1470,9 @@ sub defout { foreach my $l (@$lines) { if ($l =~ /No responses/) { # handle the case that no output from lsslp command return; + } elsif ($l =~ /Could not find any object definitions/) { + $json->{info} = $l; + last; } if ($l =~ /^Object name: / || $l =~ /^\S+:$/) { # start new node if ($l =~ /^Object name:\s+(\S+)/) { # handle the output of lsdef -t @@ -1517,6 +1520,9 @@ sub defout_remove_appended_type { foreach my $l (@$lines) { if ($l =~ /^(\S*)\s+\(.*\)$/) { # start new node push @{$json}, $1; + } elsif ($l =~ /Could not find any object definitions/) { + push @{$json}, $l; + last; } } } @@ -1883,7 +1889,7 @@ sub actionhdl { } elsif ($paramhash->{'value'}) { push @args, $urilayers[3]."=".$paramhash->{'value'}; } - if (defined($urilayers[3]) and $urilayers[3] =~ /^account/) { + if ((isPut() or isPost()) and defined($urilayers[3])) { foreach my $key (keys %$paramhash) { if (($key ne '') and (exists($paramhash->{$key}))) { push @args, $key."=".$paramhash->{$key}; From fb9edfa7dd4b68f86f36b8ec785176fb92e02194 Mon Sep 17 00:00:00 2001 From: ertaozh Date: Mon, 18 May 2015 01:56:59 -0400 Subject: [PATCH 21/26] won't update ipmi table inside rspconfig "userid=N" "username=" "password=" command --- xCAT-server/lib/xcat/plugins/ipmi.pm | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/ipmi.pm b/xCAT-server/lib/xcat/plugins/ipmi.pm index d2c5fd4ab..574ceeb72 100644 --- a/xCAT-server/lib/xcat/plugins/ipmi.pm +++ b/xCAT-server/lib/xcat/plugins/ipmi.pm @@ -763,19 +763,19 @@ sub password_set { setpassword($sessdata); return; } - - my $ipmitab = xCAT::Table->new('ipmi'); - if (!$ipmitab) { - xCAT::SvrUtils::sendmsg([1, "Failed to update ipmi table."],$callback,$sessdata->{node},%allerrornodes); - } else { - if ($sessdata->{subcommand} =~ m/username/) { - $ipmitab->setNodeAttribs($sessdata->{node}, {'username'=>$sessdata->{newusername}}); - xCAT::SvrUtils::sendmsg("set username Done",$callback,$sessdata->{node},%allerrornodes); - } elsif ($sessdata->{subcommand} =~ m/password/) { - $ipmitab->setNodeAttribs($sessdata->{node}, {'password'=>$sessdata->{newpassword}}); - xCAT::SvrUtils::sendmsg("set password Done",$callback,$sessdata->{node},%allerrornodes); - } - } + # Won't update ipmi table, since option username=<> and password=<> can be run Respectively + #my $ipmitab = xCAT::Table->new('ipmi'); + #if (!$ipmitab) { + # xCAT::SvrUtils::sendmsg([1, "Failed to update ipmi table."],$callback,$sessdata->{node},%allerrornodes); + #} else { + # if ($sessdata->{subcommand} =~ m/username/) { + # $ipmitab->setNodeAttribs($sessdata->{node}, {'username'=>$sessdata->{newusername}}); + # xCAT::SvrUtils::sendmsg("set username Done",$callback,$sessdata->{node},%allerrornodes); + # } elsif ($sessdata->{subcommand} =~ m/password/) { + # $ipmitab->setNodeAttribs($sessdata->{node}, {'password'=>$sessdata->{newpassword}}); + # xCAT::SvrUtils::sendmsg("set password Done",$callback,$sessdata->{node},%allerrornodes); + # } + #} $sessdata->{subcommand} = shift @{$sessdata->{extraargs}}; if ($sessdata->{subcommand} and $sessdata->{subcommand} ne '') { setpassword($sessdata); From bd49b870573f0d84237574c7ce83373ea1730cf7 Mon Sep 17 00:00:00 2001 From: GONG Jie Date: Mon, 18 May 2015 15:42:58 +0800 Subject: [PATCH 22/26] Fix bug #4669, change the filename to be included, pre.rh.rhel7 -> pre.rh.rhels7. --- xCAT-server/share/xcat/install/rh/compute.rhels7.tmpl | 2 +- xCAT-server/share/xcat/install/rh/kvm.rhels7.tmpl | 2 +- xCAT-server/share/xcat/install/rh/service.rhels7.tmpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/xCAT-server/share/xcat/install/rh/compute.rhels7.tmpl b/xCAT-server/share/xcat/install/rh/compute.rhels7.tmpl index 0f69955bd..b3949c8d7 100644 --- a/xCAT-server/share/xcat/install/rh/compute.rhels7.tmpl +++ b/xCAT-server/share/xcat/install/rh/compute.rhels7.tmpl @@ -148,7 +148,7 @@ reboot #INCLUDE_DEFAULT_PKGLIST# %end %pre -#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh.rhel7# +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh.rhels7# %end %post #INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.xcat# diff --git a/xCAT-server/share/xcat/install/rh/kvm.rhels7.tmpl b/xCAT-server/share/xcat/install/rh/kvm.rhels7.tmpl index b32f1f01d..0bfd40ebe 100644 --- a/xCAT-server/share/xcat/install/rh/kvm.rhels7.tmpl +++ b/xCAT-server/share/xcat/install/rh/kvm.rhels7.tmpl @@ -147,7 +147,7 @@ reboot #INCLUDE_DEFAULT_PKGLIST# %end %pre -#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh.rhel7# +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh.rhels7# %end %post #INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.xcat# diff --git a/xCAT-server/share/xcat/install/rh/service.rhels7.tmpl b/xCAT-server/share/xcat/install/rh/service.rhels7.tmpl index 9e6e91652..209f766e4 100644 --- a/xCAT-server/share/xcat/install/rh/service.rhels7.tmpl +++ b/xCAT-server/share/xcat/install/rh/service.rhels7.tmpl @@ -146,7 +146,7 @@ reboot #INCLUDE_DEFAULT_PKGLIST# %end %pre -#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh.rhel7# +#INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/pre.rh.rhels7# %end %post #INCLUDE:#ENV:XCATROOT#/share/xcat/install/scripts/post.xcat# From ae636e0afa917a28387363987abf7dabd4f3edf6 Mon Sep 17 00:00:00 2001 From: ligc Date: Mon, 18 May 2015 04:23:02 -0400 Subject: [PATCH 23/26] fix for bug 2825 and 4628: print warning with makedhcp when the node ip address could not resolved, or the ip overlaps with dynamic range --- xCAT-server/lib/xcat/plugins/dhcp.pm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/xCAT-server/lib/xcat/plugins/dhcp.pm b/xCAT-server/lib/xcat/plugins/dhcp.pm index 7a56a453e..dec7c3e59 100755 --- a/xCAT-server/lib/xcat/plugins/dhcp.pm +++ b/xCAT-server/lib/xcat/plugins/dhcp.pm @@ -593,6 +593,18 @@ sub addnode } elsif ($guess_next_server) { $nxtsrv='${next-server}'; #if floating IP support, cause gPXE command-line expansion patch to drive inheritence from network } + + # The hostname could not be resolved, print a warning message + if (!$ip) + { + $callback->( + { + warning => [ + "The hostname $hname of node $node could not be resolved." + ] + } + ); + } my $doiscsi=0; if ($ient and $ient->{server} and $ient->{target}) { $doiscsi=1; @@ -715,6 +727,18 @@ sub addnode { if ($ip and not ipIsDynamic($ip)) { print $omshell "set ip-address = $ip\n"; + } else { + # only if when ip is not blank, blank ip warning already done earlier in the code + if ($ip) + { + $callback->( + { + warning => [ + "The ip address $ip of node $node overlaps with the DHCP dynamic range specified in networks table, will not add this ip address into dhcpd.leases file." + ] + } + ); + } } if ($lstatements) { From a08d3b3aadd1dd8e136bd4cb0588b5031b1c3a30 Mon Sep 17 00:00:00 2001 From: ertaozh Date: Mon, 18 May 2015 04:45:04 -0400 Subject: [PATCH 24/26] fix bug 4667:rhels6.5 diskful installation failed with netboot=yaboot --- xCAT-server/lib/xcat/plugins/nimol.pm | 13 ++++++++----- xCAT-server/lib/xcat/plugins/yaboot.pm | 19 ++++++++++--------- 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/xCAT-server/lib/xcat/plugins/nimol.pm b/xCAT-server/lib/xcat/plugins/nimol.pm index ae02590fc..8257a8b08 100644 --- a/xCAT-server/lib/xcat/plugins/nimol.pm +++ b/xCAT-server/lib/xcat/plugins/nimol.pm @@ -361,7 +361,8 @@ sub update_export { push @tmp_options, "insecure"; $need_update = 1; } - push @new_export, join(',',@tmp_options); + my $option = join(',',@tmp_options); + push @new_export, "/install *($option)"; } else { push @new_export, $line; } @@ -391,7 +392,7 @@ sub update_syslog { close($syslog_fd); unless (grep /local2.*nimol\.log/, @curr_syslog) { my $new_syslog_fd; - open($new_syslog_fd, ">>", "/etc/exports"); + open($new_syslog_fd, ">>", "/etc/rsyslog.conf"); print $new_syslog_fd "local2.* /var/log/nimol.log\n"; close($new_syslog_fd); #system("service rsyslog restart"); @@ -412,6 +413,7 @@ sub create_imgconf_file { my $bootimg_link = "/tftpboot/vios/nodes"; my $relative_path = $bootimg_link; $relative_path =~ s/^\/tftpboot//; + $bootimg_root =~ s/^\/tftpboot//; # check the dir where the bootimage link file and bootimage configuration file stored unless (-e $bootimg_link) { mkpath($bootimg_link); @@ -430,10 +432,11 @@ sub create_imgconf_file { unless (defined($rootpw)) { return "Unable to find requested password from passwd, with key=vios,username=padmin"; } - unless (-e $bootimg_root."/viobootimg") { + + chdir($bootimg_link); + unless (-e "../../".$bootimg_root."/viobootimg") { return "Unable to find VIOS bootimg file"; } - chdir($bootimg_link); foreach my $node (@$nodes) { my $bootimg_conf_fd; my $gateway = $nethash{$node}{gateway}; @@ -444,7 +447,7 @@ sub create_imgconf_file { my $master_ip = xCAT::NetworkUtils->getipaddr($master); my $node_ip = xCAT::NetworkUtils->getipaddr($node); unless (-e "$node") { - symlink($bootimg_root."/viobootimg", "$node"); + symlink("../../".$bootimg_root."/viobootimg", "$node"); } if (-e $bootimg_link."/$node.info") { unlink($bootimg_link."/$node.info"); diff --git a/xCAT-server/lib/xcat/plugins/yaboot.pm b/xCAT-server/lib/xcat/plugins/yaboot.pm index bed779b5b..7061270ba 100644 --- a/xCAT-server/lib/xcat/plugins/yaboot.pm +++ b/xCAT-server/lib/xcat/plugins/yaboot.pm @@ -679,11 +679,12 @@ sub process_request { #} if ($do_dhcpsetup) { if (%osimagenodehash) { - chdir("$tftpdir"); + unless (-e "$tftpdir/yb/node") { + system("mkdir -p $tftpdir/yb/node"); + } + chdir("$tftpdir/yb/node"); foreach my $osimage (keys %osimagenodehash) { - unless (-e "$tftpdir/yb/node") { - system("mkdir -p $tftpdir/yb/node"); - } + my $osimgent = $osimagetab->getAttribs({imagename => $osimage },'osvers'); my $osentry = $osimgent->{'osvers'}; @@ -702,10 +703,10 @@ sub process_request { } if (($osv =~ /rh/ and int($osn) >= 6) or ($osv =~ /sles/ and int($osn) >= 11)) { - my $fpath = "/yb/". $osentry."/yaboot"; foreach my $tmp_node (@{$osimagenodehash{$osimage}}) { - unless (-e "yb/node/yaboot-$tmp_node") { - symlink("yb/$osentry/yaboot", "yb/node/yaboot-$tmp_node"); + unless (-e "yaboot-$tmp_node") { + symlink("../$osentry/yaboot", "yaboot-$tmp_node"); + #symlink("/tftpboot/yb/$osentry/yaboot", "yb/node/yaboot-$tmp_node"); } } if ($::YABOOT_request->{'_disparatetftp'}->[0]) { #reading hint from preprocess_command @@ -718,8 +719,8 @@ sub process_request { } } else { foreach my $tmp_node (@{$osimagenodehash{$osimage}}) { - unless (-e "yb/node/yaboot-$tmp_node") { - symlink("yaboot", "yb/node/yaboot-$tmp_node"); + unless (-e "yaboot-$tmp_node") { + symlink("../../yaboot", "yb/node/yaboot-$tmp_node"); } } From 2409539774ce3c7dcf6800107cab1c0a15312274 Mon Sep 17 00:00:00 2001 From: ertaozh Date: Mon, 18 May 2015 04:58:22 -0400 Subject: [PATCH 25/26] fix bug for PUT and POST attributwes of serviceprocessor object in RESTAPI --- xCAT-server/xCAT-wsapi/xcatws.cgi | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/xCAT-server/xCAT-wsapi/xcatws.cgi b/xCAT-server/xCAT-wsapi/xcatws.cgi index 7c31f6a35..db11448ba 100755 --- a/xCAT-server/xCAT-wsapi/xcatws.cgi +++ b/xCAT-server/xCAT-wsapi/xcatws.cgi @@ -1886,13 +1886,14 @@ sub actionhdl { } elsif ($params->{'resourcename'} eq "serviceprocessor") { if (isGET()) { push @args, $urilayers[3]; - } elsif ($paramhash->{'value'}) { - push @args, $urilayers[3]."=".$paramhash->{'value'}; - } - if ((isPut() or isPost()) and defined($urilayers[3])) { - foreach my $key (keys %$paramhash) { - if (($key ne '') and (exists($paramhash->{$key}))) { - push @args, $key."=".$paramhash->{$key}; + } elsif (isPut() or isPost()) { + if ($paramhash->{'value'} and defined($urilayers[3])) { + push @args, $urilayers[3]."=".$paramhash->{'value'}; + } else { + foreach my $key (keys %$paramhash) { + if (($key ne '') and (exists($paramhash->{$key}))) { + push @args, $key."=".$paramhash->{$key}; + } } } } From 1f8974af4fd58bdd0096efbd5684861336fc805f Mon Sep 17 00:00:00 2001 From: ertaozh Date: Mon, 18 May 2015 08:14:27 -0400 Subject: [PATCH 26/26] fix bug 4667:rhels6.5 diskful installation failed with netboot=yaboot, for netboot=nimol --- xCAT-server/lib/xcat/plugins/dhcp.pm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xCAT-server/lib/xcat/plugins/dhcp.pm b/xCAT-server/lib/xcat/plugins/dhcp.pm index dec7c3e59..90e96c252 100755 --- a/xCAT-server/lib/xcat/plugins/dhcp.pm +++ b/xCAT-server/lib/xcat/plugins/dhcp.pm @@ -664,7 +664,7 @@ sub addnode } elsif ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'petitboot') { $lstatements = 'option conf-file \"http://'.$nxtsrv.'/tftpboot/petitboot/'.$node.'\";'.$lstatements; } elsif ($nrent and $nrent->{netboot} and $nrent->{netboot} eq 'nimol') { - $lstatements = 'supersede server.filename=\"/vios/nodes/'.$node.'\"'.$lstatements; + $lstatements = 'supersede server.filename=\"/vios/nodes/'.$node.'\";'.$lstatements; }