**opsi-info**
opsi-info.sh
shell script to change version information of available opsi packages
**Features:**
- Display Version and package-version of any opsi product
- Edit Version and package-version of any opsi product
- Change Product version if defined in setup script (setup.ins)
updates this File String in setup.ins:
Set $ProductVersion$ = "24.1.1"
replacing the version number can be useful if you use the version as parameter in your setup script, for example
"%ScriptPath%\files\Firefox Setup $ProductVersion$esr.exe" -ms -ira
This means, updating Firefox would just require you to place the new setup exe file inside "%ScriptPath%\files\"
then setting the the new version with opsi-info.sh
- optionally set "setup" action for the updated product on all clients with the product already installed
Download Link here: http://islamadel.com/en/downloads?func=fileinfo&id=12
############################
opsi-info : view / edit opsi package information
usage:
opsi-info [arguments]
arguments:
-h : display help
-prod [product-id] : view / edit info for product-id
-ver [decimal] : set decimal value for product version
-pver [integer] : set value for package version
example: opsi-info.sh -prod internet_firefox -ver 25.0.1
sets new version "25.0.1" for product-id "internet_firefox"
############################
**opsi-info.sh**
#!/bin/bash
###############
# opsi-info
# read / edit opsi-package info
# By Islam Adel
###############
#usage: opsi-info -h (help file)
###############
#change log:
# 2013-09-02 view, edit product version, depot file autodetection
# 2013-09-03 view, edit package version, backup all edited files
# 2013-12-10 added option to update clients with product already installed, set correct file rights for edited files
# target: - prompt for software setup on all clients with status "installed"
# General-Info to find installed product on client:
# installed info:
# in /home/opsiproducts/client-name.ini
# internet_firefox = installed:none
# function:
# Find string "internet_firefox = installed:none" all "*.ini" Files in "/home/opsiproducts/" (replace internet_firefox by product name)
#
# Set for setup
# change from "internet_firefox = installed:none"
# to: "internet_firefox = installed:setup"
#
#target: - read/edit opsi package information
# - list all package-ids
# - error verification / reporting
# - read / edit package version
# - backup all relevant files
# - fix conflict if product version = package version
#to-do: auto detect depot files
#input: arguments 1. option, 2. product_id, 3. value
# option: -ver (product version)
######################
# global variables
ver="13.12.10"
#set loop delimiter as "newline"
IFS=$'\n'
#current_date_time
NOW="$(date '+%Y-%m-%d_%H-%M-%S')"
######################
# user variables
# opsi="local" #for local test
# opsi="remote" #for remote usage on server
opsi="remote"
######################
#functions
#error message
error() {
echo "ERROR: $@"
echo
# echo "use -h argument for help"
# echo
#exit
}
#display hel
f_printUsage() {
echo "opsi-info : view / edit opsi package information"
echo
echo "usage:"
echo
echo "opsi-info [arguments]"
echo
echo "arguments:"
echo
echo "-h : display help"
echo "-prod [product-id] : view / edit info for product-id"
#echo "-ver | --version : view current product version"
echo "-ver [decimal] : set decimal value for product version"
#echo "-pver | --pkgversion : view current package version"
echo "-pver [integer] : set value for package version"
echo
echo
echo "example: opsi-info.sh -prod internet_firefox -ver 25.0.1"
echo " sets new version \"25.0.1\" for product-id \"internet_firefox\""
echo
exit
}
# read all passed arguments
f_GetArgs() {
#echo "all args=[${@}]"
#echo "number of args=[${#}]"
#echo "1=${1}"
#echo "2=${2}"
#echo "3=${3}"
#echo "4=${4}"
i=0
argv=()
for arg in "$@"; do
argv[$i]="$arg"
i=$((i + 1))
#debug# echo $i=$arg
done
# Handle OPTIONS and build directory array
#n_threads=1
#check_env=1
#run_jobs=0
#set_version="3c4n.15"
#is_2010=""
i=0
dir_index=0
while test $i -lt $# ; do
arg="${argv[$i]}"
case "$arg" in
#--2010) is_2010="--2010";;
-h|--help) f_printUsage;;
#-j|--jobs) i=$((i + 1)); n_threads=${argv[$i]};;
#-rj|--run-jobs) run_jobs=1;;
#--no-env-check) check_env=0;;
#verify decimal value before setting
--version|-ver) i=$((i + 1)); if [ "$(echo "${argv[$i]}" | tr -d ".")" -eq "$(echo "${argv[$i]}" | tr -d ".")" ] > /dev/null 2>&1; then new_version="${argv[$i]}"; else error "value for -ver must be decimal"; fi;;
#verify integer value before setting
--pkgversion|-pver) i=$((i + 1)); if [ "$(echo "${argv[$i]}")" -eq "$(echo "${argv[$i]}")" ] > /dev/null 2>&1; then new_pkg_version="${argv[$i]}"; else error "value for -pver must be an integer";fi;;
--product|-prod) i=$((i + 1)); product="${argv[$i]}";;
*) if ! test -d "$arg" ; then
error "Unknown argument or directory '$arg'"; exit
else
source_dirs[$dir_index]="$arg"
dir_index=$((dir_index + 1))
fi;;
esac
i=$((i + 1))
done
}
# input file
f_Depot() {
#autodetect depot file
if [ "$opsi" == "remote" ]; then depot_dir="/var/lib/opsi/config/depots/"; fi
#local_test
if [ "$opsi" == "local" ]; then depot_dir="/Users/islam/Documents/rechnerpool/opsi/updater/opsi-server/config/depots/"; fi
dep=0
for d in $(ls "$depot_dir"*.ini 2>/dev/null | xargs -n1 basename); do
# add depot number
dep=$((dep + 1))
dep_[$i]="$d"
#echo "$d"
#prompt to choose depot number if multiple found
depot_name="$d"
depot="$depot_dir""$d"
#echo $depot_name
#echo $depot
if [ "$dep" -gt "1" ]; then
echo "[ $dep ] depots have been found"
echo "using: $depot"
#add this feature later, to choose depot number
fi
done
if [ ! "$depot" ]; then error "No Depot has been found in: $depot_dir"; exit ; fi
depot_bak_dir="$depot_dir""archiv/"
depot_bak_file="$depot_bak_dir""$depot_name""_$NOW.bak"
#create backup folder if not exist
if [ ! -d "$depot_bak_dir" ]; then mkdir -p "$depot_bak_dir"; fi
#tmp files
depot_tmp1="$depot.1.tmp"
# remove existing tmp file
if [ -f $depot_tmp1 ]; then rm -f $depot_tmp1; fi
depot_tmp2="$depot.2.tmp"
if [ -f $depot_tmp2 ]; then rm -f $depot_tmp2; fi
}
#find clients with installed product and set for setup
f_UpdateClients() {
# Find string "internet_firefox = installed:none" all "*.ini" Files in "/home/opsiproducts/" (replace internet_firefox by product name)
# first find clients, display names and prompt
# use: grep -l "internet_firefox = installed:none" /var/lib/opsi/config/clients/*.ini
echo
echo "Searching for clients with [ ${product} ] status: installed .."
echo
# Set number of clients found with product already installed
updclient=0
#Path of clients Folder
clientspath="/var/lib/opsi/config/clients/"
#backup path for clients
client_bak_dir="/var/lib/opsi/config/clients/archiv/"
#create backup folder if not exist
if [ ! -d "$client_bak_dir" ]; then mkdir -p "$client_bak_dir"; fi
# find all clients with product already installed and not set to setup
for c in $(grep -l "${product} = installed:none" "${clientspath}"*.ini 2>/dev/null); do
# print client names with product already installed, trim .ini extension
# print client name only - trim .ini extension, trim dir path
#echo ${c%.ini}
echo "$(echo ${c%.ini} | xargs -n1 basename)"
# Add number of clients and check later if results >0
updclient=$((updclient + 1))
done
#If results found, begin interaction
if [ "${updclient}" == "0" ]; then
# message if search results is 0
echo
echo "[ ${product} ] is not installed on any client."
echo
else
echo
echo "[ ${updclient} ] clients found."
echo
# Now ask if setup action should be set.
###
read -n1 -p " Set SETUP action for [ ${product} ] on listed clients ? : [ y=Yes | n=No ]: [Default: y ] "
case "${REPLY}" in
# use last path accepted
"" | "y" | "Y" | "yes" | "Yes")
# yes I want to set product for setup on clients
#echo
echo "Setting SETUP action.."
echo
for c in $(grep -l "${product} = installed:none" "${clientspath}"*.ini 2>/dev/null); do
# print client names with product already installed, trim .ini extension
#echo ${c%.ini}
# Add number of clients and check later if results >0
#updclient=$((updclient + 1))
# backup client files first
#cp -f "${c}" "${c}_$NOW.bak"
# backup original file to backup dir, trimming source file name only adding date.bak as suffix
cp -f "${c}" "${client_bak_dir}$(echo ${c} | xargs -n1 basename)_$NOW.bak"
# begin replacing string into tmp file
cat "${c}" | sed 's/'${product}' = installed:none/'${product}' = installed:setup/g' >"${c}".tmp
# replace tmp file with original file
mv -f "${c}".tmp "${c}"
# set file rights
chown opsiconfd:opsifileadmins "${c}"
chmod 660 "${c}"
#verify edit
if grep -q "${product} = installed:setup" "${c}"
then
# code if found
echo "OK: SETUP action set for: $(echo ${c} | xargs -n1 basename)"
else
# code if not found
error "SETUP action NOT set for: $(echo ${c} | xargs -n1 basename)"
fi
done
;;
# skip file, any other entry
*)
# Any other answer is now
# No changes
echo "No clients have been modified."
echo
;;
esac
fi
}
#version info in install script
f_Install() {
if [ "$opsi" == "remote" ]; then inst_dir="/opt/pcbin/install/""$product"/; fi
#local_test
if [ "$opsi" == "local" ]; then inst_dir="/Users/islam/Documents/rechnerpool/opsi/updater/opsi-server/install/""$product"/; fi
setup_file="setup.ins"
setup_bak_dir="$inst_dir""archiv/"
setup_bak_file="$setup_bak_dir""$setup_file""_$NOW.bak"
#create backup folder if not exist
if [ ! -d "$setup_bak_dir" ]; then mkdir -p "$setup_bak_dir"; fi
#Set $ProductVersion$ = "17.0.7"
if [ -f "$inst_dir""$setup_file" ]; then
#echo "setup.ins found"
#change version info in setup-script
#echo "-----------" $old_version
#cat "$inst_dir""$setup_file" | grep "Set \$ProductVersion\$ = \"$old_version"
#echo "-----------"
#backup
cp -f "$inst_dir""$setup_file" "$setup_bak_file"
cat "$inst_dir""$setup_file" | sed 's/Set \$ProductVersion\$ = "'$old_version'"/Set \$ProductVersion\$ = "'$new_version'"/g' >"$inst_dir""$setup_file".tmp
mv -f "$inst_dir""$setup_file".tmp "$inst_dir""$setup_file"
# set file rights
chown opsiconfd:opsifileadmins "$inst_dir""$setup_file"
chmod 660 "$inst_dir""$setup_file"
#verify edit
if grep -q "Set \$ProductVersion\$ = \"$new_version\"" "$inst_dir""$setup_file"
then
# code if found
echo "OK: ProductVersion replaced in $setup_file"
else
# code if not found
error "ProductVersion NOT replaced in $setup_file"
fi
fi
}
# products info
f_Product() {
if [ "$opsi" == "remote" ]; then product_dir="/var/lib/opsi/config/products/"; fi
#local test
if [ "$opsi" == "local" ]; then product_dir="/Users/islam/Documents/rechnerpool/opsi/updater/opsi-server/config/products/"; fi
#echo "$new_version"
#echo "$product"
#read pkg_ver
#set old packageversion if new is not defined
if [ ! "$new_pkg_version" ]; then new_pkg_version="$old_pkg_version"; fi
#set old product version if new is not defined
if [ ! "$new_version" ]; then new_version="$old_version"; fi
#prod_pkg_ver="$old_pkg_version"
#identify type .localboot or .netboot #later feature
product_file_old="$product"_"$old_version"-"$old_pkg_version".localboot
product_file_new="$product"_"$new_version"-"$new_pkg_version".localboot
# echo
# echo old_version="$old_version"
# echo new_version="$new_version"
# echo old_pkg_version="$old_pkg_version"
# echo new_pkg_version="$new_pkg_version"
product_bak_dir="$product_dir""archiv/"
product_bak_file="$product_bak_dir""$product_file_old""_$NOW.bak"
#create backup folder if not exist
if [ ! -d $product_bak_dir ]; then mkdir -p $product_bak_dir; fi
#check if product file exists
if [ -f "$product_dir""$product_file_old" ]; then
#### rename product file
#backup file? #later
cp -f "$product_dir""$product_file_old" "$product_bak_file"
mv -f "$product_dir""$product_file_old" "$product_dir""$product_file_new"
#check if renamed file exists? #later_feature
#### change file version in content
case "$change" in
1) # change product version
cat "$product_dir""$product_file_new" | sed 's/version: '$old_version'/version: '$new_version'/g' >"$product_dir""$product_file_new".tmp
mv -f "$product_dir""$product_file_new".tmp "$product_dir""$product_file_new"
# verify change, #later
# cat "$product_dir""$product_file_new" | grep version: '$new_version'
# set file rights
chown opsiconfd:opsifileadmins "$product_dir""$product_file_new"
chmod 660 "$product_dir""$product_file_new"
#### change file version in setup script
f_Install
### update installed clients
f_UpdateClients
;;
3) # change package version / sed ====> first match for version: only / first occurence
cat "$product_dir""$product_file_new" | awk '/version: '$old_pkg_version'/{if (M==""){sub("version: '$old_pkg_version'","version: '$new_pkg_version'");M=1}}{print}' >"$product_dir""$product_file_new".tmp
# all occurences
#cat "$product_dir""$product_file_new" | sed 's/version: '$old_pkg_version'/version: '$new_pkg_version'/g' > "$product_dir""$product_file_new".tmp
mv -f "$product_dir""$product_file_new".tmp "$product_dir""$product_file_new"
# set file rights
chown opsiconfd:opsifileadmins "$product_dir""$product_file_new"
chmod 660 "$product_dir""$product_file_new"
;;
4) #change prod. version first, then pkg version
cat "$product_dir""$product_file_new" | sed 's/version: '$old_version'/version: '$new_version'/g' >"$product_dir""$product_file_new".tmp
cat "$product_dir""$product_file_new".tmp | awk '/version: '$old_pkg_version'/{if (M==""){sub("version: '$old_pkg_version'","version: '$new_pkg_version'");M=1}}{print}' >"$product_dir""$product_file_new"
#mv -f "$product_dir""$product_file_new".tmp2 "$product_dir""$product_file_new"
# set file rights
chown opsiconfd:opsifileadmins "$product_dir""$product_file_new"
chmod 660 "$product_dir""$product_file_new"
#### change file version in setup script
f_Install
### update installed clients
f_UpdateClients
;;
esac
if [ -f "$product_dir""$product_file_new".tmp ]; then rm -f "$product_dir""$product_file_new".tmp; fi
else
error "Product file: [ $product_file_old ] not found in: [ $product_dir ]"
#restore backed up file
mv -f $depot_bak_file $depot
# set file rights
chown opsiconfd:opsifileadmins $depot
chmod 660 $depot
fi
}
######################
#script start
echo
echo "#################################"
echo "# #"
echo "# opsi-info version: $ver #"
echo "# #"
echo "# use -h for help #"
echo "# #"
echo "#################################"
echo
# read arguments
f_GetArgs $@
f_Depot
#display values
#echo "using depot file :"
#echo " $depot"
#echo ver = $new_version
#echo product = $product
#read depot file
# sed '/^start_string/s/search_string/replace_string/'
# replace line starting with "[" by "@"
# replace new lines by ";"
# replace "@" by "new line"
# replace ";;" by ";"
# replace ";" by "newline"
#cat $depot | sed '/^\[/s/\[/@\[/' | tr '\n' ';' | tr '@' '\n' | sed 's/;;/;/g' | tr ';' '\n'
#create tmp file and change structure for search
cat $depot | sed '/^\[/s/\[/@\[/' | tr '\n' ';' | tr '@' '\n' > $depot_tmp1
# find line with product name and replace string (version value) till ";"
found=0
change=0
for v in $(cat $depot_tmp1 | grep "\[$product-state\]"); do
found=$((found + 1))
if [ "$found" == "1" ]; then
# must find 1 instance only - replace only one product
# read current version
#last working: old_version=$(echo $v | sed 's/\[.*productversion.*= //g' | tr -d ";")
old_version=$(echo "$v" | sed -e 's/^.*productversion = \([.[:digit:]]*\);.*$/\1/g')
old_pkg_version=$(echo "$v" | sed -e 's/^.*packageversion = \([.[:digit:]]*\);.*$/\1/g')
# echo old_version="$old_version"
# echo new_version="$new_version"
# echo old_pkg_version="$old_pkg_version"
# echo new_pkg_version="$new_pkg_version"
# echo v="$v"
#edit only if new_version is defined
if [ "$new_version" ]; then
change=$((change + 1))
# replace old version with new, retain whole string
n=$(echo "$v" | sed -e 's/productversion = '$old_version';/\productversion = '$new_version';;/g')
#echo n="$n"
#exit
echo "replacing product version for: [ $product ], from: [ $old_version ] to: [ $new_version ]"
else
echo "current product version for: [ $product ], is: [ $old_version ]"
fi
#edit only if new_pkg_version is defined
if [ "$new_pkg_version" ]; then
change=$((change + 3))
# replace old version with new, retain whole string
p=$(echo "$v" | sed -e 's/packageversion = '$old_pkg_version';/\packageversion = '$new_pkg_version';;/g')
echo "replacing package version for: [ $product ], from: [ $old_pkg_version ] to: [ $new_pkg_version ]"
else
echo "current package version for: [ $product ], is: [ $old_pkg_version ]"
fi
else
error "[ $found ] matches found for: $product "
fi
done
#case for changes
case "$change" in
# 0) echo "# nothing to change";;
1) #echo "# change version only"
# backup original depot file
cp -f $depot $depot_bak_file
# replace version info and retain original file structure
sed 's/\'$v'/\'$n'/g' $depot_tmp1 | sed 's/;;/;/g' | tr ';' '\n' >$depot
# set file rights
chown opsiconfd:opsifileadmins $depot
chmod 660 $depot
f_Product
;;
3) #echo "# change pkg version only"
# backup original depot file
cp -f $depot $depot_bak_file
sed 's/\'$v'/\'$p'/g' $depot_tmp1 | sed 's/;;/;/g' | tr ';' '\n' >$depot
# set file rights
chown opsiconfd:opsifileadmins $depot
chmod 660 $depot
# change further files
f_Product
;;
4) #echo "# change pver + ver"
p=$(echo "$n" | sed -e 's/packageversion = '$old_pkg_version';/\packageversion = '$new_pkg_version';;/g')
# backup original depot file
cp -f $depot $depot_bak_file
# replace version info and retain original file structure
sed 's/\'$v'/\'$p'/g' $depot_tmp1 | sed 's/;;/;/g' | tr ';' '\n' >$depot
# set file rights
chown opsiconfd:opsifileadmins $depot
chmod 660 $depot
# change further files
f_Product
;;
esac
# errors only if product / arguments specified
#echo $i
if [ "$i" -gt "0" ]; then
if [ "$found" == "0" ]; then error "no matching product found"; fi
else
error "no arguments specified"
echo "use -h argument for help"
fi
# file end
echo
echo "###############################"
echo
echo "process done."
# remove existing tmp file
if [ -f $depot_tmp1 ]; then rm -f $depot_tmp1; fi
if [ -f $depot_tmp2 ]; then rm -f $depot_tmp2; fi
echo
#read -p ""
#exit