From 59485e7970a3e6dab112e98db2dffb8278ce04c1 Mon Sep 17 00:00:00 2001 From: zawz Date: Fri, 22 May 2020 01:57:21 +0200 Subject: [PATCH] Add package description + bugfixes --- .config.example | 2 +- README.md | 14 ++- compile.sh | 2 +- completion/zpkg.bash | 2 +- src/config.sh | 2 +- src/deploy.sh | 25 ++-- src/fetch.sh | 8 +- src/install.sh | 12 +- src/main.sh | 277 ++++++++++++++++++++----------------------- src/print.sh | 42 ++++++- src/remove.sh | 2 +- src/util.sh | 2 +- src/view.sh | 27 +++-- 13 files changed, 222 insertions(+), 195 deletions(-) diff --git a/.config.example b/.config.example index ae8b803..bba4fda 100644 --- a/.config.example +++ b/.config.example @@ -2,4 +2,4 @@ SSH_ADDR=example.com SSH_USER=zpkg HTTP_ADDR=example.com HTTP_PATH=zpkg -PKG_PATH='$HOME/pkg' +PKG_PATH=pkg diff --git a/README.md b/README.md index 81481a7..4ebd53f 100644 --- a/README.md +++ b/README.md @@ -23,7 +23,7 @@ Optional: wget http://zpkg.zawz.net/install.sh sh install.sh ``` -> By default the config is installed to /etc/zpkg. +> By default the config is installed to /etc/zpkg > This can be changed with the -c option If you wish to use another repository, substitute `zpkg.zawz.net` for your desired target @@ -37,7 +37,7 @@ sudo rm -rd /etc/zpkg ### Using -See `zpkg -h` +See `zpkg -h` for details ## Deploy on a server @@ -49,7 +49,7 @@ To deploy on a server you need: - HTTP server - dedicated zpkg user -You need to be able to SSH to the zpkg user. SSH keys are recommended +You need to be able to SSH to the zpkg user, SSH keys are recommended ### Process @@ -64,20 +64,22 @@ You need to be able to SSH to the zpkg user. SSH keys are recommended ``` . +-- DEPS ++-- DESC +-- ROOT | +-- / +-- HOME +-- ~ ``` -- The ROOT directory repsesents the root filesystem +- The ROOT directory represents the root filesystem - The HOME directory represents the home directory of the user - The DEPS file contains dependency packages separated by spaces or newlines. Dependencies are package names from the repository +- The DESC file contains the description of the package ### Deploying packages `zpkg deploy ` > Target directories are structured as described above -> The package name is the name of the directory +> The name of the directory is the package name ## Functionality @@ -90,4 +92,4 @@ You need to be able to SSH to the zpkg user. SSH keys are recommended - Versions - Multi-repo - +- Hooks diff --git a/compile.sh b/compile.sh index 15b5765..bff27fd 100755 --- a/compile.sh +++ b/compile.sh @@ -3,7 +3,7 @@ # config # no spaces in srcdir or ordered files SRCDIR=src -ordered='options.sh config.sh main.sh' +ordered='env.sh options.sh config.sh main.sh' # process COMMENTSCRIPT="/^\s*#/d;s/\s*#[^\"']*$//" diff --git a/completion/zpkg.bash b/completion/zpkg.bash index a6c2e0b..210fc42 100644 --- a/completion/zpkg.bash +++ b/completion/zpkg.bash @@ -7,7 +7,7 @@ _zpkg_completion() _cw1_file="deploy" if [ "$COMP_CWORD" = "1" ] ; then _compwords=$_cw1 - elif [ "$COMP_CWORD" -gt "1" ] && [ -n "$(echo "$_cw1_pkgw" | grep -w "${COMP_WORDS[1]}" 2>/dev/null)" ] ; then + elif [ "$COMP_CWORD" -gt "1" ] && echo "$_cw1_pkgw" | grep -qw -- "${COMP_WORDS[1]}" ; then _compwords=$(zpkg list-all 2>/dev/null) fi COMPREPLY=($(compgen -W "$_compwords" "${COMP_WORDS[$COMP_CWORD]}" 2>/dev/null)) diff --git a/src/config.sh b/src/config.sh index 6112ded..16fb520 100644 --- a/src/config.sh +++ b/src/config.sh @@ -21,7 +21,7 @@ then fi if [ ! -f "$config_file" ] then - echo "Error: no config file '$config_file'" > /dev/stderr + echo "Error: no config file '$config_file'" >&2 exit 1 fi diff --git a/src/deploy.sh b/src/deploy.sh index 9cafa25..0dbb914 100644 --- a/src/deploy.sh +++ b/src/deploy.sh @@ -6,28 +6,27 @@ package() src="$1" pkg="$2" echo "Packaging $(getname "$src"): $(du -sh "$src" | awk '{print $1}')iB" + + tmpdir="/tmp/zpkg_$(random_string 5)" + mkdir -p "$tmpdir" if [ ! -d "$src/ROOT" ] && [ ! -d "$src/HOME" ] && [ ! -f "$src/DEPS" ] then - tmpdir="/tmp/zpkg$(random_string 5)" - mkdir -p "$tmpdir" - cp -r "$src" "$tmpdir/ROOT" - src="$tmpdir" - clean_needed=true + mkdir -p "$tmpdir/package" + cp -r "$src" "$tmpdir/package/ROOT" + else + cp -r "$src" "$tmpdir/package" fi ( - cd "$src" + cd "$tmpdir/package" if which pv >/dev/null 2>&1 then - tar -cf - --owner=0 --group=0 -P * | pv -s "$(du -sb . | awk '{print $1}')" | xz > "$pkg" + tar -cf - --owner=0 --group=0 -P * | pv -s "$(du -sb . | awk '{print $1}')" | xz > "../$pkg" else - tar -cvJf - --owner=0 --group=0 * > "$pkg" + tar -cvJf - --owner=0 --group=0 * > "../$pkg" fi ) - mv "$src/$pkg" ./ - if [ -n "$clean_needed" ] - then - rm -rd "$tmpdir" - fi + mv "$tmpdir/$pkg" ./ + rm -rd "$tmpdir" } deploy_package() diff --git a/src/fetch.sh b/src/fetch.sh index d4c2930..bd0998b 100644 --- a/src/fetch.sh +++ b/src/fetch.sh @@ -1,9 +1,11 @@ #!/bin/sh +# $1 = package name , $2 = output fetch_package() { - wget "$HTTP_ADDRESS/$1.tar.xz" -q --show-progress -O "$1.tar.xz" 2>&1 - return $? + out="$2" + [ -z "$out" ] && out="$1.tar.xz" + wget "$HTTP_ADDRESS/$1.tar.xz" -q --show-progress -O "$out" 2>&1 } # $1 = prefix @@ -13,7 +15,7 @@ fetch_pkglist() $1 mv pkglist pkglist_bak 2>/dev/null if ! $1 wget "$HTTP_ADDRESS/pkglist" -q --show-progress -O pkglist 2>&1 then - echo "Couldn't fetch server data" > /dev/stderr + echo "Couldn't fetch server data" >&2 $1 mv pkglist_bak pkglist 2>/dev/null return 1 else diff --git a/src/install.sh b/src/install.sh index 32e4660..d349518 100644 --- a/src/install.sh +++ b/src/install.sh @@ -39,20 +39,22 @@ move_files() install_package() { - tmpdir="/tmp/zpkg$(random_string 5)" + tmpdir="/tmp/zpkg_$(random_string 5)" mkdir -p "$tmpdir" ( cd "$tmpdir" if ! fetch_package "$1" then - echo "Package '$1' not found" > /dev/stderr + echo "Package '$1' not found" >&2 return 1 fi - unpack "$1.tar.xz" - sudo mv "$1.tar.xz" "$PKG_PATH" + sudo cp "$1.tar.xz" "$PKG_PATH" + unpack "$1.tar.xz" || return $? move_files ROOT / sudo 2>/dev/null move_files HOME "$HOME" 2>/dev/null add_package_entry "$1" - ) || return $? + ) + ret=$? rm -rd "$tmpdir" 2>/dev/null + return $ret } diff --git a/src/main.sh b/src/main.sh index 730e100..686f25f 100644 --- a/src/main.sh +++ b/src/main.sh @@ -5,160 +5,135 @@ if [ -z "$opt_f" ] ; then fi -if [ -n "$1" ] -then - - if [ "$1" = "list" ] +case "$1" in +list) awk '{print $1}' "$PKG_PATH/installed" 2>/dev/null ;; +list-all) awk '{print $1}' "$PKG_PATH/pkglist" 2>/dev/null ;; +update-database) fetch_pkglist sudo ;; +fetch) + if [ -z "$2" ] then - awk '{print $1}' "$PKG_PATH/installed" 2>/dev/null - - elif [ "$1" = "list-all" ] - then - awk '{print $1}' "$PKG_PATH/pkglist" 2>/dev/null - - - elif [ "$1" = "fetch" ] - then - - if [ -z "$2" ] - then - echo "No package specified" > /dev/stderr - else - shift 1 - for I in $* - do - fetch_package "$I" - done - fi - - - elif [ "$1" = "show" ] - then - - if [ -z "$2" ] - then - echo "No package specified" > /dev/stderr - else - shift 1 - for I in $* - do - if is_installed "$I" - then - view_package "$I" - else - echo "No package '$I' installed" > /dev/stderr - fi - done - fi - - elif [ "$1" = "deps" ] - then - - if [ -z "$2" ] - then - echo "No package specified" > /dev/stderr - else - shift 1 - resolve_deps $* - fi - - elif [ "$1" = "install" ] - then - - fetch_pkglist sudo || exit $? - if [ -z "$2" ] - then - echo "No package specified" > /dev/stderr - else - shift 1 - pkglist=$(LOG=true resolve_packages $*) || exit $? - pkglist=$(INCLUDE_PACKAGES=true resolve_deps $* | tr '\n' ' ') - echo "Installing packages: $pkglist" - for I in $pkglist - do - if is_installed "$I" - then - remove_package "$I" - fi - install_package "$I" - done - fi - - elif [ "$1" = "remove" ] - then - - if [ -z "$2" ] - then - echo "No package specified" > /dev/stderr - else - shift 1 - for I in $* - do - remove_package "$I" - done - fi - - elif [ "$1" = "update-database" ] - then - - fetch_pkglist sudo - - elif [ "$1" = "update" ] - then - - fetch_pkglist sudo || exit 1 - r_pkg=$(removed_packages) - o_pkg=$(outdated_packages) - if [ -n "$r_pkg" ] - then - echo "Removing packages: "$r_pkg - for I in $r_pkg - do - remove_package $I - done - fi - if [ -n "$o_pkg" ] - then - echo "Updating packages: "$o_pkg - for I in $o_pkg - do - remove_package $I - install_package $I - done - fi - - elif [ "$1" = "list-outdated" ] - then - - tmpdir="/tmp/zpkg$(random_string 5)" - virtual_config_path "$tmpdir" || exit $? - fetch_pkglist sudo > /dev/null || exit $? - outdated_packages - sudo rm -rd "$tmpdir" - - elif [ "$1" = "list-removed" ] - then - - tmpdir="/tmp/zpkg$(random_string 5)" - virtual_config_path "$tmpdir" || exit $? - fetch_pkglist sudo > /dev/null || exit $? - removed_packages - sudo rm -rd "$tmpdir" - - elif [ "$1" = "deploy" ] - then - + echo "No package specified" >&2 + else shift 1 for I in $* do - deploy_folder "$I" || exit 1 + fetch_package "$I" done - update_remote_database - - else - usage fi - -else - usage -fi + ;; +show) + if [ -z "$2" ] + then + echo "No package specified" >&2 + else + shift 1 + for I in $* + do + if is_installed "$I" + then + view_package "$I" + else + wget "$HTTP_ADDRESS/$1.tar.xz" -q -O - 2>/dev/null | view_package_file - || { echo "Could not fetch package '$I'" >&2 ; return 1 ; } + fi + done + fi + ;; +deps) + if [ -z "$2" ] + then + echo "No package specified" >&2 + else + shift 1 + resolve_deps $* || exit $? + fi + ;; +show) + if [ -z "$2" ] + then + echo "No package specified" >&2 + else + shift 1 + for N + do + package_info $N || exit $? + done + fi + ;; +install) + fetch_pkglist sudo || exit $? + if [ -z "$2" ] + then + echo "No package specified" >&2 + else + shift 1 + pkglist=$(LOG=true resolve_packages $*) || exit $? + pkglist=$(INCLUDE_PACKAGES=true resolve_deps $* | tr '\n' ' ') + echo "Installing packages: $pkglist" + for I in $pkglist + do + if is_installed "$I" + then + remove_package "$I" + fi + install_package "$I" + done + fi + ;; +remove) + if [ -z "$2" ] + then + echo "No package specified" >&2 + else + shift 1 + for I in $* + do + remove_package "$I" + done + fi + ;; +update) + fetch_pkglist sudo || exit 1 + r_pkg=$(removed_packages) + o_pkg=$(outdated_packages) + if [ -n "$r_pkg" ] + then + echo "Removing packages: "$r_pkg + for I in $r_pkg + do + remove_package $I + done + fi + if [ -n "$o_pkg" ] + then + echo "Updating packages: "$o_pkg + for I in $o_pkg + do + remove_package $I + install_package $I + done + fi + ;; +list-outdated) + tmpdir="/tmp/zpkg_$(random_string 5)" + virtual_config_path "$tmpdir" || exit $? + fetch_pkglist > /dev/null || exit $? + outdated_packages + rm -rd "$tmpdir" + ;; +list-removed) + tmpdir="/tmp/zpkg_$(random_string 5)" + virtual_config_path "$tmpdir" || exit $? + fetch_pkglist > /dev/null || exit $? + removed_packages + rm -rd "$tmpdir" + ;; +deploy) + shift 1 + for I in $* + do + deploy_folder "$I" || exit 1 + done + update_remote_database + ;; +*) usage && exit 1 ;; +esac diff --git a/src/print.sh b/src/print.sh index 1854387..779039a 100644 --- a/src/print.sh +++ b/src/print.sh @@ -2,8 +2,8 @@ usage() { - echo "$fname [options] " - echo ' + echo "$fname [options] + Operations: update Update packages update-database Update only database @@ -11,6 +11,7 @@ Operations: remove Remove packages fetch Fetch packages into current directory show Show package files + deps Show dependencies of package list List currently installed packages list-all List all packages in repository list-outdated List outdated packages @@ -21,10 +22,43 @@ Admin operations: Options: -h Display this help -c Custom config path - -f Force running even when root -' + -f Force running when root +" } error() { printf "\033[1;31m%s\033[0m\n" "$1" >&2 } + +# $1 = package name +package_info() { + unset cleanup + status="not installed" + grep -wq "^$1" "$PKG_PATH/pkglist" 2>/dev/null || { echo "Package '$I' not found" && return 1; } + grep -wq "^$1" "$PKG_PATH/installed" 2>/dev/null && status=installed + if [ "$status" = "installed" ] && [ -f "$PKG_PATH/$1.tar.xz" ] + then + pkg="$PKG_PATH/$1.tar.xz" + else + tmpdir="/tmp/zpkg_$(random_string 5)" + pwd=$(pwd) + mkdir "$tmpdir" + fetch_package "$1" >/dev/null 2>&1 || { echo "Error fetching package" >&2 && ret=$?; } + pkg="$1.tar.xz" + fi + deps=$(deps "$1") + desc=$(desc "$pkg" 2>/dev/null) + csize=$(stat -c '%s' "$pkg" | numfmt --to=iec-i --suffix=B --padding 6) + isize=$(xz -dc "$pkg" | wc -c | numfmt --to=iec-i --suffix=B --padding 6) + [ -n "$cleanup" ] && { cd "$pwd"; rm -rd "$tmpdir"; } + + [ -n "$ret" ] && return $ret + + printf "Name: %s\n" "$1" + printf "Description: %s\n" "$desc" + echo "" + printf "Status: %s\n" "$status" + printf "Dependencies: %s\n" "$(deps "$1" | tr -s ' \n' ' ')" + printf "Package size: %s\n" "$csize" + printf "Installed size: %s\n" "$isize" +} diff --git a/src/remove.sh b/src/remove.sh index dd7a874..3946c01 100644 --- a/src/remove.sh +++ b/src/remove.sh @@ -19,7 +19,7 @@ remove_package() archive="$(pwd)/$1.tar.xz" if [ ! -f "$archive" ] || ! grep -q -w "^$1" installed then - echo "Package '$1' not installed" > /dev/stderr + echo "Package '$1' not installed" >&2 return 1 fi echo "Removing $1" diff --git a/src/util.sh b/src/util.sh index 8cc12f9..7e6f0c9 100644 --- a/src/util.sh +++ b/src/util.sh @@ -28,7 +28,7 @@ root_check() { if [ "$(id | cut -d'=' -f2 | cut -d'(' -f1)" -eq 0 ] then - echo "Cannot run as root" > /dev/stderr + echo "Cannot run as root" >&2 return 1 fi return 0 diff --git a/src/view.sh b/src/view.sh index c976492..da341ae 100644 --- a/src/view.sh +++ b/src/view.sh @@ -3,7 +3,13 @@ deps() { cd "$PKG_PATH" - grep -w "^$1" pkglist | cut -d' ' -f3- + l=$(grep -w "^$1" pkglist) || return $? + echo "$l" | cut -d' ' -f3- +} + +# $1 = pkg file +desc() { + tar -xOf "$1" DESC } resolve_packages() @@ -14,7 +20,7 @@ resolve_packages() do if ! grep -wq "^$I" pkglist 2>/dev/null then - [ "$LOG" = "true" ] && echo "Package '$I' not found" > /dev/stderr + [ "$LOG" = "true" ] && echo "Package '$I' not found" >&2 RET=1 else echo "$I" @@ -27,12 +33,14 @@ resolve_packages() resolve_deps() { ALLDEPS="" + RET=0 for I in $* do - ALLDEPS="$ALLDEPS $(deps $I)" + ALLDEPS="$ALLDEPS $(deps $I)" || { echo "Package '$I' not found" >&2 ; RET=$((RET+1)) ; } done [ "$INCLUDE_PACKAGES" = "true" ] && ALLDEPS="$ALLDEPS $*" echo "$ALLDEPS" | tr -s ' \n' '\n' | sort | uniq | sed '/^$/d' + return $RET } is_installed() @@ -42,10 +50,15 @@ is_installed() return $? } -view_package() -{ - cd "$PKG_PATH" - tar -tf "$1.tar.xz" | sed "s|^ROOT/|/|g ; /\/$/d ; s|^HOME/|$HOME/|g ; /^DEPS/d" +# $1 = file +view_package_file() { + tree=$(tar -tJf "$1" 2>/dev/null) || exit $? + echo "$tree" | sed "s|^ROOT/|/|g ; /\/$/d ; s|^HOME/|$HOME/|g ; /^DEPS/d" 2>/dev/null +} + +# $1 = package name +view_package() { + cd "$PKG_PATH" && view_package_file "$1.tar.xz" } removed_packages()