# Check either a package is installed or not # # example: ynh_package_is_installed 'yunohost' && echo "ok" # # usage: ynh_package_is_installed name # | arg: name - the package name to check ynh_package_is_installed() { dpkg-query -W -f '${Status}' "$1" 2>/dev/null \ | grep -c "ok installed" &>/dev/null } # Get the version of an installed package # # example: version=$(ynh_package_version 'yunohost') # # usage: ynh_package_version name # | arg: name - the package name to get version # | ret: the version or an empty string ynh_package_version() { if ynh_package_is_installed "$1"; then dpkg-query -W -f '${Version}' "$1" 2>/dev/null else echo '' fi } # APT wrapper for non-interactive operation # # [internal] # # usage: ynh_apt update ynh_apt() { DEBIAN_FRONTEND=noninteractive sudo apt-get -y $@ } # Update package index files # # usage: ynh_package_update ynh_package_update() { ynh_apt update } # Install package(s) # # usage: ynh_package_install name [name [...]] # | arg: name - the package name to install ynh_package_install() { ynh_apt --no-remove -o Dpkg::Options::=--force-confdef \ -o Dpkg::Options::=--force-confold install $@ } # Remove package(s) # # usage: ynh_package_remove name [name [...]] # | arg: name - the package name to remove ynh_package_remove() { ynh_apt remove $@ } # Remove package(s) and their uneeded dependencies # # usage: ynh_package_autoremove name [name [...]] # | arg: name - the package name to remove ynh_package_autoremove() { ynh_apt autoremove $@ } # Purge package(s) and their uneeded dependencies # # usage: ynh_package_autopurge name [name [...]] # | arg: name - the package name to autoremove and purge ynh_package_autopurge() { ynh_apt autoremove --purge $@ } # Build and install a package from an equivs control file # # [internal] # # example: generate an empty control file with `equivs-control`, adjust its # content and use helper to build and install the package: # ynh_package_install_from_equivs /path/to/controlfile # # usage: ynh_package_install_from_equivs controlfile # | arg: controlfile - path of the equivs control file ynh_package_install_from_equivs () { local controlfile=$1 # Check if the equivs package is installed. Or install it. ynh_package_is_installed 'equivs' \ || ynh_package_install equivs # retrieve package information local pkgname=$(grep '^Package: ' $controlfile | cut -d' ' -f 2) # Retrieve the name of the debian package local pkgversion=$(grep '^Version: ' $controlfile | cut -d' ' -f 2) # And its version number [[ -z "$pkgname" || -z "$pkgversion" ]] \ && echo "Invalid control file" && exit 1 # Check if this 2 variables aren't empty. # Update packages cache ynh_package_update # Build and install the package local TMPDIR=$(mktemp -d) # Force the compatibility level at 10, levels below are deprecated echo 10 > /usr/share/equivs/template/debian/compat # Note that the cd executes into a sub shell # Create a fake deb package with equivs-build and the given control file # Install the fake package without its dependencies with dpkg # Install missing dependencies with ynh_package_install (cp "$controlfile" "${TMPDIR}/control" && cd "$TMPDIR" \ && equivs-build ./control 1>/dev/null \ && sudo dpkg --force-depends \ -i "./${pkgname}_${pkgversion}_all.deb" 2>&1 \ && ynh_package_install -f) || ynh_die "Unable to install dependencies" [[ -n "$TMPDIR" ]] && rm -rf $TMPDIR # Remove the temp dir. # check if the package is actually installed ynh_package_is_installed "$pkgname" } # Define and install dependencies with a equivs control file # This helper can/should only be called once per app # # usage: ynh_install_app_dependencies dep [dep [...]] # | arg: dep - the package name to install in dependence # You can give a choice between some package with this syntax : "dep1|dep2" # Example : ynh_install_app_dependencies dep1 dep2 "dep3|dep4|dep5" # This mean in the dependence tree : dep1 & dep2 & (dep3 | dep4 | dep5) ynh_install_app_dependencies () { local dependencies=$@ local dependencies=${dependencies// /, } local dependencies=${dependencies//|/ | } local manifest_path="../manifest.json" if [ ! -e "$manifest_path" ]; then manifest_path="../settings/manifest.json" # Into the restore script, the manifest is not at the same place fi local version=$(grep '\"version\": ' "$manifest_path" | cut -d '"' -f 4) # Retrieve the version number in the manifest file. if [ ${#version} -eq 0 ]; then version="1.0" fi local dep_app=${app//_/-} # Replace all '_' by '-' cat > /tmp/${dep_app}-ynh-deps.control << EOF # Make a control file for equivs-build Section: misc Priority: optional Package: ${dep_app}-ynh-deps Version: ${version} Depends: ${dependencies} Architecture: all Description: Fake package for ${app} (YunoHost app) dependencies This meta-package is only responsible of installing its dependencies. EOF ynh_package_install_from_equivs /tmp/${dep_app}-ynh-deps.control \ || ynh_die "Unable to install dependencies" # Install the fake package and its dependencies rm /tmp/${dep_app}-ynh-deps.control ynh_app_setting_set $app apt_dependencies $dependencies } # Remove fake package and its dependencies # # Dependencies will removed only if no other package need them. # # usage: ynh_remove_app_dependencies ynh_remove_app_dependencies () { local dep_app=${app//_/-} # Replace all '_' by '-' ynh_package_autopurge ${dep_app}-ynh-deps # Remove the fake package and its dependencies if they not still used. }