2
0
mirror of https://github.com/xcat2/xcat-core.git synced 2025-05-22 03:32:04 +00:00

remove the install/netboot/statelite from the usage statements of nodeset, imgcapture, genimage and packimgage

This commit is contained in:
ligc 2015-05-14 03:55:42 -04:00
parent 47725c06ae
commit 8f7633c9b5
4 changed files with 0 additions and 2503 deletions

568
perl-xCAT/xCAT/Usage.pm Normal file → Executable file
View File

@ -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 <noderange> [-s net|hd] [-F] [-f] [-V|--verbose] [-m table.colum==expectedstatus] [-m table.colum==expectedstatus...] [-r <retrycount>] [-t <timeout>]
rnetboot [-h|--help|-v|--version]
zVM specific:
rnetboot <noderange> [ipl= address]",
"rpower" =>
"Usage: rpower <noderange> [--nodeps] [on|onstandby|off|suspend|reset|stat|state|boot] [-V|--verbose] [-m table.colum==expectedstatus][-m table.colum==expectedstatus...] [-r <retrycount>] [-t <timeout>]
rpower [-h|--help|-v|--version]
KVM Virtualization specific:
rpower <noderange> [boot] [ -c <path to iso> ]
PPC (with IVM or HMC) specific:
rpower <noderange> [--nodeps] [of] [-V|--verbose]
CEC (with HMC) specific:
rpower <noderange> [on|off|reset|boot|onstandby]
LPAR(with HMC) specific:
rpower <noderange> [on|off|reset|stat|state|boot|of|sms|softoff]
CEC(using Direct FSP Management) specific:
rpower <noderange> [on|onstandby|off|stat|state|resetsp]
Frame(using Direct FSP Management) specific:
rpower <noderange> [stat|state|rackstandby|exit_rackstandby|resetsp]
LPAR(using Direct FSP Management) specific:
rpower <noderange> [on|off|reset|stat|state|boot|of|sms]
Blade(using Direct FSP Management) specific:
rpower <noderange> [on|onstandby|off|cycle|state|sms]
Blade(using AMM) specific:
rpower <noderange> [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 <noderange> [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 <noderange> [all [-s]|clear|<number of entries to retrieve> [-s]] [-V|--verbose]
reventlog [-h|--help|-v|--version]",
"rinv" =>
"Usage:
Common:
rinv <noderange> [all|model|serial] [-V|--verbose]
rinv [-h|--help|-v|--version]
BMC specific:
rinv <noderange> [mprom|deviceid|uuid|guid|vpd [-t]|all [-t]]
MPA specific:
rinv <noderange> [firm|bios|diag|mprom|sprom|mparom|mac|mtm [-t]]
PPC specific(with HMC):
rinv <noderange> [all|bus|config|serial|model|firm [-t]]
PPC specific(using Direct FSP Management):
rinv <noderange> [firm]
rinv <noderange> [deconfig [-x]]
Blade specific:
rinv <noderange> [all|serial|mac|bios|diag|mprom|mparom|firm|mtm [-t]]
IBM Flex System Compute Node specific:
rinv <noderange> [firm]
VMware specific:
rinv <noderange>
zVM specific:
rinv noderange [all|config]
MIC specific:
rinv noderange [system|ver|board|core|gddr|all]",
"rsetboot" =>
"Usage: rsetboot <noderange> [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 <noderange> [hd0|hd1|hd2|hd3|net|iscsi|usbflash|floppy|none],...
PPC (using Direct FSP Management) specific:
rbootseq <noderange> [hfi|net]",
"rscan" =>
"Usage: rscan <noderange> [-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 <noderange> [snmpdest|alert|community] [-V|--verbose]
rspconfig <noderange> [snmpdest=<dest ip address>|alert=<on|off|en|dis|enable|disable>|community=<string>]
BMC specific:
rspconfig <noderange> [ip|netmask|gateway|backupgateway|garp]
rspconfig <noderange> [garp=<number of 1/2 second>]
iDataplex specific:
rspconfig <noderange> [thermprofile]
rspconfig <noderange> [thermprofile=<two digit number from chassis>]
MPA specific:
rspconfig <noderange> [sshcfg|snmpcfg|pd1|pd2|network|swnet|ntp|textid|frame]
rspconfig <singlenode> [textid=name]
rspconfig <singlenode> [frame=number]
rspconfig <singlenode> [USERID=passwd] [updateBMC=<y|n>]
rspconfig <noderange> [sshcfg=<enable|disable>|
snmpcfg=<enable|disable>|
pd1=<nonred|redwoperf|redwperf>|
pd2=<nonred|redwoperf|redwperf>|
network=<*|[ip],[host],[gateway],[netmask]>|
swnet=<[ip],[gateway],[netmask]>|
textid=<*>|
frame=<*>|
ntp=<[ntp],[ip],[frequency],[v3]>
FSP/CEC (using ASM Interface) Specific:
rspconfig <noderange> [autopower|iocap|decfg|memdecfg|procdecfg|time|date|spdump|sysdump|network|hostname]
rspconfig <noderange> autopower=<enable|disable>|
iocap=<enable|disable>|
decfg=<enable|disable>:<policy name>,...|
memdecfg=<configure|deconfigure>:<processing unit>:<bank|unit>:<bank/unit number>:id,...|
procdecfg=<configure|deconfigure>:<processing unit>:id,...|
date=<mm-dd-yyyy>|
time=<hh:mm:ss>|
network=<*|[ip],[host],[gateway],[netmask]>|
HMC_passwd=<currentpasswd,newpasswd>|
admin_passwd=<currentpasswd,newpasswd>|
general_passwd=<currentpasswd,newpasswd>|
*_passwd=<currentpasswd,newpasswd>|
hostname=<*|hostname>
FSP/CEC (using Direct FSP Management) Specific:
rspconfig <noderange> HMC_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> admin_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> general_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> *_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> [sysname]
rspconfig <noderange> [sysname=<*|name>]
rspconfig <noderange> [pending_power_on_side]
rspconfig <noderange> [pending_power_on_side=<temp|perm>]
rspconfig <noderange> [cec_off_policy]
rspconfig <noderange> [cec_off_policy=<poweroff|stayon>]
rspconfig <noderange> [huge_page]
rspconfig <noderange> [huge_page=<NUM>]
rspconfig <noderange> [BSR]
rspconfig <noderange> [setup_failover]
rspconfig <noderange> [setup_failover=<enable|disable>]
rspconfig <noderange> [force_failover]
rspconfig <noderange> --resetnet
BPA/Frame (using Direct FSP Management)specific:
rspconfig <noderange> HMC_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> admin_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> general_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> *_passwd=<currentpasswd,newpasswd>
rspconfig <noderange> [frame]
rspconfig <noderange> frame=<*|frame>
rspconfig <noderange> [sysname]
rspconfig <noderange> [sysname=<*|name>]
rspconfig <noderange> [pending_power_on_side]
rspconfig <noderange> [pending_power_on_side=<temp|perm>]
rspconfig <noderange> --resetnet
HMC specific:
rspconfig <noderange> [sshcfg]
rspconfig <noderange> [sshcfg=<enable|disable>]
CEC|Frame(using ASM)Specific:
rspconfig <noderange> [dev|celogin1]
rspconfig <noderange> [dev=<enable|disable>]|
rspconfig <noderange> [celogin1=<enable|disable>]
",
"getmacs" =>
"Usage:
Common:
getmacs [-h|--help|-v|--version]
PPC specific:
getmacs <noderange> [-F filter]
getmacs <noderange> [-M]
getmacs <noderange> [-V| --verbose] [-f] [-d] [--arp] | [-D {[-o] [-S server] [-G gateway] [-C client] | [--noping]}]
blade specific:
getmacs <noderange> [-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=<N|viosnode:slotid>] [--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 <noderange> [-V|--verbose]
lsvm [-h|--help|-v|--version]
PPC (with HMC) specific:
lsvm <noderange> [-a|--all]
PPC (using Direct FSP Management) specific:
lsvm <noderange> [-l|--long] --p775
lsvm <noderange>
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 <noderange> [-p profile][-V|--verbose]
chvm <noderange> <attr>=<val> [<attr>=<val>...]
PPC (using Direct FSP Management) specific:
chvm <noderange> --p775 [-p <profile>]
chvm <noderange> --p775 -i <id> [-m <memory_interleaving>] -r <partition_rule>
chvm <noderange> [lparname=<*|name>]
chvm <noderange> [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=<N|viosnode:slotid>] [--vios]
chvm <noderange> [del_physlots=drc_index1,drc_index2...]
chvm <noderange> [del_vadapter=slotid]
VMware specific:
chvm <noderange> [-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 <noderange> [--service][-V|--verbose]
rmvm [-h|--help|-v|--version],
rmvm [-p] [-f]
PPC (using Direct FSP Management) specific:
rmvm <noderange>",
"lsslp" =>
"Usage: lsslp [-h|--help|-v|--version]
lsslp [<noderange>][-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 [<noderange>][-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 <noderange> -p <rpm_directory> [--activate concurrent | disruptive][-V|--verbose]
rflash <noderange> [--commit | --recover] [-V|--verbose]
PPC (using Direct FSP Management) specific:
rflash <noderange> -p <rpm_directory> --activate <disruptive|deferred> [-d <data_directory>]
rflash <noderange> [--commit | --recover] [-V|--verbose]
rflash <noderange> [--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 <noderange> [-V|--verbose] [-k|--security] [-s|--sn] [-t <timeout>]
or
updatenode <noderange> [-V|--verbose] [-F|--sync | -f|--snsync] [-l|--user[username]] [--fanout=[fanout value]] [-S|--sw] [-t <timeout>]
[-P|--scripts [script1,script2,...]] [-s|--sn]
[-A|--updateallsw] [-c|--cmdlineonly] [-d alt_source_dir]
[attr=val [attr=val...]]
or
updatenode <noderange> [-V|--verbose] [script1,script2,...]
Options:
<noderange> 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 <alt_source_dir>] 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 <noderange>",
"mkflexnode" =>
"Usage:
mkflexnode [-h|--help|-v|--version]
mkflexnode <noderange>",
"nodeset" =>
"Usage:
Common:
nodeset [-h|--help|-v|--version]
nodeset <noderange> [install|shell|boot|runcmd=bmcsetup|netboot|iscsiboot|osimage[=<imagename>]|statelite|offline]",
"rmflexnode" =>
"Usage:
rmflexnode [-h|--help|-v|--version]
rmflexnode <noderange>",
"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 "";
}

View File

@ -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 <osver> [-a <arch>] -p <profile> -i <nodebootif> -n <nodenetdrivers> [--onlyinitrd] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] [--dryrun] [--noupdate]'."\n\n";
print ' genimage [-o <osver>] [-a <arch>] [-p <profile>] [-i <nodebootif>] [-n <nodenetdrivers>] [--onlyinitrd] [-r <otherifaces>] [-k <kernelver>] [-g <krpmver>] [-m statelite] [-l rootlimitsize] [-t tmplimitsize] [--permission <permission>] [--interactive] [--dryrun] [--noupdate] <imagename>'."\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 = <stdin>;
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 = <stdin>;
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 = <stdin>;
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 = <stdin>;
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? [<blank>]";
$interface = <stdin>;
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 = <stdin>;
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 = <FILE1>;
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;
}
}

846
xCAT-server/lib/xcat/plugins/imgcapture.pm Normal file → Executable file
View File

@ -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 <node> -t|--type diskless [-p | --profile <profile>] [-o|--osimage <osimage>] [-i <nodebootif>] [-n <nodenetdrivers>] [-d | --device <devicesToCapture>] [-V | --verbose] \n imgcapture <node> -t|--type sysclone -o|--osimage <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:\\(.*<part num=\\\"1\\\".*\\)\\(/>\\):\\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;

629
xCAT-server/lib/xcat/plugins/packimage.pm Normal file → Executable file
View File

@ -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(<INCLUDE>) {
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;