**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