You are not logged in.
Hi
I’ve written a quite short script to make creation and maintenance of meta packages even simpler.
Use case: You work on project "foo" and start to install a bunch of packages, more and more, step by step. Instead, install a "foo" meta package and add the packages you need to its dependencies, step by step. Later, remove the metapackage, removing all packages not needed otherwise.
Meta packages are nothing new. However, this approach omits PKGBUILD files with their individual directories, and running two tools (makepkg and pacman) as two different (root and non-root) users.
Try:
$ git clone 'https://github.com/s5k6/pacman-metapkg.git'
$ cd pacman-metapkg/
Do read the script before running, I’ve tried to make this a somewhat bearable experience ;-)
# ./metapkg example
When run as root, his should create and install metapkg_example on your system — a meta package pulling in the dependencies foot and meson>1.0.0 listed in the example file (chosen for no particular reason).
When run as unprivileged user, this prints the packages that would be installed on your system.
After updates to the input file example, simply run the script again. No outdated package files piling up anywhere.
Being a pretty normal pacman package, you can easily inspect
# pacman -Qi metapkg_example
and remove
# pacman -Rs metapkg_example
the meta package, -Rs also removing the dependencies if not needed otherwise.
This is so easy to use because it omits makepkg(8) — the downside of which is that I have to create the package file myself. I’m not entirely sure I’m doing this correctly. The creation of BUILDINFO is omitted, and I’m not absolutely sure the version constraints are expressed correctly.
Feedback on this is welcome.
Cheers
Stefan
Offline
What makes not using makepkg easy?
Online
... running two tools (makepkg and pacman) as two different (root and non-root) users
Your script runs quite many different tools. Unless you're referring to the need to manually type two commands - but this isn't even true: `makepkg -si`.
As only the part that needs root access running as root, that's a good thing, the principle of least privilege. Running your entire script as root might be safe, but it's certainly not a selling point. Escalating privileges only for the specific steps that require it would be better.
Last edited by Trilby (2024-06-20 12:28:34)
"UNIX is simple and coherent" - Dennis Ritchie; "GNU's Not Unix" - Richard Stallman
Offline
What makes not using makepkg easy?
Indeed, I’ve used makepkg(8) for maintaining local metapackages previously. Here’s a writeup of what it involves, and how metapkg makes it easier. For the example with a metapackage depending on foot and meson:
Initial creation of a meta package (I'll discuss makepkg -si below, it would only save us two lines here):
$ cd ~/my-metapackages
$ mkdir example
$ cd example
$ cat <<. >PKGBUILD
pkgname='metapkg_example'
pkgver=1.0.0
pkgrel=1
arch=(any)
pkgdesc='Metapackage only to hold dependencies'
package() {
depends=( foot meson )
}
.
$ makepkg
$ rm -r pkg src
$ su
# pacman -U metapkg_example-1.0.0-1-any.pkg.tar.zst
$ rm metapkg_example-1.0.0-1-any.pkg.tar.zst
compared to
# cd ~/my-metapackages
# cat <<. >example
foot
meson
.
# metapkg example
Updating a metapackage:
$ cat PKGBUILD # rather: edit accordingly
pkgname='metapkg_example'
pkgver=1.0.1
pkgrel=1
arch=(any)
pkgdesc='Metapackage only to hold dependencies'
package() {
depends=( foot xorg-xeyes )
}
$ makepkg
$ rm -r pkg src
$ su
# pacman -U metapkg_example-1.0.1-1-any.pkg.tar.zst
# pacman -Qdtq
# pacman -Rs meson
$ rm metapkg_example-1.0.1-1-any.pkg.tar.zst
compared to
# cat example # rather: edit accordingly
foot
xorg-xeyes
# metapkg example
I did not write metapkg for performance, but rather for ease of use. So yes, I was referring to the need to manually type two commands.
but this isn’t even true: makepkg -si.
Now makepkg -si is something I don’t do. Call me paranoid, but I don’t like tools to ask me for credentials. I have the habit to use exactly one way to invoke su, and only there do I enter the root password. I don’t want to grow accustomed to the habit to enter the password when a tool asks me in nice red letters. This is not against makepkg, it is a habit.
But yes, I do consider your objection about limiting privileges to where they are needed absolutely valid.
Your script runs quite many different tools.
I don’t think it does, comparatively.
I’ve looked at the programs called by the two approaches, makepkg first:
$ strace -o log1 -f \
-etrace=execve -esilent=attach,exit \
makepkg
$ sed -En 's/.*(execve\("([^"]+)",).*/\2/p' log1 > programs1
$ wc -l programs1
477 programs1
$ sort programs1 -u | wc -l
29
Add pacman:
# strace -o log2 -f \
-etrace=execve -esilent=attach,exit \
pacman -U metapkg_example-1.0.1-1-any.pkg.tar.zst
# sed -En 's/.*(execve\("([^"]+)",).*/\2/p' log2 > programs2
# wc -l programs2
44 programs2
# sort programs2 -u | wc -l
12
Together, the approach via makepkg gives
$ cat programs1 programs2 > programs
$ wc -l programs
521 programs
$ sort programs -u | wc -l
39
$ sort programs | uniq -c | sort -n | tail
3 /usr/bin/date
3 /usr/bin/gpgconf
3 /usr/bin/touch
4 /usr/bin/getopt
10 /usr/bin/mkdir
12 /usr/bin/find
14 /usr/bin/tput
27 /usr/bin/gettext
30 /usr/bin/gpg
378 /usr/bin/grep
That’s 521 calls to 39 different programs, 44 calls to 12 of them privileged, coming from pacman.
Using metapkg instead, we get:
# strace -o log3 -f \
-etrace=execve -esilent=attach,exit \
metapkg example
# sed -En 's/.*(execve\("([^"]+)",).*/\2/p' log3 > programs3
# wc -l programs3
66 programs3
# sort programs3 -u | wc -l
29
# sort programs3 | uniq -c | sort -n | tail
1 /usr/bin/zstd
1 /usr/local/bin/metapkg
1 /usr/share/libalpm/scripts/gtk-update-icon-cache
2 /usr/bin/bsdtar
2 /usr/bin/cat
2 /usr/bin/stat
2 /usr/share/libalpm/scripts/systemd-hook
3 /usr/bin/gpgconf
3 /usr/bin/pacman
30 /usr/bin/gpg
That’s 66 calls to 29 programs, admittedly all run as root.
This could be alleviated by running the first part (package creation) with dropped privileges, which probably would increase the complexity of the script.
The programs newly executed as root are precisely:
# comm -23 <(sort -u b/programs3) <(sort -u a/example/programs2)
/usr/bin/basename
/usr/bin/bsdtar
/usr/bin/cat
/usr/bin/comm
/usr/bin/date
/usr/bin/grep
/usr/bin/gzip
/usr/bin/head
/usr/bin/mkdir
/usr/bin/mktemp
/usr/bin/realpath
/usr/bin/rm
/usr/bin/sed
/usr/bin/sort
/usr/bin/stat
/usr/bin/zstd
/usr/local/bin/metapkg
With a look at the script’s readability (under 150 lines of code), its input sanitising, its intended use for locally maintaining groups of packages, and with an eye on the set of programs being called, this seems not totally irresponsible to me.
Last edited by stefan (2024-06-21 10:04:43)
Offline