Major rework:
- dependencies - HOME and ROOT filesystems
This commit is contained in:
parent
0eef1475a3
commit
ce4bf5ea95
20 changed files with 708 additions and 436 deletions
44
README.md
44
README.md
|
|
@ -10,7 +10,6 @@ Official repo: [http://zawz.net/zpkg](http://zawz.net/zpkg)
|
|||
## As user
|
||||
|
||||
Requirements:
|
||||
- curl
|
||||
- sudo
|
||||
- wget
|
||||
- tar
|
||||
|
|
@ -21,12 +20,25 @@ Optional:
|
|||
### Installing
|
||||
|
||||
```shell
|
||||
curl -SO http://zawz.net/zpkg/install.sh
|
||||
sudo sh install.sh
|
||||
wget http://zawz.net/zpkg/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
|
||||
|
||||
|
||||
#### 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
|
||||
|
||||
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
|
||||
|
||||
### 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
|
||||
|
||||
`zpkg deploy <pkg...>`
|
||||
Targets are architectured as the linux filesystem
|
||||
`zpkg deploy <dir...>`
|
||||
> Target directories are structured as described above
|
||||
> The package name is the name of the directory
|
||||
|
||||
## Functionality
|
||||
|
||||
- Install packages
|
||||
- Remove packages
|
||||
- Update packages
|
||||
- Install/Remove/Update packages
|
||||
- Dependency resolution
|
||||
- Config redirection
|
||||
- User Home capability
|
||||
|
||||
### Non-present functionality
|
||||
|
||||
- Dependencies
|
||||
- Versions
|
||||
- Multi-repo
|
||||
|
||||
|
|
|
|||
24
compile.sh
Executable file
24
compile.sh
Executable 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
|
||||
|
|
@ -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
|
||||
|
|
@ -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"
|
||||
|
|
@ -4,25 +4,32 @@
|
|||
|
||||
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
|
||||
PKG=zpkg
|
||||
DEST=/usr/local/bin
|
||||
BASHDEST=/etc/bash_completion.d
|
||||
mkdir -p "$DIR/$PKG$DEST" || exit $?
|
||||
mkdir -p "$DIR/$PKG$BASHDEST" || exit $?
|
||||
cp src/zpkg.bash "$ZPKG_PKG_PATH/$PKG$BASHDEST" || exit $?
|
||||
cp src/zpkg "$ZPKG_PKG_PATH/$PKG$DEST" || exit $?
|
||||
|
||||
# build
|
||||
./compile.sh || 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 $?
|
||||
# send package
|
||||
scp zpkg.tar.xz "$ssh":~/"$PKG_PATH" || exit $?
|
||||
)
|
||||
# cleanup
|
||||
rm -rd "$DIR"
|
||||
# update database
|
||||
ssh "$ssh" sh database_update.sh || exit $?
|
||||
|
|
|
|||
15
server_scripts/database_update.sh
Executable file
15
server_scripts/database_update.sh
Executable 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
73
server_scripts/gen_install.sh
Executable 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
36
src/config.sh
Normal 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
55
src/deploy.sh
Normal 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
4
src/env.sh
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
#!/bin/sh
|
||||
|
||||
config_path=/etc/zpkg
|
||||
fname="$(basename "$0")"
|
||||
23
src/fetch.sh
Normal file
23
src/fetch.sh
Normal 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
58
src/install.sh
Normal 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
162
src/main.sh
Normal 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
26
src/options.sh
Normal 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
30
src/print.sh
Normal 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
38
src/remove.sh
Normal 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
35
src/util.sh
Normal 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
77
src/view.sh
Normal 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
368
src/zpkg
|
|
@ -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
|
||||
Loading…
Reference in a new issue