mirror of
https://github.com/moparisthebest/arch-ppa
synced 2024-11-21 08:15:01 -05:00
Initial
This commit is contained in:
commit
0bb0b0294e
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
chroot
|
||||
*~
|
||||
pkg
|
132
README.md
Normal file
132
README.md
Normal file
@ -0,0 +1,132 @@
|
||||
arch-ppa
|
||||
========
|
||||
|
||||
arch-ppa is a tool that easily creates and maintains your own Arch
|
||||
package repositories. Kind of like the Personal Package Archives (PPA)
|
||||
that Ubuntu has, but way easier.
|
||||
|
||||
The Arch User Repository (AUR) is convenient, has tons of software, is
|
||||
generally awesome, but is inherently insecure. Anyone can upload
|
||||
anything they want to the AUR. This is why I don't like to use AUR
|
||||
helpers like `yaourt` or `pacaur`. Using the AUR with a helper
|
||||
requires you to be diligent in reviewing the PKGBUILDs it downloads,
|
||||
in order to make sure it doesn't include things like viruses or
|
||||
trojans, or downloading from a weird URL.
|
||||
|
||||
I wanted a way to maintain my own repository of PKGBUILDs, downloaded
|
||||
from the AUR, that I have manually verified. Building and installing
|
||||
packages built from those pre-verified PKGBUILDs resolves the
|
||||
insecurity of the AUR in my mind. This gives me the full power of the
|
||||
AUR, but allows me to automate my package installs in a way that I
|
||||
never felt comfortable with before. Seriously, why does pacaur have a
|
||||
`--noconfirm` option? That's scary.
|
||||
|
||||
The packages this tool builds can be hosted as a regular arch
|
||||
repository, which you put into your `/etc/pacman.conf`. The added
|
||||
convenience here is that although the packages came from the AUR, your
|
||||
clients install it through regular-old pacman.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
|
||||
Clone this repo somewhere. Everything will be self contained in this
|
||||
directory wherever you put it.
|
||||
|
||||
arch-ppa should not be run as root, but the user that does run it does
|
||||
need sudo privileges as the underlying devtools need it.
|
||||
|
||||
Run setup:
|
||||
|
||||
./arch-ppa setup
|
||||
|
||||
The setup installs a few dependencies like `devtools` and `git`. It
|
||||
also creates a chroot directory which is a container that will be used
|
||||
to build packages in a completely clean environment using
|
||||
`systemd-nspawn`.
|
||||
|
||||
Add packages from the AUR:
|
||||
|
||||
./arch-ppa add cower curlbomb pasystray
|
||||
|
||||
This downloads PKGBUILDs from the AUR for the listed packages: cower,
|
||||
curlbomb, pasystray, as well as all of their AUR dependencies, and
|
||||
placed into the `src` directory. You can put PKGBUILDs from other
|
||||
sources in the src directory too; they don't have to be from the
|
||||
AUR. Note that any PKGBUILD that lists a dependency of another
|
||||
package, that is not found in one of the arch repositories, needs to
|
||||
have it's own PKGBUILD in the `src` directory too. (The `add` command
|
||||
does this for you automatically, thanks to `cower -d -d`)
|
||||
|
||||
Build everything:
|
||||
|
||||
./arch-ppa clean ryan
|
||||
./arch-ppa build ryan
|
||||
|
||||
The build process operates on a single repository, in this example
|
||||
called `ryan`. You can maintain several repositories, each containing
|
||||
different sets of packages. Just make sure to give each repository a
|
||||
unique name.
|
||||
|
||||
The clean process removes the repository directory containing all the
|
||||
built packages. It also deletes the chroot for the repository from the
|
||||
`chroot` directory.
|
||||
|
||||
The build process creates a new package repository called `ryan` (or
|
||||
whatever you called yours.) It finds PKGBUILD files in the `src`
|
||||
directory and figures out the dependency chain and builds all the
|
||||
packages in the correct order. Additionally, you can specify
|
||||
individual package names after the repository name if you only wish to
|
||||
build certain packages. If you do specify package names, make sure to
|
||||
include all dependencies, as they will not be included otherwise.
|
||||
|
||||
The repository directory can be listed in your /etc/pacman.conf like this:
|
||||
|
||||
[ryan]
|
||||
Server = file:///home/ryan/git/arch-ppa/ryan
|
||||
SigLevel = Required TrustedOnly
|
||||
|
||||
This is the full path to the ryan repository just created. Run `pacman
|
||||
-Sy` and you should see pacman synchronize with the new repository
|
||||
name. Alternatively, upload the directory to a webserver and share it
|
||||
with all your friends.
|
||||
|
||||
The SigLevel option specifies how pacman should trust our
|
||||
repository. `Required TruestedOnly` is a strict rule that the key must
|
||||
be in the local pacman keyring and be assigned a trust level. Pacman
|
||||
will usually download the key without a problem, but you will still
|
||||
need to locally sign the key to trust it.
|
||||
|
||||
Mini gpg tutorial
|
||||
-----------------
|
||||
View your key information:
|
||||
|
||||
gpg -K
|
||||
|
||||
This should output something like this:
|
||||
|
||||
/home/ryan/.gnupg/pubring.kbx
|
||||
-----------------------------
|
||||
sec rsa2048/4BAACCF8 2016-04-15 [SC]
|
||||
uid [ultimate] test guy <ryantest@enigmacurry.com>
|
||||
ssb rsa2048/C22BDAA5 2016-04-15 [E]
|
||||
|
||||
My public key ID is 4BAACCF8. Always omit the part before the
|
||||
slash. If it didn't output any key information at all, this means you
|
||||
don't have a key yet. Create one and follow the prompts:
|
||||
|
||||
gpg --gen-key
|
||||
|
||||
Send your public key to the keyserver (replace with your ID):
|
||||
|
||||
gpg --send-keys 4BAACCF8
|
||||
|
||||
On each machine you will use your package repository, run the
|
||||
following to import the key and to locally sign (assign trust) the
|
||||
key (again, replace with your key ID):
|
||||
|
||||
sudo pacman-key -r 4BAACCF8
|
||||
sudo pacman-key --lsign-key 4BAACCF8
|
||||
|
||||
If you don't sign the key, pacman will complain that your packages are
|
||||
not trusted.
|
211
arch-ppa
Executable file
211
arch-ppa
Executable file
@ -0,0 +1,211 @@
|
||||
BASEDIR=$(cd $(dirname $0); pwd)
|
||||
CHROOT=$BASEDIR/chroot
|
||||
|
||||
if [ `whoami` == 'root' ]; then
|
||||
echo "Must not be run as root."
|
||||
exit 1;
|
||||
fi
|
||||
|
||||
exe() { echo "\$ $@" ; "$@" ; }
|
||||
|
||||
create_chroot() {
|
||||
(
|
||||
set -e
|
||||
if [ ! -d $CHROOT ]; then
|
||||
echo "## Creating arch chroot ..."
|
||||
exe mkdir $CHROOT
|
||||
exe mkarchroot $CHROOT/root base-devel
|
||||
# install cower:
|
||||
TMP_BUILD=`mktemp -d`
|
||||
exe cd $TMP_BUILD
|
||||
curl https://aur.archlinux.org/cgit/aur.git/snapshot/cower.tar.gz | tar xz
|
||||
exe cd cower
|
||||
exe makechrootpkg -r $CHROOT -l root -- -i
|
||||
exe rm -rf $TMP_BUILD
|
||||
echo "## Root chroot build complete."
|
||||
fi
|
||||
)
|
||||
}
|
||||
|
||||
install_system_deps() {
|
||||
(
|
||||
set -e
|
||||
pkg_dep() {
|
||||
if !(pacman -Q $1 > /dev/null 2>&1); then
|
||||
echo "Installing $1..."
|
||||
exe sudo pacman -S --noconfirm $1
|
||||
fi
|
||||
}
|
||||
pkg_dep devtools
|
||||
pkg_dep git
|
||||
)
|
||||
}
|
||||
|
||||
package_build() {
|
||||
# Build a package in a container. $1=container $2=package
|
||||
# PKGBUILD must already exist in src/
|
||||
# If package has dependencies we also maintain in src/, recursively build those first.
|
||||
(
|
||||
set -e
|
||||
if [ "$#" -ne 2 ]; then
|
||||
echo "package_build takes two args: repo_name and package_name"
|
||||
return 1
|
||||
fi
|
||||
repo_name=$1
|
||||
package_name=$2
|
||||
setup
|
||||
pkgdir=$BASEDIR/src/$package_name
|
||||
if [ ! -d $pkgdir ]; then
|
||||
echo "Package $package_name not found in $pkgdir"
|
||||
echo "Try running: package_add $package_name"
|
||||
return 1
|
||||
fi
|
||||
if [ ! -f $pkgdir/PKGBUILD ]; then
|
||||
echo "Cannot find PKGBUILD in $pkgdir"
|
||||
return 1
|
||||
fi
|
||||
if (arch-nspawn $CHROOT/$repo_name pacman -Q $package_name > /dev/null 2>&1); then
|
||||
echo "Package $package_name already built"
|
||||
return
|
||||
fi
|
||||
# Find and build dependencies:
|
||||
find_deps $package_name | while read dep; do
|
||||
# Build the dep if we haven't already yet:
|
||||
if !(arch-nspawn $CHROOT/$repo_name pacman -Q $dep > /dev/null 2>&1); then
|
||||
package_build $repo_name $dep
|
||||
fi
|
||||
done
|
||||
# Build package:
|
||||
cd $pkgdir
|
||||
rm -f *.pkg.tar.xz
|
||||
mkdir -p $BASEDIR/$repo_name
|
||||
exe makechrootpkg -r $CHROOT -l $repo_name -- -i
|
||||
exe mv *.pkg.tar.xz $BASEDIR/$repo_name
|
||||
)
|
||||
}
|
||||
|
||||
sign_packages() {
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "sign_packages requires specifying the list of packages to sign"
|
||||
return 1
|
||||
fi
|
||||
(
|
||||
set -e
|
||||
cd $(dirname $1)
|
||||
for pkg in "$@"; do
|
||||
gpg --detach-sign --use-agent $pkg
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
find_deps() {
|
||||
# Inspect package srcinfo and pull out the dependencies that we maintain in src
|
||||
(
|
||||
set -e
|
||||
setup
|
||||
cat $BASEDIR/src/$1/.SRCINFO | sed -nr 's/^\W*depends = ([-a-zA-Z0-9]+).*$/\1/p' | while read dep; do
|
||||
if [ -d $BASEDIR/src/$dep ]; then
|
||||
echo $dep
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
add() {
|
||||
# Add packages and their AUR dependencies to src
|
||||
(
|
||||
set -e
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Must specify package(s) to add"
|
||||
return 1
|
||||
fi
|
||||
setup
|
||||
if [ ! -d $BASEDIR/src ]; then
|
||||
mkdir $BASEDIR/src
|
||||
fi
|
||||
for pkg in "$@"; do
|
||||
arch-nspawn $CHROOT/root --bind=$BASEDIR/src:/src cower -q -t /src -d -d $pkg
|
||||
done
|
||||
sudo chown $USER -R $BASEDIR/src
|
||||
echo "## All requested packages added"
|
||||
)
|
||||
}
|
||||
|
||||
list() {
|
||||
if [ "$#" -ne 1 ]; then
|
||||
echo "Must specify repository name to list"
|
||||
return 1
|
||||
fi
|
||||
setup
|
||||
arch-nspawn $CHROOT/$1 pacman -Qm
|
||||
}
|
||||
|
||||
setup() {
|
||||
mkdir -p $BASEDIR/src
|
||||
install_system_deps
|
||||
create_chroot
|
||||
}
|
||||
|
||||
clean() {
|
||||
(
|
||||
set -e
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Must specify repository names to clean"
|
||||
return 1
|
||||
fi
|
||||
for repo in "$@"; do
|
||||
# Clean repository and chroot
|
||||
if [ -d $BASEDIR/chroot/$repo ]; then
|
||||
exe sudo rm -rf $BASEDIR/chroot/$repo $BASEDIR/chroot/$repo.lock
|
||||
fi
|
||||
if [ -d $BASEDIR/$repo ]; then
|
||||
exe rm -rf $BASEDIR/$repo
|
||||
fi
|
||||
done
|
||||
)
|
||||
}
|
||||
|
||||
build() {
|
||||
(
|
||||
set -e
|
||||
if [ "$#" -lt 1 ]; then
|
||||
echo "Must specify repository name to build (and optional package list to include)"
|
||||
return 1
|
||||
fi
|
||||
setup
|
||||
repo_name=$1
|
||||
mkdir -p $BASEDIR/$repo_name
|
||||
shift
|
||||
if [ "$#" -gt 0 ]; then
|
||||
# Build only requested packages
|
||||
for pkg in "$@"; do
|
||||
package_build $repo_name $pkg
|
||||
done
|
||||
echo "## All requested packages built"
|
||||
else
|
||||
# Build all packages:
|
||||
cd $BASEDIR/src
|
||||
find -type d | sed 's/\.\///' | tail -n +2 | while read pkg; do
|
||||
package_build $repo_name $pkg
|
||||
done
|
||||
echo "## All packages built"
|
||||
fi
|
||||
echo "## Updating repository database"
|
||||
cd $BASEDIR/$repo_name
|
||||
if [ `ls *.pkg.tar.xz 2> /dev/null | wc -l` -lt 1 ]; then
|
||||
echo "No packages found in $BASEDIR/$repo_name"
|
||||
return 1;
|
||||
fi
|
||||
sign_packages *.pkg.tar.xz
|
||||
repo-add $repo_name.db.tar.gz *.pkg.tar.xz
|
||||
sign_packages $repo_name.db
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
if [ "$#" -gt 0 ]; then
|
||||
$*
|
||||
else
|
||||
echo "Must specify a command, eg: add, build, list, clean"
|
||||
exit 1
|
||||
fi
|
Loading…
Reference in New Issue
Block a user