diff --git a/action.yml b/action.yml index d71c7ec..2ad3a98 100644 --- a/action.yml +++ b/action.yml @@ -22,5 +22,5 @@ runs: key: cache-apt-pkgs_${{ inputs.cache_key }} - name: Install Packages - run: ${{ github.action_path }}/run.sh "~/cache-apt-pkgs" "${{ inputs.packages }}" + run: ${{ github.action_path }}/run.sh / ~/cache-apt-pkgs ${{ inputs.packages }} shell: bash diff --git a/run.sh b/run.sh index 4c0af79..a2e6061 100755 --- a/run.sh +++ b/run.sh @@ -1,84 +1,147 @@ -#!/bin/bash -x +#!/bin/bash +# Directory that holds the cached packages. cache_dir=$1 -packages="${@:2}" +# Root directory to untar the cached packages to. +# Typically filesystem root '/' but can be changed for testing. +cache_restore_root=$2 +# List of the packages to use. +packages="${@:3}" +############################################################################## +# Validate command line arguments. +# Globals: +# cache_dir +# Arguments: +# None +# Outputs: +# None +# Side effects: +# Exits if validation fails. +############################################################################## validate_args() { - echo -n "Validating action arguments... "; + echo -n "* Validating action arguments... "; if [ ! -d "$cache_dir" ]; then - echo "aborted.\nCache directory '$cache_dir' does not exist." - return 1 + echo "aborted." + echo "Cache directory '$cache_dir' does not exist." >&2 + exit 1 fi - if [ $packages = "" ]; then - echo "aborted.\nPackages argument cannot be empty." - return 2 + if [ "$packages" == "" ]; then + echo "aborted." + echo "* Packages argument cannot be empty." >&2 + exit 2 fi for package in $packages; do - if apt-cache search ^$package$ | grep $package; then - echo "aborted.\nPackage '$package' not found." - return 3 + apt-cache search ^$package$ | grep $package > /dev/null + if [ $? -ne 0 ]; then + echo "aborted." + echo "* Package '$package' not found." >&2 + exit 3 fi done echo "done." - return 0 } +############################################################################## +# Get cached package file path. +# Globals: +# cache_dir +# Arguments: +# package name +# Outputs: +# Writes cached package file path to stdout. +############################################################################## +get_cache_filepath() { + echo "$cache_dir/$1.tar.gz" +} + +############################################################################## +# Clean the cache directory of unused packages. +# Globals: +# cache_dir +# Arguments: +# None +# Outputs: +# None +# Side effects: +# Removes unused cached packages from filesystem. +############################################################################## clean_cache() { - for dir in `ls $cache_dir`; do + for listed_filepath in $(find $cache_dir -maxdepth 1 -type f); do remove=true for package in $packages; do - if [ $dir == $package ]; then + cache_filepath=$(get_cache_filepath $package) + if [ $listed_filepath == $cache_filepath ]; then remove=false break fi - done - [ $remove ] && rm -fr $cache_dir/$dir + done + if [ $remove == true ]; then + rm -f $listed_filepath + echo "* Removed unused cached file $listed_filepath." + fi done } +############################################################################## +# Restore cached package. +# Globals: +# cache_restore_root +# Arguments: +# package +# Outputs: +# None +# Side effects; +# Untars files to filesystem and performs an APT upgrade. +############################################################################## restore_pkg() { package=$1 - package_dir=$2 + cache_filepath=$(get_cache_filepath $package) - echo -n "Restoring $package from cache $package_dir... " - sudo cp --verbose --force --recursive $package_dir/* / + echo "* Restoring $package from cache $cache_filepath... " + tar -xf $cache_filepath -C $cache_restore_root sudo apt-get --yes --only-upgrade install $package - echo "done." } +############################################################################## +# Install package and cache it to the filesystem. +# Globals: +# None +# Arguments: +# package +# Outputs: +# None +# Side effects; +# Performs an APT install of the package and creates the cached package. +############################################################################## install_and_cache_pkg() { package=$1 - package_dir=$2 + cache_filepath=$(get_cache_filepath $package) - echo -n "Clean installing $package... " - sudo apt-get --yes install $package - echo "done." + echo "* Clean installing $package... " + sudo apt-get --yes install $package - echo -n "Caching $package to $package_dir..." - mkdir --parents $package_dir - # Pipe all package files (no folders) to copy command. - sudo dpkg -L $package | + echo "* Caching $package 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; fi; done | - xargs cp -p -t $package_dir - echo "done." + xargs tar -czf $cache_filepath -C / } -validate_code = validate_args -if validate_code -ne 0; then - exit $validate_code -fi - +validate_args clean_cache for package in $packages; do - package_dir=$cache_dir/$package - if [ -d $package_dir ]; then - restore_pkg $package $package_dir + echo "* Processing package $package..." + cache_filepath=$(get_cache_filepath $package) + echo $cache_filepath + if [ -f $cache_filepath ]; then + restore_pkg $package else - install_and_cache_pkg $package $package_dir + install_and_cache_pkg $package fi done -echo "Action complete. ${#packages[@]} packages installed." +echo "Action complete. ${#packages[@]} package(s) installed."