diff --git a/install_and_cache_pkgs.sh b/install_and_cache_pkgs.sh index bbf54dc..e4f6c2c 100755 --- a/install_and_cache_pkgs.sh +++ b/install_and_cache_pkgs.sh @@ -3,49 +3,66 @@ # Fail on any error. set -e +# Include library. +script_dir="$(dirname -- "$(realpath -- "${0}")")" +source "${script_dir}/lib.sh" + # Directory that holds the cached packages. cache_dir=$1 # List of the packages to use. -packages="${@:2}" +input_packages="${@:2}" -package_count=$(echo $packages | wc -w) -echo "Clean installing and caching $package_count package(s)." +# Trim commas, excess spaces, and sort. +packages="$(normalize_package_list "${input_packages}")" + +package_count=$(echo "${packages}" | wc -w) +echo "Clean installing and caching ${package_count} package(s)." echo "Package list:" -for package in $packages; do - echo "- $package" +for package in "${packages}"; do + echo "- ${package}" done echo -n "Updating APT package list..." sudo apt-get update > /dev/null echo "done." -echo "Clean installing and caching $(echo $packages | wc -w) packages..." -for package in $packages; do - cache_filepath=$cache_dir/$package.tar.gz +manifest="" +echo "Clean installing and caching ${package_count} packages..." +for package in "${packages}"; do + get_package_name_ver "${package}" # -> package_name, package_ver + package_deps="$(apt-get install --dry-run --yes "${package_name}" | grep "^Inst" | awk '{print $2}')" - echo "- $package" - echo -n " Installing..." - sudo apt-get --yes install $package > /dev/null + echo "- ${package_name}" + echo " * Version: ${package_ver}" + echo " * Dependencies: ${package_deps}" + echo -n " * Installing..." + # Zero interaction while installing or upgrading the system via apt. + sudo DEBIAN_FRONTEND=noninteractive apt-get --yes install "${package}" > /dev/null echo "done." - echo -n " Caching to $cache_filepath..." - # Pipe all package files (no folders) to Tar. - dpkg -L $package | - while IFS= read -r f; do - if test -f $f; then echo ${f:1}; fi; #${f:1} removes the leading slash that Tar disallows - done | - xargs tar -czf $cache_filepath -C / - echo "done." + for cache_package in "${package_deps}"; do + cache_filepath="${cache_dir}/${cache_package}.tar.gz" + + if test ! -f "${cache_filepath}"; then + get_package_name_ver "${cache_package}" # -> package_name, package_ver + echo -n " Caching ${package_name} to ${cache_filepath}..." + # Pipe all package files (no folders) to Tar. + dpkg -L "${package_name}" | + while IFS= read -r f; do + if test -f $f; then echo "${f:1}"; fi; #${f:1} removes the leading slash that Tar disallows + done | + xargs tar -czf "${cache_filepath}" -C / + echo "done." + # Add package to manifest + manifest="${manifest}${package_name}:$(dpkg -s "${package_name}" | grep Version | awk '{print $2}')," + fi + done done echo "done." -manifest_filepath="$cache_dir/manifest.log" -echo -n "Writing package manifest to $manifest_filepath..." -manifest= -for package in $packages; do - manifest=$manifest$package:$(dpkg -s $package | grep Version | awk '{print $2}'), -done -# Remove trailing comma. -echo ${manifest:0:-1} > $manifest_filepath +manifest_filepath="${cache_dir}/manifest.log" +echo -n "Writing package manifest to ${manifest_filepath}..." +# Remove trailing comma and write to manifest file. +echo "${manifest:0:-1}" > "${manifest_filepath}" echo "done." \ No newline at end of file diff --git a/lib.sh b/lib.sh new file mode 100644 index 0000000..3802483 --- /dev/null +++ b/lib.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +# Sort these packages by name and split on commas. +function normalize_package_list { + stripped="$(echo \"${0}\" | sed 's/,//g')" + # Remove extraneous spaces at the middle, beginning, and end. + trimmed="$(echo \"${stripped}\" | sed 's/\s\+/ /g; s/^\s\+//g; s/\s\+$//g')" + echo "$(\"${trimmed}\" | sort)" +} + +# Split fully qualified package into name and version +function get_package_name_ver { + IFS=\= read name ver <<< "${0}" + # If version not found in the fully qualified package value. + if test -z "${ver}"; then + ver="$(grep "Version:" <<< "$(apt show ${name})" | awk '{print $2}')" + fi + echo 'package_name="${name}"; package_ver="${ver}"' +} + +function blah { + > /dev/null 2>&1 +} \ No newline at end of file diff --git a/pre_cache_action.sh b/pre_cache_action.sh index ba09879..05d2fbe 100755 --- a/pre_cache_action.sh +++ b/pre_cache_action.sh @@ -1,5 +1,9 @@ #!/bin/bash +# Include library. +script_dir="$(dirname -- "$(realpath -- "${0}")")" +source "${script_dir}/lib.sh" + # Directory that holds the cached packages. cache_dir=$1 @@ -7,34 +11,39 @@ cache_dir=$1 version=$2 # List of the packages to use. -packages=${@:3} +input_packages="${@:3}" + +# Trim commas, excess spaces, and sort. +packages="$(normalize_package_list "${input_packages}")" # Create cache directory so artifacts can be saved. mkdir -p $cache_dir echo -n "Validating action arguments (version='$version', packages='$packages')..."; -echo $version | grep -o " " > /dev/null -if [ $? -eq 0 ]; then - echo "aborted." +if grep -q " " <<< "${cache_version}"; then + echo "aborted." echo "Version value '$version' cannot contain spaces." >&2 exit 1 fi -if [ "$packages" == "" ]; then + +# Is length of string zero? +if test -z "${packages}"; then echo "aborted." echo "Packages argument cannot be empty." >&2 exit 2 fi echo "done." +versioned_packages="" echo -n "Verifying packages..." -for package in $packages; do - escaped=$(echo $package | sed 's/+/\\+/g') - apt-cache search ^$escaped$ | grep $package > /dev/null - if [ $? -ne 0 ]; then +for package in ${packages}; do + if test ! "$(apt show "${package}")"; then echo "aborted." echo "Package '$package' not found." >&2 exit 3 fi + get_package_name_ver "${package}" # -> package_name, package_ver + versioned_packages="${versioned_packages} ${package_name}=${package_ver}" done echo "done." @@ -43,15 +52,15 @@ set -e echo "Creating cache key..." -# Remove package delimiters, sort (requires newline) and then convert back to inline list. -normalized_list=$(echo $packages | sed 's/[\s,]+/ /g' | tr ' ' '\n' | sort | tr '\n' ' ') -echo "- Normalized package list is '$normalized_list'." +# TODO Can we prove this will happen again? +normalized_versioned_packages="$(normalize_package_list "${versioned_packages}")" +echo "- Normalized package list is '${normalized_versioned_packages}'." -value=$(echo $normalized_list @ $version) -echo "- Value to hash is '$value'." +value="$(echo "${normalized_versioned_packages} @ ${cache_version}")" +echo "- Value to hash is '${value}'." -key=$(echo $value | md5sum | cut -f1 -d' ') -echo "- Value hashed as '$key'." +key="$(echo "${value}" | md5sum | /bin/cut -f1 -d' ')" +echo "- Value hashed as '${key}'." echo "done." diff --git a/restore_pkgs.sh b/restore_pkgs.sh index ab87879..4c710f3 100755 --- a/restore_pkgs.sh +++ b/restore_pkgs.sh @@ -17,8 +17,8 @@ for cache_filepath in $cache_filepaths; do done echo "Reading from manifest..." -for logline in $(cat $cache_dir/manifest.log | tr ',' '\n' ); do - echo "- $(echo $logline | tr ':' ' ')" +for logline in "$(cat "${cache_dir}/manifest.log" | tr ',' '\n' )"; do + echo "- $(echo "${logline}" | tr ':' ' ')" done echo "done."