Merge pull request #986 from AladW/manpage-optfix
[aurutils.git] / lib / aur-chroot
blobeab2a2325d7950aab9a9a156011b236f650cc2d2
1 #!/bin/bash
2 # aur-chroot - build packages with systemd-nspawn
3 [[ -v AUR_DEBUG ]] && set -o xtrace
4 set -o errexit
5 argv0=chroot
6 PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
7 PS4='+(${BASH_SOURCE}:${LINENO}): ${FUNCNAME[0]:+${FUNCNAME[0]}(): }'
8 machine=$(uname -m)
10 # default arguments
11 directory=/var/lib/aurbuild/$machine
12 suffix=extra
13 makechrootpkg_args=()
14 makechrootpkg_makepkg_args=()
16 # default options
17 update=0 build=0 packagelist=0 create=0 print_path=0
19 usage() {
20 cat <<EOF
21 Usage:
22 $argv0 [-BU] [--create] [-CDM path] [package...]
23 EOF
24 exit 1
27 source /usr/share/makepkg/util/option.sh
28 source /usr/share/makepkg/util/parseopts.sh
30 opt_short='C:D:M:x:BU'
31 opt_long=('directory:' 'pacman-conf:' 'makepkg-conf:' 'build' 'update' 'create'
32 'suffix:' 'bind:' 'bind-rw:' 'path' 'makepkg-args:' 'makechrootpkg-args:')
33 opt_hidden=('dump-options' 'packagelist' 'margs:' 'cargs:')
35 if ! parseopts "$opt_short" "${opt_long[@]}" "${opt_hidden[@]}" -- "$@"; then
36 usage
38 set -- "${OPTRET[@]}"
40 unset bindmounts_ro bindmounts_rw makepkg_conf pacman_conf
41 while true; do
42 case "$1" in
43 -B|--build)
44 build=1 ;;
45 -U|--update)
46 update=1 ;;
47 --create)
48 create=1 ;;
49 --path)
50 print_path=1 ;;
51 -x|--suffix)
52 shift; suffix=$1 ;;
53 # devtools options
54 -C|--pacman-conf)
55 shift; pacman_conf=$1 ;;
56 -D|--directory)
57 shift; directory=$1 ;;
58 -M|--makepkg-conf)
59 shift; makepkg_conf=$1 ;;
60 --bind)
61 shift; bindmounts_ro+=("$1") ;;
62 --bind-rw)
63 shift; bindmounts_rw+=("$1") ;;
64 --makechrootpkg-args|--cargs)
65 shift; IFS=, read -a arg -r <<< "$1"
66 makechrootpkg_args+=("${arg[@]}") ;;
67 --makepkg-args|--margs)
68 shift; IFS=, read -a arg -r <<< "$1"
69 makechrootpkg_makepkg_args+=("${arg[@]}") ;;
70 # deprecated options
71 --packagelist)
72 packagelist=1 ;;
73 # other options
74 --dump-options)
75 printf -- '--%s\n' "${opt_long[@]}" ${AUR_DEBUG+"${opt_hidden[@]}"}
76 printf -- '%s' "${opt_short}" | sed 's/.:\?/-&\n/g'
77 exit ;;
78 --) shift; break ;;
79 esac
80 shift
81 done
83 # additional makechrootpkg arguments if none are specified
84 if (( ! ${#makechrootpkg_args[@]} )); then
85 makechrootpkg_args=(-c)
88 # required for chroot creation and update
89 # if specified, copied to the container by arch-nspawn
90 makepkg_conf=${makepkg_conf:-/usr/share/devtools/makepkg-$machine.conf}
92 if [[ ! -f $makepkg_conf ]]; then
93 printf >&2 '%s: %q is not a file\n' "$argv0" "$makepkg_conf"
94 exit 2
95 elif [[ ! -r $makepkg_conf ]]; then
96 printf >&2 '%s: %q could not be read\n' "$argv0" "$makepkg_conf"
97 exit 1
100 # required for chroot creation and update
101 # if specified, copied to the container by arch-nspawn
102 pacman_conf=${pacman_conf:-/usr/share/devtools/pacman-$suffix.conf}
104 if [[ ! -f $pacman_conf ]]; then
105 printf >&2 '%s: %q is not a file\n' "$argv0" "$pacman_conf"
106 exit 2
107 elif [[ ! -r $pacman_conf ]]; then
108 printf >&2 '%s: %q could not be read\n' "$argv0" "$pacman_conf"
109 exit 1
112 # Custom elevation command
113 if [[ $AUR_PACMAN_AUTH ]]; then
114 # shellcheck disable=SC2086
115 sudo() { command -- $AUR_PACMAN_AUTH "$@"; }
118 # bind mount file:// paths to container (#461)
119 # required for update/build steps
120 while read -r key _ value; do
121 case $key=$value in
122 Server=file://*)
123 bindmounts_rw+=("${value#file://}") ;;
124 esac
125 done < <(pacman-conf --config "$pacman_conf")
126 wait "$!"
128 # create new container, required for packagelist/update/build steps
129 if (( create )); then
130 # default to base-devel or multilib-devel, unless packages are
131 # specified on the command-line.
132 # available packages depend on the configured pacman configuration
133 if (( $# )); then
134 base_packages=("$@")
136 # XXX: use pacini to not process Include directives in pacman.conf
137 # (not supported by devtools)
138 elif [[ $(pacini --section=multilib "$pacman_conf") ]] && [[ $machine == "x86_64" ]]; then
139 base_packages=('base-devel' 'multilib-devel')
140 else
141 base_packages=('base-devel')
144 # parent path is not created by mkarchroot (#371)
145 if [[ ! -d $directory ]]; then
146 sudo install -d "$directory" -m 755 -v
149 if [[ ! -d $directory/root ]]; then
150 sudo mkarchroot -C "$pacman_conf" -M "$makepkg_conf" "$directory"/root "${base_packages[@]}"
154 # arch-nspawn makes no distinction between a missing working directory
155 # and one which does not exist
156 if [[ ! -d $directory/root ]]; then
157 printf >&2 '%s: %q is not a directory\n' "$argv0" "$directory"/root
158 printf >&2 '%s: did you run aur chroot --create?\n' "$argv0"
159 exit 20
162 # print path for processing by other tools (e.g. makepkg --packagelist)
163 if (( print_path )); then
164 realpath -- "$directory"/root
165 exit $?
168 if (( packagelist )); then
169 aur build--pkglist --config="$directory"/root/etc/makepkg.conf
170 exit $?
173 if (( update )); then
174 # locking is done by systemd-nspawn
175 sudo arch-nspawn -C "$pacman_conf" -M "$makepkg_conf" "$directory"/root \
176 "${bindmounts_ro[@]/#/--bind-ro=}" \
177 "${bindmounts_rw[@]/#/--bind=}" pacman -Syu --noconfirm "$@"
180 if (( build )); then
181 # use makechrootpkg -c as default build command (sync /root container)
182 # arguments after -- (if present) are used as makechrootpkg arguments
183 sudo --preserve-env=GNUPGHOME,SSH_AUTH_SOCK,PKGDEST makechrootpkg -r "$directory" \
184 "${bindmounts_ro[@]/#/-D}" "${bindmounts_rw[@]/#/-d}" \
185 "${makechrootpkg_args[@]}" -- "${makechrootpkg_makepkg_args[@]}"
188 # vim: set et sw=4 sts=4 ft=sh: