Major rework:

- dependencies
- HOME and ROOT filesystems
This commit is contained in:
zawz 2020-03-02 16:39:55 +01:00
parent 0eef1475a3
commit ce4bf5ea95
20 changed files with 708 additions and 436 deletions

View file

@ -10,7 +10,6 @@ Official repo: [http://zawz.net/zpkg](http://zawz.net/zpkg)
## As user ## As user
Requirements: Requirements:
- curl
- sudo - sudo
- wget - wget
- tar - tar
@ -21,12 +20,25 @@ Optional:
### Installing ### Installing
```shell ```shell
curl -SO http://zawz.net/zpkg/install.sh wget http://zawz.net/zpkg/install.sh
sudo sh install.sh sh install.sh
``` ```
> By default the config is installed to /etc/zpkg
If you wish to use another repository, substitute `zawz.net/zpkg` for your desired target If you wish to use another repository, substitute `zawz.net/zpkg` for your desired target
#### Installing to a custom location
Add the -c option to the install script to specify a custom config path for the install
### Uninstalling
```shell
zpkg remove $(zpkg list)
rm -rd /etc/zpkg
```
### Using ### Using
See `zpkg -h` See `zpkg -h`
@ -51,21 +63,35 @@ You need to be able to SSH to the zpkg user. SSH keys are recommended
3. Make available the package directory to the HTTP server 3. Make available the package directory to the HTTP server
### Package architecture
```
.
+-- DEPS
+-- ROOT
| +-- /
+-- HOME
+-- ~
```
- The ROOT directory repsesents 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
### Deploying packages ### Deploying packages
`zpkg deploy <pkg...>` `zpkg deploy <dir...>`
Targets are architectured as the linux filesystem > Target directories are structured as described above
> The package name is the name of the directory
## Functionality ## Functionality
- Install packages - Install/Remove/Update packages
- Remove packages - Dependency resolution
- Update packages
- Config redirection - Config redirection
- User Home capability
### Non-present functionality ### Non-present functionality
- Dependencies
- Versions - Versions
- Multi-repo - Multi-repo

24
compile.sh Executable file
View file

@ -0,0 +1,24 @@
#!/bin/sh
# config
# no spaces in srcdir or ordered files
SRCDIR=src
ordered='options.sh config.sh main.sh'
# process
COMMENTSCRIPT="/^\s*#/d;s/\s*#[^\"']*$//"
# order list
unset namefind list
for I in $ordered
do
namefind="$namefind ! -name $I"
list="$list $SRCDIR/$I"
done
findlist=$(find "$SRCDIR" -type f $namefind)
# create file
echo '#!/bin/sh' > zpkg
sed $COMMENTSCRIPT $findlist $list >> zpkg
chmod +x zpkg

View file

@ -1,6 +0,0 @@
#!/bin/bash
. "$(pwd)/.config"
cd "$HOME/$PKG_PATH" || exit $?
stat -c "%n %Y" ./*.tar.xz | sed 's|\.tar\.xz||g;s|^\./||g' > pkglist

View file

@ -1,43 +0,0 @@
#!/bin/bash
. "$(pwd)/.config"
# create install file
echo '#!/bin/sh
' > install.sh
cat .config >> install.sh
echo '
# Generate conf file
{
echo "SSH_ADDRESS=$SSH_USER@$SSH_ADDR"
echo "HTTP_ADDRESS=$HTTP_ADDR/$HTTP_PATH"
echo "PKG_PATH=pkg"
} > zpkg.conf
if [ ! -f "/etc/zpkg/zpkg.conf" ]
then
mkdir -p /etc/zpkg || exit $?
mv zpkg.conf /etc/zpkg || exit $?
fi
# download zpkg
mkdir -p tmp || exit $?
(
cd tmp || exit $?
if ! wget "$HTTP_ADDR/$HTTP_PATH/zpkg.tar.xz" -q -O "zpkg.tar.xz"
then
echo "Cannot reach $HTTP_ADDR/$HTTP_PATH" > /dev/stderr
exit 1
fi
tar xf zpkg.tar.xz || exit $?
# install zpkg package
usr/local/bin/zpkg install zpkg || exit $?
)
# cleanup
rm -rd tmp || exit $?
zpkg update-database >/dev/null || exit $?
' >> install.sh
mv install.sh "$HOME/$PKG_PATH"

View file

@ -4,25 +4,32 @@
ssh="$SSH_USER@$SSH_ADDR" ssh="$SSH_USER@$SSH_ADDR"
# add sources to server
ssh "$ssh" mkdir -p "$PKG_PATH" || exit $?
scp .config scripts/* "$ssh":~/ || exit $?
# make zpkg package
DIR=tmp DIR=tmp
PKG=zpkg PKG=zpkg
DEST=/usr/local/bin DEST=/usr/local/bin
BASHDEST=/etc/bash_completion.d BASHDEST=/etc/bash_completion.d
mkdir -p "$DIR/$PKG$DEST" || exit $?
mkdir -p "$DIR/$PKG$BASHDEST" || exit $? # build
cp src/zpkg.bash "$ZPKG_PKG_PATH/$PKG$BASHDEST" || exit $? ./compile.sh || exit $?
cp src/zpkg "$ZPKG_PKG_PATH/$PKG$DEST" || exit $?
# add sources to server
ssh "$ssh" mkdir -p "$PKG_PATH" || exit $?
scp .config server_scripts/* "$ssh":~/ || exit $?
fullpath="$DIR/$PKG/ROOT"
# setup package sources
mkdir -p "$fullpath$DEST" || exit $?
mkdir -p "$fullpath$BASHDEST" || exit $?
cp completion/zpkg.bash "$fullpath$BASHDEST" || exit $?
mv zpkg "$fullpath$DEST" || exit $?
# create and send package
( (
cd pkg/zpkg || exit $? cd tmp/zpkg || exit $?
tar -cvJf zpkg.tar.xz * || exit $? tar -cvJf zpkg.tar.xz * || exit $?
# send package # send package
scp zpkg.tar.xz "$ssh":~/"$PKG_PATH" || exit $? scp zpkg.tar.xz "$ssh":~/"$PKG_PATH" || exit $?
) )
# cleanup
rm -rd "$DIR" rm -rd "$DIR"
# update database # update database
ssh "$ssh" sh database_update.sh || exit $? ssh "$ssh" sh database_update.sh || exit $?

View file

@ -0,0 +1,15 @@
#!/bin/sh
. "$(pwd)/.config"
cd "$HOME/$PKG_PATH" || exit $?
PKGLIST="$(ls ./*.tar.xz)"
{
for I in $PKGLIST
do
NAME=$(echo "$I" | sed 's|\.tar\.xz||g;s|^\./||g')
TIME=$(stat -c "%Y" "$I")
DEPS=$(tar -xOf "$I" DEPS 2>/dev/null | tr -s '\n\t ' ' ')
echo "$NAME $TIME $DEPS"
done
} > pkglist

73
server_scripts/gen_install.sh Executable file
View file

@ -0,0 +1,73 @@
#!/bin/sh
. "$(pwd)/.config"
# create install file
# header
echo '#!/bin/sh
' > install.sh
# add config
cat .config >> install.sh
# body
echo '
config_path=/etc/zpkg
while getopts ":hc:" opt;
do
case $opt in
h)
usage
exit 0
;;
c)
config_path="$OPTARG"
;;
\?)
echo "Uknown option: $OPTARG"
usage
exit 1
;;
esac
done
shift $((OPTIND-1))
if [ "$(id | cut -d"=" -f2 | cut -d"(" -f1)" -eq 0 ]
then
echo "Cannot run as root" > /dev/stderr
exit 10
fi
# Generate conf file
sudo sh -c "{
echo SSH_ADDRESS=$SSH_USER@$SSH_ADDR
echo HTTP_ADDRESS=$HTTP_ADDR/$HTTP_PATH
echo PKG_PATH=pkg
} > zpkg.conf"
# install config file
sudo mkdir -p "$config_path" || exit $?
sudo mv zpkg.conf "$config_path" || exit $?
# download zpkg
mkdir -p tmp || exit $?
(
cd tmp || exit $?
if ! wget "$HTTP_ADDR/$HTTP_PATH/zpkg.tar.xz" -q -O "zpkg.tar.xz"
then
echo "Cannot reach $HTTP_ADDR/$HTTP_PATH" > /dev/stderr
exit 1
fi
tar xf zpkg.tar.xz || exit $?
# install zpkg package
ROOT/usr/local/bin/zpkg install zpkg || exit $?
)
# cleanup
rm -rd tmp || exit $?
zpkg update-database >/dev/null || exit $?
' >> install.sh
mv install.sh "$HOME/$PKG_PATH"

36
src/config.sh Normal file
View file

@ -0,0 +1,36 @@
#!/bin/sh
virtual_config_path()
{
old_cfg_path="$config_path"
old_pkg_path="$PKG_PATH"
export config_path="$1"
export PKG_PATH="$config_path/pkg"
mkdir -p "$PKG_PATH"
ln -sf "$old_pkg_path/installed" "$PKG_PATH/installed"
}
# resolve relative config_path
config_path="$(resolve_path "$config_path" "$(pwd)")"
config_file="$config_path/zpkg.conf"
if [ ! -d "$config_path" ]
then
sudo mkdir -p "$config_path" 2>/dev/null
fi
if [ ! -f "$config_file" ]
then
echo "Error: no config file '$config_file'" > /dev/stderr
exit 1
fi
. "$config_file"
# resolve relative pkg_path
PKG_PATH="$(resolve_path "$PKG_PATH" "$config_path")"
if [ ! -d "$PKG_PATH" ]
then
sudo mkdir -p "$PKG_PATH" 2>/dev/null
fi

55
src/deploy.sh Normal file
View file

@ -0,0 +1,55 @@
#!/bin/sh
package()
{
unset clean_needed
src="$1"
pkg="$2"
echo "Packaging $(getname "$src"): $(du -sh "$src" | awk '{print $1}')iB"
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
fi
(
cd "$src"
if which pv >/dev/null 2>&1
then
tar -cf - --owner=0 --group=0 -P * | pv -s "$(du -sb . | awk '{print $1}')" | xz > "$pkg"
else
tar -cvJf - --owner=0 --group=0 * > "$pkg"
fi
)
mv "$src/$pkg" ./
if [ -n "$clean_needed" ]
then
rm -rd "$tmpdir"
fi
}
deploy_package()
{
echo "Deploying $1: $(du -sh "$1" | awk '{print $1}')iB"
scp "$1" $SSH_ADDRESS:~/'$(grep "PKG_PATH=" .config | cut -d"=" -f2-)'
}
deploy_folder()
{
archive="$(getname "$1").tar.xz"
if [ -n "$(echo "$1" | grep '\.tar\.xz$' )" ]
then
deploy_package "$1" || return 1
else
package "$1" "$archive" || return 1
deploy_package "$archive" || return 1
rm "$archive" 2> /dev/null
fi
}
update_remote_database()
{
ssh $SSH_ADDRESS "~/database_update.sh"
}

4
src/env.sh Normal file
View file

@ -0,0 +1,4 @@
#!/bin/sh
config_path=/etc/zpkg
fname="$(basename "$0")"

23
src/fetch.sh Normal file
View file

@ -0,0 +1,23 @@
#!/bin/sh
fetch_package()
{
wget "$HTTP_ADDRESS/$1.tar.xz" -q --show-progress -O "$1.tar.xz" 2>&1
return $?
}
# $1 = prefix
fetch_pkglist()
{
cd "$PKG_PATH"
$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
$1 mv pkglist_bak pkglist 2>/dev/null
return 1
else
$1 rm pkglist_bak 2>/dev/null
return 0
fi
}

58
src/install.sh Normal file
View file

@ -0,0 +1,58 @@
#!/bin/sh
unpack()
{
echo "Unpacking $1"
tar -xf "$1"
}
add_package_entry()
{
(
cd "$PKG_PATH"
if grep -q -w "$1" installed 2>/dev/null
then
sudo sed "s|$1 .*\$|$1 $(date +%s)|g" -i installed
else
sudo sh -c "echo '$1 $(date +%s)' >> installed"
fi
)
}
# $1 = source_dir, $2 = dest_dir, $3 = prefix for exec
move_files()
{
# create dirs
FOLDERS=$(find "$1" -mindepth 1 -type d | sed "s|^$1/||g")
echo "$FOLDERS" | while read -r I
do
$3 mkdir -p "$2/$I"
done
# move files
FILES=$(find "$1" -mindepth 1 ! -type d | sed "s|^$1/||g")
echo "$FILES" | while read -r I
do
$3 mv "$1/$I" "$2/$I"
done
}
install_package()
{
tmpdir="/tmp/zpkg$(random_string 5)"
mkdir -p "$tmpdir"
(
cd "$tmpdir"
if ! fetch_package "$1"
then
echo "Package '$1' not found" > /dev/stderr
return 1
fi
unpack "$1.tar.xz"
sudo mv "$1.tar.xz" "$PKG_PATH"
move_files ROOT / sudo 2>/dev/null
move_files HOME "$HOME" 2>/dev/null
add_package_entry "$1"
) || return $?
rm -rd "$tmpdir" 2>/dev/null
}

162
src/main.sh Normal file
View file

@ -0,0 +1,162 @@
#!/bin/sh
[ -z "$opt_f" ] && root_check || exit 10
if [ -n "$1" ]
then
if [ "$1" = "list" ]
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
root_check
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
shift 1
for I in $*
do
deploy_folder "$I" || exit 1
done
update_remote_database
else
usage
fi
else
usage
fi

26
src/options.sh Normal file
View file

@ -0,0 +1,26 @@
#!/bin/sh
unset opt_f
while getopts ":hc:f" opt;
do
case $opt in
h)
usage
exit 0
;;
c)
config_path="$OPTARG"
;;
f)
opt_f="y"
;;
\?)
echo "Uknown option: $OPTARG"
usage
exit 1
;;
esac
done
shift $((OPTIND-1))

30
src/print.sh Normal file
View file

@ -0,0 +1,30 @@
#!/bin/sh
usage()
{
echo "$fname [options] <operation>"
echo '
Operations:
update Update packages
update-database Update only database
install <pkg...> Install packages
remove <pkg...> Remove packages
fetch <pkg...> Fetch packages into current directory
show <pkg...> Show package files
list List currently installed packages
list-all List all packages in repository
list-outdated List outdated packages
list-removed List outdated packages
Admin operations:
deploy <path...> Deploy target to package server
Options:
-h Display this help
-c <path> Custom config path
-f Force run when root
'
}
error() {
printf "\033[1;31m%s\033[0m\n" "$1" >&2
}

38
src/remove.sh Normal file
View file

@ -0,0 +1,38 @@
#!/bin/sh
# files from stdin
# $1 = prefix
delete_files()
{
while read -r in
do
if [ -n "in" ]
then
$1 rm -d "$in" 2>/dev/null
fi
done
}
remove_package()
{
cd "$PKG_PATH"
archive="$(pwd)/$1.tar.xz"
if [ ! -f "$archive" ] || ! grep -q -w "^$1" installed
then
echo "Package '$1' not installed" > /dev/stderr
return 1
fi
echo "Removing $1"
( # delete root files
cd /
tar -tf "$archive" ROOT 2>/dev/null | sed 's|^ROOT/||g' | tac | delete_files sudo
)
( # delete home files
cd "$HOME"
tar -tf "$archive" HOME 2>/dev/null | sed 's|^HOME/||g' | tac | delete_files
)
rm "$archive" 2>/dev/null
sudo sed -i "/^$1 /d" installed
}

35
src/util.sh Normal file
View file

@ -0,0 +1,35 @@
#!/bin/sh
# random alphanumeric string of $1 chars
random_string()
{
tr -cd '[:alnum:]' < /dev/urandom | head -c$1
}
# $1 = input , $2 = prefix absolute path
resolve_path()
{
if [ "$(echo $1 | cut -c1)" != "/" ]
then
echo "$2/$1"
else
echo "$1"
fi
}
# get name of the folder
getname()
{
basename "$(readlink -f "$1")"
}
# return error if user is root
root_check()
{
if [ "$(id | cut -d'=' -f2 | cut -d'(' -f1)" -eq 0 ]
then
echo "Cannot run as root" > /dev/stderr
return $1
fi
return 0
}

77
src/view.sh Normal file
View file

@ -0,0 +1,77 @@
#!/bin/sh
deps()
{
cd "$PKG_PATH"
grep -w "^$1" pkglist | cut -d' ' -f3-
}
resolve_packages()
{
RET=0
cd "$PKG_PATH"
for I in $*
do
if ! grep -wq "^$I" pkglist
then
[ "$LOG" = "true" ] && echo "Package '$I' not found" > /dev/stderr
RET=1
else
echo "$I"
fi
done
return $RET
}
# env: INCLUDE_PACKAGES
resolve_deps()
{
ALLDEPS=""
for I in $*
do
ALLDEPS="$ALLDEPS $(deps $I)"
done
[ "$INCLUDE_PACKAGES" = "true" ] && ALLDEPS="$ALLDEPS $*"
echo "$ALLDEPS" | tr -s ' \n' '\n' | sort | uniq | sed '/^$/d'
}
is_installed()
{
cd "$PKG_PATH"
grep -qw "^$1" installed
return $?
}
view_package()
{
cd "$PKG_PATH"
tar -tf "$1.tar.xz" | sed "s|^ROOT/|/|g ; /\/$/d ; s|^HOME/|$HOME/|g ; /^DEPS/d"
}
removed_packages()
{
cd "$PKG_PATH"
cat installed 2>/dev/null | while read -r in
do
name=$(echo "$in" | awk '{print $1}')
rem=$(grep -w "^$name" pkglist | awk '{print $2}')
if [ -z "$rem" ] ; then
echo $name
fi
done
}
outdated_packages()
{
cd "$PKG_PATH"
cat installed 2>/dev/null | while read -r in
do
name=$(echo "$in" | awk '{print $1}')
loc=$(echo "$in" | awk '{print $2}')
rem=$(grep -w "^$name" pkglist | awk '{print $2}')
if [ -n "$rem" ] && [ "$loc" -lt "$rem" ]
then
echo $name
fi
done
}

368
src/zpkg
View file

@ -1,368 +0,0 @@
#!/bin/sh
config_path=/etc/zpkg
getname ()
{
basename "$(readlink -f "$1")"
}
usage ()
{
echo "zpkg [options] <operation>"
echo ""
echo "Operations:"
echo " update Update packages"
echo " update-database Update only database"
echo " install <pkg...> Install packages"
echo " remove <pkg...> Remove packages"
echo " fetch <pkg...> Fetch packages into current directory"
echo " show <pkg...> Show package files"
echo " list List currently installed packages"
echo " list-all List all packages in repository"
echo " list-outdated List outdated packages"
echo " list-removed List outdated packages"
echo "Admin operations:"
echo " deploy <path...> Deploy target to package server"
echo ""
echo "Options:"
echo " -h Display this help"
echo " -c <path> Custom config path"
}
error () {
printf "\033[1;31m%s\033[0m\n" "$1" >&2
}
root_check () {
if [ "$(id | cut -d'=' -f2 | cut -d'(' -f1)" -ne 0 ]
then
echo "Root privileges required" > /dev/stderr
exit 10
fi
}
package ()
{
echo "Packaging $(getname "$1"): $(du -sh "$1" | awk '{print $1}')iB"
(
cd "$1"
if [ -n "$(command -v pv)" ]
then
tar -cf - --owner=0 --group=0 -P * | pv -s "$(du -sb . | awk '{print $1}')" | xz > "$2"
else
tar -cvJf "$2" --owner=0 --group=0 *
fi
)
mv "$1/$2" ./
}
update_remote_database ()
{
ssh $SSH_ADDRESS "~/database_update.sh"
}
deploy_folder ()
{
archive="$(getname "$1").tar.xz"
if [ -n "$(echo "$1" | grep '\.tar\.xz$' )" ]
then
deploy_package "$1" || return 1
else
package "$1" "$archive" || return 1
deploy_package "$archive" || return 1
rm "$archive" 2> /dev/null
fi
}
deploy_package ()
{
echo "Deploying $1: $(du -sh "$1" | awk '{print $1}')iB"
scp "$1" $SSH_ADDRESS:~/'$(grep "PKG_PATH=" .config | cut -d"=" -f2-)'
}
fetch_package ()
{
if ! wget "$HTTP_ADDRESS/$1.tar.xz" -q --show-progress -O "$1.tar.xz" 2>&1
then
echo "Package '$1' not found" > /dev/stderr
return 1
else
return 0
fi
}
add_package_entry ()
{
cd "$config_path"
if grep -q -w "$1" installed 2>/dev/null
then
sed "s|$1 .*|$1 $(date +%s)|g" -i installed
else
echo "$1 $(date +%s)" >> installed
fi
}
fetch_pkglist ()
{
cd "$config_path"
mv pkglist pkglist_bak 2>/dev/null
if ! wget "$HTTP_ADDRESS/pkglist" -q --show-progress -O pkglist 2>&1
then
echo "Couldn't fetch server data" > /dev/stderr
mv pkglist_bak pkglist 2>/dev/null
return 1
else
rm pkglist_bak 2>/dev/null
return 0
fi
}
view_package ()
{
cd "$PKG_PATH"
tar tf "$1.tar.xz"
}
unpack ()
{
echo "Unpacking $1"
tar xf "$1"
}
install_package ()
{
cd /
if fetch_package "$1"
then
unpack "$1.tar.xz"
mv "$1.tar.xz" "$PKG_PATH"
add_package_entry "$1"
fi
}
removed_packages ()
{
cd "$config_path"
cat installed | while read -r in
do
name=$(echo "$in" | awk '{print $1}')
rem=$(grep -w "$name" pkglist | awk '{print $2}')
if [ -z "$rem" ] ; then
echo $name
fi
done
}
outdated_packages ()
{
cd "$config_path"
cat installed | while read -r in
do
name=$(echo "$in" | awk '{print $1}')
loc=$(echo "$in" | awk '{print $2}')
rem=$(grep -w "$name" pkglist | awk '{print $2}')
if [ -n "$rem" ] && [ "$loc" -lt "$rem" ]
then
echo $name
fi
done
}
remove_package ()
{
cd "$PKG_PATH"
if [ ! -f "$1.tar.xz" ] || ! grep -q -w "$1" "$config_path/installed"
then
echo "Package '$1' not installed" > /dev/stderr
return 1
fi
echo "Removing $1"
tar tf "$1.tar.xz" | tac | while read -r in
do
rm -d "/$in" 2>/dev/null
done
rm "$1.tar.xz" 2>/dev/null
sed -i "/$1 /d" "$config_path/installed"
}
while getopts ":hc:" opt;
do
case $opt in
h)
usage
exit 0
;;
c)
config_path="$OPTARG"
;;
\?)
echo "Uknown option: $OPTARG"
usage
exit 1
;;
esac
done
config_file="$config_path/zpkg.conf"
if [ ! -d "$config_path" ]
then
mkdir -p "$config_path" 2>/dev/null
fi
if [ ! -f "$config_file" ]
then
echo "Error: no config file '$config_file'" > /dev/stderr
exit 1
fi
. "$config_file"
if [ "$(echo $PKG_PATH | cut -c1)" != "/" ]
then
PKG_PATH="$config_path/$PKG_PATH"
fi
if [ ! -d "$PKG_PATH" ]
then
mkdir -p "$PKG_PATH" 2>/dev/null
fi
if [ -n "$1" ]
then
if [ "$1" = "list" ]
then
awk '{print $1}' "$config_path/installed" 2>/dev/null
elif [ "$1" = "list-all" ]
then
awk '{print $1}' "$config_path/pkglist" 2>/dev/null
elif [ "$1" = "fetch" ]
then
shift $((OPTIND))
if [ -z "$2" ]
then
echo "No package specified" > /dev/stderr
else
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 $((OPTIND))
for I in $*
do
view_package "$I"
done
fi
elif [ "$1" = "install" ]
then
if [ -z "$2" ]
then
echo "No package specified" > /dev/stderr
else
root_check
shift $((OPTIND))
for I in $*
do
install_package "$I"
done
fi
elif [ "$1" = "remove" ]
then
if [ -z "$2" ]
then
echo "No package specified" > /dev/stderr
else
root_check
shift $((OPTIND))
for I in $*
do
remove_package "$I"
done
fi
elif [ "$1" = "update-database" ]
then
root_check
fetch_pkglist
elif [ "$1" = "update" ]
then
root_check
fetch_pkglist || 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
old_cfg_path=$config_path
config_path=/tmp/zpkg
mkdir -p $config_path
ln -sf $old_cfg_path/installed $config_path/installed
fetch_pkglist > /dev/null || exit 1
outdated_packages
elif [ "$1" = "list-removed" ]
then
old_cfg_path=$config_path
config_path=/tmp/zpkg
mkdir -p $config_path
ln -sf $old_cfg_path/installed $config_path/installed
fetch_pkglist > /dev/null || exit 1
removed_packages
elif [ "$1" = "deploy" ]
then
shift $((OPTIND))
for I in $*
do
deploy_folder "$I" || exit 1
done
update_remote_database
else
usage
fi
else
usage
fi