installns
installns
targzip.conf
#!/bin/sh #This file is used by the targzip.sh TAR_LIST="tarlist.txt"
NS_VERSION=".ns.version"
NS_KERNEL="ns-12.1-48.13.gz"
NS_SHA256="ns-12.1-48.13.sha2"
UNPACK_DIR="upgrade_dist"
TAR_NAME="NSVPX-NCore_build-12.1-48.13_nc_64.tgz"
targzip.sh
#!/bin/sh . ./targzip.conf tar_gzip()
{
if [ ! -f ./${TAR_NAME} ]
then
if [ -f ./${NS_VERSION} -a -f ./${NS_KERNEL} ];
then
sha256 -q ./${NS_KERNEL} > ./${NS_SHA256}
ls > ./${TAR_LIST}
`grep ${NS_VERSION} ./${TAR_LIST} > /dev/null 2>&1` || echo ${NS_VERSION} >> ./${TAR_LIST}
tar -zcvpf ./${TAR_NAME} -T ./${TAR_LIST}
echo "notice: file(./${TAR_NAME}) packaged done ..."
fi
else
echo "warning: file(./${TAR_NAME}) already exist, cannot be packaged."
echo "notice: Please delete the file(./${TAR_NAME})."
fi
} tar_ungzip()
{
if [ ! -f ./${UNPACK_DIR}/${NS_VERSION} ]
then
if [ -f ./${TAR_NAME} ];
then
mkdir -p ./${UNPACK_DIR}
tar -zxvpf ./${TAR_NAME} -C ./${UNPACK_DIR}
echo "notice: file(./${TAR_NAME}) unpackaged done ..."
fi
else
echo "warning: file(./${UNPACK_DIR}/${NS_VERSION}) already exist, cannot be unpackaged."
echo "notice: Please delete the file(./${UNPACK_DIR}/${NS_VERSION})."
fi
} show_status()
{
if [ -f ./${UNPACK_DIR}/${NS_VERSION} ];
then
echo "notice: file(./${TAR_NAME}) unpackaged done ..."
fi if [ -f ./${TAR_NAME} ];
then
echo "notice: file(./${TAR_NAME}) packaged done ..."
fi
} case $ in
pack)
tar_gzip;
;;
unpack)
tar_ungzip;
;;
status)
show_status;
;;
*)
echo "$0: no argument";
;;
esac
installns
将升级文件NSVPX-NCore_build-12.1-48.13_nc_64.tgz,上传至设备的“/var/nsinstall”目录下。 在命令行中执行以下命令,查看升级脚本使用帮助信息:
1) shell
2) cd /var/nsinstall/
3) ls -alh .
4) mkdir NSVPX-NCore_build-12.1-48.13_nc_64
5) tar -zxpf NSVPX-NCore_build-12.1-48.13_nc_64.tgz -C NSVPX-NCore_build-12.1-48.13_nc_64
6) cd NSVPX-NCore_build-12.1-48.13_nc_64
7) perl ./installns -h root@vpx-test# perl ./installns -h
installns: [32643]: BEGIN_TIME 1542961116 Fri Nov 23 16:18:36 2018
installns: [32643]: VERSION ns-12.1-48.13.gz
installns: [32643]: VARIANT v
installns: [32643]: Options are: h Usage:
-F FIPS install
-h Help
-Y Answer Yes to everything
-y Force Reboot
-n Don't Reboot
-c Force Clean up
-N Don't check ns.conf
-G No curses
-L Enable CallHome
-e Upgrading from\to "enhancement" build
-R Resize swap and /var. all data on /var will be erased
root@vpx-test# 在命令行中执行以下命令,进行系统升级,升级成功后,会自动重启系统:
perl ./installns -g -G -N -L -y
#!/usr/bin/perl
$vers = "12.1-48.13" ;
$variant = "v" ;
# FILE: $Id: //depot/main/rs_121_48_11_RTM/usr.src/netscaler/installns/template.pl#1 $
# LAST CHECKIN: $Author: build $
# $DateTime: 2018/05/21 14:04:28 $ # Copyright 2004-2018 Citrix Systems, Inc. All rights reserved.
# This software and documentation contain valuable trade
# secrets and proprietary property belonging to Citrix Systems, Inc.
# None of this software and documentation may be copied,
# duplicated or disclosed without the express
# written permission of Citrix Systems, Inc. #
### Begin installns script
# two variables are created when this file is processed by the Netscaler build.
# "vers" is the external version number of the software releaase, e.g. 9.0
# "variant" is either "v" for the multi-core netscaler software or "k" for the legacy kernel mode packet engine
# The template for this script is found in usr.src/netscaler/installns/template.pl $ENV{PATH} = '/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin'; use Getopt::Std;
use File::Path;
use File::Copy;
use Sys::Syslog; ### Variable Initialization
$debug_print = ;
$kernel = "ns-$vers.gz";
$kernelname = "ns-$vers";
$loaderconf = "/boot/loader.conf";
$newpath = "/nsconfig";
$newpathlicense = "$newpath/license";
$svm_check_path = "/mps";
$varstr = "/var";
$varpath = "$varstr/netscaler";
$varbakpath = "$varpath/nsbackup";
$templatespath = "$varstr/nstemplates";
$templateslinkpath = "$newpath/nstemplates";
$templatesoldpath = "$newpath/templates";
$applicationtemplatespath = "$templatespath/applications";
$apptemplatesdeploymentfilespath = "$applicationtemplatespath/deployment_files";
$entitytemplatespath = "$templatespath/entities";
$lbvservertemplatespath = "$templatespath/entities/lb vserver";
$lbvserverdeploymentfilepath = "$templatespath/entities/lb vserver/deployment_files";
$reportspath = "$templatespath/reports";
$nitropath = "$varpath/nitro";
$mastoolspath = "$varpath/mastools";
$min_var_freespace = ; # leave just over 4GB for core files (1k blocks). From nslog.sh.
$flashpath = "/flash";
$ch_conf = "/flash/nsconfig/.callhome.conf";
$sshdir = "ssh";
$ssldir = "ssl";
$sslfipsdir = "fips";
$docdir = "doc";
$helpdir = "help";
$help_ciscodir="help_cisco";
$msndir = "msn";
$guidir = "gui";
$state_file = "$varstr/nsinstall/installns_state";
$locdbdir = "locdb";
$inCompassDbRoot = "gcf1";
$inCompassDb = "$inCompassDbRoot/data";
my %options = ();
my $flag_Y = ;
my $old_ns_cert = ;
@dirs = (
"$newpath", "$newpath/$sshdir",
"$newpath/$ssldir", "$varpath",
"$varpath/$ssldir", "$varpath/$docdir",
"$varpath/$helpdir", "$templatespath", "$varpath/$help_ciscodir",
"$entitytemplatespath", "$lbvservertemplatespath", "$lbvserverdeploymentfilepath",
"$applicationtemplatespath", "$apptemplatesdeploymentfilespath",
"$reportspath", "$varpath/$guidir",
"$newpath/$sslfipsdir", "$varpath/$msndir",
"$nitropath", "$mastoolspath", "$newpathlicense/$ssldir",
"$varpath/$locdbdir", "$varstr/$inCompassDbRoot", "$varstr/$inCompassDb"
); @files = ( "ns.conf", "ns.lic", "resolv.conf", "rc.netscaler" );
$fips = ;
$| = ;
$version = `uname -a`;
$ignore_platform_checks = "no";
$nsconf_check = 'yes';
$user_nsconf_check = 'yes';
$nocurses = ;
$callhome_flag = ;
$gui_flag = ;
$enh_flag = ;
$resize_flag = ; #options for syslogging the installation activity
$syslog_ident = "installns: ";
$syslog_opt = "ndelay,pid,nofatal,perror";
$syslog_facility = "LOG_USER";
$syslog_level = "LOG_NOTICE"; ### Subroutine Definitions #write a string to the system log
sub log_status {
my $log_msg = $_[]; print "$log_msg\n";
syslog $syslog_level, "%s", $log_msg;
} sub log_status_no_console {
my $log_msg = $_[]; syslog $syslog_level, "%s", $log_msg;
} #write a string to the state log and the syslog. This file contains information about the current
#install process that may later be used to restart or undo this installation
sub log_state {
my $log_msg = $_[]; print STATE_LOG "$log_msg\n";
syslog $syslog_level, "%s", $log_msg;
} #print trace messages about subroutine execution
#goes to syslog and to standard output. mostly for developer use.
sub log_trace {
my $log_msg = $_[]; if ($debug_print) {
log_status($log_msg);
}
} # This function checks that the hardware (sysid) is compatible with the this release of the Netscaler Software
# Note that this install script is specific to a given release, i.e. this script installs release '$vers' and no other version.
sub check_sysid {
my $this_subroutine_name = ( caller() )[];
my $ret = `sysctl netscaler.sysid`; log_trace " \nBEGIN $this_subroutine_name"; if ( $ignore_platform_checks eq "yes" ) {
log_status "*** WARNING *** System platform id checks are disabled. You may end up with an invalid installation. ****";
log_status "Your system id is reported as $ret";
}
else {
if ( $variant eq "k" ) {
if ($ret =~ // || $ret =~ // ) {
ns_die(
"Error: This version of Netscaler software is incompatible with the hardware platform $ret, please install the 8.1 release instead"
);
}
elsif ($ret =~ // || $ret =~ // || $ret =~ // || $ret =~ // || $ret =~ // || $ret =~ // ) {
ns_die(
"\nError: This version of Netscaler software is incompatible with the hardware platform $ret please install the 9.3 release instead"
);
}
elsif ( $ret =~ /(|||)/ ||
$ret =~ /(||)/ ||
$ret =~ // ||
$ret =~ // ||
$ret =~ /(|||)/ ||
$ret =~ /(||)/ ||
$ret =~ /(||)/ ||
$ret =~ /(||||||||||||||||)/ ||
$ret =~ /(||||)/ ||
$ret =~ /(||)/ ) {
ns_die(
"Error: This version of Netscaler software is incompatible with the hardware platform $ret, please install an nCore release \"nc\" variant instead"
);
}
}
elsif ( $variant eq "v" ) {
# Hydra is dead
if ( $ret =~ /(||)$/ ) {
ns_die(
"Error: This version of Netscaler software is incompatible with the hardware platform $ret, please install the 10.5 release instead"
);
}
# Check for MPX SP0/SP2, Sparta, Athens 1/2,
# Constantinople, Corinth, Galata, Rome, Thebes, Beringer,
# Decapolis, Corinth-T, Pentapolis,
# ROAD and Gladius-M platforms
elsif ( $ret !~ /(||)$/ &&
$ret !~ /$/ &&
$ret !~ /(|)$/ &&
$ret !~ /(|||)$/ &&
$ret !~ /(||)$/ &&
$ret !~ /(|)$/ &&
$ret !~ /$/ &&
$ret !~ /$/ &&
$ret !~ /$/ &&
$ret !~ /(|||||)$/ &&
$ret !~ /(||||)$/ &&
$ret !~ /(|||||||||)$/ &&
$ret !~ /(||)$/ &&
$ret !~ /(|||)$/ &&
$ret !~ /(||)$/ &&
$ret !~ /(||||)$/ &&
$ret !~ /(|||)$/ &&
$ret !~ /(||||||)$/ &&
$ret !~ /$/ &&
$ret !~ /(||||||||||||||||)$/ &&
$ret !~ /(||||)$/ &&
$ret !~ /(||)$/ ) {
ns_die(
"Error: This version of Netscaler software is incompatible with the hardware platform $ret, please contact NetScaler support to make sure you have the correct software release."
);
}
}
else {
ns_die(
"Error: This script does not understand the variant ($variant) that you are trying to install. Please check to see if you have the correct software release."
);
}
}
log_trace "END $this_subroutine_name";
} ## end sub check_sysid # This function checks for the Hardware requirement for VPX
sub check_vpx {
my $this_subroutine_name = (caller() )[];
my $sysid = `sysctl -n netscaler.sysid`; log_trace " \nBEGIN $this_subroutine_name"; if(stat($svm_check_path) != NULL) {
ns_die("ERROR: This image belongs to NetScaler. Aborting Installation...");
} if ($sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ) {
## 45xxxx sysid == VPX 9.x release & above
my $ncpu = `sysctl -n hw.ncpu`;
my $mem = `sysctl -n hw.realmem`;
if ( $variant eq "k" ) {
if ( $mem < ) {
print "\n WARNING: NetScaler on Classic VPX requires minimum 1 Gigabytes to start \n";
}
}
elsif ( $variant eq "v" ) {
if ( $ncpu < || $mem < ) {
ns_die("ERROR: NetScaler on nCore VPX requires minimum 2 Gigabytes and 2 cpus to start.");
}
}
}
# For HyperV and SDX: Classic Build is not supported
if ($sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ) {
if ( $variant eq "k" ) {
ns_die("ERROR: NetScaler on classic VPX is not supported.\n");
}
}
log_trace "END $this_subroutine_name";
} ## end sub check_vpx # This function ensures upgrade does not cause instance to be bootstrapped.
sub cloud_prevent_bootstrap {
my $this_subroutine_name = (caller() )[];
my $sysid = `sysctl -n netscaler.sysid`; log_trace " \nBEGIN $this_subroutine_name"; if ($sysid == ) {
`touch /nsconfig/aws_bootstrap`;
}
log_trace "END $this_subroutine_name";
} # This function invokes an executable which checks for an upgrade or downgrade
# situation and gives the user a chance to swap config files
sub check_nsconf {
my $this_subroutine_name = ( caller() )[];
log_trace " \nBEGIN $this_subroutine_name"; if ( !$nsconf_check ) {
if ( !$user_nsconf_check ) {
log_status "ns.conf check skipped at user's request";
} else {
log_status "ns.conf check skipped";
}
return;
} chmod(, './nsconfig');
system('./nsconfig check wait' . ($nocurses ? ',nocurses' : '')); log_trace "END $this_subroutine_name";
} ## end sub check_nsconf sub check_callhome {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name";
if (!(-e $ch_conf)) {
"\n CallHome feature will be enabled after the reboot.
This lets the NetScaler device/instance automatically upload diagnostic
and usage information to Citrix. This data will help detect critical errors
and will also be used to improve the features and the product You can also configure this feature anytime using the command line
interface or the configuration utility. Please see the documentation
for more details.\n\n";
}
log_trace "END $this_subroutine_name";
} ## end sub check_callhome # This routine will be used to check sym link with standard
# configuration files during upgrade or downgrade. If symlink exists,
# it can contain some customized settings which will not applicable
# during build upgrade or downgrade. So we will log message in syslog
# file so that user will know reason of failure of process starting.
sub check_sym_link() {
my $this_subroutine_name = ( caller() )[];
log_trace " \n BEGIN $this_subroutine_name";
# Provide list of files by comma seperation
my @conf_files = ( "/etc/sshd_config", "/etc/httpd.conf" );
foreach $elem (@conf_files) {
if ( ( stat($elem) != NULL ) && ( -l $elem ) ) {
log_status "WARNING:A symbolic link exists for $elem. Please review it for compatibility!!!" }
} } # Various pre-flight checks
sub check_system_before_install {
my $this_subroutine_name = ( caller() )[];
$kernpath = "/flash/";
$loaderconf = "/flash/boot/loader.conf"; log_trace " \nBEGIN $this_subroutine_name";
check_sysid();
check_sym_link();
check_vpx();
check_nsconf();
check_callhome();
statfs($kernpath);
setup_paths();
log_trace "END $this_subroutine_name";
} ## end sub check_system_before_install # Copy the new kernel from the disk to the flash. Try to save the old flash kernel on disk first.
sub copy_kernel {
my $this_subroutine_name = ( caller() )[];
my $running_kernel_file_name = `sysctl kern.bootfile`;
my $i = ;
my @timeData = localtime(time);
my $year = + $timeData[];
my $curr_time =
"ns_"
. $year . "_"
. $timeData[] . "_"
. $timeData[] . "_"
. $timeData[] . "_"
. $timeData[] . "_"
. $timeData[]; log_trace " \nBEGIN $this_subroutine_name"; $bk_dir = "$varbakpath/$curr_time-running-kernel/";
mkpath($bk_dir)
|| ns_die("Error: Failed to create archive directory $bk_dir ($!)\n"); # If the user select the archive option earlier, there may not be a kernel in /flash. otherwise back it up
if ( -f $running_kernel_filename ) {
log_status_no_console
"Backing up running $running_kernel_filename to $bk_dir/$running_kernel_filename ... ";
system("cp $running_kernel_filename $bk_dir") ==
|| ns_die(
"Error: Can't back up running kernel $running_kernel_filename\n");
$kernel_backed_up = " yes";
}
else {
$kernel_backed_up = " no";
}
my $srcsha2sum = `sha256 -q ./$kernel`
|| ns_die("Error: Can't checksum $kernel\n"); # Compare checksum of new kernel/image file against stored checksum in build tarball
log_status_no_console "Checksumming ns-${vers}.gz ... ";
my $stored_sha2_sum = `cat ns-${vers}.sha2`
|| ns_die("Error: Can't find checksum of build ns-${vers}\n");
if ( $stored_sha2_sum != $srcsha2sum ) {
log_status(
"Error: the checksum $srcsha2sum of the kernel tarball $kernel is different than the stored checksum $stored_sha2_sum of the installing kernel tarball ns-${vers}. You may have a corrupt or incorrect distribution\n"
);
ns_die(
" The new kernel is not installed. Your current running kernel is preserved.\n"
);
}
log_status_no_console "Checksum ok. "; open( IN, "< ./$kernel" )
or ns_die("Failed to open $kernel for reading ($!), aborting...\n");
open( OUT, "> $kernpath$kernel" )
or
ns_die("Failed to open $kernpath$kernel for writing ($!), aborting...\n"); $blksize = ( stat IN )[] || ;
log_status("Copying $kernel to $kernpath$kernel ... ");
log_state("BEGIN KERNEL_COPY");
$kernel_copied = "no"; while ( $len = sysread IN, $buf, $blksize ) {
if ( !defined $len ) {
next if $! =~ /^Interrupted/;
ns_die("Read error: $!\n");
}
$offset = ;
while ($len) {
defined( $written = syswrite OUT, $buf, $len, $offset )
or ns_die("System write error: $!\n");
$len -= $written;
$offset += $written;
} # Print status dots for copy
if ( $i % == ) {
print ".";
}
$i++;
} ## end while ( $len = sysread IN...
print "\n"; close(IN);
close(OUT);
my $dstsha2sum = `sha256 -q $kernpath$kernel`
|| ns_die("Error: Can't checksum $kernpath$kernel\n"); if ( !( $srcsha2sum eq $dstsha2sum ) ) {
log_status(
"Warning: ./$kernel:$srcsha2sum and $kernpath$kernel:$dstsha2sum checksums differ!\n"
); # attempt to restore kernel archived above.
if ( $kernel_backed_up eq "yes" ) {
log_status(
"Attempting to restore previous kernel $running_kernel_filename to flash\n"
);
system('cp $bk_dir/$running_kernel_filename. gz /flash/') ==
|| ns_die(
"Error: Can't restore backup of $running_kernel_filename\n");
ns_die(
"Installation failed: Mismatched kernel checksum, check free space on destination partition. Previous kernel $running_kernel_filename. gz restored to flash."
);
} ## end if ( $kernel_backed_up...
} ## end if ( !( $srcsha2sum eq ...
log_state("END KERNEL_COPY");
$kernel_copied = "yes"; log_trace "END $this_subroutine_name";
} ## end sub copy_kernel # This function converts all the imported object names and
# their corresponding mapping file entries to lower case before upgrade.
sub convert_import_object_to_lower_case
{
my $subroutine_name = ( caller() )[];
log_trace " \nBEGIN $subroutine_name";
@import_objects = ("/var/download/custom", "/var/download/htmlerrorurl", "/var/download/xmlerrorurl", "/var/download/xmlschema","/var/download/wsdl");
foreach (@import_objects) {
my $dirname = $_;
if (opendir( DIR, $dirname )) {
my @list_of_files = readdir(DIR);
foreach (@list_of_files) {
rename "$dirname/$_","$dirname/\L$_";
}
closedir(DIR);
}
}
@import_mapping_files = ("/var/download/mapping-custom", "/var/download/mapping-htmlerrorpage", "/var/download/mapping-xmlerrorpage", "/var/download/mapping-xmlschema", "/var/download/mapping-wsdl");
foreach (@import_mapping_files) {
if (open(FH, "<", $_)) {
if (open(FOH, ">>", $_.tmp)) {
foreach $line (<FH>) {
@csv = split(',', $line);
my $lowercasename = lc @csv[];
$line =~ s/@csv[]/$lowercasename/g;
print FOH $line;
}
close(FOH);
}
close(FH);
rename $_.tmp,$_;
}
}
log_trace "END $subroutine_name";
} # end sub convert_import_object_to_lower_case sub handle_learn_db_before_upgrade {
my $this_subroutine_name = ( caller() )[];
log_trace " \nBEGIN $this_subroutine_name";
opendir( DIR, "/var/nslog/asl/" ) || return;
my @list_of_files = grep(/\.db$/,readdir(DIR));
foreach (@list_of_files) {
rename ("/var/nslog/asl/".$_,"/var/nslog/asl/"."\L$_");
log_state("$_ renamed to \L$_");
}
closedir(DIR);
log_trace "END $subroutine_name";
} sub handle_file {
my $this_subroutine_name = ( caller() )[];
my $path = $_[];
my $argc = $_[];
my $line = $_[];
my @cmdbuf = split( /\s+/, $line );
my $file = $cmdbuf[$argc];
my @filenamebuf = split( /\//, $file );
my $filename = $filenamebuf[$#filenamebuf]; log_trace " \nBEGIN $this_subroutine_name"; $cmdbuf[$argc] = "$filename"; copy_file( $file, "$path/$filename" ); push @files, "$filename";
log_trace "END $this_subroutine_name";
} ## end sub handle_file sub install_usr_share()
{
if ( -f "./usr.share.tgz")
{
log_status "Installing usr share in flash partition...";
`tar xpfz usr.share.tgz -C $flashpath >> ./err_msg`;
}
} sub install_doc {
my $this_subroutine_name = ( caller() )[];
my $errs; log_trace " \nBEGIN $this_subroutine_name";
`rm -f ./err_msg`; if ( -f "./ns-$vers-doc.tgz" ) {
log_status "Installing documentation...";
`tar xfpz ns-$vers-doc.tgz -C $varpath/$docdir > ./err_msg`;
}
if ( -f "./err_msg" && $debug_print ) {
$errs = `cat ./err_msg`;
log_status $errs;
}
log_trace "END $this_subroutine_name";
} ## end sub install_doc sub install_help()
{
if ( -f "./help.tgz")
{
log_status "Installing online help...";
`tar xpfz help.tgz -C $varpath/$helpdir >> ./err_msg`;
}
} sub install_help_cisco()
{
if ( -f "./help_cisco.tgz")
{
log_status "Installing Cisco online help...";
`tar xpfz help_cisco.tgz -C $varpath/$help_ciscodir >> ./err_msg`;
}
} sub install_LogonPoint()
{
if ( -f "./LogonPoint.tgz")
{
log_status "Installing Logon Point ...";
if ( -d "$varpath/logon/LogonPoint/custom")
{
if (glob("$varpath/logon/LogonPoint/custom/*.json")){
`tar xpfz LogonPoint.tgz -C $varpath/ --exclude='custom/script.js' --exclude='custom/style.css' --exclude='custom/*.json' >> ./err_msg`;
}
else {
`tar xpfz LogonPoint.tgz -C $varpath/ --exclude='custom/script.js' --exclude='custom/style.css' >> ./err_msg`;
}
}
else {
`tar xpfz LogonPoint.tgz -C $varpath/ >> ./err_msg`;
}
system("perl $varpath/logon/themes/EULA/eula_upgrade.pl") == or log_status "Couldnt execute eula_upgrade.pl error: $?";
}
} sub install_LoginSchemaFiles()
{
if ( -f "./LoginSchema.tgz")
{
log_status "Installing Login Schema files ...";
`tar xpfz LoginSchema.tgz -C $newpath/loginschema/ >> ./err_msg`;
}
} sub install_app_catalog_files()
{
if ( -f "./app_catalog.tgz")
{
log_status "Installing SaaS Template app catalog files ...";
`tar xpfz app_catalog.tgz -C $varstr/ >> ./err_msg`;
}
} sub install_scom_mp()
{
if ( -f "./CitrixNetScalerManagementPackSCOM2012.msi")
{
log_status "Installing SCOM Management Pack...";
`cp -f CitrixNetScalerManagementPackSCOM2012.msi $varpath/$msndir >> ./err_msg`;
} if ( -f "./CitrixNetScalerLoadBalancer.msi")
{
log_status "Installing LoadBalancer Pack...";
`cp -f CitrixNetScalerLoadBalancer.msi $varpath/$msndir >> ./err_msg`;
}
} sub install_callhome_cert()
{
if ( -f "./BaltimoreCyberTrustRoot.cert")
{
log_status "Installing Jazz certificate ...";
`cp -f BaltimoreCyberTrustRoot.cert $newpathlicense/$ssldir >> ./err_msg`;
}
if ( -f "./BaltimoreCyberTrustRoot_CH.cert")
{
log_status "Installing Call Home certificate ...";
`cp -f BaltimoreCyberTrustRoot_CH.cert $newpathlicense/$ssldir >> ./err_msg`;
}
if ( -f "./cis.citrix.com.pem")
{
log_status "Installing CIS server certificate ...";
`cp -f cis.citrix.com.pem $newpathlicense/$ssldir >> ./err_msg`;
}
} sub install_linux_package()
{
log_status "Installing Debian, RPM packages ...";
if ( ! -d "$varpath/$guidir/vpn/scripts/linux" )
{
system("mkdir -p $varpath/$guidir/vpn/scripts/linux") == || ns_die("Error: Can't create $varpath/$guidir/vpn/scripts/linux");
}
system("cp -f nsg* $varpath/$guidir/vpn/scripts/linux/") == || ns_die("Error: Failed to copy Linux packages to the new path\n"); system("cp -f clientversions.xml $varpath/$guidir/vpn/scripts/linux/") == || ns_die("Error: Failed to copy clientversions.xml to the new path\n");
system("ln -s $varpath/$guidir/vpn/scripts/linux/* /netscaler/ns_gui/vpn/scripts/linux/ 2>> ./err_msg");
} sub install_geoipdb()
{
if ( -f "./Citrix_Netscaler_InBuilt_GeoIP_DB_IPv4.gz" && -f "./Citrix_Netscaler_InBuilt_GeoIP_DB_IPv6.gz")
{
log_status "Installing Geo-IP DB Citrix_Netscaler_InBuilt_GeoIP_DB_IPv4.gz and Citrix_Netscaler_InBuilt_GeoIP_DB_IPv6.gz …";
if ( ! -d "$varpath/inbuilt_db" )
{
`mkdir -p $varpath/inbuilt_db >> ./err_msg`;
}
`mv ./Citrix_Netscaler_InBuilt_GeoIP_DB_IPv4.gz $varpath/inbuilt_db >> ./err_msg`;
`mv ./Citrix_Netscaler_InBuilt_GeoIP_DB_IPv6.gz $varpath/inbuilt_db >> ./err_msg`;
`cd $varpath/inbuilt_db/ ; gunzip -f Citrix_Netscaler_InBuilt_GeoIP_DB_IPv4.gz >> ./err_msg`;
`cd $varpath/inbuilt_db/ ; gunzip -f Citrix_Netscaler_InBuilt_GeoIP_DB_IPv6.gz >> ./err_msg`;
}
elsif ( -f "./Citrix_Netscaler_InBuilt_GeoIP_DB.csv.gz")
{
log_status "Installing Geo-IP DB...";
if ( ! -d "$varpath/inbuilt_db" )
{
`mkdir -p $varpath/inbuilt_db >> ./err_msg`;
}
`mv ./Citrix_Netscaler_InBuilt_GeoIP_DB.csv.gz $varpath/inbuilt_db >> ./err_msg`;
`cd $varpath/inbuilt_db/ ; gunzip -f Citrix_Netscaler_InBuilt_GeoIP_DB.csv.gz >> ./err_msg`;
}
} sub install_nfast()
{
if ( -f "./thales_dirs.tar")
{
if ( -d "/var/opt/nfast")
{
log_status "/var/opt/nfast directory exists. Extracting hardserver files.";
`tar xpf thales_dirs.tar -C /var opt/nfast/sbin/hardserver >> ./err_msg`;
`tar xpf thales_dirs.tar -C /var opt/nfast/scripts/startup/hardserver >> ./err_msg`;
`tar xpf thales_dirs.tar -C /var opt/nfast/scripts/startup/hs_log_roll >> ./err_msg`;
}
else {
log_status "Installing thales files...";
`tar xpf thales_dirs.tar -C /var >> ./err_msg`;
}
}
} sub install_safenet()
{
if ( -f "./safenet_dirs.tar")
{
if( -d "/var/safenet/")
{
log_status "/var/safenet/ directory exists.";
#forcefully copy safenet_dirs.tar and install_client.sh
`cp -f safenet_dirs.tar /var/safenet >> ./err_msg`;
`tar xpf safenet_dirs.tar -C /var safenet/install_client.sh >> ./err_msg`;
}
else {
log_status "Installing safenet files...";
`tar xpf safenet_dirs.tar -C /var >> ./err_msg`;
}
}
} # Installs the empty database files that will be used for the NetStar inCompass SDK
# for URL categorization in the SWG URL filtering feature.
sub install_inCompass_db_files()
{
if ( -f "./inCompass-db-files.tgz")
{
if ( ! -d "$varstr/$inCompassDb" )
{
system("mkdir -p $varstr/$inCompassDb") == || ns_die("Error: Can't create $varstr/$inCompassDb");
}
log_status "Installing inCompass DB files...";
`tar xpfz inCompass-db-files.tgz -C $varstr/$inCompassDb >> ./err_msg`;
}
} #Removing vPath Libraries as vPath is not supported # Install Python Libraries
sub install_python {
if ( -f "./python.tgz") {
log_status "Extracting python...";
if ( -d "$varstr/python" ) {
system("rm -rf $varstr/python") == || ns_die("Error: Failed to remove contents of $varstr/python ($!)\n");
}
`tar xvpfz python.tgz -C $varstr >> ./err_msg`;
}
} sub install_python_nitro {
my $errs;
my $python_sdk;
log_trace " \nBEGIN $this_subroutine_name";
log_status "Extracting python nitro...";
if ( -f "$nitropath/nitro-python.tgz" ) {
`tar xvpfz $nitropath/nitro-python.tgz -C $nitropath >> ./err_msg`;
if ( -f "./err_msg" && $debug_print ) {
$errs = `cat ./err_msg`;
log_status $errs;
}
`tar -xpf $nitropath/ns_nitro-python_*.tar -C $nitropath`;
$python_sdk = glob "$nitropath/nitro-python-*";
if ( -e $python_sdk ) {
`cd $python_sdk; /var/python/bin/python ./setup.py install; cd ..`;
# Clean up Python PY files
`rm -rf $python_sdk`;
}
log_status "Extracting python nitro... done";
}
log_trace "END $this_subroutine_name";
} ## end sub nstall_nitro_python sub install_cloudautoscale {
my $errs;
log_trace " \nBEGIN $this_subroutine_name"; $rainmanpath="$varpath/rainman"; if ( -f "./cloudautoscale.tgz" ) {
log_status "Installing Rainman scripts...";
`tar xfpz ./cloudautoscale.tgz -C $varpath/ > ./err_msg`;
}
if ( -f "./err_msg" && $debug_print ) {
$errs = `cat ./err_msg`;
log_status $errs;
}
if ( -d "$rainmanpath" ) {
log_status "Extracting cloud autoscale...";
`cd $rainmanpath; /var/python/bin/python $rainmanpath/setup.py clean >> ./err_msg`;
`cd $rainmanpath; /var/python/bin/python $rainmanpath/setup.py bdist_egg --exclude-source-files >> ./err_msg`;
`cd $rainmanpath; /var/python/bin/python $rainmanpath/setup.py easy_install $rainmanpath/dist/Rainman-*-py2..egg >> ./err_msg`;
if ( -f "./err_msg" && $debug_print ) {
$errs = `cat ./err_msg`;
log_status $errs;
}
`cd; rm -rf $rainmanpath`
}
log_status "Done Extracting cloud autoscale...";
log_trace "END $this_subroutine_name";
} ## end sub install_cloudautoscale sub install_azureautoconfig
{
my $this_subroutine_name = ( caller() )[];
my $errs;
log_trace " \nBEGIN $this_subroutine_name";
my $configpath = "$varpath/azureautoconfig";
if ( -f "./azureautoconfig.tgz" )
{
log_status "Azure Auto Config Script untarring";
`tar xfpz ./azureautoconfig.tgz -C $varpath/ > ./err_msg`;
if ( -f "./err_msg" ) {
$errs = `cat ./err_msg`;
log_status $errs;
`rm -rf ./err_msg`;
}
}
else
{
log_status "AzureAutoConfig script tar not found";
}
if ( -d "$configpath" )
{
log_status "Installing AzureAutoConfig script";
`cd $configpath; /var/python/bin/python $configpath/setup.py clean >> ./err_msg`;
`cd $configpath; /var/python/bin/python $configpath/setup.py bdist_egg --exclude-source-files >> ./err_msg`;
`cd $configpath; /var/python/bin/python $configpath/setup.py easy_install $configpath/dist/AzureAutoConfig-*-py2..egg >> ./err_msg`;
if ( -f "./err_msg" ) {
$errs = `cat ./err_msg`;
log_status $errs;
`rm -rf ./err_msg`;
} `rm -rf $configpath`;
}
else
{
log_status "Not found azureautoconfig folder";
}
log_trace "END $this_subroutine_name";
} sub install_azureagent
{
my $this_subroutine_name = ( caller() )[];
my $errs;
log_trace " \nBEGIN $this_subroutine_name";
my $waagentconfigpath = "$varpath/azureagent";
if ( -f "./azureagent.tgz" )
{
log_status "Azure Agent script untarring";
`tar xfpz ./azureagent.tgz -C $varpath/ > ./err_msg`;
if ( -f "./err_msg" ) {
$errs = `cat ./err_msg`;
log_status $errs;
`rm -rf ./err_msg`;
}
}
else
{
log_status "Azure Agent tar not found";
}
if ( -d "$waagentconfigpath" )
{
log_status "Installing Azure Agent script";
`cd $waagentconfigpath; /var/python/bin/python $waagentconfigpath/setup.py clean >> ./err_msg`;
`cd $waagentconfigpath; /var/python/bin/python $waagentconfigpath/setup.py bdist_egg --exclude-source-files >> ./err_msg`;
`cd $waagentconfigpath; /var/python/bin/python $waagentconfigpath/setup.py easy_install $waagentconfigpath/dist/waagent-*-py2..egg >> ./err_msg`;
if ( -f "./err_msg" ) {
$errs = `cat ./err_msg`;
log_status $errs;
`rm -rf ./err_msg`;
}
`mv $waagentconfigpath/waagent.conf /nsconfig/`;
`rm -rf $waagentconfigpath`;
}
else
{
log_status "Not found Agent folder";
}
log_trace "END $this_subroutine_name";
} sub install_epa_package()
{
if ( -f "./epaPackage.exe")
{
log_status "Installing EPA Package ...";
if ( ! -d "$varpath/$guidir/epa/scripts/win" )
{
system("mkdir -p $varpath/$guidir/epa/scripts/win") == || ns_die("Error: Can't create $varpath/$guidir/epa/scripts/win");
}
system("cp epaPackage.exe $varpath/$guidir/epa/scripts/win/") == ||
ns_die("Error: Failed to copy epaPackage to the new path\n");
system("cp version.xml $varpath/$guidir/epa/") == || ns_die("Error: Can't cp Version file\n");
}
if ( -f "./Citrix_Endpoint_Analysis.dmg")
{
print "Installing Mac EPA and Mac EPA version file...\n";
if ( ! -d "$varpath/$guidir/epa/scripts/mac" )
{
system("mkdir -p $varpath/$guidir/epa/scripts/mac") == || ns_die("Error: Can't create $varpath/$guidir/epa/scripts/mac");
}
system("cp ./Citrix_Endpoint_Analysis.dmg $varpath/$guidir/epa/scripts/mac/") == || ns_die("Error: Can't copy Mac EPA binary\n");
system("cp ./epamacversion.txt $varpath/$guidir/epa/scripts/mac/") == || ns_die("Error: Can't cp Mac EPA version file\n");
}
if ( -f "./MacLibs.zip")
{
print "Installing Mac EPA libraries...\n";
if ( ! -d "$varpath/$guidir/epa/scripts/mac" )
{
system("mkdir -p $varpath/$guidir/epa/scripts/mac") == || ns_die("Error: Can't create $varpath/$guidir/epa/scripts/mac");
}
system("cp ./MacLibs.zip $varpath/$guidir/epa/scripts/mac/") == || ns_die("Error: Can't copy Mac EPA libraries\n");
}
if( -f "./nsepa.deb")
{
log_status "Installing Linux EPA and Linux EPA version file...\n";
if ( ! -d "$varpath/$guidir/epa/scripts/linux" )
{
system("mkdir -p $varpath/$guidir/epa/scripts/linux") == || ns_die("Error: Can't create $varpath/$guidir/epa/scripts/linux");
}
system("cp nsepa* $varpath/$guidir/epa/scripts/linux/") == || ns_die("Error: Can't copy Linux EPA binary\n");
}
}
# If a separate GUI tarball exists, install it on the disk.
# Netscaler releases have the capability to generate the GUI targets in the memory file system
# or on the /var partition. If the GUI tarball does not exist, the GUI is resident in the memory image and
# no installation is required.
sub install_gui {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name";
if ( -f "./ns-$vers-gui.tar" ) {
if ( -d "$varpath/$guidir" ) {
system("rm -rf $varpath/$guidir/*") ==
|| ns_die(
"Error: Failed to remove contents of $varpath/$guidir ($!)\n");
}
log_status "Installing GUI...";
system ("tar xfp ns-$vers-gui.tar -C $varpath/$guidir") ==
|| ns_die("Error: Can't un-tar GUI\n");
} # if AppTemplates.xml is found due to older builds, we need to remove that file
if ( -f "$templatesoldpath/applications/AppTemplates.xml" ) {
system("rm -f $templatesoldpath/applications/AppTemplates.xml");
} if ( !(-l $templateslinkpath) )
{
if ( -d "$templatesoldpath" ) {
system("cp -rf $templatesoldpath/* $templatespath") == ||
ns_die("Error: Failed to copy templates to the new path\n");
}
#Before creating link, make sure there is no directory/file in the same name
`rm -rf $templateslinkpath`;
system("ln -s $templatespath $templateslinkpath") == ||
ns_die("Error: Failed to create templates link\n");
} if ( -d "$applicationtemplatespath" ) {
system("chmod 777 $applicationtemplatespath") ==
|| ns_die(
"Error: Failed to change permission of $applicationtemplatespath ($!)\n"
);
if ( -d "$apptemplatesdeploymentfilespath" ) {
system("chmod 777 $apptemplatesdeploymentfilespath") ==
|| ns_die(
"Error: Failed to change permission of $apptemplatesdeploymentfilespath ($!)\n"
);
}
} if ( -d "$lbvservertemplatespath" ) {
system("chmod 777 '$lbvservertemplatespath'") ==
|| ns_die(
"Error: Failed to change permission of $lbvservertemplatespath ($!)\n"
);
if ( -d "$lbvserverdeploymentfilepath" ) {
system("chmod 777 '$lbvserverdeploymentfilepath'") ==
|| ns_die(
"Error: Failed to change permission of $lbvserverdeploymentfilepath ($!)\n"
);
}
} if ( -d "$reportspath" ) {
system("chmod 777 $reportspath") ==
|| ns_die(
"Error: Failed to change permission of $reportspath ($!)\n"
);
if ( -f "$reportspath/reports.xml" ) {
system("chmod 777 $reportspath/reports.xml") ==
|| ns_die(
"Error: Failed to change permission of $reportspath/reports.xml ($!)\n"
);
}
} if ( -f "./Citrix_Access_Gateway.dmg")
{
print "Installing Mac binary and Mac version file...\n";
if ( ! -d "$varpath/$guidir/vpns/scripts/mac" )
{
system("mkdir -p $varpath/$guidir/vpns/scripts/mac") == || ns_die("Error: Can't create $varpath/$guidir/vpns/scripts/mac");
}
system("mv ./Citrix_Access_Gateway.dmg $varpath/$guidir/vpns/scripts/mac/Citrix_Access_Gateway.dmg") == || ns_die("Error: Can't mv Mac binary\n");
system("mv ./macversion.txt $varpath/$guidir/vpns/scripts/mac/macversion.txt") == || ns_die("Error: Can't mv Mac version file\n");
}
log_trace "END $this_subroutine_name";
} ## end sub install_gui sub install_mastools{
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name";
if ( -f "./mastools_scripts.tgz") {
log_status "Installing MASTools scripts...";
if ( ! -e "$mastoolspath/conf/agent.conf" ) {
log_status "Extracting MASTools...";
if ( -d "$mastoolspath" ) {
log_status "rm -rf $mastoolspath/*";
system("rm -rf $mastoolspath/*") == || ns_die("Error: Can't remove existing $mastoolspath/*");
}
else {
log_status "mkdir -p $mastoolspath";
system("mkdir -p $mastoolspath") == || ns_die("Error: Can't create $mastoolspath");
}
log_status "tar xpfz ./mastools_scripts.tgz -C $mastoolspath";
system("tar xpfz ./mastools_scripts.tgz -C $mastoolspath") == || die "unable to unpack ./mastools-$vers.tgz at $mastoolspath\n";
system("mkdir -p $mastoolspath/logs");
system("mkdir -p $mastoolspath/conf");
system("echo '0.0-0.0' > $mastoolspath/version.txt");
if ( -e "$mastoolspath/scripts/mastools_init.sh" ) {
system("chmod +x $mastoolspath/scripts/mastools_init.sh");
}
}
}
} # Install Nitro
sub install_nitro {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name";
if ( -f "./ns-$vers-nitro-java.tgz" || -f "./ns-$vers-nitro-csharp.tgz" || -f "./ns-$vers-nitro-rest.tgz"
|| -f "./ns-$vers-nitro-python.tgz" || -f "./ns-$vers-nitro-perl-samples.tgz" || -f "./ns-$vers-nitro-powershell.tgz") {
if ( -d "$nitropath" ) {
system("rm -rf $nitropath/*") ==
|| ns_die("Error: Failed to remove contents of $nitropath ($!)\n");
}
log_status "Installing NITRO...";
system ("cp -f ns-$vers-nitro-java.tgz $nitropath/ns-$vers-nitro-java.tgz") ==
|| ns_die("Error: Can't copy NITRO java\n");
system ("cp -f ns-$vers-nitro-csharp.tgz $nitropath/ns-$vers-nitro-csharp.tgz") ==
|| ns_die("Error: Can't copy NITRO csharp\n");
system ("cp -f ns-$vers-nitro-rest.tgz $nitropath/ns-$vers-nitro-rest.tgz") ==
|| ns_die("Error: Can't copy NITRO rest\n");
system ("cp -f ns-$vers-nitro-python.tgz $nitropath/ns-$vers-nitro-python.tgz") ==
|| ns_die("Error: Can't copy NITRO python\n");
system ("cp -f ns-$vers-nitro-perl-samples.tgz $nitropath/ns-$vers-nitro-perl-samples.tgz") ==
|| ns_die("Error: Can't copy NITRO perl samples\n");
system ("cp -f ns-$vers-nitro-powershell.tgz $nitropath/ns-$vers-nitro-powershell.tgz") ==
|| ns_die("Error: Can't copy NITRO powershell\n");
#Before creating link, make sure there is no directory/file in the same name
`rm -rf $nitropath/nitro-java.tgz`;
`rm -rf $nitropath/nitro-csharp.tgz`;
`rm -rf $nitropath/nitro-rest.tgz`;
`rm -rf $nitropath/nitro-python.tgz`;
`rm -rf $nitropath/nitro-perl-samples.tgz`;
`rm -rf $nitropath/nitro-powershell.tgz`;
system("ln -s $nitropath/ns-$vers-nitro-java.tgz $nitropath/nitro-java.tgz") ==
|| ns_die("Error: Failed to create nitro java link\n");
system("ln -s $nitropath/ns-$vers-nitro-csharp.tgz $nitropath/nitro-csharp.tgz") ==
|| ns_die("Error: Failed to create nitro csharp link\n");
system("ln -s $nitropath/ns-$vers-nitro-rest.tgz $nitropath/nitro-rest.tgz") ==
|| ns_die("Error: Failed to create nitro rest link\n");
system("ln -s $nitropath/ns-$vers-nitro-python.tgz $nitropath/nitro-python.tgz") ==
|| ns_die("Error: Failed to create nitro python link\n");
system("ln -s $nitropath/ns-$vers-nitro-perl-samples.tgz $nitropath/nitro-perl-samples.tgz") ==
|| ns_die("Error: Failed to create nitro perl samples link\n");
system("ln -s $nitropath/ns-$vers-nitro-powershell.tgz $nitropath/nitro-powershell.tgz") ==
|| ns_die("Error: Failed to create nitro powershell link\n");
}
} # Upgrade script to run BEFORE booting with new build
# Add commands in /flash/nsconfig/ns_before_upgrade.sh, which will be run BEFORE boot.
sub upgrade_before_pe_start {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; # Upgrade all files, including imported objects
log_status "Creating before PE start upgrade script ..."; if (open(BEFORE_UPGRADE, "> /flash/nsconfig/upgrade_before_pe_start.sh ")) {
print BEFORE_UPGRADE "#!/usr/bin/bash\n";
print BEFORE_UPGRADE "/usr/bin/logger -p local0.err \"Starting upgrade of AppFw signature files\"\n";
print BEFORE_UPGRADE "/usr/local/bin/perl /netscaler/upgrade_appfw_imports.pl -before_ppe_start\n";
print BEFORE_UPGRADE "/usr/bin/logger -p local0.err \"Finished upgrade of AppFw signature files\"\n"; close(BEFORE_UPGRADE);
} else {
log_status "Failed to create script to be run before PE start. Please reopen and save back all AppFw signatures after reboot.\n";
}
log_trace "END $this_subroutine_name";
} ## end sub upgrade_before_pe_start # Upgrade script to run after booting with new build
# Add commands in /flash/nsconfig/nsafterupgrade.sh, which will be run after boot.
sub after_upgrade {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; # Upgrade all files, including imported objects
log_status "Creating after upgrade script ..."; if (open(AFTER_UPGR, "> /flash/nsconfig/nsafterupgrade.sh ")) {
close(AFTER_UPGR);
} else {
log_status "Failed to create script to be run after upgrade. Please reopen and save back all AppFw signatures after reboot.\n";
}
log_trace "END $this_subroutine_name";
} ## end sub after_upgrade sub install_lom {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; if ( -f "./bmc_releases" ) {
log_status "Storing LOM firmware...";
`mv bmc_releases /var/tmp/`;
}
if ( -f "./11k5_bmc.bin" ) {
`mv *_bmc.bin /var/tmp/`;
}
} ## end sub install_lom sub install_nic_firmware { my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; if ( -d "Intel" ) {
log_status "Storing NIC firmware...";
`mv Intel /var/tmp/`;
}
if ( -f "Silicom" ) {
`mv Silicom /var/tmp/`;
}
if ( -d "Mellanox" ) {
log_status "Storing NIC firmware...";
if ( -d "/var/tmp/Mellanox" ) {
`rm -rf /var/tmp/Mellanox`;
}
`mv Mellanox /var/tmp/`;
}
} ## end sub install_nic_firmware # Install Open VM Tools
sub install_vmtools {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name";
if ( -f "./open-vm-tools.tgz" ) {
# start fresh with /var/vmtools
system("rm -rf /var/vmtools") ==
|| ns_die("Error: Failed to remove /var/vmtools ($!)\n");
system("mkdir -p /var/vmtools") ==
|| ns_die("Error: Can't create /var/vmtools ($!)\n");
system ("tar xzfp open-vm-tools.tgz -C /var/vmtools") ==
|| ns_die("Error: Can't un-tar open-vm-tools ($!)\n");
}
} ## end sub install_vmtools sub copy_file {
my $this_subroutine_name = ( caller() )[];
my $file1 = $_[];
my $file2 = $_[]; log_trace " \nBEGIN $this_subroutine_name"; open( IN, "< $file1" )
or ns_die("Failed to open $file1 for reading ($!), aborting...\n");
open( OUT, "> $file2" )
or ns_die("Failed to open $file2 for writing ($!), aborting...\n"); $blksize = ( stat IN )[] || ; # preferred block size?
log_status "\nCopying $file1 to $file2: ";
while ( $len = sysread IN, $buf, $blksize ) {
if ( !defined $len ) {
next if $! =~ /^Interrupted/; # ^Z and fg
ns_die("Read error: $!\n");
}
$offset = ;
while ($len) {
defined( $written = syswrite OUT, $buf, $len, $offset )
or ns_die("Write error: $!\n");
$len -= $written;
$offset += $written;
}
} ## end while ( $len = sysread IN... close(IN);
close(OUT);
log_trace "END $this_subroutine_name";
} ## end sub copy_file sub fipscheck_loaderconf {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; open( LDCONF, "$loaderconf" );
@ldconf = <LDCONF>;
close(LDCONF);
foreach $ldline (@ldconf) {
if ( $ldline =~ /kern.vm.caviumfips.size/i ) {
$fips = ;
}
}
log_trace "END $this_subroutine_name";
} ## end sub fipscheck_loaderconf sub mod_loaderconf {
my $this_subroutine_name = ( caller() )[];
my $sysid = `sysctl -n netscaler.sysid`;
my $is_simple_gateway = `sysctl -n netscaler.is_simple_gateway`; log_trace " \nBEGIN $this_subroutine_name"; if ( !$fips ) {
fipscheck_loaderconf();
}
log_status_no_console "Changing $loaderconf for $kernelname ...\n";
open( LDCONF, ">$loaderconf" )
|| ns_die("Failed to open $loaderconf ($!), aborting...\n");
print LDCONF "autoboot_delay=3\n";
print LDCONF "boot_verbose=0\n";
print LDCONF "kernel=\"/$kernelname\"\n";
print LDCONF "vfs.root.mountfrom=\"ufs:/dev/md0c\"\n";
if ($sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == ) {
# For NS VPX on Xen we need console on both serial and vga
print LDCONF "console=\"vidconsole,comconsole\"\n";
}
if ($fips) {
print LDCONF "kern.vm.caviumfips.size=134217728\n";
}
# Ensure loader.conf has the right value when upgrading simple gateway appliance
if ($is_simple_gateway == ) {
print LDCONF "netscaler.is_simple_gateway=1\n"
} close(LDCONF);
log_trace "END $this_subroutine_name";
} ## end sub mod_loaderconf sub prompt_epaProfileWarning()
{
local $v = $vers;
unless($v =~ m/^(\.)\S+(\.e)$/) {
local $epa_count = `grep -i -c 'add vpn epaprofile' /nsconfig/ns.conf`;
if($epa_count > )
{
print "\n***************************************** WARNING *****************************************\n\n";
print "Advanced EPA profiles have been found in the running NetScaler 10.1.e configuration.\n";
print "The Advanced EPA feature has changed in later versions of NetScaler requiring reconfiguration of the policy expressions for this feature after an upgrade.\n";
print "A copy of the running 10.1.e configuration has been saved to /var/ns.conf.deprecated-AEPA.\n\n";
print "*******************************************************************************************\n";
log_trace " \nAdvanced EPA was found to be configured";
}
system("cp /nsconfig/ns.conf /var/ns.conf.deprecated-AEPA");
}
} #find old 512/1024bit ns-server certificate/key
sub find_old_server_cert {
# All new images generate 2K server certificate,
# however if NS is having any older service certificate, it'll not generate.
# For this we are removing older 512bit or 1024bit server certificate during upgrade
# and reboot will take care of generating new certificate. my $ns_server_cert = "/nsconfig/ssl/ns-server.cert"; my $key_sz = `openssl x509 -in $ns_server_cert -noout -text`;
die "openssl couldn't be run, please reach Citrix Support.\n" unless defined $key_sz;
# OpenSSL did run - check its exit code
die "openssl failed with exit code $?. please reach Citrix Support.\n" if $?; $key_sz=~/Public-Key:\s*\((\d+)/;
die "openssl output can't be parsed, please reach Citrix Support.\n" unless defined $; if ($ <= ) {
if ($key_sz =~ /NetScaler Generated Certificate/) {
$old_ns_cert = ;
}
}
} sub prompt_reboot {
my $this_subroutine_name = ( caller() )[]; if ( $options{n} ) {
exit();
}
elsif ( $flag_Y || $options{y} ) {
if ($old_ns_cert == ) {
`touch /nsconfig/ssl/.gen_new_cert`;
}
log_status "Rebooting ...\n";
`/sbin/reboot`;
}
else {
if ( $gui_flag ) {
print "\nInstallation has completed.\n\nReboot is required for configuration changes to take effect.";
exit ;
}
print "\nInstallation has completed.\n\nReboot NOW? [Y/N] ";
open( TTY, "+</dev/tty" ) or die "no tty: $!";
sysread( TTY, $ans, );
read_until_newline(TTY);
close(TTY); if ( $ans =~ /y/i ) {
if ($old_ns_cert == ) {
`touch /nsconfig/ssl/.gen_new_cert`;
}
log_status "Rebooting ...\n";
`/sbin/reboot`;
} elsif ($old_ns_cert == ) {
`touch /nsconfig/ssl/.gen_new_cert`;
}
} ## end else [ if ( $options{y} )
log_trace "END $this_subroutine_name";
} ## end sub prompt_reboot sub move_file {
my $this_subroutine_name = ( caller() )[];
my $file = $_[]; log_trace " \nBEGIN $this_subroutine_name"; $newfile = $file . ".old";
log_status "Moving file $file to $newfile...\n";
move( $file, $newfile )
|| ns_die("Error: Failed to move $file to $newfile ($!)\n");
log_trace "END $this_subroutine_name";
} ## end sub move_file sub setup_paths {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; log_status_no_console "Checking directories ...";
foreach $elem (@dirs) {
move_file($elem) if -f $elem;
if ( stat($elem) == NULL ) {
log_status_no_console "$elem does not exist, creating\n";
if ( mkdir( $elem, ) != ) {
ns_die("Failed to create $elem ($!), aborting\n");
}
}
}
log_trace "END $this_subroutine_name";
} ## end sub setup_paths sub statfs {
my $this_subroutine_name = ( caller() )[];
my $path = $_[];
my @statbuf = split( /\n/, `df -k $path` );
my @kernstats = stat("./$kernel");
my @stats = split( /\s+/, $statbuf[] );
my $kernsize = int( $kernstats[] / ); log_trace " \nBEGIN $this_subroutine_name"; log_status_no_console "Size of kernel $kernel is $kernsize kilobytes";
log_status_no_console
"Available space on $path filesystem is $stats[3] kilobytes"; if ( $stats[] < $kernsize ) {
log_status
"Available space on $path filesystem is insufficient to install $kernel\n"; if ( $gui_flag ) {
log_status "Error: No space left on $path filesystem, aborting installation...\n";
unlink("/$kernel");
exit ;
}
ns_die(
"Error: No space left on $path filesystem, aborting installation...\n"
);
} ## end if ( $stats[3] < $kernsize) my $varoutstr = `df -k $varstr | grep $varstr`;
my @varoutlst = split( " ", $varoutstr );
my $varfree = $varoutlst[];
log_status_no_console "Available space on $varstr is $varfree kilobytes"; if ( $varfree < $min_var_freespace ) {
log_status
" $varfree 1k blocks free space on $varstr is insufficient to operate the Netscaler\n";
if ( $gui_flag ) {
log_status "Error: Please free space on $varstr and then re-install. You may want to examine /var/log or in /var/netscaler/nsbackup.\n";
unlink("/$kernel");
exit ;
}
ns_die(
"Error: Please free space on $varstr and then re-install. You may want to examine /var/log or in /var/netscaler/nsbackup.\n"
);
}
log_trace "END $this_subroutine_name";
} ## end sub statfs sub ns_die {
log_status "@_\n";
unlink("/$kernel");
exit(-);
} sub print_banner {
print "\n";
log_status "installns version ($vers) kernel ($kernel)\n"; print " The Netscaler version $vers checksum file is located on \n";
" http://www.mycitrix.com under Support > Downloads > Citrix NetScaler.\n";
" Select the Release $vers link and expand the \"Show Documentation\" link\n";
print " to view the SHA2 checksum file for build $vers.\n"; check_enhanced_upgrade(); check_sysid(); check_vpx(); repart_swap_var(); my $sysid = `sysctl -n netscaler.sysid`;
if (($sysid != ) || ($sysid != )) {
install_Bootloader();
"\n There may be a pause of up to 3 minutes while data is written to the flash.\n";
print " Do not interrupt the installation process once it has begun.\n\n";
if (!($gui_flag)) {
print "Installation will proceed in 5 seconds, CTRL-C to abort\n";
sleep();
}
log_status "Installation is starting ...";
} ## end sub print_banner sub print_help {
print "
Usage:
-F FIPS install
-h Help
-Y Answer Yes to everything
-y Force Reboot
-n Don't Reboot
-c Force Clean up
-N Don't check ns.conf
-G No curses
-L Enable CallHome
-e Upgrading from\\to \"enhancement\" build
-R Resize swap and \/var. all data on \/var will be erased
";
exit();
} ## end sub print_help sub read_until_newline($) {
my $in = shift;
my $char;
my $Done = ; do {
sysread( $in, $char, );
$Done = ( $char == '\n' );
} until ( $Done != );
} ## end sub read_until_linefeed($) sub read_until_eof($) {
my $in = shift; sysseek( $in, , SEEK_END );
} ## end sub read_until_eof($) sub Bootloader_Announcement() {
local $ans; log_status "\n A new FreeBSD bootloader installation is required.\n";
printf(" Many files in /flash/boot will be overwritten.\n");
printf(" /flash/boot/defaults/loader.conf will be moved\n");
printf(" to /flash/boot/defaults/loader.conf.old\n"); if ($flag_Y) {
return ;
} printf("\n One can either complete the new bootloader installation\n");
printf(" or cancel installing the new NetScaler update\n");
printf("\n Do you wish to continue bootloader installation? [Y/N] "); open( TTY, "+</dev/tty" ) or die "no tty: $!";
sysread( TTY, $ans, );
read_until_newline(TTY);
close(TTY); if ( $ans eq 'y' || $ans eq 'Y' ) {
return ;
} exit ;
} ## end sub Bootloader_Announcement() sub unpack_MANIFEST_SUMS() {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; system("tar xzf ${full_pkgtgz} ./MANIFEST ./MD5SUMS > /dev/null 2>&1") ==
|| die "unable to unpack MANIFEST and MD5SUMS"; open( S, "<MD5SUMS" ) || die "unable to open MD5SUMS";
$iPkgSums = ;
while (<S>) {
$PkgSums[$iPkgSums] = $_;
$iPkgSums++;
}
close S;
log_trace "END $this_subroutine_name"; } ## end sub unpack_MANIFEST_SUMS() sub generate_NewSums() {
my $this_subroutine_name = ( caller() )[]; log_trace " \nBEGIN $this_subroutine_name"; open( M, '<MANIFEST' ) || die "unable to open MANIFEST";
$iNewSums = ;
while (<M>) {
$file = $_;
$NewSums[$iNewSums] = `cd /flash/boot ; (sha256 $file) > /dev/null`; # print "PkgSums[$iNewSums]=$PkgSums[$iNewSums] NewSums[$iNewSums]=$NewSums[$iNewSums]\n"; if ( $PkgSums[$iNewSums] ne $NewSums[$iNewSums] ) {
$bootloader_OverWrite = ;
}
$iNewSums++;
} ## end while (<M>)
close M;
log_trace "END $this_subroutine_name"; } ## end sub generate_NewSums() sub install_Bootloader {
my $this_subroutine_name = ( caller() )[];
my $is_nCore = `sysctl -n netscaler.nCore`; # if it is nCore, we do not need to install a new bootloader.
if ( $is_nCore == ) {
return ;
} log_trace " \nBEGIN $this_subroutine_name"; $bootloader_tgz = "bootloader.tgz";
$bootdir = "/flash/boot";
$bootloader_pkgdir = `pwd`;
chomp($bootloader_pkgdir);
$full_pkgtgz = "$bootloader_pkgdir" . "/" . "$bootloader_tgz"; $iPkgSums = ;
@PkgSums; $iNewSums = ;
@NewSums; $bootloader_OverWrite = ; if ( $variant ne "v" ) {
return ;
} if ( -f ${bootloader_tgz} ) {
unpack_MANIFEST_SUMS();
generate_NewSums(); if ( $bootloader_OverWrite > ) {
Bootloader_Announcement(); if ( -f "/flash/boot/defaults/loader.conf" ) {
system(
"mv /flash/boot/defaults/loader.conf /flash/boot/defaults/loader.conf.old"
) ==
|| die
"Error moving /flash/boot/defaults/loader.conf to /flash/boot/defaults/loader.conf.old";
} log_status_no_console "Unpacking new bootloader in ${bootdir}\n";
system(
"cd ${bootdir} ; tar xzf ${full_pkgtgz} --exclude MANIFEST --exclude MD5SUMS "
) ==
|| die "Error unpacking Bootloader";
} ## end if ( $bootloader_OverWrite...
} ## end if ( -f ${bootloader_tgz...
log_trace "END $this_subroutine_name"; } ## end sub install_Bootloader sub check_swap_var_size() { my $ans; my $var_df;
my $var_dev;
my $var_slice;
my $var_part;
my $var_letter; my $disk_size, $disk_offset;
my $recover_size, $recover_offset;
my $swapb_dev, $swapb_size, $swapb_offset;
my $swapg_dev, $swapg_size=, $swapg_offset=;
my $var_size, $var_offset; my $target_var_size, $target_var_offset;
my $target_swapb_size, $target_swapb_offset;
my $target_swapg_size, $target_swapg_offset; my $target_swapb_blocks = * * * / ; # 8 GB
my $target_swapg_blocks = * * * / ; # 32 GB
my $this_subroutine_name = ( caller() )[]; my $NeedNewDiskLabel=; log_trace " \nBEGIN $this_subroutine_name"; # Get the /var device
$var_df = `df | grep var`;
chomp($var_df);
if ($debug_print) {
log_status "var_df=${var_df}\n";
} $var_df =~ m/^(\/dev\/[ad][ad][-])/;
$var_dev = $; $var_df =~ m/^(\/dev\/...s1)/;
$var_slice = $; $var_df =~ m/^(\/dev\/...s1.)/;
$var_part = $; $var_df =~ m/^\/dev\/...s1(.)/;
$var_letter = $; if ($debug_print) {
log_status "var_df=$var_df\n";
log_status "var_dev=$var_dev\n";
log_status "var_slice=$var_slice\n";
log_status "var_part=$var_part\n";
} # swap is always slice b (8GB/Classic) & g (32GB/nCore):
my $disklabel = `disklabel ${var_slice}`;
if ($debug_print) { log_status "disklabel=\n${disklabel}\n"; }
$swapb_dev = "${var_dev}" . "s1b";
$swapg_dev = "${var_dev}" . "s1g"; if ($disklabel =~ /\s+a:/) {
$disklabel =~ m/\s+a:\s+(\d+)\s+(\d+)\s+/;
$recover_size = $;
$recover_offset = $;
} if ($disklabel =~ /\s+b:/) {
$disklabel =~ m/\s+b:\s+(\d+)\s+(\d+)\s+/;
$swapb_size = $;
$swapb_offset = $;
} if ($disklabel =~ /\s+c:/) {
$disklabel =~ m/\s+c:\s+(\d+)\s+(\d+)\s+/;
$disk_size = $;
$disk_offset = $;
} if ($disklabel =~ /\s+${var_letter}:/) {
$disklabel =~ m/\s+${var_letter}: (\d+)\s+(\d+)\s+/;
$var_size = $;
$var_offset = $; } if ($disklabel =~ /\s+g:/) {
$disklabel =~ m/\s+g:\s+(\d+)\s+(\d+)\s+/;
$swapg_size = $;
$swapg_offset = $;
} if ($debug_print) {
log_status "disklabel=${disklabel}\n"; log_status "disk_size=${disk_size}\n";
log_status "disk_offset=${disk_offset}\n"; log_status "recover_size=${recover_size}\n";
log_status "recover_offset=${recover_offset}\n"; log_status "swapb_dev=${swapb_dev}\n";
log_status "swapb_size=${swapb_size}\n";
log_status "swapb_offset=${swapb_offset}\n"; log_status "var_dev=${var_dev}\n";
log_status "var_size=${var_size}\n";
log_status "var_offset=${var_offset}\n"; log_status "swapg_dev=${swapg_dev}\n";
log_status "swapg_size=${swapg_size}\n";
log_status "swapg_offset=${swapg_offset}\n";
} ## end if ($debug_print) if ( $swapg_size < $target_swapg_blocks ) {
$NeedNewDiskLabel = ;
} $target_swapb_size = $target_swapb_blocks;
$target_swapg_size = $target_swapg_blocks; $target_swapb_offset = $swapb_offset; $target_var_size = $disk_size - $recover_size - $target_swapb_size - $target_swapg_size;
$target_var_offset = $target_swapb_offset + $target_swapb_size; $target_swapg_offset = $target_var_offset + $target_var_size; if ( $NeedNewDiskLabel == ) {
my $target_disklabel = $disklabel; $target_disklabel =~ s/${swapb_size}/${target_swapb_size}/;
$target_disklabel =~ s/${swapb_offset}/${target_swapb_offset}/;
$target_disklabel =~ s/${var_size}/${target_var_size}/;
$target_disklabel =~ s/${var_offset}/${target_var_offset}/; if ( $swapg_size != ) {
$target_disklabel =~ s/${swapg_size}/${target_swapg_size}/;
$target_disklabel =~ s/${swapg_offset}/${target_swapg_offset}/;
} else {
$target_disklabel = $target_disklabel . "\n g: $target_swapg_size $target_swapg_offset swap\n";
} print "
A re-sizing of swap and /var is required.
All data on /var will be erased.
"; if ($flag_Y == ) {
print "option Y given, answer is YES";
$ans = 'y';
} elsif ($resize_flag){
$ans = 'y';
} else {
if ( !$gui_flag ) {
print "Please reply 'N' if you need to save data from /var. Do you wish to continue? [Y/N] "; open( TTY, "+</dev/tty" ) or die "no tty: $!";
sysread( TTY, $ans, );
read_until_newline(TTY);
close(TTY);
} else {
exit ;
}
} if ( $ans eq 'y' || $ans eq 'Y' ) { if ( $debug_print == ) {
open( ORIG_DISKLABEL, ">$orig_disklabel_fn" )
|| die "Error opening $orig_disklabel_fn";
print ORIG_DISKLABEL $disklabel;
close ORIG_DISKLABEL;
} open( NEW_DISKLABEL, ">$new_disklabel_fn" )
|| die "Error opening $new_disklabel_fn";
print NEW_DISKLABEL $target_disklabel;
close NEW_DISKLABEL; if ($debug_print) { log_status "$target_disklabel\n"; }
} ## end if ( $ans eq 'y' || $ans...
else {
log_status "Aborting installation....";
exit ;
}
} ## end if ( $swap_size < $target_swap_blocks)
log_trace "END $this_subroutine_name"; } ## end sub check_swap_var_size() sub repart_swap_var() {
my $this_subroutine_name = ( caller() )[];
my $sysid = `sysctl -n netscaler.sysid`; log_trace " \nBEGIN $this_subroutine_name"; # change swap size on ONLY 64bit nCore/MCNS/VMPE systems
if ( $variant ne "v" ) { return ; } # Change swap size ONLY on NON-VPX systems
if ($sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == || $sysid == ||
$sysid == || $sysid == )
{ return ; } local $new_disklabel_fn = "/flash/nsconfig/.new_disklabel";
local $orig_disklabel_fn = "/flash/nsconfig/.orig_disklabel"; check_swap_var_size(); log_trace "END $this_subroutine_name"; } ## end sub repart_swap_var() # Handle Interrupts
sub interrupt_int {
my ($signal) = @_;
my $no_answer = ;
print "Caught user interrupt.\n";
if ( $kernel_copied eq "no" ) {
"WARNING: The kernel has not been copied successfully. Your Netscaler may not be bootable !!\n";
}
while ($no_answer) {
print "\nAre you sure you want to quit ? [Y/N] "; open( TTY, "+</dev/tty" ) or die "no tty: $!";
sysread( TTY, $buf, );
read_until_eof(TTY);
close(TTY); if ( $buf =~ /y/i ) {
log_state "ABORTED_INTERRUPT\n";
ns_die("ABORTED INSTALLATION DUE TO USER INTERRUPT\n");
}
elsif ( $buf =~ /n/i ) {
$no_answer = ;
}
}
} sub interrupt_other {
my ($signal) = @_;
log_state "ABORTED_OTHER: $signal";
ns_die("ABORTED INSTALLATION DUE TO SIGNAL $signal\n");
} sub check_install_ns_enhanced {
$vers =~ m/\.(e)$/;
my $ns_ver_installns_enhanced = $; if ( $ns_ver_installns_enhanced eq "e" ) {
return ;
}
return ;
} sub check_running_ns_enhanced {
my $ns_ver_ln = `/netscaler/nscli -U %%:.:. sh ver`;
my $ns_ver_num;
my $ns_ver_build;
chomp($ns_ver); $ns_ver_ln =~ m/ NS([-]+\.[-]): Build/;
$ns_ver_num = $; if ( $ns_ver_num >= "9.1") {
$ns_ver_ln =~ m/Build ([-]+\.[-]+[\.e]*\.[ncl]+), /;
$ns_ver_build = $; $ns_ver_build =~ m/\.(e)\.[ncl]+$/;
$ns_ver_build_enhanced = $; if ( $ns_ver_build_enhanced eq "e" ) {
return ;
} }
return ;
} sub check_enhanced_upgrade {
my $installns_enhanced = check_install_ns_enhanced();
my $running_ns_enhanced = check_running_ns_enhanced();
my $ask = ; if ( $running_ns_enhanced == && $installns_enhanced == ) {
print "\nWarning: you are upgrading from \"maintenance\" to \"enhancement\" software version.";
$ask = ;
}
if ( $running_ns_enhanced == && $installns_enhanced == ) {
print "\nWarning: you are upgrading from \"enhancement\" to \"maintenance\" software version.";
$ask = ;
} if (!$ask) {
return ;
} if ($flag_Y) {
return ;
} if ( !$gui_flag ) { if ( !$enh_flag ) {
print " Do you want to continue? [Y/N] "; open( TTY, "+</dev/tty" ) or die "no tty: $!";
sysread( TTY, $ans, );
read_until_newline(TTY);
close(TTY); if ( $ans eq 'y' || $ans eq 'Y' ) {
return ; # YES - do the install
}
exit ; # NO - don't do the install
} else {
return ; # YES - do the install
}
} else {
if ( !$enh_flag ) {
exit ; # NO - don't do the install
} else {
return ; # YES - do the install
}
}
} ### Subroutines for cleaning up ntp configuration start here #### # If $file exists, and contains any references to $reg_ex
# move $file to $backup_file, and return true (1)
# Otherwise return false (0)
sub fix_file_setup ($$$) {
my ($file, $backup_file, $reg_ex) = @_; my $this_subroutine_name = ( caller() )[];
log_trace " \nBEGIN $this_subroutine_name"; my $ret;
my $fix_needed = ;
if (-e $file) {
$fix_needed = `grep -c $reg_ex $file`;
}
if ($fix_needed == ) {
return ;
}
$ret = rename $file, $backup_file;
if ($ret != ) {
log_status_no_console "Unable to upgrade $file to remove references to $reg_ex";
return ;
}
return ;
} # If $monitrc exists, and contains any references to ntp
# move $monitrc to $monitrc_backup,
# and then copy it to $monitrc without the lines relating to ntp, including
# expected comments etc.
# Basically we're expecting a pattern like
# [comments] check-process-line start-line stop-line [if-line] white-space
# One (or more) block(s) like this may contain ntp, in which case we delete
# the whole block. Any of check-process etc. may be commented out; we don't
# care
# It would be nice to get rid of /nsconfig/monitrc entirely, if
# only existed for ntp, but since we can't be sure, leave it present
# (side effect - if /etc/monitrc has change between releases, the user will
# still have the old behaviour.)
sub fix_monitrc () {
my $this_subroutine_name = ( caller() )[];
log_trace " \nBEGIN $this_subroutine_name"; my $monitrc = "/nsconfig/monitrc";
my $monitrc_backup = "$monitrc.prev";
my $ret;
my $fix_needed = fix_file_setup($monitrc, $monitrc_backup, "ntp"); if ($fix_needed == ) {
return;
} $ret = open (OLD, $monitrc_backup);
if (!$ret) {
log_status_no_console "Unable to upgrade $monitrc to remove references to ntp";
return;
}
$ret = open (NEW, ">$monitrc");
if (!$ret) {
log_status_no_console "Unable to upgrade $monitrc to remove references to ntp";
close OLD;
return;
} my $line;
my $in_ntp = ;
while ($line = <OLD>) {
if ($line =~ /ntp/) {
$in_ntp = ;
} if ($in_ntp) {
# Seen "ntp", we want a 'check' line
if ($line =~ /check process/) {
if (not $line =~ /ntpd/) {
# Not our line, better stop processing as ntp
$in_ntp = ;
}
} elsif (not $line =~ /\S/) {
# Nothing but whitespace - end of ntp block
# stop processing as ntp _after_ this line
$in_ntp = ;
next;
}
}
if (not $in_ntp) {
print NEW $line;
}
}
close OLD;
close NEW;
# Monit demands 0700 (or stricter) permissions on $monitrc
chmod (, $monitrc);
log_trace "END $this_subroutine_name";
} # If $rc_conf exists, and contains any references to ntp
# move $rc_conf to $rc_conf_backup,
# and then copy it to $rc_conf without the lines relating to ntp, including
# expected comments etc.
# Basically we're expecting a pattern like
# [comments] ntpd_enable_line [ntp_disable_line] [ntp_flags_line]
# Any of ntpd_enable_line etc. may be commented out; we don't care
# return 1 IFF we found a non-commented out ntpd_enable line that set
# the value to YES ; otherwise return 0
# Such a line looks like:
# ntpd_enable="YES"
sub fix_rc_conf () {
my $this_subroutine_name = ( caller() )[];
log_trace " \nBEGIN $this_subroutine_name"; my $rc_conf = "/nsconfig/rc.conf";
my $rc_conf_backup = "$rc_conf.prev";
my $ret;
my $fix_needed = fix_file_setup($rc_conf, $rc_conf_backup, "ntp"); if ($fix_needed == ) {
return ;
} $ret = open (OLD, $rc_conf_backup);
if (!$ret) {
log_status "Unable to upgrade $rc_conf to remove references to ntp at ".__FILE__." line ".__LINE__;
return ;
}
$ret = open (NEW, ">$rc_conf");
if (!$ret) {
log_status "Unable to upgrade $rc_conf to remove references to ntp at ".__FILE__." line ".__LINE__;
close OLD;
return ;
}
my $line;
my $in_ntp = ;
my $got_enable = ;
my $found_ntp_enabled = ;
while ($line = <OLD>) {
if ($line =~ /ntpd/) {
$in_ntp = ;
} # once we've seen enable, we're out of ntp as soon as we see a line
# without the ntp token
if ($got_enable) {
if (not $line =~ /ntp/) {
$in_ntp = ;
$got_enable = ;
}
} if ($in_ntp) {
# Seen "ntpd", we want an 'ntpd_enable' line
if ($line =~ /enable/) {
if (not $line =~ /ntp/) {
# Not our line, better stop processing as ntp
$in_ntp = ;
$got_enable = ;
} else {
$got_enable = ;
# but is it really enabled?
if ((not $line =~ /#.*ntpd_enable/)
and ($line =~ /ntpd_enable.*YES/)) {
$found_ntp_enabled = ;
}
}
}
}
if (not $in_ntp) {
print NEW $line;
}
}
close OLD;
close NEW;
log_trace "END $this_subroutine_name";
return $found_ntp_enabled;
} # Fix up $rc_netscaler
# We will change it
# (1) if it exists, and has a reference to ntp which doesn't use ntpd_ctl
# (2) if it exists, and our $new_enable argument is true (1)
# We will create it
# (3) if it does nto exist, and our $new_enable argument is true (1)
# If we are changing it, we'll mv the existing file to $rc_netscaler_backup
sub fix_rc_netscaler ($) {
my $this_subroutine_name = ( caller() )[];
log_trace " \nBEGIN $this_subroutine_name"; my ($new_enable) = @_;
my $rc_netscaler = "/nsconfig/rc.netscaler";
my $rc_netscaler_backup = "$rc_netscaler.prev";
my $new_rc_netscaler_ntp_line = "/bin/sh /etc/ntpd_ctl full_start";
my $ret;
my $fix_needed = ;
my $mv_needed = ;
my $new_style_line_written = ; if (-e $rc_netscaler) {
my $has_ntp = `grep -c ntp $rc_netscaler` + ;
my $has_new_ntp = `grep -c \"$new_rc_netscaler_ntp_line\" $rc_netscaler` + 0; # This test is slightly hypersensitive, as it triggers on a commented
# out ntp line - not something we create, but a customer might
if (($has_ntp > $has_new_ntp) or ($new_enable and not $has_new_ntp)) {
$fix_needed = 1;
}
$mv_needed = 1;
} else {
$fix_needed = $new_enable;
} if ($fix_needed == 0) {
return;
} if ($mv_needed) {
$ret = rename $rc_netscaler, $rc_netscaler_backup;
if ($ret != 1) {
log_status "Unable to upgrade $rc_netscaler to normalize references to ntpd at ".__FILE__." line ".__LINE__;
return;
} $ret = open (OLD, $rc_netscaler_backup);
if (!$ret) {
log_status "Unable to upgrade $rc_netscaler to normalize references to ntpd at ".__FILE__." line ".__LINE__;
return;
} } $ret = open (NEW, ">$rc_netscaler");
if (!$ret) {
log_status "Unable to upgrade $rc_netscaler to normalize references to ntpd at ".__FILE__." line ".__LINE__;
close OLD;
return;
} if ($mv_needed) {
# Copy old to new, with replacement if necc.
my $line;
while ($line = <OLD>) {
if (not $line =~ /ntp/) {
print NEW $line;
next;
}
# process line which had ntp
if ($line =~ /#.*ntp/) {
# just dump comments
next;
}
if ($line =~ /$new_rc_netscaler_ntp_line/) {
# Write the new-style line, and we don't need to add another
print NEW $line;
$new_style_line_written = 1;
next;
}
# whatever we found was an old style line, replace if it's
# the first we've seen
if (not $new_style_line_written) {
print NEW "$new_rc_netscaler_ntp_line\n";
$new_style_line_written = 1;
} }
close OLD;
}
if ($new_enable and not $new_style_line_written) {
print NEW "$new_rc_netscaler_ntp_line\n";
}
close NEW;
log_trace "END $this_subroutine_name";
} # Given a restrict or server line, in format
# [#] server|restrict [-6|-4] host_or_ip [lots more stuff]
# Find and return the host or IP
# If the line is commented out (has a # before the host_or_ip) return the
# empty string
# First argument is the line, second is either "server" or "restrict"
sub parse_out_host($$) {
my ($line, $keyword) = @_; my $this_subroutine_name = ( caller(0) )[3];
log_trace " \nBEGIN $this_subroutine_name - keyword $keyword; line $line"; my @tokens = split /\s+/, $line;
my $i;
my $got_keyword = 0;
my $host;
my $rest;
for ($i = 0; $i < @tokens; $i++) {
my $token = $tokens[$i];
if ($token =~ /#/) {
return "";
} elsif ($token =~ /$keyword/) {
$got_keyword = 1;
} elsif ($got_keyword and $token =~ /-6/) {
next;
} elsif ($got_keyword and $token =~ /-4/) {
next;
} elsif ($got_keyword) {
# the next thing has to be a host name or ip
return $token;
}
}
# short or otherwise malformed line
return "";
} # Fix up $ntp_conf
# We will change it
# (1) if it exists, and doesn't have an includefile line
# (2) if it exists, and has servers without restrict lines
# If we are changing it, we'll mv the existing file to $ntp_conf_backup
my $ntp_conf = "/nsconfig/ntp.conf";
sub fix_ntp_conf () {
my $this_subroutine_name = ( caller(0) )[3];
log_trace " \nBEGIN $this_subroutine_name";
my $ntp_conf_backup = "$ntp_conf.prev";
my $new_includefile_line = "includefile /etc/ntp.common.conf";
my $new_restrict_tail = "nomodify notrap nopeer noquery";
my $ret; if (not -e $ntp_conf) {
return;
} # Note - this will trigger on a comment, even one that mentions includefile
# i.e. we won't upgrade an ntp.conf that even mentions includefile in
# a comment.
my $has_includefile = `grep -c includefile $ntp_conf`; my $servers = `grep server $ntp_conf`;
my @servers_arr = split /\n/, $servers;
my $restricts = `grep restrict $ntp_conf`;
my @restricts_arr = split /\n/, $restricts; if ($has_includefile != 0) {
# If we have at least as many restrict lines as server lines
# as well as an includefile line, we figure it's already been
# updated.
if ($#servers_arr <= $#restricts_arr) {
return;
}
} $ret = rename $ntp_conf, $ntp_conf_backup;
if ($ret != 1) {
log_status "Unable to upgrade $ntp_conf at ".__FILE__." line ".__LINE__;
return;
} $ret = open (OLD, $ntp_conf_backup);
if (!$ret) {
log_status "Unable to upgrade $ntp_conf at ".__FILE__." line ".__LINE__;
return;
} $ret = open (NEW, ">$ntp_conf");
if (!$ret) {
log_status "Unable to upgrade $ntp_conf at ".__FILE__." line ".__LINE__;
close OLD;
return;
} if ($has_includefile == 0) {
# Start by putting a good includefile at the start of the file
print NEW "$new_includefile_line\n";
} # Get the restricts into a hash, so we can recognize servers
# without matching restricts
my %restricts_hash;
foreach my $restrict_line (@restricts_arr) {
my $host = parse_out_host($restrict_line, "restrict"); if ($host ne "") {
$restricts_hash{$host} = $restrict_line;
}
} # Copy old to new, with replacement if necc.
my $line;
while ($line = <OLD>) {
# Copy whatever we found
print NEW $line;
if ($line =~ /server/) {
my $host = parse_out_host($line, "server");
if ($host ne "") {
if (not exists $restricts_hash{$host}) {
# no matching restrict line, so we need to add it
print NEW "restrict $host $new_restrict_tail\n";
}
}
}
}
close OLD;
close NEW;
log_trace "END $this_subroutine_name";
} # Handling of ntp changed rather significantly at 11.0, backported to various
# earlier releases. If a system being upgraded already has ntp enabled,
# we want to change their ntp configuration to conform to the new methods.
# (An old-style configuration will have subtle problems on a new-style release.)
# Old config files will saved as /nsconfig/*.prev,
# e.g. /nsconfig/ntp.conf will be saved as /nsconfig/ntp.conf.prev
# Warning: downgrade is not handled automatically.
sub fix_ntp {
my $this_subroutine_name = ( caller(0) )[3];
log_trace " \nBEGIN $this_subroutine_name"; # $version comes from uname -a, format looks like:
# FreeBSD ns 8.4-NETSCALER-11.0 FreeBSD 8.4-NETSCALER-11.0 #0: Fri Mar 20 14:01:39 PDT 2015 root@sjcdbldbsd8404.eng.citrite.net:/usr/obj/home/build/TOT/usr.src/sys/NS64 amd64
my ($junk1, $junk2, $ns_name) = split /\s+/, $version;
my ($junk3, $ns_ver) = split /-NETSCALER-/, $ns_name;
my ($major, $minor) = split /\./, $ns_ver; # This one gives build as well as major and minor
# Format like: netscaler.version: NetScaler NS11.0: Build 43.1.nc, Date: Mar 20 2015, 14:00:35
# my $ns_version = `sysctl netscaler.version`;
# Include this (parsed) in the test below if things ever get more complex
# (As it is, it's safe to rerun this on OK config files thru all of 11.00
# even though some builds of 10.1, 10.5, and 11.0 will have new-style
# NTP configs) # Nothing needs to be done if the release is late enough
if (($major > 11) || (($major == 11) && ($minor > 0))) {
return;
} return if (! (-e $ntp_conf)); fix_monitrc();
my $enabled_in_rc_conf = fix_rc_conf();
fix_rc_netscaler($enabled_in_rc_conf);
fix_ntp_conf;
log_trace "END $this_subroutine_name";
} ### Main execution starts here
open STATE_LOG, ">$state_file";
openlog $syslog_ident, $syslog_opt, $syslog_facility; $date = time();
$localdate = localtime(); log_state "BEGIN_TIME $date $localdate";
log_state "VERSION $kernel";
log_state "VARIANT $variant "; getopts( 'egRLchYynfFGNS6', \%options ); while (($okey, $ovalue) = each %options)
{
$opt_string .= "$okey";
}
$log_string="Options are: ";
if ($opt_string ne "" ) {
log_status_no_console "$log_string $opt_string";
}else {
log_status_no_console "No options"
} if ( $options{h} ) {
print_help();
} if ( $options{Y} ) {
$flag_Y = 1;
$nsconf_check = 0;
$user_nsconf_check = 0;
} # Initialize Interrupt Handling
$SIG{'INT'} = 'interrupt_int';
$SIG{'QUIT'} = 'interrupt_int';
$SIG{'HUP'} = 'interrupt_other';
$SIG{'ABRT'} = 'interrupt_other';
$SIG{'STOP'} = 'interrupt_othert';
$SIG{'KILL'} = 'interrupt_othert'; if ( $options{F} ) {
$fips = 1;
log_status_no_console "detected fips";
} if ( $options{G} ) {
$nocurses = 1;
} if ( $options{L} ) {
$callhome_flag = 1;
} if ( $options{e} ) {
$enh_flag=1;
} if ( $options{R} ) {
$resize_flag=1;
} # This is for internal use. GUI need to run installns
# with this flag to skip any user interaction during upgrade.
if ( $options{g} ) {
$gui_flag = 1;
} if ( $options{N} ) {
$nsconf_check = 0;
$user_nsconf_check = 0;
} #nsconf utility can't run on 4.9 BSD. It also has issues on versions less than 9.2
if ( $version =~ '4.9-NETSCALER' || $version =~ 'NETSCALER-9.0' || $version =~ 'NETSCALER-9.1') {
$nsconf_check = 0;
} if ( $options{c} ) {
"-c Force Clean up option is now obsolete and will not do anything\n";
"Please discontinue the use of -c option and clean up file system manually if needed.\n";
} if ( $options{S} ) {
# Use at your own risk. not recommended.
$ignore_platform_checks = "yes";
} print_banner(); if ( $version =~ '4.4-RELEASE' ) {
log_status_no_console "detected Version < NS6.";
ns_die(
"This version of installns is not supported on software versions prior to 6.0"
);
}
else {
log_status_no_console "detected Version >= NS6.";
log_status_no_console "Installation path for kernel is /flash";
check_system_before_install();
cloud_prevent_bootstrap();
}
find_old_server_cert();
copy_kernel();
mod_loaderconf();
install_usr_share();
install_doc();
install_help();
install_help_cisco();
install_LogonPoint();
install_LoginSchemaFiles();
install_app_catalog_files();
install_scom_mp();
install_gui();
install_epa_package();
install_nitro();
install_mastools();
install_lom();
install_nic_firmware();
install_linux_package();
install_callhome_cert();
install_geoipdb();
install_nfast();
install_safenet();
install_inCompass_db_files();
install_python(); if ( $variant eq "v" ) {
install_python_nitro();
install_cloudautoscale();
}
$ret = `sysctl netscaler.vpx_on_cloud`;
if ( $ret =~ /3$/ ) {
install_azureautoconfig();
install_azureagent();
# Remove the .mdinfo file so that a fresh skuid is fecthed from IMDS.
# This is needed to avoid license decryption failure when we change UUID scheme.
`rm -rf /nsconfig/.AZURE/.mdinfo`
}
fix_ntp();
upgrade_before_pe_start();
after_upgrade();
$ret = `sysctl netscaler.sysid`;
if ( $ret =~ /45001[0|1]$/) {
install_vmtools();
} log_status_no_console "prompting for reboot"; $date = time();
$localdate = localtime(); log_state "END_TIME $date $localdate";
close STATE_LOG; prompt_epaProfileWarning(); #turn off file sync, turned on automatically after ns reboot
system("chmod /etc/crontab");
system("sed -i .temp '/[[:<:]]nsfsyncd[[:>:]]/s/^/#/g' /etc/crontab"); # This function is called to convert all the imported objects to lower
# case before upgrade.
convert_import_object_to_lower_case(); #Convert learn db files to lower case before upgrade
handle_learn_db_before_upgrade(); prompt_reboot(); closelog;
### End installns script
================== End
installns的更多相关文章
- NetScaler 12.1 Deploy Package
NetScaler 12.1 Deploy Package NS_VPX_Deploy_Package 百度网盘共享地址https://pan.baidu.com/s/1OT0Hxuz6ZBLwwM5 ...
随机推荐
- Python中的常规习题
循环总结 while 语句 for 语句 - 字符串 - range() 函数 break 语句 continue 语句 学习笔记传送门 列表学习 # 练习: # 输入一个整数n, 判断这个整数是否是 ...
- valgrind使用简介
1.问题 虽然C/C++是一种非常有用且功能强大的语言,但很难调试. 某些时候可能遇到内存错误. 如果知道出错 ,或者程序一直崩溃,我们可以用gdb/DBX去调试. 但是,有时遇到的问题是由于内存错误 ...
- django orm 操作表
django orm 操作表 1.基本操作 增 models.Tb1.objects.create(c1='xx', c2='oo') 增加一条数据,可以接受字典类型数据 **kwargs inser ...
- 主成分分析——PCA
在数据挖掘过程中,当一个对象有多个属性(即该对象的测量过程产生多个变量)时,会产生高维度数据,这给数据挖掘工作带来了难度,我们希望用较少的变量来描述数据的绝大多数信息,此时一个比较好的方法是先对数据进 ...
- telnet命令详解
基础命令学习目录 原文链接:https://www.cnblogs.com/PatrickLiu/p/8556762.html telnet命令用于登录远程主机,对远程主机进行管理.telnet因为采 ...
- servlet的方法解析
一般来说servlet继承了HttpServlet,我们可以覆盖某些方法来实现自己的功能. Init()和Init(ServletConfig config),我们一般只需覆盖后者,因为这个可以从se ...
- 【CSAPP笔记】6. 汇编语言——控制
原先刊于自己的域名下面,考虑到博客园之前发过一半,不想烂尾,故在博客园发一版. 到目前为止我们只考虑了直线代码的执行行为,也就是指令一条接着一条执行.C语言中的某些语句,比如条件语句.循环.分支语句, ...
- express框架结合ejs模板引擎使用
我们在项目里建立一个views文件夹(必须),如果你不想使用views文件夹的话需要调用app.set("views","自定义文件夹名"),然后在里面建立一个 ...
- form表单转化json对象
利用 $.fn 可以让每一个jquery 对象都能直接使用这个方法. //form表单转化json对象$.fn.serializeObject = function () { var o = {}; ...
- 《简明Python教程》学习笔记
<简明Python教程>是网上比较好的一个Python入门级教程,尽管版本比较老旧,但是其中的基本讲解还是很有实力的. Ch2–安装Python:下载安装完成后,在系统的环境变量里,在Pa ...