Add support for incremental updates
The 'portzap install' command would always install the entire ports tree, whether for the first time or on a subsequent update where copying the entire tree isn't neccessary. This change is an attempt at only copying ports that have been modified in some way. Rather than dealing with modifications file by file, a port that is found to have modifications has its entire directory copied. This makes life easier but is a bit slower.
This commit is contained in:
parent
62dda8940b
commit
8763cd2b82
5 changed files with 93 additions and 31 deletions
|
@ -5,19 +5,20 @@ portzap is a utility for staying up to date with the
|
|||
The utility stores a transient copy of the ports tree in `/home/_portzap/ports/`.
|
||||
The transient copy can be created, and updated by an unprivileged user account
|
||||
who is a member of the `_portzap` group. The transient copy can then be installed
|
||||
into the `/usr/ports` directory by root.
|
||||
into the `/usr/ports/` directory by root.
|
||||
|
||||
## Usage
|
||||
|
||||
* `portzap clone` <br>
|
||||
This command clones HardenedBSD's ports tree into `/home/_portzap/ports`.
|
||||
This command clones HardenedBSD's ports tree into `/home/_portzap/ports/`.
|
||||
|
||||
* `portzap pull` <br>
|
||||
This command pulls updates into `/home/_portzap/ports`.
|
||||
This command pulls updates into `/home/_portzap/ports/`.
|
||||
|
||||
* `portzap install` <br>
|
||||
This command should be run as root. <br>
|
||||
The command installs `/home/_portzap/ports` into `/usr/ports`.
|
||||
The command installs `/home/_portzap/ports/` into `/usr/ports/`. <br>
|
||||
After the first installation, future installations try to save time by being incremental.
|
||||
|
||||
## Sources
|
||||
|
||||
|
|
59
bin/portzap
59
bin/portzap
|
@ -6,6 +6,7 @@
|
|||
# Configuration
|
||||
ports_url="https://git.hardenedbsd.org/hardenedbsd/ports.git"
|
||||
ports_dir="/usr/ports/"
|
||||
portzap_rev="$ports_dir/.portzap_last_rev"
|
||||
portzap_dir="/home/_portzap/ports"
|
||||
libexec_dir=$(realpath $(dirname $0)/../libexec/portzap/)
|
||||
|
||||
|
@ -17,6 +18,9 @@ pull_mask=007
|
|||
|
||||
##
|
||||
# Utils
|
||||
. $libexec_dir/functions/perms.sh
|
||||
. $libexec_dir/functions/fs.sh
|
||||
. $libexec_dir/functions/git.sh
|
||||
exit_on_missing_deps() {
|
||||
deps=$1
|
||||
for dep in $deps; do
|
||||
|
@ -28,24 +32,6 @@ exit_on_missing_deps() {
|
|||
done
|
||||
}
|
||||
|
||||
has_portzap_access() {
|
||||
groups=$(id -Gn)
|
||||
in_group=1
|
||||
for g in $groups; do
|
||||
if [ $g = "_portzap" ];
|
||||
then
|
||||
in_group=0
|
||||
fi
|
||||
done
|
||||
return $in_group
|
||||
}
|
||||
|
||||
user_is_not_root() {
|
||||
user_id=$(id -u)
|
||||
result=$(test $user_id -ne "0")
|
||||
return $result
|
||||
}
|
||||
|
||||
##
|
||||
# Commands
|
||||
help() {
|
||||
|
@ -98,16 +84,35 @@ install() {
|
|||
exit 1
|
||||
fi
|
||||
|
||||
echo "Please wait..."
|
||||
cd $portzap_dir
|
||||
find -s . -maxdepth 1 -type f \
|
||||
\( -not -name ".gitignore" \) \
|
||||
\( -not -name ".arcconfig" \) \
|
||||
-exec $libexec_dir/install-file $ports_dir {} +
|
||||
find -s . -maxdepth 1 -type d \
|
||||
\( -not -name "." \) \
|
||||
\( -not -name ".git" \) \
|
||||
\( -not -name ".hooks" \) \
|
||||
-exec $libexec_dir/install-directory $ports_dir $libexec_dir {} +
|
||||
if [ -e "$portzap_rev" ]; then
|
||||
rev=$(cat $portzap_rev)
|
||||
port_dirs=$(modified_ports $rev)
|
||||
rm_files=$(git diff --name-only --diff-filter=D $rev..HEAD)
|
||||
for file in $rm_files; do
|
||||
rm $ports_dir/$file
|
||||
done
|
||||
for dir in $port_dirs; do
|
||||
if [ -f "$dir" ]; then
|
||||
$libexec_dir/install-file $ports_dir $dir
|
||||
else
|
||||
$libexec_dir/install-directory $ports_dir $libexec_dir $dir
|
||||
fi
|
||||
done
|
||||
else
|
||||
find -s . -maxdepth 1 -type f \
|
||||
\( -not -name ".gitignore" \) \
|
||||
\( -not -name ".arcconfig" \) \
|
||||
-exec $libexec_dir/install-file $ports_dir {} +
|
||||
find -s . -maxdepth 1 -type d \
|
||||
\( -not -name "." \) \
|
||||
\( -not -name ".git" \) \
|
||||
\( -not -name ".hooks" \) \
|
||||
-exec $libexec_dir/install-directory $ports_dir $libexec_dir {} +
|
||||
fi
|
||||
echo $(git rev-parse HEAD) > $portzap_rev
|
||||
echo "Done."
|
||||
}
|
||||
|
||||
case $1 in
|
||||
|
|
24
libexec/portzap/functions/fs.sh
Executable file
24
libexec/portzap/functions/fs.sh
Executable file
|
@ -0,0 +1,24 @@
|
|||
#!/bin/sh
|
||||
|
||||
##
|
||||
# Returns the depth of a path
|
||||
port_depth() {
|
||||
p=$1
|
||||
result=$(echo $p | tr '/' '\n' | grep . | wc -l)
|
||||
return $result
|
||||
}
|
||||
|
||||
##
|
||||
# Returns the entry point for a port relative to /usr/ports
|
||||
# (eg: ./ftp/curl/)
|
||||
port_dirname() {
|
||||
p=$1
|
||||
port_depth "$p"
|
||||
depth=$?
|
||||
if [ $depth -gt 2 ]; then
|
||||
p=$(dirname $p)
|
||||
port_dirname "$p"
|
||||
else
|
||||
echo $p
|
||||
fi
|
||||
}
|
11
libexec/portzap/functions/git.sh
Normal file
11
libexec/portzap/functions/git.sh
Normal file
|
@ -0,0 +1,11 @@
|
|||
##
|
||||
# Returns a list of new, and modified files between two points / commits.
|
||||
modified_ports() {
|
||||
rev=$1
|
||||
files=$(git diff --name-only --diff-filter=AM $rev..HEAD)
|
||||
for file in $files; do
|
||||
dirs="$dirs $(port_dirname $file)"
|
||||
done
|
||||
dirs=$(echo $dirs | tr ' ' '\n' | uniq)
|
||||
echo $dirs
|
||||
}
|
21
libexec/portzap/functions/perms.sh
Normal file
21
libexec/portzap/functions/perms.sh
Normal file
|
@ -0,0 +1,21 @@
|
|||
##
|
||||
# Returns true when current user is in _portzap group
|
||||
has_portzap_access() {
|
||||
groups=$(id -Gn)
|
||||
in_group=1
|
||||
for g in $groups; do
|
||||
if [ $g = "_portzap" ];
|
||||
then
|
||||
in_group=0
|
||||
fi
|
||||
done
|
||||
return $in_group
|
||||
}
|
||||
|
||||
##
|
||||
# Returns true when current user is root
|
||||
user_is_not_root() {
|
||||
user_id=$(id -u)
|
||||
result=$(test $user_id -ne "0")
|
||||
return $result
|
||||
}
|
Loading…
Reference in a new issue