From 86a813eaa125b009b5faf6fdfd356d066a123a6e Mon Sep 17 00:00:00 2001 From: awalsh128 Date: Sat, 15 Oct 2022 21:58:58 -0700 Subject: [PATCH] Made cache directory variable and more refinements to postinst. --- install_and_cache_pkgs.sh | 19 +++----------- lib.sh | 54 ++++++++++++++++++++++++++++++--------- post_cache_action.sh | 4 +-- restore_pkgs.sh | 20 +++++++++------ 4 files changed, 60 insertions(+), 37 deletions(-) diff --git a/install_and_cache_pkgs.sh b/install_and_cache_pkgs.sh index bb3ae67..6c6a2cb 100755 --- a/install_and_cache_pkgs.sh +++ b/install_and_cache_pkgs.sh @@ -64,9 +64,6 @@ done log_empty_line -# Post install script install location {package name}.postinst -postinst_dirpath="/var/lib/dpkg/info/" - installed_package_count=$(wc -w <<< "${installed_packages}") log "Caching ${installed_package_count} installed packages..." for installed_package in ${installed_packages}; do @@ -76,19 +73,11 @@ for installed_package in ${installed_packages}; do if test ! -f "${cache_filepath}"; then read installed_package_name installed_package_ver < <(get_package_name_ver "${installed_package}") log " * Caching ${installed_package_name} to ${cache_filepath}..." - - # Pipe all package files (no folders) to Tar. - dpkg -L "${installed_package_name}" | - while IFS= read -r f; do - if test -f $f || test -L $f; then echo "${f:1}"; fi; #${f:1} removes the leading slash that Tar disallows - done | - sudo xargs tar -cf "${cache_filepath}" -C / - # Append post install scripts if enabled and available. - postinst_filepath=$(get_postinst_filepath "${package_name}") - if test "${execute_postinst}" == "true" && test ! -z "${postinst_filepath}"; then - tar -caf "${cache_filepath}" "${postinst_filepath}" - fi + # Pipe all package files (no folders) and postinst control data to Tar. + { dpkg -L "${installed_package_name}" & get_postinst_filepath "${package_name}"; } | + while IFS= read -r f; do test -f "${f}" -o -L "${f}" && get_tar_relpath "${f}"; done | + sudo xargs tar -cf "${cache_filepath}" -C / log " done (compressed size $(du -h "${cache_filepath}" | cut -f1))." fi diff --git a/lib.sh b/lib.sh index 86101cd..1c49215 100755 --- a/lib.sh +++ b/lib.sh @@ -1,13 +1,12 @@ #!/bin/bash -# Sort these packages by name and split on commas. -####################################### +############################################################################### # Sorts given packages by name and split on commas. # Arguments: # The comma delimited list of packages. # Returns: # Sorted list of space delimited packages. -####################################### +############################################################################### function normalize_package_list { local stripped=$(echo "${1}" | sed 's/,//g') # Remove extraneous spaces at the middle, beginning, and end. @@ -16,14 +15,14 @@ function normalize_package_list { echo "${sorted}" } -####################################### +############################################################################### # Gets a list of installed packages from a Debian package installation log. # Arguments: # The filepath of the Debian install log. # Returns: # The list of space delimited pairs with each pair colon delimited. # : ... -####################################### +############################################################################### function get_installed_packages { install_log_filepath="${1}" local regex="^Unpacking ([^ :]+)([^ ]+)? (\[[^ ]+\]\s)?\(([^ )]+)" @@ -43,13 +42,13 @@ function get_installed_packages { fi } -####################################### +############################################################################### # Splits a fully qualified package into name and version. # Arguments: # The colon delimited package pair or just the package name. # Returns: # The package name and version pair. -####################################### +############################################################################### function get_package_name_ver { IFS=\: read name ver <<< "${1}" # If version not found in the fully qualified package value. @@ -59,15 +58,28 @@ function get_package_name_ver { echo "${name}" "${ver}" } -####################################### +############################################################################### +# Gets the package name from the cached package filepath in the +# path/to/cache/dir/:.tar format. +# Arguments: +# Filepath to the cached packaged. +# Returns: +# The package name. +############################################################################### +function get_package_name_from_cached_filepath { + basename ${cached_pkg_filepath} | awk -F\: '{print $1}' +} + +############################################################################### # Gets the Debian postinst file location. # Arguments: +# Root directory to search from. # Name of the unqualified package to search for. # Returns: # Filepath of the postinst file, otherwise an empty string. -####################################### +############################################################################### function get_postinst_filepath { - filepath="/var/lib/dpkg/info/${1}" + filepath="${1}/var/lib/dpkg/info/${2}.postinst" if test -f "${filepath}"; then echo "${filepath}" else @@ -75,12 +87,30 @@ function get_postinst_filepath { fi } + +############################################################################### +# Gets the relative filepath acceptable by Tar. Just removes the leading slash +# that Tar disallows. +# Arguments: +# Absolute filepath to archive. +# Returns: +# The relative filepath to archive. +############################################################################### +function get_tar_relpath { + filepath=${1} + if test ${filepath:0:1} = "/"; then + echo "${filepath:1}" + else + echo "${filepath}" + fi +} + function log { echo "$(date +%H:%M:%S)" "${@}"; } function log_err { >&2 echo "$(date +%H:%M:%S)" "${@}"; } function log_empty_line { echo ""; } -####################################### +############################################################################### # Writes the manifest to a specified file. # Arguments: # Type of manifest being written. @@ -88,7 +118,7 @@ function log_empty_line { echo ""; } # File path of the manifest being written. # Returns: # Log lines from write. -####################################### +############################################################################### function write_manifest { if [ ${#2} -eq 0 ]; then log "Skipped ${1} manifest write. No packages to install." diff --git a/post_cache_action.sh b/post_cache_action.sh index 9ebdb69..264cbed 100755 --- a/post_cache_action.sh +++ b/post_cache_action.sh @@ -26,9 +26,9 @@ packages="${@:5}" script_dir="$(dirname -- "$(realpath -- "${0}")")" if [ "$cache_hit" == true ]; then - ${script_dir}/restore_pkgs.sh ~/cache-apt-pkgs "${cache_restore_root}" "${execute_postinst}" + ${script_dir}/restore_pkgs.sh "${cache_dir}" "${cache_restore_root}" "${execute_postinst}" else - ${script_dir}/install_and_cache_pkgs.sh ~/cache-apt-pkgs "${execute_postinst}" ${packages} + ${script_dir}/install_and_cache_pkgs.sh "${cache_dir}" "${execute_postinst}" ${packages} fi log_empty_line diff --git a/restore_pkgs.sh b/restore_pkgs.sh index 1cb7b4e..9016a31 100755 --- a/restore_pkgs.sh +++ b/restore_pkgs.sh @@ -39,16 +39,20 @@ cached_pkg_filecount=$(echo ${cached_pkg_filepaths} | wc -w) log "Restoring ${cached_pkg_filecount} packages from cache..." for cached_pkg_filepath in ${cached_pkg_filepaths}; do + log "- $(basename "${cached_pkg_filepath}") restoring..." - sudo tar -xf "${cached_pkg_filepath}" -C "${cache_restore_root}" > /dev/null - - # Execute post install script if available. - postinst_filepath=$(get_postinst_filepath "${package_name}") - if test "${execute_postinst}" == "true" && test ! -z "${postinst_filepath}"; then - sh -x ${postint_filepath} - fi - log " done" + + # Execute post install script if available. + if test "${execute_postinst}" == "true"; then + package_name=$(get_package_name_from_cached_filepath ${package_name}) + postinst_filepath=$(get_postinst_filepath "${cache_restore_root}" "${package_name}") + if test ! -z "${postinst_filepath}"; then + log "- Executing ${postinst_filepath}..." + sudo sh -x ${postinst_filepath} + log " done" + fi + fi done log "done"