aboutsummaryrefslogtreecommitdiff
path: root/bin/InstallPackage-RPM
diff options
context:
space:
mode:
Diffstat (limited to 'bin/InstallPackage-RPM')
-rwxr-xr-xbin/InstallPackage-RPM508
1 files changed, 0 insertions, 508 deletions
diff --git a/bin/InstallPackage-RPM b/bin/InstallPackage-RPM
deleted file mode 100755
index 099f670..0000000
--- a/bin/InstallPackage-RPM
+++ /dev/null
@@ -1,508 +0,0 @@
-#!/bin/bash
-
-source ScriptFunctions
-Import File
-Import GoboLinux
-Import Log
-Import OptionParser
-
-### Options ###################################################################
-
-scriptDescription="Install RPM and DEB packages on GoboLinux."
-scriptCredits="Copyright (C) Lucas C. Villa Real, 2016,2017 - Released under the GNU GPL."
-helpOnNoArguments=yes
-scriptUsage="<file.rpm> [file.rpm]"
-scriptExample="xispita-2.0.3-1.x86_64.rpm"
-
-Add_Option_Entry "n" "app-name" "Override program name"
-Add_Option_Entry "e" "version-number" "Override program version number"
-Add_Option_Entry "l" "symlink" "If symlinks should be created and wether they should be forced on conflicts." "yes" "yes no force"
-Add_Option_Boolean "W" "no-web" "Do not search the web to resolve dependencies."
-Parse_Options "$@"
-
-### Functions #################################################################
-
-function fetch_package() {
- local inputfile="$1"
- local filename=$(basename "$inputfile")
- if Is_URL "$inputfile"
- then
- if wget --help | grep -q "no-check-certificate"
- then wget_cmd="wget --no-check-certificate"
- else wget_cmd="wget"
- fi
- Quiet ${wget_cmd} -c "${inputfile}" -O "${goboTemp}/${filename}" || Die "Error downloading package."
- echo "${goboTemp}/${filename}"
- else
- echo "$inputfile"
- fi
-}
-
-function uncompress_package() {
- local inputfile="$1"
- thirdparty_uncompress "$inputfile"
-}
-
-function determine_flattening_level() {
- local rootdirs="bin$\|sbin$\|lib$\|lib64$\|libexec$\|include$\|share$"
- local filenames=$(for i in "${inputfiles[@]}"; do thirdparty_filenames $i; done)
-
- Log_Verbose "$filenames"
- if echo "$filenames" | grep -q "/opt/$rootdirs"
- then
- # 1-level /opt hierarchy
- echo "1"
- elif echo "$filenames" | grep -q "/opt/[^/]*/$rootdirs"
- then
- # 2-level /opt hierarchy
- echo "2"
- elif echo "$filenames" | grep -q "/opt"
- then
- # Get the longest common prefix among the $filenames list that starts
- # with "/opt" and then determine how many path levels we have there.
- local commonprefix=$(echo "$filenames" | grep "/opt" | sed -e 'N;s/^\(.*\).*\n\1.*$/\1\n\1/;D')
- local numslashes=$(echo "$commonprefix" | grep -o "/" | wc -l)
- let numslashes=numslashes-1
- if [ "$numslashes" = 1 ]
- then
- Log_Verbose "Package seems to have a 1-level /opt structure"
- echo "1"
- elif [ "$numslashes" = 2 ]
- then
- Log_Verbose "Package seems to have a 2-level /opt structure"
- echo "2"
- else
- Log_Error "Could not determine this package's /opt structure, assuming 2-level"
- echo "2"
- fi
- fi
-}
-
-function flatten_package() {
- local inputfile="$1"
-
- Log_Normal "Flattening directory structure."
-
- function create_opt_links() {
- local vendordir="$1"
- local unmanagedopt="Resources/Unmanaged/opt"
- for pkgdir in $(basename --multiple ./opt/$vendordir/*)
- do
- mkdir ${verbose} -p "${unmanagedopt}/$vendordir/$pkgdir"
- if [ -h "/opt/$vendordir/$pkgdir" ]
- then
- Log_Error "Too many programs are attempting to populate /opt/$vendordir/$pkgdir"
- Log_Error "This feature is not supported by InstallPackage-RPM at this time."
- continue
- fi
- for optfile in $(basename --multiple ./opt/$vendordir/$pkgdir/*)
- do
- if [ ! -e "${unmanagedopt}/$vendordir/$pkgdir/$optfile" ]
- then
- ln ${verbose} -fs $target/$optfile "${unmanagedopt}/$vendordir/$pkgdir/$optfile"
- fi
- done
- done
- }
-
- function flatten_opt_1_level() {
- # Flatten 1-level dir: opt/pkgname/{bin,sbin,...}
- cp ${verbose} -a ./opt/*/* .
- create_opt_links ""
- realpath ./opt/* | sed "s,$(realpath $PWD),,g" >> Resources/UnmanagedFiles
- }
-
- function flatten_opt_2_levels() {
- # Flatten 2-levels dir: opt/vendorname/pkgname/{bin,sbin,...}
- cp ${verbose} -a ./opt/*/*/* .
- for vendordir in $(basename --multiple ./opt/*)
- do
- create_opt_links "$vendordir"
- done
- realpath ./opt/*/* | sed "s,$(realpath $PWD),,g" >> Resources/UnmanagedFiles
- }
-
- if [ -d "./usr" ]
- then
- cp ${verbose} -a ./usr/* .
- rm -rf -- ./usr
- fi
- if [ -d "./etc" ]
- then
- mkdir -p Resources/Defaults/Settings
- mv ${verbose} ./etc/* Resources/Defaults/Settings
- rm -rf -- ./etc
- fi
- if [ -d "./lib64" ]
- then
- Quiet rmdir lib
- if [ ! -d "./lib" ]
- then mv ./lib64 lib
- else cp -a ./lib64/* ./lib/
- fi
- rm -rf ./lib64
- fi
- if [ -d "./var" ]
- then
- mkdir -p Resources/Unmanaged/$goboVariable
- find ./var | sed "s,./var,$goboVariable,g" >> Resources/UnmanagedFiles
- mv ${verbose} ./var/* Resources/Unmanaged/$goboVariable
- rm -rf -- ./var
- fi
- if [ -d "./opt" ]
- then
- # Prevent the creation of backlinks to directories that would be pruned later on
- find share -type d | xargs rmdir -p --ignore-fail-on-non-empty
- rmdir * 2> /dev/null
- mkdir -p Resources/Unmanaged/opt
- if [ "$flatteninglevel" = "1" ]
- then
- Log_Verbose "Flattening 1-level /opt directory"
- flatten_opt_1_level
- elif [ "$flatteninglevel" = "2" ]
- then
- Log_Verbose "Flattening 2-level /opt directory"
- flatten_opt_2_levels
- fi
- rm -rf -- ./opt
- fi
- if [ -e Resources/UnmanagedFiles ]
- then
- # If multiple RPM files are being merged, then ensure we have no dups
- cat Resources/UnmanagedFiles | sort -n | uniq > x && mv x Resources/UnmanagedFiles
- fi
- rmdir * 2> /dev/null
-}
-
-function is_inputfile() {
- local dependency="$1"
- local pkgname=$(echo "$dependency" | cut -d'(' -f1 | awk {'print $1'})
- printf "%s\n" "${inputnames[@]}" | grep -q "^${pkgname}$" && return 0
- return 1
-}
-
-function populate_dependencies() {
- local inputfile="$1"
- thirdparty_dependencies "$inputfile" | while read dependency
- do
- if echo "$dependency" | grep -q "^/"
- then
- depinfo=$(take_dependency_from_path "$inputfile" "$dependency" "")
- if [ "$depinfo" ]
- then echo "$depinfo"
- else echo "# Unresolved path-based dependency: $dependency"
- fi
- elif echo "$dependency" | grep -q "^lib.*\.so*\|.*\.so\.*"
- then
- libname=$(echo "$dependency" | cut -d'(' -f1)
- wantedsymbol=$(echo "$dependency" | cut -d'(' -f2 | cut -d')' -f1)
- depinfo=$(take_dependency_from_path "$inputfile" "$goboLibraries/$libname" "$wantedsymbol")
- if [ "$depinfo" ]
- then echo "$depinfo"
- else echo "# Unresolved path-based library dependency: $dependency"
- fi
- elif is_basic_symbol "$dependency"
- then
- Log_Verbose "Skipping basic symbol: $dependency"
- elif is_inputfile "$dependency"
- then
- Log_Verbose "Skipping dependency passed as input file: $dependency"
- else
- depinfo=$(lookup_pkgname "$dependency")
- if [ "$depinfo" ]
- then echo "$depinfo"
- else echo "# Unresolved dependency: $dependency"
- fi
- fi
- done
-}
-
-function populate_resources() {
- local inputfile="$1"
- local arch=$(thirdparty_arch "$inputfile")
- local description=$(thirdparty_description "$inputfile")
- local release=$(thirdparty_release "$inputfile")
- local distro=$(thirdparty_distribution "$inputfile")
-
- Log_Normal "Populating Resources."
- mkdir -p Resources
-
- if [ "$arch" ]
- then echo "$arch" > Resources/Architecture
- else echo "$(uname -m)" > Resources/Architecture
- fi
- echo "$release" > Resources/Revision
-
- # Note that we never truncate neither Resources/PackageSource nor
- # Resources/Description or Resources/Dependencies. This is to
- # enable the installation of multiple RPM/DEB files under the same
- # /Programs entry while keeing metadata of all the original files
- # around.
-
- [ -e Resources/PackageSource ] && echo >> Resources/PackageSource
- echo "[File] $(basename $inputfile)" >> Resources/PackageSource
- echo "[Distribution] $distro" >> Resources/PackageSource
-
- if [ "$description" ]
- then
- [ -e Resources/Description ] && echo "" >> Resources/Description
- echo "[Name] $(thirdparty_name $inputfile)" >> Resources/Description
- echo "[Summary] $(thirdparty_summary $inputfile)" >> Resources/Description
- echo "[License] $(thirdparty_license $inputfile)" >> Resources/Description
- echo "[Description] $(thirdparty_description $inputfile)" >> Resources/Description
- echo "[Homepage] $(thirdparty_url $inputfile)" >> Resources/Description
- fi
-
- Log_Normal "Processing dependencies."
- alldeps=$(mktemp ThirdPartyInstaller.XXXXXXXXXX)
- populate_dependencies "$inputfile" >> Resources/Dependencies
- cat Resources/Dependencies | sort -n | uniq > "$alldeps"
- cat "$alldeps" > Resources/Dependencies
- rm -f -- "$alldeps"
-}
-
-function lookup_symbol() {
- local depname="$1"
- local testversion="$2"
- local arch="$3"
- local symbol="$4"
- local testarch=$(cat "$goboPrograms/$depname/$testversion/Resources/Architecture" 2> /dev/null)
-
- if [ "$testarch" ] && [ "$testarch" = "$arch" ]
- then
- Log_Verbose "Looking for symbol $symbol on $goboPrograms/$depname/$testversion/$path"
- if nm "$goboPrograms/$depname/$testversion/$path" 2> /dev/null | grep --max-count=1 -q "$symbol"
- then
- Log_Verbose "Match: $depname $testversion"
- echo "$depname $testversion"
- return 0
- fi
- fi
- return 1
-}
-
-function take_dependency_from_path() {
- # TODO since $2 may come in the form '/usr/lib/libfoo >= version', we have to pick the
- # path from the first part of the string. Right now we're using awk to get it, but that
- # will not work if the dependency path contains spaces.
-
- local inputfile="$1"
- local originalpath=$(echo "$2" | awk '{print $1}')
- local path=$(echo "$originalpath" | sed 's,/usr,,g')
- local symbol="$3"
- local fullpath="$(readlink -f $path)"
- local arch=$(thirdparty_arch "$inputfile")
- local distro=$(thirdparty_distribution "$inputfile")
-
- local depname=
- local depversion=
-
- if echo "$fullpath" | grep -q "^${goboPrograms}"
- then
- # If given, we search for the presence of @symbol on the given target file.
- # We iterate over different installations of the same program looking for
- # that symbol. If none of the installations have it, we fallback to printing
- # the dependency currently linked on /System/Index.
- #
- # Note that when iterating over installed programs we skip those entries whose
- # Resources/Architecture do not match the output of $(rpminfo --arch).
-
- depname=$(echo "$fullpath" | cut -d/ -f3)
- depversion=$(echo "$fullpath" | cut -d/ -f4)
- if [ "$symbol" ]
- then
- for testversion in $(ls $goboPrograms/$depname/ | grep -v "Settings\|Variable\|Current")
- do
- lookup_symbol "$depname" "$testversion" "$arch" "$symbol" && return 0
- done
- fi
-
- Log_Verbose "Fallback: $depname $depversion"
- echo "$depname $depversion"
- else
- # We have a path, but we don't have a link to that file under /System/Index.
- # Our first attempt is to search over the list of installed programs anyhow,
- # because some programs may not be currently activated.
-
- for fullpath in $(ls $goboPrograms/*/*/$path 2> /dev/null | grep -v "Current")
- do
- depname=$(echo "$fullpath" | cut -d/ -f3)
- testversion=$(echo "$fullpath" | cut -d/ -f4)
- [ -z "$depversion" ] && depversion="$testversion"
- Log_Verbose "Looking for symbol on candidate file $candidate ($depname, $testversion)"
- lookup_symbol "$depname" "$testversion" "$arch" "$symbol" && return 0
- done
-
- # We don't have a match. If we have a file name that satisfies the path but
- # that doesn't contain the requested symbol, we simply return that path.
-
- if [ "$depname" ] && [ "$depversion" ]
- then
- echo "$depname $depversion"
- return 0
- fi
-
- # We don't have a matching filename under /System/Index nor under /Programs/*/*.
- # What we do now is to query remote RPM/DEB databases to find which package hosts the
- # dependency file.
-
- if ! Boolean "no-web"
- then
- Log_Normal "Searching the remote $(thirdparty_backend) database for the package hosting $originalpath"
- depname=$(third_party_search_remotedb "$originalpath" "$arch" "$distro")
- if [ "$depname" ]
- then
- # TODO: we could now lookup the GoboLinux recipe store to find whether we
- # have it or not
- echo "$(GuessProgramCase $depname)"
- return 0
- fi
- fi
- fi
-}
-
-function lookup_pkgname() {
- local dependency="$1"
- local pkgname=$(echo "$dependency" | cut -d'(' -f1)
-
- # GoboLinux doesn't have "devel" packages like most mainstream distros do
- local goboname=$(echo "$pkgname" | sed 's,-devel$,,g')
-
- # Do we have a GoboLinux package installed with a matching name?
- for testname in $(ls $goboPrograms/)
- do
- # Case-insensitive comparison (requires Bash 4)
- if [ "${testname,,}" = "${pkgname,,}" ] || [ "${testname,,}" = "${goboname,,}" ]
- then
- echo "$testname" && return 0
- fi
- done
-
- # Query the GoboLinux recipe store.
- if ! Boolean "no-web"
- then
-
- local recipeurl=$(FindPackage -t recipe "${pkgname}" || FindPackage -t recipe "${goboname}")
- if [ "$recipeurl" ]
- then
- # TODO we're potentially discarding the wanted version(s) of the given dep
- echo "$(basename $recipeurl | sed 's,\(.*\)--.*--.*,\1,g')" && return 0
- fi
- fi
-
- # TODO Query the remote RPM database for $pkgname
-
- # TODO Query the remote DEB database for $pkgname
-
- return 1
-}
-
-function is_basic_symbol() {
- local dependency="$1"
- echo "$dependency" | grep -q "^rtld(" && return 0
- return 1
-}
-
-function deduce_program_name() {
- local inputfile="$1"
- local name=$(thirdparty_name "$inputfile")
- echo $name
-}
-
-function prepare_program_entry() {
- local inputfile="$1"
-
- if [ ${#inputfiles[@]} -gt 1 ] && Is_Entry "app-name" && [ ! -z "$programname" ]
- then
- # We have already prepared this program's entry on /Programs
- return
- fi
- if Is_Entry "app-name"
- then programname=$(Entry "app-name")
- else programname="$(deduce_program_name $inputfile)"
- fi
- if Is_Entry "version-number"
- then programversion=$(Entry "version-number")
- else programversion=$(printf "%s_%s" $(thirdparty_version "$inputfile") $(thirdparty_release "$inputfile"))
- fi
-
- # Prepare /Programs tree and update program name (PrepareProgram may have changed its case)
- PrepareProgram -t "$programname" "$programversion"
- programname=$(ls $goboPrograms/ | grep -i "^${programname}$")
- target="$goboPrograms/$programname/$programversion"
-}
-
-### Operation #################################################################
-
-Is_Writable "${goboPrograms}" || Verify_Superuser
-
-if Boolean "verbose"
-then verbose="--verbose"
-else verbose=
-fi
-
-# The inputfiles array holds the full path of all RPM/DEB input files
-# The inputnames array holds the package name of all RPM/DEB input files
-inputfiles=()
-inputnames=()
-rpmcount=0
-debcount=0
-eval `Args_To_Array inputfiles_`
-for entry in "${inputfiles_[@]}"
-do
- inputfiles+=( "$(readlink -f ${entry} || echo ${entry})" )
- inputnames+=( "$(rpminfo --name $entry)" )
- echo "$entry" | grep -qi "\.deb" && let debcount=debcount+1
- echo "$entry" | grep -qi "\.rpm" && let rpmcount=rpmcount+1
-done
-
-# Sanity checks, then import the backend to handle the package format
-if [ $rpmcount -gt 0 ] && [ $debcount -gt 0 ]
-then
- Die "Error: cannot handle both RPM and DEB files in a single shot."
-elif [ $rpmcount -gt 0 ]
-then
- Import RPM
-elif [ $debcount -gt 0 ]
-then
- Import DEB
-fi
-
-# These will be set by prepare_program_entry()
-unset programname
-unset programversion
-unset target
-
-# Determine the flattening level of /opt. In other words, whether
-# we have something like:
-# /opt/pkgname/{bin,sbin...} (1-level), or
-# /opt/vendorname/pkgname/{bin,sbin...} (2-level)
-
-flatteninglevel=$(determine_flattening_level)
-
-# Installation pipeline
-for entry in "${inputfiles[@]}"
-do
- Log_Normal "Processing $(basename $entry)"
- inputfile=$(fetch_package "$entry")
- prepare_program_entry "$inputfile"
- Quiet pushd "$target" || Die "Could not enter $target"
-
- uncompress_package "$inputfile"
- flatten_package "$inputfile"
- populate_resources "$inputfile"
-
- Quiet popd
- Is_URL "$entry" && rm -f -- "$inputfile"
-done
-
-# Symlinking
-if [ $(Entry "symlink") = "no" ]
-then
- Log_Normal "Done."
- exit 0
-fi
-
-[ -d "$target/Resources/Defaults/Settings" ] && UpdateSettings "$programname" "$programversion"
-SymlinkProgram "$programname" "$programversion"
-Log_Normal "Done."