Let my HOME alone 1/2
This commit is contained in:
parent
2ae37e902e
commit
a83e45df5e
94 changed files with 328 additions and 58 deletions
455
config/scripts/debloc
Executable file
455
config/scripts/debloc
Executable file
|
@ -0,0 +1,455 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# Installs Debian packages on a Debian system
|
||||
# with no root access, in the user home
|
||||
|
||||
# CONFIGURATION
|
||||
|
||||
# Verifications
|
||||
|
||||
if [[ -z $DEBIAN_MIRROR && ! -f /etc/apt/sources.list ]]; then
|
||||
echo "Unable to find a mirror. Try setting DEBIAN_MIRROR (see help)."
|
||||
exit 1
|
||||
fi
|
||||
if [[ -z $DEBIAN_DB && ! $(which apt &> /dev/null) ]]; then
|
||||
echo "Unable to find a database for packages to install. Try setting DEBIAN_DB (see help)."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Overrides
|
||||
|
||||
[ -z $DEBLOC_PREFIX ] && DEBLOC_PREFIX=$(dpkg --print-architecture)
|
||||
[ -z $DEBLOC_DB ] && DEBLOC_DB=${XDG_CONFIG_HOME:-$HOME/.config}/debloc/$DEBLOC_PREFIX
|
||||
[ -z $DEBLOC_ROOT ] && DEBLOC_ROOT=$HOME/.debloc/$DEBLOC_PREFIX
|
||||
DEBLOC_LD=$DEBLOC_ROOT/ld
|
||||
|
||||
if [ -z "$DEBIAN_MIRROR" ]; then
|
||||
DEBIAN_MIRROR="$(cat /etc/apt/sources.list | grep '^deb ' | grep main | grep -v backports)"
|
||||
DEBIAN_MIRROR="$(echo -e "$DEBIAN_MIRROR" | cut -d ' ' -f 2 | sed 's/\/$//' | sort | uniq)"
|
||||
fi
|
||||
|
||||
# Preparation
|
||||
|
||||
mkdir -p $DEBLOC_DB &> /dev/null
|
||||
mkdir -p $DEBLOC_ROOT &> /dev/null
|
||||
|
||||
# PRIVATE FUNCTIONS
|
||||
|
||||
# Tell if a package exists
|
||||
function _debloc-exists { # package
|
||||
if [[ -n $DEBIAN_DB && -f $DEBIAN_DB ]]; then
|
||||
grep "^Package: $1\$" $DEBIAN_DB --quiet
|
||||
else
|
||||
LANG=C apt-cache show $1 &> /dev/null
|
||||
fi
|
||||
if [ $? == 0 ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Return the real package associated with a virtual package
|
||||
# If not a virtual package, return the input
|
||||
function _debloc-filterVirtual { # package
|
||||
pkg=$1
|
||||
if [[ -n $DEBIAN_DB && -f $DEBIAN_DB ]]; then
|
||||
echo $pkg
|
||||
else
|
||||
LANG=C apt-cache policy $1 | grep "Candidate" | grep "(none)" > /dev/null
|
||||
if [ $? == 0 ]; then
|
||||
# TODO This is not really accurate
|
||||
LANG=C apt-cache showpkg $pkg | tail -1 | cut -d ' ' -f 1
|
||||
else
|
||||
echo $pkg
|
||||
fi
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Tell if a package is installed via debloc
|
||||
function _debloc-locallyInstalled { # package
|
||||
if [ -f $DEBLOC_DB/$1 ]; then
|
||||
return 1
|
||||
else
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Tell if a package is installed system-wide
|
||||
function _debloc-globallyInstalled { # package
|
||||
STATUS=$(mktemp)
|
||||
LANG=C dpkg --list $1 &> $STATUS
|
||||
if [ $? != 0 ]; then
|
||||
rm -f $STATUS > /dev/null
|
||||
return 0
|
||||
fi
|
||||
cat $STATUS | grep '^Status:' | grep ' installed' --quiet
|
||||
if [ $? != 0 ]; then
|
||||
rm -f $STATUS > /dev/null
|
||||
return 0
|
||||
else
|
||||
rm -f $STATUS > /dev/null
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Get informations about a package
|
||||
function _debloc-packageShow { # package
|
||||
pkg=$1
|
||||
if [[ -n $DEBIAN_DB && -f $DEBIAN_DB ]]; then
|
||||
startline=$(grep "^Package: ${pkg}\$" $DEBIAN_DB --line-number | tail -1 | cut -d ':' -f 1)
|
||||
if [ -z "$startline" ]; then
|
||||
return 0
|
||||
fi
|
||||
sed -n "$startline,$(expr $startline + 100)p" $DEBIAN_DB | while read line; do
|
||||
if [ -z "$line" ]; then
|
||||
return 0
|
||||
fi
|
||||
echo $line
|
||||
done
|
||||
return 1
|
||||
else
|
||||
LANG=C apt-cache show $pkg | while read line; do
|
||||
if [ -z "$line" ]; then
|
||||
return 0
|
||||
fi
|
||||
echo "$line"
|
||||
done
|
||||
return 0
|
||||
fi
|
||||
}
|
||||
|
||||
# Get the path of a package
|
||||
function _debloc-packagePath { # package
|
||||
_debloc-packageShow $1 | grep "^Filename:" | head -1 | cut -d ':' -f 2 | sed -e 's/^[[:space:]]*//'
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get the md5sum of a package
|
||||
function _debloc-packageMd5sum { # package
|
||||
_debloc-packageShow $1 | grep "^MD5sum:" | cut -d ':' -f 2 | sed -e 's/^[[:space:]]*//'
|
||||
return 0
|
||||
}
|
||||
|
||||
# Update symbolics links in $DEBLOC_ROOT/lib
|
||||
function _debloc-ldconfig {
|
||||
mkdir -p $DEBLOC_LD &> /dev/null
|
||||
rm -f $DEBLOC_LD &> /dev/null
|
||||
find $DEBLOC_ROOT{/usr,}/lib -type f -name "*.so*" | while read lib; do
|
||||
ln --symbolic --force "$lib" "$DEBLOC_LD/$(basename $lib)"
|
||||
done &> /dev/null
|
||||
find $DEBLOC_ROOT{/usr,}/lib -type l -name "*.so*" | while read link; do
|
||||
yes | cp --force --no-dereference --preserve=links "$link" "$DEBLOC_LD" &> /dev/null
|
||||
done &> /dev/null
|
||||
}
|
||||
|
||||
# Fix absolute symbolic links
|
||||
function _debloc-fixRootSymlinks {
|
||||
find $DEBLOC_ROOT -type l | while read src
|
||||
do
|
||||
dst="$(readlink "$src")"
|
||||
if echo "$dst" | grep '^/' | grep -q -v "^$DEBLOC_ROOT"
|
||||
then
|
||||
newDst="$DEBLOC_ROOT$dst"
|
||||
if [ -f "$newDst" ]
|
||||
then
|
||||
echo "$src → $newDst"
|
||||
rm "$src"
|
||||
ln -s "$newDst" "$src"
|
||||
else
|
||||
echo "Ignoring $src pointing to $dst"
|
||||
fi
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
function _debloc-fixPkgconfPrefix {
|
||||
sed "s|^prefix=/usr$|prefix=$DEBLOC_ROOT/usr|" $(find $DEBLOC_ROOT -type f -name "*.pc") -i
|
||||
}
|
||||
|
||||
function debloc_fix {
|
||||
echo "Fixing absolute symbolic links..."
|
||||
_debloc-fixRootSymlinks
|
||||
echo "Linking libraries in /ld"
|
||||
_debloc-ldconfig
|
||||
echo "Fixing prefix in pkg-config files"
|
||||
_debloc-fixPkgconfPrefix
|
||||
}
|
||||
|
||||
# Install debian archive
|
||||
function _debloc-installDeb { # path
|
||||
TMP_DIR=$(mktemp -d) &> /dev/null
|
||||
$(cd $TMP_DIR; ar x "$1")
|
||||
TAR_FILE=$(find $TMP_DIR -type f -name "data.tar.*" | head -1)
|
||||
if [ -e "$TAR_FILE" ]; then
|
||||
# Output for DB saving
|
||||
tar tf $TAR_FILE
|
||||
tar xf $TAR_FILE -C $DEBLOC_ROOT
|
||||
|
||||
# _debloc-ldconfig
|
||||
mkdir -p $DEBLOC_LD &> /dev/null
|
||||
tar tf $TAR_FILE | grep '^.\(/usr\)\?/lib/' | grep '\.so' | while read file; do
|
||||
lib=$(readlink -f $DEBLOC_ROOT/$file)
|
||||
if [ -f $lib ]; then
|
||||
ln --symbolic --force "$lib" "$DEBLOC_LD/$(basename $file)"
|
||||
fi
|
||||
if [ -h $lib ]; then
|
||||
yes | cp --force --no-dereference --preserve=links "$(basename $link)" "$DEBLOC_LD/" &> /dev/null
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
rm -rf $TMP_DIR &> /dev/null
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
# Install package
|
||||
function _debloc-install { # package
|
||||
pkg=$1
|
||||
|
||||
DEB_FILE=$(mktemp) &> /dev/null
|
||||
path=$(_debloc-packagePath $pkg)
|
||||
echo -e "${DEBIAN_MIRROR}" | while read mirror; do
|
||||
if [ -z "$mirror" ]; then
|
||||
continue
|
||||
fi
|
||||
url=${mirror}/${path}
|
||||
echo "→ Downloading $url"
|
||||
wget "$url" --quiet -O $DEB_FILE
|
||||
if [ $? == 0 ]; then
|
||||
break
|
||||
fi
|
||||
done
|
||||
if [ ! -s $DEB_FILE ]; then
|
||||
echo "→ Failed (no deb file)!"
|
||||
rm $DEBLOC_DB/$pkg &> /dev/null
|
||||
return 4
|
||||
fi
|
||||
|
||||
echo "→ Verifying sums"
|
||||
theo=$(_debloc-packageMd5sum $pkg)
|
||||
real=$(md5sum $DEB_FILE | cut -d ' ' -f 1)
|
||||
if [ "$theo" != "$real" ]; then
|
||||
rm -f $DEB_FILE &> /dev/null
|
||||
echo "→ Failed (sum doesn't match)!"
|
||||
rm $DEBLOC_DB/$pkg &> /dev/null
|
||||
return 5
|
||||
fi
|
||||
|
||||
echo "→ Installing"
|
||||
_debloc-installDeb $DEB_FILE > $DEBLOC_DB/$pkg
|
||||
|
||||
echo "→ Done!"
|
||||
rm -f $DEB_FILE &> /dev/null
|
||||
return 0
|
||||
}
|
||||
|
||||
# Get the dependencies of a package
|
||||
function _debloc-packageDeps { # package
|
||||
_debloc-packageShow $1 | grep '^Depends:' | sed 's/Depends: //' | sed 's/, /\n/g' | cut -d ' ' -f 1
|
||||
return 0
|
||||
}
|
||||
|
||||
# Install package with dependencies
|
||||
function _debloc-installDeps { # package
|
||||
pkg=$1
|
||||
echo "Installing $pkg"
|
||||
touch $DEBLOC_DB/$pkg # To prevent cyclic deps
|
||||
_debloc-packageDeps $pkg | while read dep; do
|
||||
dep=$(_debloc-filterVirtual $dep)
|
||||
_debloc-locallyInstalled $dep
|
||||
if [ $? == 1 ]; then
|
||||
echo "- Dependency $dep is already installed with Debloc"
|
||||
continue
|
||||
fi
|
||||
_debloc-globallyInstalled $dep
|
||||
if [ $? == 1 ]; then
|
||||
echo "- Dependency $dep is already installed on the system"
|
||||
continue
|
||||
fi
|
||||
_debloc-installDeps $dep | while read line; do echo "- $line"; done
|
||||
done
|
||||
_debloc-install $pkg
|
||||
return 0
|
||||
}
|
||||
|
||||
# PUBLIC FUNCTIONS
|
||||
|
||||
function proxy_set_help {
|
||||
echo "Usage: $0 env"
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo ' eval "$(debloc env)"'
|
||||
return 0
|
||||
}
|
||||
function debloc_env {
|
||||
echo "export PATH=\"$DEBLOC_ROOT/usr/bin:$DEBLOC_ROOT/usr/games/:$DEBLOC_ROOT/usr/lib/git-core:\$PATH\""
|
||||
echo "export LIBRARY_PATH=\"$DEBLOC_LD:\$LIBRARY_PATH\""
|
||||
echo "export C_INCLUDE_PATH=\"$DEBLOC_ROOT/usr/include:\$C_INCLUDE_PATH\""
|
||||
echo "export CPLUS_INCLUDE_PATH=\"$DEBLOC_ROOT/usr/include:$DEBLOC_ROOT/usr/include/python2.7/:$DEBLOC_ROOT/usr/include/x86_64-linux-gnu/python2.7/:\$CPLUS_INCLUDE_PATH\""
|
||||
echo "export LD_LIBRARY_PATH=\"$DEBLOC_LD:\$LD_LIBRARY_PATH\""
|
||||
echo "export PYTHONPATH=\"$DEBLOC_ROOT/usr/lib/python2/dist-packages:$DEBLOC_ROOT/usr/lib/python3/dist-packages:$DEBLOC_ROOT/usr/lib/python2.7/dist-packages:$DEBLOC_ROOT/usr/lib/python3.5/dist-packages:\$PYTHONPATH\""
|
||||
echo "export QT_QPA_PLATFORM_PLUGIN_PATH=\"$DEBLOC_ROOT/usr/lib/x86_64-linux-gnu/qt5/plugins/platforms\""
|
||||
echo "export PKG_CONFIG_PATH=\"$DEBLOC_ROOT/usr/share/pkgconfig/:$DEBLOC_ROOT/usr/lib/x86_64-linux-gnu/pkgconfig/:$DEBLOC_ROOT/usr/lib/pkgconfig/:\$PKG_CONFIG_PATH\""
|
||||
}
|
||||
|
||||
function debloc_info {
|
||||
echo "DEBLOC_PREFIX=$DEBLOC_PREFIX"
|
||||
echo "DEBLOC_ROOT=$DEBLOC_ROOT"
|
||||
echo "DEBLOC_DB=$DEBLOC_DB"
|
||||
echo "DEBLOC_LD=$DEBLOC_LD"
|
||||
echo "DEBIAN_MIRROR='$DEBIAN_MIRROR'"
|
||||
echo "DEBIAN_DB=$DEBIAN_DB"
|
||||
}
|
||||
|
||||
function debloc_install_help {
|
||||
echo "Usage: $0 install PACKAGE"
|
||||
echo
|
||||
echo "Arguments:"
|
||||
echo " PACKAGE Package name"
|
||||
return 0
|
||||
}
|
||||
|
||||
function debloc_install { # package
|
||||
if [ -z $1 ]; then
|
||||
debloc_deb_help
|
||||
fi
|
||||
for pkg in $*
|
||||
do
|
||||
if [ $pkg == '--force' ] || [ $pkg == '-f' ]; then
|
||||
force=0
|
||||
fi
|
||||
done
|
||||
for pkg in $*; do
|
||||
if [ $pkg == '--force' ] || [ $pkg == '-f' ]; then
|
||||
continue
|
||||
fi
|
||||
pkg=$(_debloc-filterVirtual $pkg)
|
||||
_debloc-exists $pkg
|
||||
if [ $? == 0 ]; then
|
||||
echo "Unknown package $pkg"
|
||||
continue
|
||||
fi
|
||||
if [ ! -v force ]; then
|
||||
_debloc-locallyInstalled $pkg
|
||||
if [ $? == 1 ]; then
|
||||
echo "Package $pkg is already installed with Debloc"
|
||||
continue
|
||||
fi
|
||||
_debloc-globallyInstalled $pkg
|
||||
if [ $? == 1 ]; then
|
||||
echo "Package $pkg is already installed on the system"
|
||||
continue
|
||||
fi
|
||||
fi
|
||||
_debloc-installDeps $pkg
|
||||
done
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
function debloc_deb_help {
|
||||
echo "Usage: $0 deb PATH"
|
||||
echo
|
||||
echo "Arguments:"
|
||||
echo " PATH Path to the .deb file"
|
||||
return 0
|
||||
}
|
||||
function debloc_deb { # path
|
||||
if [ -z $1 ]; then
|
||||
debloc_deb_help
|
||||
fi
|
||||
for path in $*; do
|
||||
if [ ! -f "$path" ]; then
|
||||
echo "$path is not a file"
|
||||
return 6
|
||||
fi
|
||||
echo "Installing $(basename $path)"
|
||||
_debloc-installDeb "$(readlink -f $path)" > $DEBLOC_DB/$(basename $path)
|
||||
done
|
||||
return 0
|
||||
|
||||
}
|
||||
|
||||
function debloc_altern_help {
|
||||
echo "Usage: $0 altern PROGRAM ALTERNATIVE"
|
||||
echo
|
||||
echo "Arguments:"
|
||||
echo " PROGRAM Program to set the alternative for"
|
||||
echo " ALTERNATIVE Alternative to set"
|
||||
echo
|
||||
echo "Examples:"
|
||||
echo " $0 altern vim nox"
|
||||
echo " $0 altern dmenu xft"
|
||||
return 0
|
||||
}
|
||||
function debloc_altern { # program alternative
|
||||
if [[ -z $1 || -z $2 ]]; then
|
||||
debloc_altern_help
|
||||
exit 1
|
||||
fi
|
||||
if [ -f "$DEBLOC_ROOT/usr/bin/$1.$2" ]; then
|
||||
dest="$DEBLOC_ROOT/usr/bin/$1"
|
||||
alte="$DEBLOC_ROOT/usr/bin/$1.$2"
|
||||
elif [ -f "$DEBLOC_ROOT/bin/$1.$2" ]; then
|
||||
dest="$DEBLOC_ROOT/bin/$1"
|
||||
alte="$DEBLOC_ROOT/bin/$1.$2"
|
||||
else
|
||||
echo "Unknown alternative for $1 : $2"
|
||||
exit 1
|
||||
fi
|
||||
if [ -e "$dest" ]; then
|
||||
rm $dest
|
||||
fi
|
||||
ln -s "$alte" "$dest"
|
||||
}
|
||||
|
||||
function debloc_flush {
|
||||
rm -rf $DEBLOC_ROOT/* &> /dev/null
|
||||
rm -f $DEBLOC_DB/* &> /dev/null
|
||||
}
|
||||
|
||||
# TODO Other word for 'fake filesystem' and/or explain what this is
|
||||
function debloc_help {
|
||||
command="$1"
|
||||
if [ -n "$command" ]; then
|
||||
if type "debloc_${command}_help" &> /dev/null; then
|
||||
shift
|
||||
"debloc_${command}_help" "$@"
|
||||
return $?
|
||||
fi
|
||||
fi
|
||||
echo "Usage: $0 COMMAND"
|
||||
echo
|
||||
echo "Commands:"
|
||||
echo " env Provides the environment variables required to run applications from the fake filesystem"
|
||||
echo " info Gives some information about the fake filesystem"
|
||||
echo " install Install a debian package in the fake filesystem"
|
||||
echo " deb Install from a .deb file in the fake filesystem"
|
||||
echo " altern Update alternative"
|
||||
echo " fix Apply some fixes in the fake filesystem"
|
||||
echo " flush Remove every package installed from the fake filesystem"
|
||||
echo " help Get help with commands"
|
||||
echo
|
||||
echo "Environment variables:"
|
||||
echo " DEBLOC_PREFIX Name of the fake filesystem to use (default: uses dpkg architecture)"
|
||||
echo " DEBLOC_ROOT Path of the fake filesystem (default: ~/.debloc/\$DEBLOC_PREFIX/)"
|
||||
echo " DEBLOC_DB Database of the fake filesystem (default: \$XDG_CONFIG_HOME/debloc/\$DEBLOC_PREFIX)"
|
||||
echo " DEBIAN_MIRROR Multiline list of debian mirror (default: uses /etc/apt/sources.list)"
|
||||
echo " DEBIAN_DB Path to a file with all packages description (default: uses apt-cache showpkg)"
|
||||
echo " help Get help with commands"
|
||||
return 0
|
||||
}
|
||||
|
||||
# MAIN
|
||||
|
||||
command="$1"
|
||||
shift
|
||||
if type "debloc_$command" &> /dev/null; then
|
||||
"debloc_$command" "$@"
|
||||
else
|
||||
debloc_help
|
||||
fi
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue