Vous êtes sur la page 1sur 7

#!

/bin/ksh

# install-repo.ksh
# unpacks and installs Solaris IPS repository

# args:
# location of zip files
# filesystem to set up repo

typeset mkiso=false
typeset imageopt=false
typeset verify=false
typeset ignoredeps=""
typeset chkdigest=false
typeset sumcomp=""
typeset singlezip=false
typeset firstpiece="_1of"
typeset isziprepo=""
typeset solimage=""
typeset ckfile=""
typeset autoadd=false
typeset DIGESTALG="sha256"
typeset DIGEST="/usr/bin/digest -a $DIGESTALG -v"
typeset OSTOPLEVEL="COPYRIGHT NOTICES"

Usage () {
cat << EOF
USAGE:
install-repo.ksh -d dest [-s zipsrc] [-i image-name] [-c] [-v] [-I] [-y]

-d dest = destination directory to hold repository


-s zipsrc = full path to directory holding zip files. default: current directory
-i image = name of image: e.g. sol-11_2-repo. default: name found in directory
-c = compare digests of downloaded zip files
-v = verify repo after unzipping (minimum Solaris 11.1.7 required)
-I = create an ISO image
-y = add to existing repository without prompting for yes or no. Use
with caution.

Destination directory will contain top-level ISO files including README.


Repository is directly under destination.
ISO image is created in current directory, or zipsrc directory from -s argument.
EOF
}

if [ $# -eq 0 ]; then
Usage
exit 1
fi

typeset ZIPLOC=$(pwd)

while getopts Ii:s:d:vchy char; do


case $char in
s) ZIPLOC=$OPTARG
if [ ! -d $ZIPLOC -o ! -r $ZIPLOC ] ; then
echo "$ZIPLOC: directory does not exist \c"
echo "or is not readable. Exiting."
exit 1
fi
[[ "$ZIPLOC" == /* ]] || {
echo "\n$ZIPLOC must use absolute pathname \c"
echo "starting with /. Exiting."
exit 1
}
;;
d) typeset REPOLOC=$OPTARG
if [ ! -d $REPOLOC -o ! -w $REPOLOC ] ; then
echo "$REPOLOC: directory does not exist \c"
echo "or is not writable. Exiting."
exit 1
fi
[[ "$REPOLOC" == . ]] && typeset REPOLOC=$(pwd)
;;
v) typeset verify=true;;
i) typeset image=$OPTARG;;
I) typeset mkiso=true;;
c) typeset chkdigest=true;;
y) typeset autoadd=true;;
h) Usage
exit ;;
\?) echo "use -h option for usage."
exit 1
;;
:) echo "Option -$OPTARG requires a value"
echo "use -h option for usage."
exit 1
;;
esac
done

shift OPTIND-1
if [ $# -gt 0 ]; then
echo "Too many arguments: $@"
Usage
exit 1
fi

if [ -z "$REPOLOC" ]; then
echo "ERROR: Missing -d argument for repository directory."
Usage
exit 1
fi

if [ ! -w "$ZIPLOC" -a "$mkiso" == true ]; then


echo "$ZIPLOC is not writable for ISO file creation. Exiting."
exit 1
fi

if [ -z "$image" ]; then
# -i option not used: need to determine which image to operate on
# Have to assume that latest zipped repo file is correct.
# Otherwise, no way of determining which to use.

# get list of all zip archives that may be the initial repo archive
typeset ziplist=$(ls -t $ZIPLOC/*.zip 2> /dev/null |
grep -v _[2-9]of 2> /dev/null)
# no zip files in directory
if [ -z "$ziplist" ];then
echo "Cannot locate any initial zip archive segments in \c"
echo "$ZIPLOC."
echo "Exiting."
exit 1
fi

# search each zip from newest to oldest for a publisher directory


# indicating that it contains a repository
for zipfile in $ziplist; do
# ignore first few files in archive in case there are
# readmes, etc.
typeset isziprepo=$(unzip -l $zipfile | head -7 | tail -1 |
awk '{print $NF}' | grep "^publisher/")
if [ -n "$isziprepo" ]; then
# found the first (or only) repo archive segment
typeset zip1=$zipfile
break
fi
done

if [ -z "$zip1" ];then
# cannot find any zip file containing publisher directory
echo "Cannot locate any initial zip archive segments in \c"
echo "$ZIPLOC."
echo "Exiting."
exit 1
fi

if [[ "$zip1" != *_1of* ]];then


# if repo segment is not labeled "1ofX", then it is a single
# segment zip archive file
typeset singlezip=true
typeset -i ZIPCNT=1
typeset firstpiece=""
fi
# set image name based on the "1of" segment
# examples:
# if segment is V12345-01_1of2.zip, then image is V12345-01
# if segment is sol-11_2-repo_1of4.zip, then image is sol-11_2-repo
typeset image=$(echo $zip1 | sed "s|.*/\(.*\)${firstpiece}.*\.zip|\1|" | head
-1)
# base digest file on image name
typeset ckfile=$ZIPLOC/${image}_digest.txt
[[ "$image" != *-repo ]] && {
# get "Solaris"-format image name to use later
if ! $(ls $ZIPLOC/*-repo_digest.txt > /dev/null 2>&1); then
echo "Cannot find digest file in $ZIPLOC to \c"
echo "retrieve image information. Exiting."
exit 1
fi
typeset solimage=$(ls -t $ZIPLOC/*-repo_digest.txt | \
head -1 | sed -n "s|.*/\(.*\)_digest.txt|\1|p")
# link original format names to download names
typeset ckfile=$ZIPLOC/${solimage}_digest.txt
}
else
# -i option used to identify image name
typeset imageopt=true
# OTN uses hyphen to separate parts, others use underscore
if [[ -f $ZIPLOC/${image}.zip ]]; then
typeset singlezip=true
typeset -i ZIPCNT=1
typeset firstpiece=""
elif [ ! -f $ZIPLOC/${image}${firstpiece}* ]; then
echo "Cannot find zip images with $image name. Exiting."
exit 1
fi
# need to determine solaris-style name from digest file
# search all digest files for match to determine file to use
sumcomp=$($DIGEST $ZIPLOC/${image}${firstpiece}*.zip | awk '{print $NF}')
for sumfile in $ZIPLOC/*digest.txt; do
if grep -q $sumcomp $sumfile; then
# found it
typeset ckfile=$sumfile
# use matching digest file to determine
# "Solaris"-format name
solimage=$(echo $ckfile |
sed -n "s|.*/\(.*\)_digest.txt|\1|p")
continue
fi
done
if [ -z "$ckfile" ]; then
echo "No matching digest file found. Exiting."
exit 1
fi
fi

if [ -z "$solimage" ]; then
# define solimage to be same as image if not already set above
# it would not be defined if neither the -i nor -c option is used
typeset solimage=$image
# print out name of Solaris image to avoid confusion
[[ $imageopt == false ]] && echo "Using ${image} download."
else
# print out name of download image to avoid confusion
[[ $imageopt == false ]] &&
echo "Using ${image} files for ${solimage} download."
fi

typeset -i zipnum=1
typeset rebuild=false
typeset existingpubs=false

# check if repo already exists, give option to abort


if [ -d $REPOLOC/publisher/solaris ]; then
typeset existingpubs=true
# if full Solaris repo, then display current version from entire pkg
currentrepo=$(LC_ALL=C pkg info -g $REPOLOC entire 2>/dev/null | \
sed -n "s/.*Branch: //p")
if [ -z "$currentrepo" ]; then
# give option to proceed if not full Solaris repo
echo "$REPOLOC appears to be an existing repository but \c"
echo "does not contain"
echo "the \"entire\" IPS package. Please check contents of \c"
echo "$REPOLOC."
else
echo "IPS repository exists at destination $REPOLOC"
echo "Current version: $currentrepo"
fi
else
# look for non-solaris publishers
nonsolpubs=$(ls $REPOLOC/publisher 2>/dev/null)
if [ -n "$nonsolpubs" ]; then
echo "The following publisher(s) exist in $REPOLOC:"
echo $nonsolpubs
typeset existingpubs=true
fi
fi

if [ "$existingpubs" == true ]; then


# if -y flag was used, then just add to existing repo without prompting
if [ "$autoadd" == false ]; then
echo "Do you want to add to this repository? (y/n)[n]: \c"
read answer
case $answer in
y|Y|yes|Yes) ;;
*)
echo "Please choose a different destination. Exiting."
exit 1
;;
esac
else
echo "Adding packages to existing repository."
fi
typeset rebuild=true
# allow overwriting of current repo files except for pkg5.repository
typeset zipreplace="-o"
typeset zipkeep="-x pkg5.repository"
fi

if [ -z "$ZIPCNT" ]; then
typeset -i ZIPCNT=$(ls $ZIPLOC/${image}_*of*.zip | wc -w | awk '{print $1}')
fi
# validate zip files
# need to compare .zip files with digests
if [ "$chkdigest" == true ]; then
if [ ! -f "$ckfile" ]; then
echo "Cannot find digest file $ckfile. Exiting."
exit 1
fi
# get first zip files, digest value, if not already defined
if [ -z "$sumcomp" ]; then
sumcomp=$($DIGEST $ZIPLOC/${image}${firstpiece}*.zip |
awk '{print $NF}')
fi
echo "\nComparing digests of downloaded files...\c"
if [ "$image" != "$solimage" ]; then
# since digest file is shipped with "solaris"-style naming,
# the file needs to be edited to use actual zip filenames
sed "s/$solimage/$image/" $ckfile > /tmp/cksumbase$$
else
cp $ckfile /tmp/cksumbase$$
fi
# generate digest values of downloaded files
(cd $ZIPLOC; $DIGEST $image*.zip) > /tmp/cksumdl$$
diff /tmp/cksumbase$$ /tmp/cksumdl$$ > /tmp/cksumdiff$$ || {
echo "\n< actual"
echo "> expected"
cat /tmp/cksumdiff$$
echo "Digests do not match. Please confirm that \c"
echo "${image} files exist"
echo "and should be used, or retry downloading mismatched files."
rm -f /tmp/cksum*$$
echo "Exiting."
exit 1
}
echo "done. Digests match.\n"
rm -f /tmp/cksum*$$
fi

# determine number of segments for the image, used to uncompress in a loop


typeset -i zipnum=1
while [ ! $zipnum -gt $ZIPCNT ]; do
if [ "$singlezip" == false ]; then
zipname=${image}_${zipnum}of$ZIPCNT.zip
else
zipname=${image}.zip
fi
if [ ! -f $ZIPLOC/$zipname ]; then
echo "One or more download files are missing."
echo "$ZIPLOC contains:"
ls -1 $ZIPLOC | egrep "$image.*of.*.zip"
echo "Exiting."
exit 1
fi
echo "Uncompressing $zipname...\c"
# ignore if files are already in repo. Only report failures
unzip -qd $REPOLOC $zipreplace $ZIPLOC/$zipname $zipkeep 2>/dev/null|| {
echo "\nERROR: Unzip of $zipname failed."
echo "Use -c option for digest compare."
echo "Script can be re-run after problem has been addressed."
echo "If new repo was created, then remove before restarting."
echo "Exiting."
exit 1
}
echo "done."
# Get next segment
zipnum=zipnum+1
done
echo "Repository can be found in $REPOLOC."

# if adding to existing repo, rebuild catalog and index


if [ "$rebuild" == true ]; then
pkgrepo -s $REPOLOC rebuild || exit 1
fi

if [ "$verify" == true ]; then


# pkgrepo verify is only available on s11.1.7 and above
typeset currvers=$(pkg list -H entire 2> /dev/null | \
awk '{print $2}' | sed "s/.*-//")
if [ -z "$currvers" ]; then
echo "pkg:/entire is not installed on this system."
echo "Cannot confirm minimum OS for verification. No \c"
echo "verification done."
else
majnum=$(echo $currvers | awk -F. '{print $2}')
minnum=$(echo $currvers | awk -F. '{print $3}')
srunum=$(echo $currvers | awk -F. '{print $4}')
bldnum=$(echo $currvers | awk -F. '{print $6}')
if [ $majnum -eq 175 -a $minnum -le 1 ]; then
if [ "$majnum.$minnum" == "175.1" -a $srunum -ge 7 ]; then
:
else
echo "Skipping verify option - not supported on \c"
echo "this server."
fi
else
# starting at s12.0 bld 63, verify includes dependency checks
# sparse repos will fail unless option is disabled
if [ $majnum -ge 12 -a $bldnum -ge 63 ]; then
ignoredeps="--disable dependency"
fi
pkgrepo -s $REPOLOC verify $ignoredeps || exit 1
fi
fi
fi

if [ "$mkiso" == true ]; then


echo "Building ISO image...\c"
VNAME=$(echo $solimage | /usr/gnu/bin/tr 'a-z' 'A-Z' |
sed "s/-REPO/_REPO/")
cd $REPOLOC
# unbundled products may not have top-level copyright files
if $(ls $OSTOPLEVEL > /dev/null 2>&1) ; then
typeset TOPLEVEL=$OSTOPLEVEL
else
typeset TOPLEVEL=
fi

# Use the graft-points option to allow relocation of the repository itself


# into a repo subdirectory on the ISO
/usr/bin/mkisofs -o $ZIPLOC/$solimage.iso -no-limit-pathtables \
-l -allow-leading-dots -A "Oracle Solaris $solimage Release Repository" \
-publisher "Copyright 2017 Oracle and/or its affiliates. All rights reserved." \
-p pkg-inquiry_ww@oracle.com -R -uid 0 -gid 0 -V ${VNAME} -v -graft-points \
repo/publisher=publisher repo/pkg5.repository=pkg5.repository $TOPLEVEL \
README-repo-iso.txt > $ZIPLOC/mkiso.log 2>& 1
if [ $? -gt 0 ]; then
echo "\nError generating ISO file. Please check \c"
echo "$ZIPLOC/mkiso.log for errors."
fi
echo "done."
echo "ISO image can be found at:"
echo "$ZIPLOC/${solimage}.iso"
echo "Instructions for using the ISO image can be found at:"
echo "$REPOLOC/README-repo-iso.txt"
fi

Vous aimerez peut-être aussi