Skip to content

Commit 81bcfbc

Browse files
committed
feat: apt wrapper
Signed-off-by: Brian Ketelsen <[email protected]>
1 parent a51b159 commit 81bcfbc

File tree

3 files changed

+134
-0
lines changed

3 files changed

+134
-0
lines changed

build_files/build

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#!/bin/bash
22
set -ouex pipefail
33

4+
5+
6+
47
# Repository setup
58
mkdir -p /etc/apt/keyrings
69
curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.gpg
@@ -176,3 +179,20 @@ sed -i "s/^BUILD_ID=.*/BUILD_ID=\"$BUILD_ID\"/" /usr/lib/os-release
176179
# and avoid issues with /var/opt being mounted on top
177180
mkdir -p "/usr/share/factory/opt/incus"
178181
mv /opt/incus /usr/share/factory/opt/
182+
183+
# probably belong in build_files/shared/finalize, but
184+
# Make wrapper scripts executable
185+
chmod +x /usr/libexec/apt-wrapper /usr/libexec/dpkg-wrapper 2>/dev/null || true
186+
187+
188+
189+
# Set up apt/dpkg wrappers for read-only operation
190+
# Move real binaries and replace with wrappers
191+
if [ -f /usr/libexec/apt-wrapper ] && [ ! -f /usr/bin/apt.real ]; then
192+
mv /usr/bin/apt /usr/bin/apt.real
193+
ln -sf /usr/libexec/apt-wrapper /usr/bin/apt
194+
fi
195+
if [ -f /usr/libexec/dpkg-wrapper ] && [ ! -f /usr/bin/dpkg.real ]; then
196+
mv /usr/bin/dpkg /usr/bin/dpkg.real
197+
ln -sf /usr/libexec/dpkg-wrapper /usr/bin/dpkg
198+
fi
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
#!/bin/bash
2+
# Wrapper for apt that allows read-only operations on immutable systems
3+
# but blocks package installation/removal with a helpful message
4+
5+
REAL_APT=/usr/bin/apt.real
6+
7+
# Read-only commands that should always work
8+
readonly_commands=(
9+
"list"
10+
"search"
11+
"show"
12+
"showsrc"
13+
"depends"
14+
"rdepends"
15+
"policy"
16+
"madison"
17+
"changelog"
18+
"source"
19+
"download"
20+
"moo"
21+
"help"
22+
"--help"
23+
"-h"
24+
"--version"
25+
"-v"
26+
)
27+
28+
# Check if the first non-option argument is a read-only command
29+
for arg in "$@"; do
30+
# Skip options
31+
[[ "$arg" == -* ]] && continue
32+
33+
# Check if it's a read-only command
34+
for cmd in "${readonly_commands[@]}"; do
35+
if [[ "$arg" == "$cmd" ]]; then
36+
exec "$REAL_APT" "$@"
37+
fi
38+
done
39+
40+
# First non-option arg wasn't a read-only command
41+
break
42+
done
43+
44+
# For any other command, check if we're on an immutable system
45+
if [[ -f /run/ostree-booted ]] || [[ -f /run/nbc-booted ]] || [[ -d /sysroot/ostree ]]; then
46+
echo "Error: This is an immutable system (bootc/ostree/nbc)." >&2
47+
echo "" >&2
48+
echo "Package installation/removal is not supported at runtime." >&2
49+
echo "To modify the system, you need to:" >&2
50+
echo " 1. Modify the Containerfile and rebuild the image, or" >&2
51+
echo " 2. Use 'bootc switch' to switch to a different image" >&2
52+
echo "" >&2
53+
echo "For user applications, consider using:" >&2
54+
echo " - Flatpak: flatpak install <app>" >&2
55+
echo " - Homebrew: brew install <package>" >&2
56+
echo " - Distrobox: distrobox create && distrobox enter" >&2
57+
echo "" >&2
58+
echo "Read-only apt commands still work: apt list, apt search, apt show" >&2
59+
exit 1
60+
fi
61+
62+
# If not immutable (e.g., in a container build), run normally
63+
exec "$REAL_APT" "$@"
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#!/bin/bash
2+
# Wrapper for dpkg that allows read-only operations on immutable systems
3+
# but blocks package installation/removal with a helpful message
4+
5+
REAL_DPKG=/usr/bin/dpkg.real
6+
7+
# Read-only options (these query the database without modifying it)
8+
# Run normally if ANY of these are the primary action
9+
for arg in "$@"; do
10+
case "$arg" in
11+
-l|--list|-L|--listfiles|-s|--status|-S|--search|-p|--print-avail|\
12+
--get-selections|--print-architecture|--print-foreign-architectures|\
13+
--compare-versions|--help|--version|-\?|--license|--audit|-C|\
14+
--yet-to-unpack|--predep-package|--admindir=*|--instdir=*|--root=*)
15+
exec "$REAL_DPKG" "$@"
16+
;;
17+
esac
18+
done
19+
20+
# Check for query options that might appear anywhere
21+
has_query_option=false
22+
for arg in "$@"; do
23+
case "$arg" in
24+
-l|--list|-L|--listfiles|-s|--status|-S|--search|-p|--print-avail)
25+
has_query_option=true
26+
break
27+
;;
28+
esac
29+
done
30+
31+
if $has_query_option; then
32+
exec "$REAL_DPKG" "$@"
33+
fi
34+
35+
# For any other command, check if we're on an immutable system
36+
if [[ -f /run/ostree-booted ]] || [[ -f /run/nbc-booted ]] || [[ -d /sysroot/ostree ]]; then
37+
echo "Error: This is an immutable system (bootc/ostree/nbc)." >&2
38+
echo "" >&2
39+
echo "Direct package manipulation is not supported at runtime." >&2
40+
echo "To modify the system, rebuild the container image." >&2
41+
echo "" >&2
42+
echo "Read-only dpkg commands still work:" >&2
43+
echo " dpkg -l # List installed packages" >&2
44+
echo " dpkg -L <pkg> # List files in a package" >&2
45+
echo " dpkg -s <pkg> # Show package status" >&2
46+
echo " dpkg -S <file> # Find which package owns a file" >&2
47+
exit 1
48+
fi
49+
50+
# If not immutable (e.g., in a container build), run normally
51+
exec "$REAL_DPKG" "$@"

0 commit comments

Comments
 (0)