MultiDVD

From Wiki-UX.info
Jump to: navigation, search
#!/usr/bin/sh
# make_dvd_recovery
# usage: make_dvd_recovery backup -a host:mountpoint\n"
#        make_dvd_recovery makeiso -m iso target directory\n"

__header() {
printf "======= %s/%s/%s Started make_dvd_recovery. (%s %s %s\n\t%s %s %s)\n" \
   $(date "+%m %d %y") \
   $(date "+%c %Z")
}

__footer() {
printf "\n======= %s/%s/%s %s %s make_dvd_recovery completed\n" \
   $(date "+%m %d %y %T %Z")
}

__error() {
printf "\n======= %s/%s/%s %s %s make_dvd_recovery failed with errors!\n" \
   $(date "+%m %d %y %T %Z")
   exit $1
}

__save_config() {
printf "\t* Creating System Configuration.\n"
printf "\t* /opt/ignite/bin/save_config -f\n\t%s/system_cfg %s\n" $CWD

/opt/ignite/bin/save_config -f $CWD/system_cfg $bootvg

if [[ ! $? -eq 0 ]]; then
   printf "ERROR:\tFailed to create %s/system_cfg" $CWD
   __error 1
fi
}

__save_file_list() {
# flist will contain all files form root (/), /stand and /usr

printf "\t* Creating Archive File List\n"
grep -F "$bootvg" /etc/fstab | grep -ve "/ " -e "/stand" -e "/usr" | \
   awk 'BEGIN {print "inc_entire vg00"} {printf "exclude %s\n", $2}' \
> $CWD/content_file

/opt/ignite/lbin/list_expander -f $CWD/content_file > $CWD/flist

if [[ ! $? -eq 0 ]]; then
   printf "ERROR:\tFailed to create %s/content_file\n" $CWD
   __error 2
fi
}

__packing() {
# Implements "First Fit Decreasing" packing algorithm
# The algorithm does not ensure maximum space utilization,
# nonetheless, provides very good results on small packing
# sets without testing all available combinations.

printf "\t* Distributing archives among DVD MEDIA\n"
cd ${CWD}/archives

# First DVD always contains system.gz archive
if [[ -f system.gz ]]; then
   ls -l system.gz | awk '{printf "%s %d\n", $9, $5/1024}' > ${CWD}/disk1.lst
   printf "\t* %s\t(%9d KB) fits in disk1\n" $(head -n 1 ${CWD}/disk1.lst)
else
   __error 5
fi

# Create archive list in KBs (without base.gz)
ls -l *.gz | grep -v system.gz | awk '{printf "%s %d\n", $9, $5/1024}' | sort -nrk 2,2 > ${CWD}/archives.lst

# If MAXSIZE undefined, set size 4.4 GB (300 MB overhead)
if [[ -z $MAXSIZE ]]; then
   MAXSIZE=4613734
fi

COUNT=1
while [[ $(wc -l ${CWD}/archives.lst | awk '{print $1}') -gt 0 ]]; do
   AVAILABLE=${MAXSIZE}

   for archive in $(cat ${CWD}/disk${COUNT}.lst | awk '{print $1}')
   do
      SIZE=$(grep ^${archive} ${CWD}/disk${COUNT}.lst | awk '{print $2}')
      AVAILABLE=$(expr ${AVAILABLE} - ${SIZE})
   done

   if [[ ${AVAILABLE} -gt $(head -n 1 ${CWD}/archives.lst | awk '{print $2}') ]]; then
      printf "\t* %s\t(%9d KB) fits in disk%d\n" $(head -n 1 ${CWD}/archives.lst) ${COUNT}
      head -n 1 ${CWD}/archives.lst >> ${CWD}/disk${COUNT}.lst
      LINES=$(wc -l ${CWD}/archives.lst | awk '{print $1}')
      tail -n $(expr ${LINES} - 1) ${CWD}/archives.lst > ${CWD}/archives.tmp
      cp ${CWD}/archives.tmp ${CWD}/archives.lst
      COUNT=1
   else
      COUNT=$(expr $COUNT + 1)
      if [[ ! -f ${CWD}/disk${COUNT}.lst ]]; then
         touch ${CWD}/disk${COUNT}.lst
      fi
   fi
done

cd $CWD
}

__save_disk1_archive_config() {
printf "\t* Creating Disk #1 Archive Configuration\n"

# disk1.cfg software source and system.gz archive
cat > $CWD/disk1.cfg << EOF
(${ARCH}) {
#########################################################
##  Software Sources
#########################################################

sw_source "disk1 archives"{
   description = "Recovery Disk #1 Archive"

   load_order = 0
   source_format = archive
   change_media = FALSE

   post_load_script = "/opt/ignite/data/scripts/os_arch_post_l"
   post_config_script = "/opt/ignite/data/scripts/os_arch_post_c"
}


#########################################################
##  Software Categories
#########################################################

sw_category "Languages" {
   description = "Languages"
}

sw_category "HPUXEnvironments"{
    description = "HP-UX Operating Environments"
}

init sw_sel "system archive" {
   description = "Base System Recovery Archive"

   sw_source = "disk1 archives"
   sw_category = "HPUXEnvironments"
   archive_type = gzip tar
   archive_path = "archives/system.gz"
} = TRUE

EOF

# Additional archives on disk1.cfg
for archive in $(awk '! /system.gz/ {split($1, a, "."); print a[1]}' ${CWD}/disk1.lst)
do
cat >> $CWD/disk1.cfg  << EOF

init sw_sel "$archive archive" {
   description = "${archive} Recovery Archive"

   sw_source = "disk1 archives"
   sw_category = "HPUXEnvironments"
   archive_type = gzip tar
   archive_path = "archives/${archive}.gz"
} = TRUE

EOF
done

# disk1.cfg last part
cat >> $CWD/disk1.cfg << EOF
_hp_os_bitness visible_if false

######################################################
##  Languages
##  Specified so that the selector in the UI will
##  not be empty.  Cannot use the "disk1 archive" sw_source
##  because there is not archives associated with it.
##
##  The "no select" sw_source is a no-op source since
##  has is of "cmd" format, and does not have any scripts
##  specified. Every sw_sel needs a sw_source.
##
#####################################################

sw_source "no select" {
   source_format = cmd
}

init sw_sel "English" {
   description = "English Language Environment"
   sw_source = "no select"
   sw_category = "Languages"
   locale = { "SET_NULL_LOCALE:English", "C:English" }
} = TRUE

######################################################
##  Keyboards
#####################################################

_hp_keyboard = {
    "Not_Applicable",
    "PS2_DIN_US_English"
}
init _hp_keyboard = "PS2_DIN_US_English"
}
EOF

}

__save_disks_archive_config() {

# disk#.cfg software source
cat > $CWD/disk${1}.cfg << EOF
    sw_source "disk${1} archives" {
        description = "Recovery Disk #${1} Archive"
        source_format = archive
        source_type = "DSK"
        change_media = TRUE
   }

    sw_category "Archives" {
        description = "Archives for Individual File Systems"
    }


   #####################################################
   ##  Software Selections
   #####################################################
EOF


# Additional archives on disk#.cfg
printf "\t* Creating Disk #${1} Archive Configuration\n"

for archive in $(awk '{split($1, a, "."); print a[1]}' ${CWD}/disk${1}.lst)
do
cat >> $CWD/disk${1}.cfg << EOF

init sw_sel "${archive} archive" {
       description = "${archive} Recovery Archive"
       sw_source = "disk${1} archives"
       archive_type = gzip tar
       archive_path = "archives/${archive}.gz"
       sw_category = "Archives"
   } = TRUE
EOF
done
}

__save_archives() {
# Saves NFS archive share
echo ${NFS} > ${CWD}/archives.nfs

# Mount NFS archive share
if [[ ! -d $CWD/archives ]]; then
   mkdir $CWD/archives
fi

mount -F nfs ${NFS} $CWD/archives

# Create system archive root (/), /stand, /usr

/opt/ignite/data/scripts/make_sys_image -s local -d $CWD/archives \
-n system.gz -R -g $CWD/flist \
-w $CWD/system_archive.log

if [[ ! $? -eq 0 ]]; then
   __error 3
fi

# Create individual file system archives

cd /
for mountpoint in $(awk -F"/" '/exclude/ {print $2}' $CWD/content_file)
do
   printf "\t* Archiving contents of /%s via tar to\n\t%s/%s.gz\n" \
      $mountpoint $CWD/archives $mountpoint
   pax -wx ustar -f - $mountpoint 2> /dev/null | \
      /usr/contrib/bin/gzip > $CWD/archives/$mountpoint.gz 2> /dev/null
   if [[ $? -gt 0 ]]; then
      printf "\t* Creation of %s archive failed.\n" $mountpoint
   else
      printf "\t* Creation of %s archive complete.\n\n" $mountpoint
   fi
done
}

__makeiso() {
__header()
printf "\t* Creating ISO DVD images\n"

CWD="/var/opt/ignite/recovery/latest"
ISO=$1
RELEASE=$(uname -r)

# Mount archives NFS
if [[ -f ${CWD}/archives.nfs ]]; then
      mount -F nfs $(cat ${CWD}/archives.nfs) $CWD/archives
else
   printf "\tERROR:\t Previous NFS archive mount point not found on archives.nfs\n"
   __error 7
fi

# Makes DVD #1 ISO file
printf "\t* Creating ISO media image(s): \n"

rm -rf ${CWD}/archives/pseudo_root
mkdir -p ${CWD}/archives/pseudo_root/archives

if [[ $? -gt 0 ]]; then
   printf "ERROR:\tFailed to create %s/archives/pseudo_root directory\n" ${CWD}
   __error 6
fi

printf "\t === Step 1: Make a boot-image (LIF volume) ===\n"
cat > ${CWD}/make_medialif.sh << EOF
/opt/ignite/bin/make_medialif \\
-l ${CWD}/archives/pseudo_root/bootvol.lif \\
-f /opt/ignite/data/Rel_${RELEASE}/config \\
-f ${CWD}/system_cfg \\
-f ${CWD}/disk1.cfg \\
EOF

for conf in $(cd $CWD; ls disk*.cfg | grep -v disk1.cfg )
do
   printf "-f %s " $CWD/${conf} >> $CWD/make_medialif.sh
done

# Display make_medialif command
cat $CWD/make_medialif.sh | awk '{printf "\t%s\n", $0}'

sh $CWD/make_medialif.sh

# Display instl_adm command
printf "\t/opt/ignite/bin/instl_adm -b -F %s/bootvol.lif\n" $CWD/archives/pseudo_root
/opt/ignite/bin/instl_adm -b -F $CWD/archives/pseudo_root/bootvol.lif

printf "\t === Step 2: Make DVD #1 ISO media image  ===\n"

# Linking archive file to pseudo_root archive
printf "\t* Linking archives to %s/archives/pseudo_root\n" ${CWD}
for archive in $(cat ${CWD}/disk1.lst | awk '{print $1}')
do
   ln ${CWD}/archives/${archive} ${CWD}/archives/pseudo_root/archives/${archive}
done

if [[ ${ARCH} = "is_hppa"  ]]; then
   cat > ${CWD}/mkisofs.sh << EOF
/opt/ignite/lbin/mkisofs -U -max-iso9660-filenames -R -eltorito-alt-boot \\
-no-emul-boot -b bootvol.lif -o ${ISO}/disk1.iso \\
${CWD}/archives/pseudo_root
EOF
else
   cat > ${CWD}/mkisofs.sh << EOF
cp -p /opt/ignite/boot/Rel_${RELEASE}/EFI_CD_image ${CWD}/archives/pseudo_root

/opt/ignite/lbin/mkisofs -D -R -U -max-iso9660-filenames \\
-no-emul-boot -b EFI_CD_image \\
-eltorito-alt-boot -no-emul-boot -b bootvol.lif \\
-o ${ISO}/disk1.iso \\
${CWD}/archives/pseudo_root
EOF
fi

# Display mkisofs command
cat $CWD/mkisofs.sh | awk '{printf "\t%s\n", $0}'

# Executes mkisofs command
sh $CWD/mkisofs.sh

# Makes Additional DVD ISO file(s)
printf "\t === Step 3: Make Additional DVD ISO media image(s) ===\n"

cd ${CWD}
for image in $(ls disk*.lst | awk '! /disk1.lst/ {split($1, a, "."); print a[1]}')
do
   printf "\t* Creating %s ISO image\n" $image
   rm -rf ${CWD}/archives/pseudo_root
   mkdir -p ${CWD}/archives/pseudo_root/archives

   printf "\t* Linking archives to %s/archives/pseudo_root\n" ${CWD}
   for archive in $(cat ${CWD}/${image}.lst | awk '{print $1}')
   do
      ln ${CWD}/archives/${archive} ${CWD}/archives/pseudo_root/archives/${archive}
   done

   cat > ${CWD}/mkisofs.sh << EOF
/opt/ignite/lbin/mkisofs -U -max-iso-9660-filenames \\
-R -o ${ISO}/${image}.iso \\
${CWD}/archive/pseudo_root
EOF

   # Display mkisofs command
   cat $CWD/mkisofs.sh | awk '{printf "\t%s\n", $0}'

   # Executes mkisofs command
   sh $CWD/mkisofs.sh
done

# Unmount archives NFS
cd /
umount $CWD/archives
}

# main()
# Define System Architecture

if [[ $(model | awk '{print $1}') = ia64 ]]; then
   export ARCH=is_ia64
else
   export ARCH=is_hppa
fi

# Check if /var/opt/ignite/recovery exists

if [[ ! -d /var/opt/ignite/recovery ]]; then
   printf "NOTE:\t/var/opt/ignite/recovery directory does not exist. Will create it.\n"
   printf "\t* Creating local directories for configuration files and archive.\n\n"
   mkdir -pm 755 /var/opt/ignite/recovery
   chown bin:bin /var/opt/ignite/recovery
fi

case $1 in
"backup")
   # Create working directory (Removes all previous versions)
   rm -rf /var/opt/ignite/recovery/*

   export CWD=/var/opt/ignite/recovery/$(date "+%Y-%m-%d,%H:%M")

   if [[ ! -d $CWD ]]; then
      mkdir $CWD
      ln -s $CWD /var/opt/ignite/recovery/latest
   fi

   # Test if system boot volume runs VxVM or LVM volume group manager

   if [[ -d /dev/vx/dsk/rootdg ]]; then
      export bootvg=rootdg
   else
      export bootvg=vg00
   fi

   if [[ $2 = "-a" ]]; then
      if [[ ! -d $CWD/archives ]]; then
         mkdir $CWD/archives
      fi
      export NFS=${3}
   else
      printf "ERROR:\tMissing NFS archive mount point\n"
      __error 4
   fi

   __header
   __save_config
   __save_file_list
   __save_archives
   __save_disk1_archive_config

   COUNT=1
   for disk in $(cd $CWD; ls disk*.lst | grep -v disk1.lst)
   do
      COUNT=$(expr ${COUNT} + 1)
      __save_disks_archive_config ${COUNT}
   done

   __packing

   umount $CWD/archives
   __footer
   ;;
"makeiso")
   if [[ $2 = "-m" ]]; then
      if [[ ! -d $3 ]]; then
         printf "\t* Creating ISO backing storage directory\n"
         mkdir $3
         if [[ $0 -gt 0 ]]; then
            __error 5
         fi
      fi
   fi
   __makeiso $3
   ;;
*)
   printf "usage: make_dvd_recovery backup -a host:mountpoint\n"
   printf "       make_dvd_recovery makeiso -m iso target directory\n"
   ;;
esac