forked from artix/artools
		
	Compare commits
	
		
			50 Commits
		
	
	
		
			0.32.2
			...
			artools/0.
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| ac672b1623 | |||
| d3af81c7ec | |||
| 5a7ddda12c | |||
| 17f079f4d5 | |||
| ebb601d90f | |||
| bd5e8b403a | |||
| ce17e42320 | |||
| 885f852ca8 | |||
| 3bb00c8c69 | |||
| 5862982bbb | |||
| 608c929d4f | |||
| 35bb702c78 | |||
| 1cebf87b28 | |||
| 3d6d8cc255 | |||
| 6c98f044af | |||
| a342de8b30 | |||
| de2bf041ae | |||
| 8c58b3fa26 | |||
| 85f1e1208b | |||
| 1b7d3b6fdd | |||
| 1d2d57e795 | |||
| bec37d8236 | |||
| 3830037e44 | |||
| acea4e1deb | |||
| 87a95d998e | |||
| 38c0528697 | |||
| e8708ce0c5 | |||
| 41947d9367 | |||
| 858a5f7aed | |||
| 718e2cfc7f | |||
| e3c9a47c97 | |||
| 7dd3f27c12 | |||
| 6d5235a115 | |||
| b14524dca4 | |||
| 5faa5ef599 | |||
| 334a2c2487 | |||
| 2bc6150221 | |||
| 645563b0c5 | |||
| fb8da6fedd | |||
| c31acae021 | |||
| ca1082a8e5 | |||
| 6f12273730 | |||
| b9b15f549d | |||
| c81b643fb2 | |||
| 4362707456 | |||
| 5d8cdf19fe | |||
| 7084a086fa | |||
| 8744bb5355 | |||
| 75747a7d9d | |||
| 75d1e7ce2a | 
							
								
								
									
										28
									
								
								.github/workflows/lint.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										28
									
								
								.github/workflows/lint.yaml
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1,28 @@ | |||||||
|  | name: Artools shellcheck | ||||||
|  | run-name: ${{ gitea.actor }} | ||||||
|  | on: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - artools/0.32.x | ||||||
|  |       - master | ||||||
|  |     tags: | ||||||
|  |       - 0.* | ||||||
|  |   pull_request: | ||||||
|  |     types: [opened, reopened] | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   lint: | ||||||
|  |     runs-on: ubuntu-latest | ||||||
|  |     steps: | ||||||
|  |       - name: checkout repo | ||||||
|  |         uses: actions/checkout@main | ||||||
|  |       - name: build artools | ||||||
|  |         run: make | ||||||
|  |       - name: shellcheck artools | ||||||
|  |         uses: ludeeus/action-shellcheck@master | ||||||
|  |         env: | ||||||
|  |           SHELLCHECK_OPTS: -x -e SC2034 | ||||||
|  |         with: | ||||||
|  |           scandir: './build/bin' | ||||||
|  |           format: tty | ||||||
|  |  | ||||||
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @@ -12,3 +12,5 @@ PKGBUILD | |||||||
| contrib/artixlinux | contrib/artixlinux | ||||||
| build/ | build/ | ||||||
| tmp/ | tmp/ | ||||||
|  | checks/ | ||||||
|  | check.sh | ||||||
|   | |||||||
							
								
								
									
										6
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| SHELL=/bin/bash | SHELL=/bin/bash | ||||||
|  |  | ||||||
| V=0.31 | V=0.32 | ||||||
| BUILDTOOLVER ?= $(V) | BUILDTOOLVER ?= $(V) | ||||||
|  |  | ||||||
| CHROOTVER=0.12 | CHROOTVER=0.12 | ||||||
| @@ -32,7 +32,6 @@ MAKEPKG_CONFIGS=$(wildcard config/makepkg/*) | |||||||
| PACMAN_CONFIGS=$(wildcard config/pacman/*) | PACMAN_CONFIGS=$(wildcard config/pacman/*) | ||||||
| SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*) | SETARCH_ALIASES = $(wildcard config/setarch-aliases.d/*) | ||||||
|  |  | ||||||
| TOOLS_CONFIGS_BASE=$(wildcard config/conf/*base*) |  | ||||||
| TOOLS_CONFIGS_PKG=$(wildcard config/conf/*pkg*) | TOOLS_CONFIGS_PKG=$(wildcard config/conf/*pkg*) | ||||||
| TOOLS_CONFIGS_ISO=$(wildcard config/conf/*iso*) | TOOLS_CONFIGS_ISO=$(wildcard config/conf/*iso*) | ||||||
|  |  | ||||||
| @@ -73,7 +72,6 @@ $(eval $(call buildInScript,build/lib,src/lib/,,644)) | |||||||
| conf_base: | conf_base: | ||||||
| 	@install -d $(BUILDDIR)/pacman.conf.d $(BUILDDIR)/artools | 	@install -d $(BUILDDIR)/pacman.conf.d $(BUILDDIR)/artools | ||||||
| 	@cp -a $(PACMAN_CONFIGS) $(BUILDDIR)/pacman.conf.d | 	@cp -a $(PACMAN_CONFIGS) $(BUILDDIR)/pacman.conf.d | ||||||
| 	@cp -a $(TOOLS_CONFIGS_BASE) $(BUILDDIR)/artools |  | ||||||
|  |  | ||||||
| conf_pkg: | conf_pkg: | ||||||
| 	@install -d $(BUILDDIR)/makepkg.conf.d $(BUILDDIR)/artools | 	@install -d $(BUILDDIR)/makepkg.conf.d $(BUILDDIR)/artools | ||||||
| @@ -95,8 +93,6 @@ install_base: binprogs_base | |||||||
| 	install -dm0755 $(DESTDIR)$(LIBDIR) | 	install -dm0755 $(DESTDIR)$(LIBDIR) | ||||||
| 	cp -ra $(BUILDDIR)/lib/base $(DESTDIR)$(LIBDIR) | 	cp -ra $(BUILDDIR)/lib/base $(DESTDIR)$(LIBDIR) | ||||||
|  |  | ||||||
| 	for conf in $(notdir $(TOOLS_CONFIGS_BASE)); do install -Dm0644 $(BUILDDIR)/$(TOOLS)/$$conf $(DESTDIR)$(SYSCONFDIR)/$(TOOLS)/$${conf##*/}; done |  | ||||||
|  |  | ||||||
| 	for conf in $(notdir $(PACMAN_CONFIGS)); do install -Dm0644 $(BUILDDIR)/pacman.conf.d/$$conf $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done | 	for conf in $(notdir $(PACMAN_CONFIGS)); do install -Dm0644 $(BUILDDIR)/pacman.conf.d/$$conf $(DESTDIR)$(DATADIR)/pacman.conf.d/$${conf##*/}; done | ||||||
|  |  | ||||||
| install_pkg: binprogs_pkg | install_pkg: binprogs_pkg | ||||||
|   | |||||||
							
								
								
									
										13
									
								
								README.md
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								README.md
									
									
									
									
									
								
							| @@ -45,21 +45,22 @@ artools | |||||||
|   * libisoburn |   * libisoburn | ||||||
|   * mtools |   * mtools | ||||||
|   * squashfs-tools |   * squashfs-tools | ||||||
|  |   * go-yq | ||||||
|  |  | ||||||
|  |  | ||||||
| #### Configuration | #### Configuration | ||||||
|  |  | ||||||
| artools-{base,pkg,iso}.conf are the configuration files for artools. | artools-{pkg,iso}.conf are the configuration files for artools. | ||||||
| By default, the config files are installed in | By default, the config files are installed in | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| /etc/artools/artools-{base,pkg,iso}.conf | /etc/artools/artools-{pkg,iso}.conf | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| A user artools-{base,pkg,iso}.conf can be placed in | A user artools-{pkg,iso}.conf can be placed in | ||||||
|  |  | ||||||
| ```bash | ```bash | ||||||
| $HOME/.config/artools/artools-{base,pkg,iso}.conf | $HOME/.config/artools/artools-{pkg,iso}.conf | ||||||
| ``` | ``` | ||||||
|  |  | ||||||
| If the userconfig is present, artools will load the userconfig values, however, if variables have been set in the systemwide | If the userconfig is present, artools will load the userconfig values, however, if variables have been set in the systemwide | ||||||
| @@ -68,8 +69,8 @@ These values take precedence over the userconfig. | |||||||
| Best practise is to leave systemwide file untouched. | Best practise is to leave systemwide file untouched. | ||||||
| By default it is commented and shows just initialization values done in code. | By default it is commented and shows just initialization values done in code. | ||||||
|  |  | ||||||
| Tools configuration is done in artools-{base,pkg,iso}.conf or by args. | Tools configuration is done in artools-{pkg,iso}.conf or by args. | ||||||
| Specifying args will override artools-{base,pkg,iso}.conf settings. | Specifying args will override artools-{pkg,iso}.conf settings. | ||||||
|  |  | ||||||
| Both, pacman.conf and makepkg.conf for chroots are loaded from | Both, pacman.conf and makepkg.conf for chroots are loaded from | ||||||
|  |  | ||||||
|   | |||||||
| @@ -1,20 +0,0 @@ | |||||||
| #!/hint/bash |  | ||||||
| # shellcheck disable=2034 |  | ||||||
|  |  | ||||||
| ############################################# |  | ||||||
| ################ artools-base ############### |  | ||||||
| ############################################# |  | ||||||
|  |  | ||||||
| # build dir where buildpkg or buildiso chroots are created |  | ||||||
| # CHROOTS_DIR=/var/lib/artools |  | ||||||
|  |  | ||||||
| # the workspace directory |  | ||||||
| # WORKSPACE_DIR="${USER_HOME}/artools-workspace" |  | ||||||
|  |  | ||||||
| # the arch to build |  | ||||||
| # ARCH=$(uname -m) |  | ||||||
|  |  | ||||||
| # default pacman.conf repos to include |  | ||||||
| # possible buildpkg values: {system,world,galaxy,lib32}{-gremlins,-goblins} |  | ||||||
| # possible buildiso values: {world,galaxy}{-gremlins,-goblins} |  | ||||||
| # REPO="world" |  | ||||||
| @@ -5,20 +5,33 @@ | |||||||
| ################ artools-iso ################ | ################ artools-iso ################ | ||||||
| ############################################# | ############################################# | ||||||
|  |  | ||||||
| # the iso storage directory | # default chroots dir where buildiso chroots are created | ||||||
|  | # CHROOTS_DIR=/var/lib/artools | ||||||
|  |  | ||||||
|  | # default workspace directory | ||||||
|  | # WORKSPACE_DIR="${USER_HOME}/artools-workspace" | ||||||
|  |  | ||||||
|  | # default arch to build | ||||||
|  | # ARCH=$(uname -m) | ||||||
|  |  | ||||||
|  | # default pacman.conf repos to include | ||||||
|  | # possible values: {world,galaxy}{-gremlins,-goblins} | ||||||
|  | # REPO="world" | ||||||
|  |  | ||||||
|  | # default iso storage directory | ||||||
| # ISO_POOL="${WORKSPACE_DIR}/iso" | # ISO_POOL="${WORKSPACE_DIR}/iso" | ||||||
|  |  | ||||||
| # the dist release; default: auto | # default dist release; default: auto | ||||||
| # ISO_VERSION=$(date +%Y%m%d) | # ISO_VERSION=$(date +%Y%m%d) | ||||||
|  |  | ||||||
| # possible values: openrc, runit, s6, suite66, dinit | # default init system, possible values: openrc, runit, s6, suite66, dinit | ||||||
| # INITSYS="openrc" | # INITSYS="openrc" | ||||||
|  |  | ||||||
| # gpg key; leave empty or commented to skip img signing | # gpg key; leave empty or commented to skip img signing | ||||||
| # GPG_KEY="" | # GPG_KEY="" | ||||||
|  |  | ||||||
| # possible values: zstd (default), xz | # default compression, possible values: zstd (default), xz | ||||||
| # COMPRESSION="zstd" | # COMPRESSION="zstd" | ||||||
|  |  | ||||||
| # zstd only: range 1..22 | # default compression level, zstd only: range 1..22 | ||||||
| # COMPRESSION_LEVEL=15 | # COMPRESSION_LEVEL=15 | ||||||
|   | |||||||
| @@ -5,9 +5,23 @@ | |||||||
| ################ artools-pkg ################ | ################ artools-pkg ################ | ||||||
| ############################################# | ############################################# | ||||||
|  |  | ||||||
| # gitea user access token for buildtree | # default chroots dir where buildpkg chroots are created | ||||||
|  | # CHROOTS_DIR=/var/lib/artools | ||||||
|  |  | ||||||
|  | # default workspace directory | ||||||
|  | # WORKSPACE_DIR="${USER_HOME}/artools-workspace" | ||||||
|  |  | ||||||
|  | # default arch to build | ||||||
|  | # ARCH=$(uname -m) | ||||||
|  |  | ||||||
|  | # default pacman.conf repos to include | ||||||
|  | # possible values: {system,world,galaxy,lib32}{-gremlins,-goblins} | ||||||
|  | # REPO="world" | ||||||
|  |  | ||||||
|  | # gitea user access token for gitea api | ||||||
| # GIT_TOKEN='' | # GIT_TOKEN='' | ||||||
|  |  | ||||||
|  | # default workspace dir for artixpkg | ||||||
| # TREE_DIR_ARTIX=${WORKSPACE_DIR}/artixlinux | # TREE_DIR_ARTIX=${WORKSPACE_DIR}/artixlinux | ||||||
|  |  | ||||||
| # default repos root for deploypkg | # default repos root for deploypkg | ||||||
|   | |||||||
| @@ -44,7 +44,8 @@ CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fno-plt -fexceptions \ | |||||||
|         -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \ |         -Wp,-D_FORTIFY_SOURCE=2 -Wformat -Werror=format-security \ | ||||||
|         -fstack-clash-protection -fcf-protection" |         -fstack-clash-protection -fcf-protection" | ||||||
| CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" | CXXFLAGS="$CFLAGS -Wp,-D_GLIBCXX_ASSERTIONS" | ||||||
| LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro,-z,now" | LDFLAGS="-Wl,-O1 -Wl,--sort-common -Wl,--as-needed -Wl,-z,relro -Wl,-z,now \ | ||||||
|  |          -Wl,-z,pack-relative-relocs" | ||||||
| LTOFLAGS="-flto=auto" | LTOFLAGS="-flto=auto" | ||||||
| RUSTFLAGS="" | RUSTFLAGS="" | ||||||
| #-- Make Flags: change this for DistCC/SMP systems | #-- Make Flags: change this for DistCC/SMP systems | ||||||
|   | |||||||
							
								
								
									
										17
									
								
								contrib/iso/profile.conf.example
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								contrib/iso/profile.conf.example
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | ################ install ################ | ||||||
|  |  | ||||||
|  | # start services | ||||||
|  | # bluetoothd, cupsd, DM are added to the pkglist dynamicly | ||||||
|  | # metalog or syslog-ng is added to the pkglist dynamicly | ||||||
|  | # connmand or NetworkManager is added to the pkglist dynamicly | ||||||
|  | # only added if in array, these pkgs have no list entry | ||||||
|  |  | ||||||
|  | SERVICES=('acpid' 'bluetoothd' 'cronie' 'cupsd' 'metalog' 'connmand') | ||||||
|  |  | ||||||
|  | ################# live-session ################# | ||||||
|  |  | ||||||
|  | # default value | ||||||
|  | # PASSWORD="artix" | ||||||
|  |  | ||||||
|  | # Set to false to disable autologin in the live session | ||||||
|  | AUTOLOGIN="false" | ||||||
| @@ -8,40 +8,81 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/chroot.sh |  | ||||||
| source "${LIBDIR}"/base/chroot.sh |  | ||||||
| # shellcheck source=src/lib/base/mount.sh | # shellcheck source=src/lib/base/mount.sh | ||||||
| source "${LIBDIR}"/base/mount.sh | source "${LIBDIR}"/base/mount.sh | ||||||
|  | # shellcheck source=src/lib/base/unshare-mount.sh | ||||||
|  | source "${LIBDIR}"/base/unshare-mount.sh | ||||||
|  | # shellcheck source=src/lib/base/chroot.sh | ||||||
|  | source "${LIBDIR}"/base/chroot.sh | ||||||
|  |  | ||||||
|  |  | ||||||
|  | artix-chroot() { | ||||||
|  |     check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" | ||||||
|  | #     (( EUID == 0 )) || die 'This script must be run with root privileges' | ||||||
|  |  | ||||||
|  |     [[ -d $chrootdir ]] || die "Can't create chroot on non-directory %s" "$chrootdir" | ||||||
|  |  | ||||||
|  |     "$setup" "$chrootdir" || die "failed to setup chroot %s" "$chrootdir" | ||||||
|  |     if (( ! keepresolvconf )); then | ||||||
|  |         chroot_add_resolv_conf "$chrootdir" || die "failed to setup resolv.conf" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if ! mountpoint -q "$chrootdir"; then | ||||||
|  |         warning "$chrootdir is not a mountpoint. This may have undesirable side effects." | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     chroot_args=() | ||||||
|  |     [[ $userspec ]] && chroot_args+=(--userspec "$userspec") | ||||||
|  |  | ||||||
|  |     SHELL=/bin/bash $pid_unshare chroot "${chroot_args[@]}" -- "$chrootdir" "${args[@]}" | ||||||
|  | } | ||||||
|  |  | ||||||
| usage() { | usage() { | ||||||
|     printf 'usage: %s chroot-dir [command]\n' "${0##*/}" |     cat <<EOF | ||||||
|     printf '    -h             Print this help message\n' | usage: ${0##*/} chroot-dir [command] [arguments...] | ||||||
|     printf '\n' |  | ||||||
|     printf "    If 'command' is unspecified, %s will launch /bin/sh.\n" "${0##*/}" |     -h                  Print this help message | ||||||
|     printf '\n' |     -N                  Run in unshare mode as a regular user | ||||||
|     printf '\n' |     -u <user>[:group]   Specify non-root user and optional group to use | ||||||
|     exit "$1" |     -r                  Do not change the resolv.conf within the chroot | ||||||
|  |  | ||||||
|  | If 'command' is unspecified, ${0##*/} will launch /bin/bash. | ||||||
|  |  | ||||||
|  | Note that when using artix-chroot, the target chroot directory *should* be a | ||||||
|  | mountpoint. This ensures that tools such as pacman(8) or findmnt(8) have an | ||||||
|  | accurate hierarchy of the mounted filesystems within the chroot. | ||||||
|  |  | ||||||
|  | If your chroot target is not a mountpoint, you can bind mount the directory on | ||||||
|  | itself to make it a mountpoint, i.e. 'mount --bind /your/chroot /your/chroot'. | ||||||
|  |  | ||||||
|  | EOF | ||||||
| } | } | ||||||
|  |  | ||||||
| orig_args=("$@") | orig_args=("$@") | ||||||
|  |  | ||||||
| opts=':h' | opts=':hNu:r' | ||||||
|  |  | ||||||
| while getopts ${opts} arg; do | while getopts ${opts} arg; do | ||||||
|     case "${arg}" in |     case "${arg}" in | ||||||
|         h|?) usage 0 ;; |         h) usage; exit 0 ;; | ||||||
|  |         N) unshare=1 ;; | ||||||
|  |         u) userspec=$OPTARG ;; | ||||||
|  |         r) keepresolvconf=1 ;; | ||||||
|  |         :) die '%s: option requires an argument -- '\''%s'\' "${0##*/}" "$OPTARG" ;; | ||||||
|  |         ?) die '%s: invalid option -- '\''%s'\' "${0##*/}" "$OPTARG" ;; | ||||||
|     esac |     esac | ||||||
| done | done | ||||||
| shift $(( OPTIND - 1 )) |  | ||||||
|  |  | ||||||
| check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" | (( $# )) || die 'No chroot directory specified' | ||||||
|  |  | ||||||
| chrootdir=$1 | chrootdir="$1" | ||||||
| shift | shift | ||||||
|  |  | ||||||
| [[ -d ${chrootdir} ]] || die "Can't create chroot on non-directory %s" "${chrootdir}" | args=("$@") | ||||||
|  | if (( unshare )); then | ||||||
| chroot_api_mount "${chrootdir}" || die "failed to setup API filesystems in chroot %s" "${chrootdir}" |     setup=unshare_setup | ||||||
| chroot_add_resolv_conf "${chrootdir}" |     "$mount_unshare" bash -c "$(declare_all); artix-chroot" | ||||||
|  | else | ||||||
| SHELL=/bin/sh unshare --fork --pid chroot "${chrootdir}" "$@" |     setup=chroot_setup | ||||||
|  |     artix-chroot | ||||||
|  | fi | ||||||
|   | |||||||
| @@ -18,26 +18,50 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/mount.sh | # shellcheck source=src/lib/base/mount.sh | ||||||
| source "${LIBDIR}"/base/mount.sh | source "${LIBDIR}"/base/mount.sh | ||||||
|  | # shellcheck source=src/lib/base/unshare-mount.sh | ||||||
|  | source "${LIBDIR}"/base/unshare-mount.sh | ||||||
| # shellcheck source=src/lib/base/chroot.sh | # shellcheck source=src/lib/base/chroot.sh | ||||||
| source "${LIBDIR}"/base/chroot.sh | source "${LIBDIR}"/base/chroot.sh | ||||||
|  |  | ||||||
|  |  | ||||||
| #{{{ functions | #{{{ functions | ||||||
|  |  | ||||||
| copy_mirrorlist(){ | basestrap() { | ||||||
|     cp -a /etc/pacman.d/mirrorlist "$1/etc/pacman.d/" |     check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" | ||||||
| } | #     (( EUID == 0 )) || die 'This script must be run with root privileges' | ||||||
|  |  | ||||||
| copy_keyring(){ |     # create obligatory directories | ||||||
|     if [[ -d /etc/pacman.d/gnupg ]] && [[ ! -d $1/etc/pacman.d/gnupg ]]; then |     msg "Creating install root at %s" "$newroot" | ||||||
|         cp -a /etc/pacman.d/gnupg "$1/etc/pacman.d/" |     install -d -m755 "$newroot"/var/{cache/pacman/pkg,lib/pacman,log} | ||||||
|  |     install -d -m755 "$newroot"/{dev,run,etc/pacman.d} | ||||||
|  |     install -d -m1777 "$newroot"/tmp | ||||||
|  |     install -d -m555 "$newroot"/{sys,proc} | ||||||
|  |  | ||||||
|  |     # mount API filesystems | ||||||
|  |     "$setup" "$newroot" || die "failed to setup chroot %s" "$newroot" | ||||||
|  |  | ||||||
|  |     if [[ ! -d $newroot/etc/pacman.d/gnupg ]]; then | ||||||
|  |         if (( initkeyring )); then | ||||||
|  |             pacman-key --gpgdir "$newroot"/etc/pacman.d/gnupg --init | ||||||
|  |         elif (( copykeyring )) && [[ -d /etc/pacman.d/gnupg ]]; then | ||||||
|  |             # if there's a keyring on the host, copy it into the new root | ||||||
|  |             cp -a --no-preserve=ownership /etc/pacman.d/gnupg "$newroot/etc/pacman.d/" | ||||||
|  |         fi | ||||||
|     fi |     fi | ||||||
| } |  | ||||||
|  |  | ||||||
| create_min_fs(){ |     msg 'Installing packages to %s' "$newroot" | ||||||
|     msg "Creating install root at %s" "$1" |     if ! $pid_unshare pacman -r "$newroot" "${pacman_args[@]}"; then | ||||||
|     mkdir -m 0755 -p "$1"/var/{cache/pacman/pkg,lib/pacman,log} "$1"/{dev,run,etc/pacman.d} |         die 'Failed to install packages to new root' | ||||||
|     mkdir -m 1777 -p "$1"/tmp |     fi | ||||||
|     mkdir -m 0555 -p "$1"/{sys,proc} |  | ||||||
|  |     if (( copymirrorlist )); then | ||||||
|  |         # install the host's mirrorlist onto the new root | ||||||
|  |         cp -a /etc/pacman.d/mirrorlist "$newroot/etc/pacman.d/" | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     if (( copyconf )); then | ||||||
|  |         cp -a "$pacman_config" "$newroot/etc/pacman.conf" | ||||||
|  |     fi | ||||||
| } | } | ||||||
|  |  | ||||||
| #}}} | #}}} | ||||||
| @@ -46,50 +70,69 @@ newroot=/mnt | |||||||
|  |  | ||||||
| hostcache=0 | hostcache=0 | ||||||
| copykeyring=1 | copykeyring=1 | ||||||
|  | initkeyring=0 | ||||||
| copymirrorlist=1 | copymirrorlist=1 | ||||||
| pacmode=-Sy | pacmode=-Sy | ||||||
|  | pacman_args=() | ||||||
|  | unshare=0 | ||||||
|  | copyconf=0 | ||||||
|  | pacman_config=/etc/pacman.conf | ||||||
|  |  | ||||||
| usage() { | usage() { | ||||||
|     printf "usage: %s [options] root [packages...]\n" "${0##*/}" |   cat <<EOF | ||||||
|     printf " -C <config>      Use an alternate config file for pacman\n" | usage: ${0##*/} [options] root [packages...] | ||||||
|     printf " -c               Use the package cache on the host, rather than the target\n" |  | ||||||
|     printf " -G               Avoid copying the host's pacman keyring to the target\n" |   Options: | ||||||
|     printf " -i               Avoid auto-confirmation of package selections\n" |     -C <config>    Use an alternate config file for pacman | ||||||
|     printf " -M               Avoid copying the host's mirrorlist to the target\n" |     -c             Use the package cache on the host, rather than the target | ||||||
|     printf ' -U               Use pacman -U to install packages\n' |     -D             Skip pacman dependency checks | ||||||
|     printf " -h               Print this help message\n" |     -G             Avoid copying the host's pacman keyring to the target | ||||||
|     printf '\n' |     -i             Prompt for package confirmation when needed (run interactively) | ||||||
|     printf ' basestrap installs packages to the specified new root directory.\n' |     -K             Initialize an empty pacman keyring in the target (implies '-G') | ||||||
|     printf ' If no packages are given, basestrap defaults to the "base" group.\n' |     -M             Avoid copying the host's mirrorlist to the target | ||||||
|     printf '\n' |     -N             Run in unshare mode as a regular user | ||||||
|     printf '\n' |     -P             Copy the host's pacman config to the target | ||||||
|     exit "$1" |     -U             Use pacman -U to install packages | ||||||
|  |  | ||||||
|  |     -h             Print this help message | ||||||
|  |  | ||||||
|  | basestrap installs packages to the specified new root directory. If no packages | ||||||
|  | are given, basestrap defaults to the "base" group. | ||||||
|  |  | ||||||
|  | EOF | ||||||
| } | } | ||||||
|  |  | ||||||
| orig_args=("$@") | orig_args=("$@") | ||||||
|  |  | ||||||
| opts=':C:cGiMU' | opts=':C:cDGiKMNPU' | ||||||
|  |  | ||||||
| while getopts ${opts} arg; do | while getopts ${opts} arg; do | ||||||
|     case "${arg}" in |     case "${arg}" in | ||||||
|         C) pacman_conf=$OPTARG ;; |         C) pacman_config=$OPTARG ;; | ||||||
|  |         D) pacman_args+=(-dd) ;; | ||||||
|         c) hostcache=1 ;; |         c) hostcache=1 ;; | ||||||
|         i) interactive=1 ;; |         i) interactive=1 ;; | ||||||
|         G) copykeyring=0 ;; |         G) copykeyring=0 ;; | ||||||
|  |         K) initkeyring=1 ;; | ||||||
|         M) copymirrorlist=0 ;; |         M) copymirrorlist=0 ;; | ||||||
|  |         N) unshare=1 ;; | ||||||
|  |         P) copyconf=1 ;; | ||||||
|         U) pacmode=-U ;; |         U) pacmode=-U ;; | ||||||
|         h|?) usage 0 ;; |         :) die '%s: option requires an argument -- '\''%s'\' "${0##*/}" "$OPTARG" ;; | ||||||
|  |         ?) die '%s: invalid option -- '\''%s'\' "${0##*/}" "$OPTARG" ;; | ||||||
|     esac |     esac | ||||||
| done | done | ||||||
| shift $(( OPTIND - 1 )) | shift $(( OPTIND - 1 )) | ||||||
|  |  | ||||||
| check_root "" "${BASH_SOURCE[0]}" "${orig_args[@]}" |  | ||||||
|  |  | ||||||
| (( $# )) || die "No root directory specified" | (( $# )) || die "No root directory specified" | ||||||
| newroot=$1; shift | newroot=$1; shift | ||||||
| pacman_args=("${@:-base}") |  | ||||||
|  |  | ||||||
| if (( ! hostcache ));then | [[ -d $newroot ]] || die "%s is not a directory" "$newroot" | ||||||
|  |  | ||||||
|  | pacman_args+=("$pacmode" "${@:-base}" --config="$pacman_config") | ||||||
|  |  | ||||||
|  | if (( ! hostcache )); then | ||||||
|   pacman_args+=(--cachedir="$newroot/var/cache/pacman/pkg") |   pacman_args+=(--cachedir="$newroot/var/cache/pacman/pkg") | ||||||
| fi | fi | ||||||
|  |  | ||||||
| @@ -97,26 +140,10 @@ if (( ! interactive )); then | |||||||
|   pacman_args+=(--noconfirm) |   pacman_args+=(--noconfirm) | ||||||
| fi | fi | ||||||
|  |  | ||||||
| [[ -n $pacman_conf ]] && pacman_args+=(--config="$pacman_conf") | if (( unshare )); then | ||||||
|  |     setup=unshare_setup | ||||||
| [[ -d $newroot ]] || die "%s is not a directory" "$newroot" |     "$mount_unshare" bash -c "$(declare_all); basestrap" | ||||||
|  | else | ||||||
| # create obligatory directories |     setup=chroot_setup | ||||||
| create_min_fs "$newroot" |     basestrap | ||||||
|  |  | ||||||
| # mount API filesystems |  | ||||||
| chroot_api_mount "$newroot" || die "failed to setup API filesystems in new root" |  | ||||||
|  |  | ||||||
| if (( copykeyring ));then |  | ||||||
|     copy_keyring "$newroot" |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| msg2 'Installing packages to %s' "$newroot" |  | ||||||
| if ! unshare --fork --pid pacman -r "$newroot" $pacmode "${pacman_args[@]}"; then |  | ||||||
|     die 'Failed to install packages to new root' |  | ||||||
| fi |  | ||||||
|  |  | ||||||
|  |  | ||||||
| if (( copymirrorlist ));then |  | ||||||
|     copy_mirrorlist "$newroot" |  | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -12,10 +12,12 @@ source "${LIBDIR}"/base/message.sh | |||||||
| #{{{ filesystems | #{{{ filesystems | ||||||
|  |  | ||||||
| declare -A pseudofs_types=([anon_inodefs]=1 | declare -A pseudofs_types=([anon_inodefs]=1 | ||||||
|  |                         [apparmorfs]=1 | ||||||
|                         [autofs]=1 |                         [autofs]=1 | ||||||
|                         [bdev]=1 |                         [bdev]=1 | ||||||
|                         [bpf]=1 |                         [binder]=1 | ||||||
|                         [binfmt_misc]=1 |                         [binfmt_misc]=1 | ||||||
|  |                         [bpf]=1 | ||||||
|                         [cgroup]=1 |                         [cgroup]=1 | ||||||
|                         [cgroup2]=1 |                         [cgroup2]=1 | ||||||
|                         [configfs]=1 |                         [configfs]=1 | ||||||
| @@ -25,31 +27,55 @@ declare -A pseudofs_types=([anon_inodefs]=1 | |||||||
|                         [devpts]=1 |                         [devpts]=1 | ||||||
|                         [devtmpfs]=1 |                         [devtmpfs]=1 | ||||||
|                         [dlmfs]=1 |                         [dlmfs]=1 | ||||||
|  |                         [dmabuf]=1 | ||||||
|  |                         [drm]=1 | ||||||
|                         [efivarfs]=1 |                         [efivarfs]=1 | ||||||
|  |                         [fuse]=1 | ||||||
|  |                         [fuse.archivemount]=1 | ||||||
|  |                         [fuse.avfsd]=1 | ||||||
|  |                         [fuse.dumpfs]=1 | ||||||
|  |                         [fuse.encfs]=1 | ||||||
|                         [fuse.gvfs-fuse-daemon]=1 |                         [fuse.gvfs-fuse-daemon]=1 | ||||||
|  |                         [fuse.gvfsd-fuse]=1 | ||||||
|  |                         [fuse.lxcfs]=1 | ||||||
|  |                         [fuse.rofiles-fuse]=1 | ||||||
|  |                         [fuse.vmware-vmblock]=1 | ||||||
|  |                         [fuse.xwmfs]=1 | ||||||
|                         [fusectl]=1 |                         [fusectl]=1 | ||||||
|                         [hugetlbfs]=1 |                         [hugetlbfs]=1 | ||||||
|  |                         [ipathfs]=1 | ||||||
|                         [mqueue]=1 |                         [mqueue]=1 | ||||||
|                         [nfsd]=1 |                         [nfsd]=1 | ||||||
|                         [none]=1 |                         [none]=1 | ||||||
|  |                         [nsfs]=1 | ||||||
|  |                         [overlay]=1 | ||||||
|                         [pipefs]=1 |                         [pipefs]=1 | ||||||
|                         [proc]=1 |                         [proc]=1 | ||||||
|                         [pstore]=1 |                         [pstore]=1 | ||||||
|                         [ramfs]=1 |                         [ramfs]=1 | ||||||
|  |                         [resctrl]=1 | ||||||
|                         [rootfs]=1 |                         [rootfs]=1 | ||||||
|                         [rpc_pipefs]=1 |                         [rpc_pipefs]=1 | ||||||
|                         [securityfs]=1 |                         [securityfs]=1 | ||||||
|  |                         [selinuxfs]=1 | ||||||
|  |                         [smackfs]=1 | ||||||
|                         [sockfs]=1 |                         [sockfs]=1 | ||||||
|                         [spufs]=1 |                         [spufs]=1 | ||||||
|                         [sysfs]=1 |                         [sysfs]=1 | ||||||
|                         [tmpfs]=1) |                         [tmpfs]=1 | ||||||
|  |                         [tracefs]=1 | ||||||
|  |                         [vboxsf]=1 | ||||||
|  |                         [virtiofs]=1) | ||||||
|  |  | ||||||
| declare -A fsck_types=([cramfs]=1 | declare -A fsck_types=([btrfs]=0    # btrfs doesn't need a regular fsck utility | ||||||
|  |                     [cramfs]=1 | ||||||
|  |                     [erofs]=1 | ||||||
|                     [exfat]=1 |                     [exfat]=1 | ||||||
|                     [ext2]=1 |                     [ext2]=1 | ||||||
|                     [ext3]=1 |                     [ext3]=1 | ||||||
|                     [ext4]=1 |                     [ext4]=1 | ||||||
|                     [ext4dev]=1 |                     [f2fs]=1 | ||||||
|  |                     [fat]=1 | ||||||
|                     [jfs]=1 |                     [jfs]=1 | ||||||
|                     [minix]=1 |                     [minix]=1 | ||||||
|                     [msdos]=1 |                     [msdos]=1 | ||||||
| @@ -69,11 +95,15 @@ fstype_has_fsck() { | |||||||
|     (( fsck_types["$1"] )) |     (( fsck_types["$1"] )) | ||||||
| } | } | ||||||
|  |  | ||||||
|  | try_cast() ( | ||||||
|  |     _=$(( $1#$2 )) | ||||||
|  | ) 2>/dev/null | ||||||
|  |  | ||||||
| valid_number_of_base() { | valid_number_of_base() { | ||||||
|     local base=$1 len=${#2} i |     local base="$1" len=${#2} i | ||||||
|  |  | ||||||
|     for (( i = 0; i < len; i++ )); do |     for (( i = 0; i < len; i++ )); do | ||||||
|         { _=$(( $base#${2:i:1} )) || return 1; } 2>/dev/null |         try_cast "$base" "${2:i:1}" || return 1 | ||||||
|     done |     done | ||||||
|  |  | ||||||
|     return 0 |     return 0 | ||||||
| @@ -81,7 +111,6 @@ valid_number_of_base() { | |||||||
|  |  | ||||||
| mangle() { | mangle() { | ||||||
|     local i chr out |     local i chr out | ||||||
|  |  | ||||||
|     local {a..f}= {A..F}= |     local {a..f}= {A..F}= | ||||||
|  |  | ||||||
|     for (( i = 0; i < ${#1}; i++ )); do |     for (( i = 0; i < ${#1}; i++ )); do | ||||||
| @@ -100,7 +129,6 @@ mangle() { | |||||||
|  |  | ||||||
| unmangle() { | unmangle() { | ||||||
|     local i chr out len=$(( ${#1} - 4 )) |     local i chr out len=$(( ${#1} - 4 )) | ||||||
|  |  | ||||||
|     local {a..f}= {A..F}= |     local {a..f}= {A..F}= | ||||||
|  |  | ||||||
|     for (( i = 0; i < len; i++ )); do |     for (( i = 0; i < len; i++ )); do | ||||||
| @@ -127,7 +155,6 @@ dm_name_for_devnode() { | |||||||
|     else |     else | ||||||
|         # don't leave the caller hanging, just print the original name |         # don't leave the caller hanging, just print the original name | ||||||
|         # along with the failure. |         # along with the failure. | ||||||
|         print '%s' "$1" |  | ||||||
|         error 'Failed to resolve device mapper name for: %s' "$1" |         error 'Failed to resolve device mapper name for: %s' "$1" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
| @@ -185,19 +212,11 @@ optstring_append_option() { | |||||||
|     optstring_normalize "$1" |     optstring_normalize "$1" | ||||||
| } | } | ||||||
|  |  | ||||||
| optstring_prepend_option() { |  | ||||||
|     if ! optstring_has_option "$1" "$2"; then |  | ||||||
|         declare -g "$1=$2,${!1}" |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     optstring_normalize "$1" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| optstring_get_option() { | optstring_get_option() { | ||||||
|     local opts o |     local _opts o | ||||||
|  |  | ||||||
|     IFS=, read -ra opts <<<"${!1}" |     IFS=, read -ra _opts <<<"${!1}" | ||||||
|     for o in "${opts[@]}"; do |     for o in "${_opts[@]}"; do | ||||||
|         if optstring_match_option "$2" "$o"; then |         if optstring_match_option "$2" "$o"; then | ||||||
|             declare -g "$o" |             declare -g "$o" | ||||||
|             return 0 |             return 0 | ||||||
| @@ -214,7 +233,7 @@ optstring_has_option() { | |||||||
| } | } | ||||||
|  |  | ||||||
| write_source() { | write_source() { | ||||||
|     local src=$1 spec label uuid comment=() |     local src="$1" spec label uuid comment=() | ||||||
|  |  | ||||||
|     label=$(lsblk -rno LABEL "$1" 2>/dev/null) |     label=$(lsblk -rno LABEL "$1" 2>/dev/null) | ||||||
|     uuid=$(lsblk -rno UUID "$1" 2>/dev/null) |     uuid=$(lsblk -rno UUID "$1" 2>/dev/null) | ||||||
| @@ -242,7 +261,7 @@ write_source() { | |||||||
|         ;; |         ;; | ||||||
|     esac |     esac | ||||||
|  |  | ||||||
|     [[ -n "${comment[*]}" ]] && printf '# %s\n' "${comment[*]}" |     [[ -n ${comment[*]} ]] && printf '# %s\n' "${comment[*]}" | ||||||
|  |  | ||||||
|     if [[ $spec ]]; then |     if [[ $spec ]]; then | ||||||
|         printf '%-20s' "$bytag=$(mangle "$spec")" |         printf '%-20s' "$bytag=$(mangle "$spec")" | ||||||
| @@ -267,15 +286,27 @@ optstring_apply_quirks() { | |||||||
|     fi |     fi | ||||||
|  |  | ||||||
|     case $fstype in |     case $fstype in | ||||||
|  |         btrfs) | ||||||
|  |             # Having only one of subvol= and subvolid= is enough for mounting a btrfs subvolume | ||||||
|  |             # And having subvolid= set prevents things like 'snapper rollback' to work, as it | ||||||
|  |             # updates the subvolume in-place, leaving subvol= unchanged with a different subvolid. | ||||||
|  |             if optstring_has_option "$varname" subvol; then | ||||||
|  |                 optstring_remove_option "$varname" subvolid | ||||||
|  |             fi | ||||||
|  |         ;; | ||||||
|         f2fs) |         f2fs) | ||||||
|             # These are Kconfig options for f2fs. Kernels supporting the options will |             # These are build-time or runtime-unchangeable options for f2fs. | ||||||
|             # only provide the negative versions of these (e.g. noacl), and vice versa |             # The former means that kernels supporting the options will only | ||||||
|  |             # provide the negative versions of these (e.g. noacl), and vice versa | ||||||
|             # for kernels without support. |             # for kernels without support. | ||||||
|             optstring_remove_option "$varname" noacl,acl,nouser_xattr,user_xattr |             # The latter means that the options can only be specified/changed | ||||||
|  |             # during the initial mount but not remount. | ||||||
|  |             optstring_remove_option "$varname" noacl,acl,nouser_xattr,user_xattr,atgc | ||||||
|         ;; |         ;; | ||||||
|         vfat) |         vfat) | ||||||
|             # Before Linux v3.8, "cp" is prepended to the value of the codepage. |             # Before Linux v3.8, "cp" is prepended to the value of the codepage. | ||||||
|             if optstring_get_option "$varname" codepage && [[ "$codepage" = cp* ]]; then |             # shellcheck disable=SC2154 | ||||||
|  |             if optstring_get_option "$varname" codepage && [[ $codepage = cp* ]]; then | ||||||
|                 optstring_remove_option "$varname" codepage |                 optstring_remove_option "$varname" codepage | ||||||
|                 optstring_append_option "$varname" "codepage=${codepage#cp}" |                 optstring_append_option "$varname" "codepage=${codepage#cp}" | ||||||
|             fi |             fi | ||||||
| @@ -290,11 +321,12 @@ usage() { | |||||||
| usage: ${0##*/} [options] root | usage: ${0##*/} [options] root | ||||||
|  |  | ||||||
|   Options: |   Options: | ||||||
|     -f FILTER      Restrict output to mountpoints matching the prefix FILTER |     -f <filter>    Restrict output to mountpoints matching the prefix FILTER | ||||||
|     -L             Use labels for source identifiers (shortcut for -t LABEL) |     -L             Use labels for source identifiers (shortcut for -t LABEL) | ||||||
|     -p             Exclude pseudofs mounts (default behavior) |     -p             Exclude pseudofs mounts (default behavior) | ||||||
|     -P             Include printing mounts |     -P             Include pseudofs mounts | ||||||
|     -t TAG         Use TAG for source identifiers |     -t <tag>       Use TAG for source identifiers (TAG should be one of: LABEL, | ||||||
|  |                       UUID, PARTLABEL, PARTUUID) | ||||||
|     -U             Use UUIDs for source identifiers (shortcut for -t UUID) |     -U             Use UUIDs for source identifiers (shortcut for -t UUID) | ||||||
|  |  | ||||||
|     -h             Print this help message |     -h             Print this help message | ||||||
| @@ -332,7 +364,6 @@ if ! mountpoint -q "$root"; then | |||||||
| fi | fi | ||||||
|  |  | ||||||
| # handle block devices | # handle block devices | ||||||
| findmnt -Recvruno SOURCE,TARGET,FSTYPE,OPTIONS,FSROOT "$root" | |  | ||||||
| while read -r src target fstype opts fsroot; do | while read -r src target fstype opts fsroot; do | ||||||
|     if (( !pseudofs )) && fstype_is_pseudofs "$fstype"; then |     if (( !pseudofs )) && fstype_is_pseudofs "$fstype"; then | ||||||
|         continue |         continue | ||||||
| @@ -360,6 +391,7 @@ while read -r src target fstype opts fsroot; do | |||||||
|     if [[ $fsroot != / && $fstype != btrfs ]]; then |     if [[ $fsroot != / && $fstype != btrfs ]]; then | ||||||
|         # it's a bind mount |         # it's a bind mount | ||||||
|         src=$(findmnt -funcevo TARGET "$src")$fsroot |         src=$(findmnt -funcevo TARGET "$src")$fsroot | ||||||
|  |         src="/${src#"$root"/}" | ||||||
|         if [[ $src -ef $target ]]; then |         if [[ $src -ef $target ]]; then | ||||||
|             # hrmm, this is weird. we're probably looking at a file or directory |             # hrmm, this is weird. we're probably looking at a file or directory | ||||||
|             # that was bound into a chroot from the host machine. Ignore it, |             # that was bound into a chroot from the host machine. Ignore it, | ||||||
| @@ -393,7 +425,7 @@ while read -r src target fstype opts fsroot; do | |||||||
|     printf '\t%-10s' "/$(mangle "${target#/}")" "$fstype" "$opts" |     printf '\t%-10s' "/$(mangle "${target#/}")" "$fstype" "$opts" | ||||||
|     printf '\t%s %s' "$dump" "$pass" |     printf '\t%s %s' "$dump" "$pass" | ||||||
|     printf '\n\n' |     printf '\n\n' | ||||||
| done | done < <(findmnt -Recvruno SOURCE,TARGET,FSTYPE,OPTIONS,FSROOT "$root") | ||||||
|  |  | ||||||
| # handle swaps devices | # handle swaps devices | ||||||
| { | { | ||||||
| @@ -409,6 +441,9 @@ done | |||||||
|         # skip files marked deleted by the kernel |         # skip files marked deleted by the kernel | ||||||
|         [[ $device = *'\040(deleted)' ]] && continue |         [[ $device = *'\040(deleted)' ]] && continue | ||||||
|  |  | ||||||
|  |         # skip devices not part of the prefix | ||||||
|  |         [[ $device = "$prefixfilter"* ]] || continue | ||||||
|  |  | ||||||
|         if [[ $type = file ]]; then |         if [[ $type = file ]]; then | ||||||
|             printf '%-20s' "${device#"${root%/}"}" |             printf '%-20s' "${device#"${root%/}"}" | ||||||
|         elif [[ $device = /dev/dm-+([0-9]) ]]; then |         elif [[ $device = /dev/dm-+([0-9]) ]]; then | ||||||
|   | |||||||
| @@ -6,20 +6,16 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
| DATADIR=${DATADIR:-'@datadir@'} | DATADIR=${DATADIR:-'@datadir@'} | ||||||
| SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/iso/util.sh | # shellcheck source=src/lib/iso/util.sh | ||||||
| source "${LIBDIR}"/iso/util.sh | source "${LIBDIR}"/iso/util.sh | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/chroot.sh | # shellcheck source=src/lib/base/chroot.sh | ||||||
| source "${LIBDIR}"/base/chroot.sh | source "${LIBDIR}"/base/chroot.sh | ||||||
| # shellcheck source=src/lib/base/mount.sh | # shellcheck source=src/lib/iso/mount.sh | ||||||
| source "${LIBDIR}"/iso/mount.sh | source "${LIBDIR}"/iso/mount.sh | ||||||
| # shellcheck source=src/lib/iso/services.sh | # shellcheck source=src/lib/iso/services.sh | ||||||
| source "${LIBDIR}"/iso/services.sh | source "${LIBDIR}"/iso/services.sh | ||||||
| # shellcheck source=src/lib/base/yaml.sh |  | ||||||
| source "${LIBDIR}"/base/yaml.sh |  | ||||||
| # shellcheck source=src/lib/iso/calamares.sh | # shellcheck source=src/lib/iso/calamares.sh | ||||||
| source "${LIBDIR}"/iso/calamares.sh | source "${LIBDIR}"/iso/calamares.sh | ||||||
| # shellcheck source=src/lib/iso/config.sh | # shellcheck source=src/lib/iso/config.sh | ||||||
| @@ -92,6 +88,8 @@ make_rootfs() { | |||||||
|         msg "Prepare [Base installation] (rootfs)" |         msg "Prepare [Base installation] (rootfs)" | ||||||
|         local rootfs="${work_dir}/rootfs" |         local rootfs="${work_dir}/rootfs" | ||||||
|  |  | ||||||
|  |         load_pkgs "${root_list}" | ||||||
|  |  | ||||||
|         prepare_dir "${rootfs}" |         prepare_dir "${rootfs}" | ||||||
|  |  | ||||||
|         basestrap "${basestrap_args[@]}" "${rootfs}" "${packages[@]}" |         basestrap "${basestrap_args[@]}" "${rootfs}" "${packages[@]}" | ||||||
| @@ -113,6 +111,8 @@ make_livefs() { | |||||||
|         msg "Prepare [Live installation] (livefs)" |         msg "Prepare [Live installation] (livefs)" | ||||||
|         local livefs="${work_dir}/livefs" |         local livefs="${work_dir}/livefs" | ||||||
|  |  | ||||||
|  |         load_pkgs "${live_list}" | ||||||
|  |  | ||||||
|         prepare_dir "${livefs}" |         prepare_dir "${livefs}" | ||||||
|  |  | ||||||
|         mount_overlayfs "${livefs}" "${work_dir}" |         mount_overlayfs "${livefs}" "${work_dir}" | ||||||
| @@ -137,6 +137,8 @@ make_bootfs() { | |||||||
|     if [[ ! -e ${work_dir}/bootfs.lock ]]; then |     if [[ ! -e ${work_dir}/bootfs.lock ]]; then | ||||||
|         msg "Prepare [/iso/boot]" |         msg "Prepare [/iso/boot]" | ||||||
|  |  | ||||||
|  |         load_pkgs "${common_dir}/Packages-boot" | ||||||
|  |  | ||||||
|         prepare_dir "${iso_root}/boot" |         prepare_dir "${iso_root}/boot" | ||||||
|  |  | ||||||
|         cp "${work_dir}"/rootfs/boot/vmlinuz* "${iso_root}"/boot/vmlinuz-"${arch}" |         cp "${work_dir}"/rootfs/boot/vmlinuz* "${iso_root}"/boot/vmlinuz-"${arch}" | ||||||
| @@ -148,6 +150,7 @@ make_bootfs() { | |||||||
|         if "${use_dracut}"; then |         if "${use_dracut}"; then | ||||||
|             prepare_initramfs_dracut "${bootfs}" |             prepare_initramfs_dracut "${bootfs}" | ||||||
|         else |         else | ||||||
|  |             basestrap "${basestrap_args[@]}" "${bootfs}" "${packages[@]}" | ||||||
|             prepare_initramfs_mkinitcpio "${bootfs}" |             prepare_initramfs_mkinitcpio "${bootfs}" | ||||||
|         fi |         fi | ||||||
|  |  | ||||||
| @@ -262,10 +265,8 @@ mk_boot(){ | |||||||
| } | } | ||||||
|  |  | ||||||
| mk_chroots(){ | mk_chroots(){ | ||||||
|     load_pkgs "${root_list}" |  | ||||||
|     run_safe "make_rootfs" |     run_safe "make_rootfs" | ||||||
|     if [[ -n ${live_list} ]]; then |     if [[ -n ${live_list} ]]; then | ||||||
|         load_pkgs "${live_list}" |  | ||||||
|         run_safe "make_livefs" |         run_safe "make_livefs" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
|   | |||||||
| @@ -81,7 +81,7 @@ trap_abort() { | |||||||
| trap_exit() { | trap_exit() { | ||||||
|     local r=$? |     local r=$? | ||||||
|     trap - EXIT INT QUIT TERM HUP |     trap - EXIT INT QUIT TERM HUP | ||||||
|     cleanup $r |     cleanup "$r" | ||||||
| } | } | ||||||
|  |  | ||||||
| cleanup() { | cleanup() { | ||||||
|   | |||||||
| @@ -9,73 +9,39 @@ ignore_error() { | |||||||
|     return 0 |     return 0 | ||||||
| } | } | ||||||
|  |  | ||||||
| trap_setup(){ | chroot_add_mount() { | ||||||
|     [[ $(trap -p EXIT) ]] && die 'Error! Attempting to overwrite existing EXIT trap' |  | ||||||
|     trap "$1" EXIT |  | ||||||
| } |  | ||||||
|  |  | ||||||
| chroot_mount() { |  | ||||||
| #     msg2 "mount: [%s]" "$2" | #     msg2 "mount: [%s]" "$2" | ||||||
|     mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}") |     mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}") | ||||||
| } | } | ||||||
|  |  | ||||||
| chroot_add_resolv_conf() { | chroot_maybe_add_mount() { | ||||||
|     local chrootdir=$1 resolv_conf=$1/etc/resolv.conf |  | ||||||
|  |  | ||||||
|     [[ -e /etc/resolv.conf ]] || return 0 |  | ||||||
|  |  | ||||||
|     # Handle resolv.conf as a symlink to somewhere else. |  | ||||||
|     if [[ -L $chrootdir/etc/resolv.conf ]]; then |  | ||||||
|         # readlink(1) should always give us *something* since we know at this point |  | ||||||
|         # it's a symlink. For simplicity, ignore the case of nested symlinks. |  | ||||||
|         resolv_conf=$(readlink "$chrootdir/etc/resolv.conf") |  | ||||||
|         if [[ $resolv_conf = /* ]]; then |  | ||||||
|             resolv_conf=$chrootdir$resolv_conf |  | ||||||
|         else |  | ||||||
|             resolv_conf=$chrootdir/etc/$resolv_conf |  | ||||||
|         fi |  | ||||||
|  |  | ||||||
|         # ensure file exists to bind mount over |  | ||||||
|         if [[ ! -f $resolv_conf ]]; then |  | ||||||
|             install -Dm644 /dev/null "$resolv_conf" || return 1 |  | ||||||
|         fi |  | ||||||
|     elif [[ ! -e $chrootdir/etc/resolv.conf ]]; then |  | ||||||
|         # The chroot might not have a resolv.conf. |  | ||||||
|         return 0 |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     chroot_mount /etc/resolv.conf "$resolv_conf" --bind |  | ||||||
| } |  | ||||||
|  |  | ||||||
| chroot_mount_conditional() { |  | ||||||
|     local cond=$1; shift |     local cond=$1; shift | ||||||
|     if eval "$cond"; then |     if eval "$cond"; then | ||||||
|         chroot_mount "$@" |         chroot_add_mount "$@" | ||||||
|     fi |     fi | ||||||
| } | } | ||||||
|  |  | ||||||
| chroot_setup(){ | chroot_setup(){ | ||||||
|     local mnt="$1" |     local mnt="$1" | ||||||
|     local tmpfs_opts="${2:-mode=1777,strictatime,nodev,nosuid}" |     local tmpfs_opts="${2:-mode=1777,strictatime,nodev,nosuid}" | ||||||
|     chroot_mount_conditional "! mountpoint -q '$mnt'" "$mnt" "$mnt" --bind && |  | ||||||
|     chroot_mount proc "$mnt/proc" -t proc -o nosuid,noexec,nodev && |  | ||||||
|     chroot_mount sys "$mnt/sys" -t sysfs -o nosuid,noexec,nodev,ro && |  | ||||||
|     ignore_error chroot_mount_conditional "[[ -d '$mnt/sys/firmware/efi/efivars' ]]" \ |  | ||||||
|         efivarfs "$mnt/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev && |  | ||||||
|     chroot_mount udev "$mnt/dev" -t devtmpfs -o mode=0755,nosuid && |  | ||||||
|     chroot_mount devpts "$mnt/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && |  | ||||||
|     chroot_mount shm "$mnt/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && |  | ||||||
|     chroot_mount /run "$mnt/run" -t tmpfs -o nosuid,nodev,mode=0755 && |  | ||||||
|     chroot_mount tmp "$mnt/tmp" -t tmpfs -o "${tmpfs_opts}" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| chroot_api_mount() { |  | ||||||
|     CHROOT_ACTIVE_MOUNTS=() |     CHROOT_ACTIVE_MOUNTS=() | ||||||
|     trap_setup chroot_api_umount |     [[ $(trap -p EXIT) ]] && die 'Error! Attempting to overwrite existing EXIT trap' | ||||||
|     chroot_setup "$1" "$2" |     trap 'chroot_teardown' EXIT | ||||||
|  |  | ||||||
|  |     #chroot_maybe_add_mount "! mountpoint -q '$mnt'" "$mnt" "$mnt" --bind && | ||||||
|  |     chroot_add_mount proc "$mnt/proc" -t proc -o nosuid,noexec,nodev && | ||||||
|  |     chroot_add_mount sys "$mnt/sys" -t sysfs -o nosuid,noexec,nodev,ro && | ||||||
|  |     ignore_error chroot_maybe_add_mount "[[ -d '$mnt/sys/firmware/efi/efivars' ]]" \ | ||||||
|  |         efivarfs "$mnt/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev && | ||||||
|  |     chroot_add_mount udev "$mnt/dev" -t devtmpfs -o mode=0755,nosuid && | ||||||
|  |     chroot_add_mount devpts "$mnt/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec && | ||||||
|  |     chroot_add_mount shm "$mnt/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev && | ||||||
|  |     chroot_add_mount /run "$mnt/run" -t tmpfs -o nosuid,nodev,mode=0755 && | ||||||
|  |     chroot_add_mount tmp "$mnt/tmp" -t tmpfs -o "${tmpfs_opts}" | ||||||
| } | } | ||||||
|  |  | ||||||
| chroot_api_umount() { | chroot_teardown() { | ||||||
|     if (( ${#CHROOT_ACTIVE_MOUNTS[@]} )); then |     if (( ${#CHROOT_ACTIVE_MOUNTS[@]} )); then | ||||||
| #         msg2 "umount: [%s]" "${CHROOT_ACTIVE_MOUNTS[@]}" | #         msg2 "umount: [%s]" "${CHROOT_ACTIVE_MOUNTS[@]}" | ||||||
|         umount "${CHROOT_ACTIVE_MOUNTS[@]}" |         umount "${CHROOT_ACTIVE_MOUNTS[@]}" | ||||||
| @@ -83,4 +49,40 @@ chroot_api_umount() { | |||||||
|     unset CHROOT_ACTIVE_MOUNTS |     unset CHROOT_ACTIVE_MOUNTS | ||||||
| } | } | ||||||
|  |  | ||||||
|  | resolve_link() { | ||||||
|  |     local target=$1 | ||||||
|  |     local root=$2 | ||||||
|  |  | ||||||
|  |     # If a root was given, make sure it ends in a slash. | ||||||
|  |     [[ -n $root && $root != */ ]] && root=$root/ | ||||||
|  |  | ||||||
|  |     while [[ -L $target ]]; do | ||||||
|  |         target=$(readlink -m "$target") | ||||||
|  |         # If a root was given, make sure the target is under it. | ||||||
|  |         # Make sure to strip any leading slash from target first. | ||||||
|  |         [[ -n $root && $target != $root* ]] && target=$root${target#/} | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     printf %s "$target" | ||||||
|  | } | ||||||
|  |  | ||||||
|  | chroot_add_resolv_conf() { | ||||||
|  |     local chrootdir=$1 | ||||||
|  |     local src | ||||||
|  |     local dest="$chrootdir/etc/resolv.conf" | ||||||
|  |  | ||||||
|  |     src=$(resolve_link /etc/resolv.conf) | ||||||
|  |  | ||||||
|  |     # If we don't have a source resolv.conf file, there's nothing useful we can do. | ||||||
|  |     [[ -e $src ]] || return 0 | ||||||
|  |  | ||||||
|  |     if [[ ! -e "$dest" && ! -h "$dest" ]]; then | ||||||
|  |             # There may be no resolv.conf in the chroot. In this case, we'll just exit. | ||||||
|  |             # The chroot environment must not be concerned with DNS resolution. | ||||||
|  |             return 0 | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     chroot_add_mount "$src" "$dest" -c --bind | ||||||
|  | } | ||||||
|  |  | ||||||
| #}}} | #}}} | ||||||
|   | |||||||
							
								
								
									
										78
									
								
								src/lib/base/unshare-mount.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/lib/base/unshare-mount.sh
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,78 @@ | |||||||
|  | #!/hint/bash | ||||||
|  | # | ||||||
|  | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  |  | ||||||
|  | #{{{ mount | ||||||
|  |  | ||||||
|  | chroot_add_mount_lazy() { | ||||||
|  |     mount "$@" && CHROOT_ACTIVE_LAZY=("$2" "${CHROOT_ACTIVE_LAZY[@]}") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | chroot_bind_device() { | ||||||
|  |     touch "$2" && CHROOT_ACTIVE_FILES=("$2" "${CHROOT_ACTIVE_FILES[@]}") | ||||||
|  |     chroot_add_mount "$1" "$2" --bind | ||||||
|  | } | ||||||
|  |  | ||||||
|  | chroot_add_link() { | ||||||
|  |     ln -sf "$1" "$2" && CHROOT_ACTIVE_FILES=("$2" "${CHROOT_ACTIVE_FILES[@]}") | ||||||
|  | } | ||||||
|  |  | ||||||
|  | unshare_setup() { | ||||||
|  |     CHROOT_ACTIVE_MOUNTS=() | ||||||
|  |     CHROOT_ACTIVE_LAZY=() | ||||||
|  |     CHROOT_ACTIVE_FILES=() | ||||||
|  |     [[ $(trap -p EXIT) ]] && die '(BUG): attempting to overwrite existing EXIT trap' | ||||||
|  |     trap 'unshare_teardown' EXIT | ||||||
|  |  | ||||||
|  |     chroot_add_mount_lazy "$1" "$1" --bind && | ||||||
|  |     chroot_add_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev && | ||||||
|  |     chroot_add_mount_lazy /sys "$1/sys" --rbind && | ||||||
|  |     chroot_add_link /proc/self/fd "$1/dev/fd" && | ||||||
|  |     chroot_add_link /proc/self/fd/0 "$1/dev/stdin" && | ||||||
|  |     chroot_add_link /proc/self/fd/1 "$1/dev/stdout" && | ||||||
|  |     chroot_add_link /proc/self/fd/2 "$1/dev/stderr" && | ||||||
|  |     chroot_bind_device /dev/full "$1/dev/full" && | ||||||
|  |     chroot_bind_device /dev/null "$1/dev/null" && | ||||||
|  |     chroot_bind_device /dev/random "$1/dev/random" && | ||||||
|  |     chroot_bind_device /dev/tty "$1/dev/tty" && | ||||||
|  |     chroot_bind_device /dev/urandom "$1/dev/urandom" && | ||||||
|  |     chroot_bind_device /dev/zero "$1/dev/zero" && | ||||||
|  |     chroot_add_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 && | ||||||
|  |     chroot_add_mount tmp "$1/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid | ||||||
|  | } | ||||||
|  |  | ||||||
|  | unshare_teardown() { | ||||||
|  |     chroot_teardown | ||||||
|  |  | ||||||
|  |     if (( ${#CHROOT_ACTIVE_LAZY[@]} )); then | ||||||
|  |         umount --lazy "${CHROOT_ACTIVE_LAZY[@]}" | ||||||
|  |     fi | ||||||
|  |     unset CHROOT_ACTIVE_LAZY | ||||||
|  |  | ||||||
|  |     if (( ${#CHROOT_ACTIVE_FILES[@]} )); then | ||||||
|  |         rm "${CHROOT_ACTIVE_FILES[@]}" | ||||||
|  |     fi | ||||||
|  |     unset CHROOT_ACTIVE_FILES | ||||||
|  | } | ||||||
|  |  | ||||||
|  | pid_unshare="unshare --fork --pid" | ||||||
|  | mount_unshare="$pid_unshare --mount --map-auto --map-root-user --setuid 0 --setgid 0" | ||||||
|  |  | ||||||
|  | # This outputs code for declaring all variables to stdout. For example, if | ||||||
|  | # FOO=BAR, then running | ||||||
|  | #     declare -p FOO | ||||||
|  | # will result in the output | ||||||
|  | #     declare -- FOO="bar" | ||||||
|  | # This function may be used to re-declare all currently used variables and | ||||||
|  | # functions in a new shell. | ||||||
|  | declare_all() { | ||||||
|  |   # Remove read-only variables to avoid warnings. Unfortunately, declare +r -p | ||||||
|  |   # doesn't work like it looks like it should (declaring only read-write | ||||||
|  |   # variables). However, declare -rp will print out read-only variables, which | ||||||
|  |   # we can then use to remove those definitions. | ||||||
|  |   declare -p | grep -Fvf <(declare -rp) | ||||||
|  |   # Then declare functions | ||||||
|  |   declare -pf | ||||||
|  | } | ||||||
|  |  | ||||||
|  | #}}} | ||||||
| @@ -1,48 +0,0 @@ | |||||||
| #!/hint/bash |  | ||||||
| # |  | ||||||
| # SPDX-License-Identifier: GPL-3.0-or-later |  | ||||||
|  |  | ||||||
| #{{{ base conf |  | ||||||
|  |  | ||||||
| prepare_dir(){ |  | ||||||
|     [[ ! -d $1 ]] && mkdir -p "$1" |  | ||||||
|     return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| if [[ -n $SUDO_USER ]]; then |  | ||||||
|     eval "USER_HOME=~$SUDO_USER" |  | ||||||
| else |  | ||||||
|     USER_HOME=$HOME |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| USER_CONF_DIR="${XDG_CONFIG_HOME:-$USER_HOME/.config}/artools" |  | ||||||
|  |  | ||||||
| prepare_dir "${USER_CONF_DIR}" |  | ||||||
|  |  | ||||||
| load_base_config(){ |  | ||||||
|  |  | ||||||
|     local conf="$1/artools-base.conf" |  | ||||||
|  |  | ||||||
|     [[ -f "$conf" ]] || return 1 |  | ||||||
|  |  | ||||||
|     # shellcheck source=config/conf/artools-base.conf |  | ||||||
|     [[ -r "$conf" ]] && source "$conf" |  | ||||||
|  |  | ||||||
|     CHROOTS_DIR=${CHROOTS_DIR:-'/var/lib/artools'} |  | ||||||
|  |  | ||||||
|     WORKSPACE_DIR=${WORKSPACE_DIR:-"${USER_HOME}/artools-workspace"} |  | ||||||
|  |  | ||||||
|     ARCH=${ARCH:-"$(uname -m)"} |  | ||||||
|  |  | ||||||
|     REPO=${REPO:-'world'} |  | ||||||
|  |  | ||||||
|     return 0 |  | ||||||
| } |  | ||||||
|  |  | ||||||
| #}}} |  | ||||||
|  |  | ||||||
|  |  | ||||||
| load_base_config "${USER_CONF_DIR}" || load_base_config "${SYSCONFDIR}" |  | ||||||
|  |  | ||||||
| prepare_dir "${WORKSPACE_DIR}" |  | ||||||
|  |  | ||||||
| @@ -4,44 +4,50 @@ | |||||||
|  |  | ||||||
| #{{{ calamares | #{{{ calamares | ||||||
|  |  | ||||||
| write_services_conf(){ | yaml_array() { | ||||||
|     local key1="$1" val1="$2" key2="$3" val2="$4" |     local array | ||||||
|     local yaml |  | ||||||
|     yaml=$(write_yaml_header) |     for entry in "$@"; do | ||||||
|     yaml+=$(write_yaml_map 0 "$key1" "$val1") |         array="${array:-}${array:+,} ${entry}" | ||||||
|     yaml+=$(write_yaml_map 0 "$key2" "$val2") |  | ||||||
|     yaml+=$(write_yaml_map 0 'services') |  | ||||||
|     for svc in "${SERVICES[@]}"; do |  | ||||||
|         yaml+=$(write_yaml_seq 2 "$svc") |  | ||||||
|     done |     done | ||||||
|     yaml+=$(write_empty_line) |     printf "%s\n" "[${array}]" | ||||||
|     printf '%s\n' "${yaml}" | } | ||||||
|  |  | ||||||
|  | write_services_conf() { | ||||||
|  |     local key1="$1" key2="$2" val1="$3" val2="$4" | ||||||
|  |     local conf="$5"/services-"${INITSYS}".conf | ||||||
|  |     local svc | ||||||
|  |     svc=$(yaml_array "${SERVICES[@]}") | ||||||
|  |  | ||||||
|  |     yq -n '"---"' > "$conf" | ||||||
|  |  | ||||||
|  |     key1="$key1" key2="$key2" val1="$val1" val2="$val2" svc="$svc" \ | ||||||
|  |     yq -P 'with( | ||||||
|  |         .; | ||||||
|  |             eval(strenv(key1)) = env(val1) | | ||||||
|  |             eval(strenv(key2)) = env(val2) | | ||||||
|  |             .services = env(svc))' \ | ||||||
|  |         -i "$conf" | ||||||
|  |  | ||||||
|  |     if [[ ${INITSYS} == 's6' ]]; then | ||||||
|  |         yq -P '.defaultBundle = "default"' -i "$conf" | ||||||
|  |     fi | ||||||
| } | } | ||||||
|  |  | ||||||
| write_services_openrc_conf(){ | write_services_openrc_conf(){ | ||||||
|     local conf="$1"/services-openrc.conf |     write_services_conf '.initdDir' '.runlevelsDir' '/etc/init.d' '/etc/runlevels' "$1" | ||||||
|     write_services_conf 'initdDir' '/etc/init.d' 'runlevelsDir' '/etc/runlevels' > "$conf" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| write_services_runit_conf(){ | write_services_runit_conf(){ | ||||||
|     local conf="$1"/services-runit.conf |     write_services_conf '.svDir' '.runsvDir' '/etc/runit/sv' '/etc/runit/runsvdir' "$1" | ||||||
|     write_services_conf 'svDir' '/etc/runit/sv' 'runsvDir' '/etc/runit/runsvdir' > "$conf" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| write_services_s6_conf(){ | write_services_s6_conf(){ | ||||||
|     local conf="$1"/services-s6.conf |     write_services_conf '.svDir' '.dbDir' '/etc/s6/sv' '/etc/s6/rc/compiled' "$1" | ||||||
|     write_services_conf 'svDir' '/etc/s6/sv' 'dbDir' '/etc/s6/rc/compiled' > "$conf" |  | ||||||
|     printf '%s\n' "defaultBundle: default" >> "$conf" |  | ||||||
| } |  | ||||||
|  |  | ||||||
| write_services_suite66_conf(){ |  | ||||||
|     local conf="$1"/services-suite66.conf |  | ||||||
|     write_services_conf 'svDir' '/etc/66/service' 'runsvDir' '/var/lib/66/system' > "$conf" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| write_services_dinit_conf(){ | write_services_dinit_conf(){ | ||||||
|     local conf="$1"/services-dinit.conf |     write_services_conf '.initdDir' '.runsvDir' '/etc/dinit.d' '/etc/dinit.d/boot.d' "$1" | ||||||
|     write_services_conf 'initdDir' '/etc/dinit.d' 'runsvDir' '/etc/dinit.d/boot.d' > "$conf" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| configure_calamares(){ | configure_calamares(){ | ||||||
|   | |||||||
| @@ -28,15 +28,12 @@ export_gpg_publickey() { | |||||||
| } | } | ||||||
|  |  | ||||||
| prepare_initramfs_mkinitcpio() { | prepare_initramfs_mkinitcpio() { | ||||||
|     local mnt="$1" packages=() mkinitcpio_conf k |     local mnt="$1" mkinitcpio_conf k | ||||||
|  |  | ||||||
|     mkinitcpio_conf=mkinitcpio-default.conf |     mkinitcpio_conf=mkinitcpio-default.conf | ||||||
|     [[ "${profile}" == 'base' ]] && mkinitcpio_conf=mkinitcpio-pxe.conf |     [[ "${profile}" == 'base' ]] && mkinitcpio_conf=mkinitcpio-pxe.conf | ||||||
|     k=$(<"$mnt"/usr/src/linux/version) |     k=$(<"$mnt"/usr/src/linux/version) | ||||||
|  |  | ||||||
|     packages+=($(read_from_list "${common_dir}/Packages-boot")) |  | ||||||
|     basestrap "${basestrap_args[@]}" "$mnt" "${packages[@]}" |  | ||||||
|  |  | ||||||
|     if [[ -n "${GPG_KEY}" ]]; then |     if [[ -n "${GPG_KEY}" ]]; then | ||||||
|         exec {ARTIX_GNUPG_FD}<>"${key_export}" |         exec {ARTIX_GNUPG_FD}<>"${key_export}" | ||||||
|         export ARTIX_GNUPG_FD |         export ARTIX_GNUPG_FD | ||||||
|   | |||||||
| @@ -5,13 +5,13 @@ | |||||||
| #{{{ iso | #{{{ iso | ||||||
|  |  | ||||||
| get_disturl(){ | get_disturl(){ | ||||||
|     # shellcheck disable=1091 |     # shellcheck disable=SC2034 | ||||||
|     . /usr/lib/os-release |     . /usr/lib/os-release | ||||||
|     printf "%s\n" "${HOME_URL}" |     printf "%s\n" "${HOME_URL}" | ||||||
| } | } | ||||||
|  |  | ||||||
| get_osname(){ | get_osname(){ | ||||||
|     # shellcheck disable=1091 |     # shellcheck disable=SC2034 | ||||||
|     . /usr/lib/os-release |     . /usr/lib/os-release | ||||||
|     printf "%s\n" "${NAME}" |     printf "%s\n" "${NAME}" | ||||||
| } | } | ||||||
|   | |||||||
| @@ -26,7 +26,7 @@ load_profile(){ | |||||||
|  |  | ||||||
|     [[ -f $profile_dir/${profile}/profile.conf ]] || return 1 |     [[ -f $profile_dir/${profile}/profile.conf ]] || return 1 | ||||||
|  |  | ||||||
|     # shellcheck disable=1090 |     # shellcheck source=contrib/iso/profile.conf.example | ||||||
|     [[ -r "$profile_dir/${profile}"/profile.conf ]] && . "$profile_dir/${profile}"/profile.conf |     [[ -r "$profile_dir/${profile}"/profile.conf ]] && . "$profile_dir/${profile}"/profile.conf | ||||||
|  |  | ||||||
|     AUTOLOGIN=${AUTOLOGIN:-true} |     AUTOLOGIN=${AUTOLOGIN:-true} | ||||||
| @@ -43,20 +43,35 @@ load_profile(){ | |||||||
| read_from_list() { | read_from_list() { | ||||||
|     local list="$1" |     local list="$1" | ||||||
|     local _space="s| ||g" |     local _space="s| ||g" | ||||||
|     local _clean=':a;N;$!ba;s/\n/ /g' |     #local _clean=':a;N;$!ba;s/\n/ /g' | ||||||
|  |     local _clean='/^$/d' | ||||||
|     local _com_rm="s|#.*||g" |     local _com_rm="s|#.*||g" | ||||||
|     local _init="s|@initsys@|${INITSYS}|g" |     local _init="s|@initsys@|${INITSYS}|g" | ||||||
|     local pkgs |  | ||||||
|  |  | ||||||
|     mapfile -t pkgs < <(sed "$_com_rm" "$list" \ |     mapfile -t pkgs < <(sed "$_com_rm" "$list" \ | ||||||
|             | sed "$_space" \ |             | sed "$_space" \ | ||||||
|             | sed "$_init" \ |             | sed "$_init" \ | ||||||
|             | sed "$_clean") |             | sed "$_clean" | sort -u) | ||||||
|  |  | ||||||
|     printf "%s\n" "${pkgs[@]}" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| read_from_services() { | load_pkgs(){ | ||||||
|  |     local pkglist="$1" | ||||||
|  |     packages=() | ||||||
|  |  | ||||||
|  |     if [[ "${pkglist##*/}" == "Packages-Root" ]]; then | ||||||
|  |         for l in base apps "${INITSYS}"; do | ||||||
|  |             msg2 "Loading Packages: [%s] ..." "Packages-${l}" | ||||||
|  |             read_from_list "${common_dir}/Packages-${l}" | ||||||
|  |             packages+=("${pkgs[@]}") | ||||||
|  |  | ||||||
|  |         done | ||||||
|  |  | ||||||
|  |         if [[ -n "${live_list}" ]]; then | ||||||
|  |             msg2 "Loading Packages: [Packages-xorg] ..." | ||||||
|  |             read_from_list "${common_dir}/Packages-xorg" | ||||||
|  |             packages+=("${pkgs[@]}") | ||||||
|  |         fi | ||||||
|  |  | ||||||
|         for svc in "${SERVICES[@]}"; do |         for svc in "${SERVICES[@]}"; do | ||||||
|             case "$svc" in |             case "$svc" in | ||||||
|                 sddm|gdm|lightdm|mdm|greetd|lxdm|xdm) |                 sddm|gdm|lightdm|mdm|greetd|lxdm|xdm) | ||||||
| @@ -68,28 +83,11 @@ read_from_services() { | |||||||
|                 syslog-ng|metalog) packages+=("$svc-${INITSYS}") ;; |                 syslog-ng|metalog) packages+=("$svc-${INITSYS}") ;; | ||||||
|             esac |             esac | ||||||
|         done |         done | ||||||
| } |  | ||||||
|  |  | ||||||
| load_pkgs(){ |  | ||||||
|     local pkglist="$1" |  | ||||||
|     packages=() |  | ||||||
|  |  | ||||||
|     if [[ "${pkglist##*/}" == "Packages-Root" ]]; then |  | ||||||
|         for l in base apps "${INITSYS}"; do |  | ||||||
|             msg2 "Loading Packages: [%s] ..." "Packages-${l}" |  | ||||||
|             packages+=($(read_from_list "${common_dir}/Packages-${l}")) |  | ||||||
|         done |  | ||||||
|         if [[ -n "${live_list}" ]]; then |  | ||||||
|             msg2 "Loading Packages: [%s] ..." "Packages-xorg" |  | ||||||
|             packages+=($(read_from_list "${common_dir}/Packages-xorg")) |  | ||||||
|     fi |     fi | ||||||
|     msg2 "Loading Packages: [%s] ..." "${pkglist##*/}" |     msg2 "Loading Packages: [%s] ..." "${pkglist##*/}" | ||||||
|         packages+=($(read_from_list "${pkglist}")) |     read_from_list "${pkglist}" | ||||||
|         read_from_services |     packages+=("${pkgs[@]}") | ||||||
|     else |  | ||||||
|         msg2 "Loading Packages: [%s] ..." "${pkglist##*/}" |  | ||||||
|         packages+=($(read_from_list "${pkglist}")) |  | ||||||
|     fi |  | ||||||
| } | } | ||||||
|  |  | ||||||
| #}}} | #}}} | ||||||
|   | |||||||
| @@ -4,6 +4,21 @@ | |||||||
|  |  | ||||||
| #{{{ iso conf | #{{{ iso conf | ||||||
|  |  | ||||||
|  | prepare_dir(){ | ||||||
|  |     [[ ! -d $1 ]] && mkdir -p "$1" | ||||||
|  |     return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if [[ -n $SUDO_USER ]]; then | ||||||
|  |     eval "USER_HOME=~$SUDO_USER" | ||||||
|  | else | ||||||
|  |     USER_HOME=$HOME | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | USER_CONF_DIR="${XDG_CONFIG_HOME:-$USER_HOME/.config}/artools" | ||||||
|  |  | ||||||
|  | prepare_dir "${USER_CONF_DIR}" | ||||||
|  |  | ||||||
| load_iso_config(){ | load_iso_config(){ | ||||||
|  |  | ||||||
|     local conf="$1/artools-iso.conf" |     local conf="$1/artools-iso.conf" | ||||||
| @@ -13,6 +28,14 @@ load_iso_config(){ | |||||||
|     # shellcheck source=config/conf/artools-iso.conf |     # shellcheck source=config/conf/artools-iso.conf | ||||||
|     [[ -r "$conf" ]] && source "$conf" |     [[ -r "$conf" ]] && source "$conf" | ||||||
|  |  | ||||||
|  |     CHROOTS_DIR=${CHROOTS_DIR:-'/var/lib/artools'} | ||||||
|  |  | ||||||
|  |     WORKSPACE_DIR=${WORKSPACE_DIR:-"${USER_HOME}/artools-workspace"} | ||||||
|  |  | ||||||
|  |     ARCH=${ARCH:-"$(uname -m)"} | ||||||
|  |  | ||||||
|  |     REPO=${REPO:-'world'} | ||||||
|  |  | ||||||
|     ISO_POOL=${ISO_POOL:-"${WORKSPACE_DIR}/iso"} |     ISO_POOL=${ISO_POOL:-"${WORKSPACE_DIR}/iso"} | ||||||
|  |  | ||||||
|     ISO_VERSION=${ISO_VERSION:-"$(date +%Y%m%d)"} |     ISO_VERSION=${ISO_VERSION:-"$(date +%Y%m%d)"} | ||||||
|   | |||||||
| @@ -272,8 +272,17 @@ update_yaml_move() { | |||||||
|             -i "${REPO_DB}" |             -i "${REPO_DB}" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | show_agent() { | ||||||
|  |     local agent="orion" | ||||||
|  |     if grep @galaxy "${REPO_CI}" &>/dev/null; then | ||||||
|  |         agent="taurus" | ||||||
|  |     fi | ||||||
|  |     msg2 "agent: %s" "$agent" | ||||||
|  | } | ||||||
|  |  | ||||||
| show_db() { | show_db() { | ||||||
|     if ! yq -r ${REPO_DB} 1>/dev/null 2>/dev/null; then |     show_agent | ||||||
|  |     if ! yq -r "${REPO_DB}" 1>/dev/null 2>/dev/null; then | ||||||
|         die "${REPO_DB} invalid!" |         die "${REPO_DB} invalid!" | ||||||
|     fi |     fi | ||||||
|     yq -rP '. | with_entries(select(.value.name))' "${REPO_DB}" |     yq -rP '. | with_entries(select(.value.name))' "${REPO_DB}" | ||||||
|   | |||||||
| @@ -13,8 +13,8 @@ set -e | |||||||
|  |  | ||||||
| commit_ci(){ | commit_ci(){ | ||||||
|     [[ -d .artixlinux ]] || mkdir .artixlinux |     [[ -d .artixlinux ]] || mkdir .artixlinux | ||||||
|     if [[ ${AGENT} == ${ARTIX_DB[11]} ]]; then |     if [[ ${AGENT} == "${ARTIX_DB[11]}" ]]; then | ||||||
|         printf "@Library('artix-ci@${AGENT}') import org.artixlinux.RepoPackage\n" > "${REPO_CI}" |         printf "@Library('artix-ci@%s') import org.artixlinux.RepoPackage\n" "${AGENT}" > "${REPO_CI}" | ||||||
|     else |     else | ||||||
|         printf "@Library('artix-ci') import org.artixlinux.RepoPackage\n" > "${REPO_CI}" |         printf "@Library('artix-ci') import org.artixlinux.RepoPackage\n" > "${REPO_CI}" | ||||||
|     fi |     fi | ||||||
| @@ -35,7 +35,7 @@ artixpkg_git_config_usage() { | |||||||
|     OPTIONS |     OPTIONS | ||||||
|         -m, --maintainer       Set the maintainer topic via gitea api |         -m, --maintainer       Set the maintainer topic via gitea api | ||||||
|         -d, --drop             Drop the maintainer topic via gitea api |         -d, --drop             Drop the maintainer topic via gitea api | ||||||
|         -a, --agent=NAME       Set the CI agent (default: official) |         -a, --agent NAME       Set the CI agent (default: official) | ||||||
|                                Possible values: [official, galaxy] |                                Possible values: [official, galaxy] | ||||||
|         --protocol https       Configure remote url to use https |         --protocol https       Configure remote url to use https | ||||||
|         -j, --jobs N           Run up to N jobs in parallel (default: $(nproc)) |         -j, --jobs N           Run up to N jobs in parallel (default: $(nproc)) | ||||||
| @@ -136,10 +136,12 @@ artixpkg_git_config() { | |||||||
|         -a|--agent) |         -a|--agent) | ||||||
|             (( $# <= 1 )) && die "missing argument for %s" "$1" |             (( $# <= 1 )) && die "missing argument for %s" "$1" | ||||||
|             AGENT="$2" |             AGENT="$2" | ||||||
|  |             RUNCMD+=" -a ${AGENT}" | ||||||
|             shift 2 |             shift 2 | ||||||
|         ;; |         ;; | ||||||
|         --agent=*) |         --agent=*) | ||||||
|             AGENT="${1#*=}" |             AGENT="${1#*=}" | ||||||
|  |             RUNCMD+=" -a ${AGENT}" | ||||||
|             shift |             shift | ||||||
|         ;; |         ;; | ||||||
|         --protocol=https) |         --protocol=https) | ||||||
| @@ -186,7 +188,7 @@ artixpkg_git_config() { | |||||||
|  |  | ||||||
|     # Load makepkg.conf variables to be available for packager identity |     # Load makepkg.conf variables to be available for packager identity | ||||||
|     msg "Collecting packager identity from makepkg.conf" |     msg "Collecting packager identity from makepkg.conf" | ||||||
|     # shellcheck disable=2119 |     # shellcheck source=config/makepkg/x86_64.conf | ||||||
|     load_makepkg_config |     load_makepkg_config | ||||||
|     if [[ -n ${PACKAGER} ]]; then |     if [[ -n ${PACKAGER} ]]; then | ||||||
|         if ! packager_name=$(get_packager_name "${PACKAGER}") || \ |         if ! packager_name=$(get_packager_name "${PACKAGER}") || \ | ||||||
|   | |||||||
| @@ -108,7 +108,7 @@ artixpkg_git_create() { | |||||||
|             fi |             fi | ||||||
|             msg_success "Successfully created ${pkgbase}" |             msg_success "Successfully created ${pkgbase}" | ||||||
|         fi |         fi | ||||||
|         if [[ ${TEAM} == ${ARTIX_DB[11]} ]]; then |         if [[ ${TEAM} == "${ARTIX_DB[11]}" ]]; then | ||||||
|             AGENT+=(--agent="${TEAM}") |             AGENT+=(--agent="${TEAM}") | ||||||
|         fi |         fi | ||||||
|         if (( clone )); then |         if (( clone )); then | ||||||
|   | |||||||
| @@ -124,7 +124,7 @@ artixpkg_git_pull() { | |||||||
|  |  | ||||||
|     for pkgbase in "${pkgbases[@]}"; do |     for pkgbase in "${pkgbases[@]}"; do | ||||||
|         if [[ -d ${pkgbase} ]]; then |         if [[ -d ${pkgbase} ]]; then | ||||||
|             ( cd ${pkgbase} || return |             ( cd "${pkgbase}" || return | ||||||
|  |  | ||||||
|                 msg "Pulling ${pkgbase} ..." |                 msg "Pulling ${pkgbase} ..." | ||||||
|                 if ! git pull origin master; then |                 if ! git pull origin master; then | ||||||
|   | |||||||
| @@ -113,7 +113,7 @@ artixpkg_git_push() { | |||||||
|  |  | ||||||
|     for pkgbase in "${pkgbases[@]}"; do |     for pkgbase in "${pkgbases[@]}"; do | ||||||
|         if [[ -d ${pkgbase} ]]; then |         if [[ -d ${pkgbase} ]]; then | ||||||
|             ( cd ${pkgbase} || return |             ( cd "${pkgbase}" || return | ||||||
|  |  | ||||||
|                 msg "Pushing ${pkgbase} ..." |                 msg "Pushing ${pkgbase} ..." | ||||||
|                 if ! git push origin master; then |                 if ! git push origin master; then | ||||||
|   | |||||||
| @@ -11,33 +11,6 @@ source "${LIBDIR}"/pkg/db/db.sh | |||||||
| set -e | set -e | ||||||
|  |  | ||||||
|  |  | ||||||
| check_pkgbuild_validity() { |  | ||||||
|     # shellcheck source=contrib/makepkg/PKGBUILD.proto |  | ||||||
|     . ./PKGBUILD |  | ||||||
|  |  | ||||||
|     # skip when there are no sources available |  | ||||||
|     if (( ! ${#source[@]} )); then |  | ||||||
|         return |  | ||||||
|     fi |  | ||||||
|  |  | ||||||
|     # validate sources hash algo is at least > sha1 |  | ||||||
|     local bad_algos=("cksums" "md5sums" "sha1sums") |  | ||||||
|     local good_hash_algo=false |  | ||||||
|  |  | ||||||
|     # from makepkg libmakepkg/util/schema.sh |  | ||||||
|     for integ in "${known_hash_algos[@]}"; do |  | ||||||
|         local sumname="${integ}sums" |  | ||||||
|         if [[ -n ${!sumname} ]] && ! in_array "${sumname}" "${bad_algos[@]}"; then |  | ||||||
|             good_hash_algo=true |  | ||||||
|             break |  | ||||||
|         fi |  | ||||||
|     done |  | ||||||
|  |  | ||||||
|     if ! $good_hash_algo; then |  | ||||||
|         die "PKGBUILD lacks a secure cryptographic checksum, insecure algorithms: ${bad_algos[*]}" |  | ||||||
|     fi |  | ||||||
| } |  | ||||||
|  |  | ||||||
| has_remote_changes() { | has_remote_changes() { | ||||||
|     local status |     local status | ||||||
|     msg "Checking for remote changes ..." |     msg "Checking for remote changes ..." | ||||||
|   | |||||||
| @@ -8,6 +8,30 @@ ARTOOLS_INCLUDE_REPO_ADD_SH=1 | |||||||
| set -e | set -e | ||||||
|  |  | ||||||
|  |  | ||||||
|  | check_pkgbuild_validity() { | ||||||
|  |     # skip when there are no sources available | ||||||
|  |     if (( ! ${#source[@]} )); then | ||||||
|  |         return | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     # validate sources hash algo is at least > sha1 | ||||||
|  |     local bad_algos=("cksums" "md5sums" "sha1sums") | ||||||
|  |     local good_hash_algo=false | ||||||
|  |  | ||||||
|  |     # from makepkg libmakepkg/util/schema.sh | ||||||
|  |     for integ in "${known_hash_algos[@]}"; do | ||||||
|  |         local sumname="${integ}sums" | ||||||
|  |         if [[ -n ${!sumname} ]] && ! in_array "${sumname}" "${bad_algos[@]}"; then | ||||||
|  |             good_hash_algo=true | ||||||
|  |             break | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  |  | ||||||
|  |     if ! $good_hash_algo; then | ||||||
|  |         die "PKGBUILD lacks a secure cryptographic checksum, insecure algorithms: ${bad_algos[*]}" | ||||||
|  |     fi | ||||||
|  | } | ||||||
|  |  | ||||||
| artixpkg_repo_add_usage() { | artixpkg_repo_add_usage() { | ||||||
|     local -r COMMAND=${_ARTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} |     local -r COMMAND=${_ARTOOLS_COMMAND:-${BASH_SOURCE[0]##*/}} | ||||||
|     cat <<- _EOF_ |     cat <<- _EOF_ | ||||||
| @@ -86,6 +110,8 @@ artixpkg_repo_add() { | |||||||
|             fi |             fi | ||||||
|             ( cd "${pkgbase}" || return |             ( cd "${pkgbase}" || return | ||||||
|  |  | ||||||
|  |                 if ! has_remote_changes; then | ||||||
|  |  | ||||||
|                     if [[ ! -f PKGBUILD ]]; then |                     if [[ ! -f PKGBUILD ]]; then | ||||||
|                         die "No PKGBUILD found in (%s)" "${pkgbase}" |                         die "No PKGBUILD found in (%s)" "${pkgbase}" | ||||||
|                     fi |                     fi | ||||||
| @@ -93,6 +119,10 @@ artixpkg_repo_add() { | |||||||
|                     # shellcheck source=contrib/makepkg/PKGBUILD.proto |                     # shellcheck source=contrib/makepkg/PKGBUILD.proto | ||||||
|                     source PKGBUILD |                     source PKGBUILD | ||||||
|  |  | ||||||
|  |                     check_pkgbuild_validity | ||||||
|  |  | ||||||
|  |                     manage-pkgbuild-keys --export | ||||||
|  |  | ||||||
|                     update_yaml_base |                     update_yaml_base | ||||||
|                     update_yaml_add "${REBUILD}" "${ADD}" "${NOCHECK}" "${DEST}" |                     update_yaml_add "${REBUILD}" "${ADD}" "${NOCHECK}" "${DEST}" | ||||||
|  |  | ||||||
| @@ -130,6 +160,8 @@ artixpkg_repo_add() { | |||||||
|                             warning "Could not query ${REPO_DB}" |                             warning "Could not query ${REPO_DB}" | ||||||
|                         fi |                         fi | ||||||
|                     fi |                     fi | ||||||
|  |  | ||||||
|  |                 fi | ||||||
|             ) |             ) | ||||||
|         fi |         fi | ||||||
|  |  | ||||||
|   | |||||||
| @@ -80,22 +80,24 @@ artixpkg_repo_move() { | |||||||
|             fi |             fi | ||||||
|             ( cd "${pkgbase}" || return |             ( cd "${pkgbase}" || return | ||||||
|  |  | ||||||
|  |                 if ! has_remote_changes; then | ||||||
|  |  | ||||||
|                     if [[ ! -f PKGBUILD ]]; then |                     if [[ ! -f PKGBUILD ]]; then | ||||||
|                         die "No PKGBUILD found in (%s)" "${pkgbase}" |                         die "No PKGBUILD found in (%s)" "${pkgbase}" | ||||||
|                     fi |                     fi | ||||||
|  |  | ||||||
|                 local commit_msg src_version dest_version |                     local commit_msg src_version # dest_version | ||||||
|                     commit_msg=$(get_commit_msg 'move' "${DEST}" "${SRC}") |                     commit_msg=$(get_commit_msg 'move' "${DEST}" "${SRC}") | ||||||
|  |  | ||||||
|                     src_version=$(version_from_yaml "${SRC}") |                     src_version=$(version_from_yaml "${SRC}") | ||||||
|                 dest_version=$(version_from_yaml "${DEST}") | #                     dest_version=$(version_from_yaml "${DEST}") | ||||||
|  |  | ||||||
|                     if [[ "$src_version" != null ]]; then |                     if [[ "$src_version" != null ]]; then | ||||||
|  |  | ||||||
|                     local ret | #                         local ret | ||||||
|                     ret=$(vercmp "$src_version" "$dest_version") | #                         ret=$(vercmp "$src_version" "$dest_version") | ||||||
|  | # | ||||||
|                     if (( ret > 0 )); then | #                         if (( ret > 0 )); then | ||||||
|  |  | ||||||
|                             update_yaml_move "${SRC}" "${DEST}" |                             update_yaml_move "${SRC}" "${DEST}" | ||||||
|  |  | ||||||
| @@ -128,17 +130,19 @@ artixpkg_repo_move() { | |||||||
|  |  | ||||||
|                             fi |                             fi | ||||||
|  |  | ||||||
|                     elif (( ret < 0 )); then | #                         elif (( ret < 0 )); then | ||||||
|  | # | ||||||
|                         error "invalid move: version $src_version < $dest_version!" | #                             error "${pkgbase}: invalid move: version $src_version < $dest_version!" | ||||||
|  | # | ||||||
|  | #                         else | ||||||
|  | #                             error "${pkgbase}: invalid move: version $src_version = $dest_version!" | ||||||
|  | # | ||||||
|  | #                         fi | ||||||
|  |  | ||||||
|                     else |                     else | ||||||
|                         error "invalid move: version $src_version = $dest_version!" |                         error "${pkgbase}: invalid move: version $src_version!" | ||||||
|  |  | ||||||
|                     fi |                     fi | ||||||
|  |  | ||||||
|                 else |  | ||||||
|                     error "invalid move: version $src_version!" |  | ||||||
|                 fi |                 fi | ||||||
|  |  | ||||||
|             ) |             ) | ||||||
|   | |||||||
| @@ -73,6 +73,8 @@ artixpkg_repo_remove() { | |||||||
|             fi |             fi | ||||||
|             ( cd "${pkgbase}" || return |             ( cd "${pkgbase}" || return | ||||||
|  |  | ||||||
|  |                 if ! has_remote_changes; then | ||||||
|  |  | ||||||
|                     if [[ ! -f PKGBUILD ]]; then |                     if [[ ! -f PKGBUILD ]]; then | ||||||
|                         die "No PKGBUILD found in (%s)" "${pkgbase}" |                         die "No PKGBUILD found in (%s)" "${pkgbase}" | ||||||
|                     fi |                     fi | ||||||
| @@ -106,6 +108,8 @@ artixpkg_repo_remove() { | |||||||
|                         fi |                         fi | ||||||
|  |  | ||||||
|                     fi |                     fi | ||||||
|  |  | ||||||
|  |                 fi | ||||||
|             ) |             ) | ||||||
|         fi |         fi | ||||||
|  |  | ||||||
|   | |||||||
| @@ -4,6 +4,21 @@ | |||||||
|  |  | ||||||
| #{{{ pkg conf | #{{{ pkg conf | ||||||
|  |  | ||||||
|  | prepare_dir(){ | ||||||
|  |     [[ ! -d $1 ]] && mkdir -p "$1" | ||||||
|  |     return 0 | ||||||
|  | } | ||||||
|  |  | ||||||
|  | if [[ -n $SUDO_USER ]]; then | ||||||
|  |     eval "USER_HOME=~$SUDO_USER" | ||||||
|  | else | ||||||
|  |     USER_HOME=$HOME | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | USER_CONF_DIR="${XDG_CONFIG_HOME:-$USER_HOME/.config}/artools" | ||||||
|  |  | ||||||
|  | prepare_dir "${USER_CONF_DIR}" | ||||||
|  |  | ||||||
| load_pkg_config(){ | load_pkg_config(){ | ||||||
|  |  | ||||||
|     local conf="$1/artools-pkg.conf" |     local conf="$1/artools-pkg.conf" | ||||||
| @@ -13,6 +28,14 @@ load_pkg_config(){ | |||||||
|     # shellcheck source=config/conf/artools-pkg.conf |     # shellcheck source=config/conf/artools-pkg.conf | ||||||
|     [[ -r "$conf" ]] && source "$conf" |     [[ -r "$conf" ]] && source "$conf" | ||||||
|  |  | ||||||
|  |     CHROOTS_DIR=${CHROOTS_DIR:-'/var/lib/artools'} | ||||||
|  |  | ||||||
|  |     WORKSPACE_DIR=${WORKSPACE_DIR:-"${USER_HOME}/artools-workspace"} | ||||||
|  |  | ||||||
|  |     ARCH=${ARCH:-"$(uname -m)"} | ||||||
|  |  | ||||||
|  |     REPO=${REPO:-'world'} | ||||||
|  |  | ||||||
|     local git_domain="gitea.artixlinux.org" |     local git_domain="gitea.artixlinux.org" | ||||||
|  |  | ||||||
|     GIT_HTTPS=${GIT_HTTPS:-"https://${git_domain}"} |     GIT_HTTPS=${GIT_HTTPS:-"https://${git_domain}"} | ||||||
|   | |||||||
| @@ -37,8 +37,6 @@ fi | |||||||
|  |  | ||||||
| export _ARTOOLS_COMMAND='artixpkg' | export _ARTOOLS_COMMAND='artixpkg' | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/pkg/util.sh | # shellcheck source=src/lib/pkg/util.sh | ||||||
| source "${LIBDIR}"/pkg/util.sh | source "${LIBDIR}"/pkg/util.sh | ||||||
|  |  | ||||||
|   | |||||||
| @@ -6,12 +6,12 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
| DATADIR=${DATADIR:-'@datadir@'} | DATADIR=${DATADIR:-'@datadir@'} | ||||||
| SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/chroot.sh | # shellcheck source=src/lib/base/chroot.sh | ||||||
| source "${LIBDIR}"/base/chroot.sh | source "${LIBDIR}"/base/chroot.sh | ||||||
|  | # shellcheck source=src/lib/pkg/util.sh | ||||||
|  | source "${LIBDIR}"/pkg/util.sh | ||||||
|  |  | ||||||
| create_first=false | create_first=false | ||||||
| rebuild=false | rebuild=false | ||||||
| @@ -52,7 +52,7 @@ while getopts "${opts}" arg; do | |||||||
|         d) repo="$OPTARG" ;; |         d) repo="$OPTARG" ;; | ||||||
|         a) arch="$OPTARG" ;; |         a) arch="$OPTARG" ;; | ||||||
|         c) create_first=true ;; |         c) create_first=true ;; | ||||||
|         m) rebuild=true; repo=${repo%-*} ;; |         m) rebuild=true ;; | ||||||
|         C) mkchrootpkg_args+=(-C) ;; |         C) mkchrootpkg_args+=(-C) ;; | ||||||
|         N) mkchrootpkg_args+=(-N) ;; |         N) mkchrootpkg_args+=(-N) ;; | ||||||
|         n) mkchrootpkg_args+=(-n) ;; |         n) mkchrootpkg_args+=(-n) ;; | ||||||
| @@ -60,6 +60,10 @@ while getopts "${opts}" arg; do | |||||||
|     esac |     esac | ||||||
| done | done | ||||||
|  |  | ||||||
|  | if "${rebuild}"; then | ||||||
|  |     repo=${repo%-*} | ||||||
|  | fi | ||||||
|  |  | ||||||
| if [[ "${repo}" == lib32* ]]; then | if [[ "${repo}" == lib32* ]]; then | ||||||
|     base_packages+=('multilib-devel') |     base_packages+=('multilib-devel') | ||||||
| fi | fi | ||||||
|   | |||||||
| @@ -57,7 +57,7 @@ while (( $# )); do | |||||||
|             shift |             shift | ||||||
|             break |             break | ||||||
|             ;; |             ;; | ||||||
|         -*|--*) |         --*|-*) | ||||||
|             die "invalid argument: %s" "$1" |             die "invalid argument: %s" "$1" | ||||||
|             ;; |             ;; | ||||||
|         *) |         *) | ||||||
| @@ -76,10 +76,10 @@ fi | |||||||
|  |  | ||||||
| # Source user-specific makepkg.conf overrides | # Source user-specific makepkg.conf overrides | ||||||
| if [[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" ]]; then | if [[ -r "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" ]]; then | ||||||
|     # shellcheck source=/dev/null |     # shellcheck source=config/makepkg/x86_64.conf | ||||||
|     source "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" |     source "${XDG_CONFIG_HOME:-$HOME/.config}/pacman/makepkg.conf" | ||||||
| elif [[ -r "$HOME/.makepkg.conf" ]]; then | elif [[ -r "$HOME/.makepkg.conf" ]]; then | ||||||
|     # shellcheck source=/dev/null |     # shellcheck source=config/makepkg/x86_64.conf | ||||||
|     source "$HOME/.makepkg.conf" |     source "$HOME/.makepkg.conf" | ||||||
| fi | fi | ||||||
|  |  | ||||||
| @@ -152,7 +152,11 @@ for _pkgname in "${pkgname[@]}"; do | |||||||
|     find-libprovides "$pkgfile" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname" |     find-libprovides "$pkgfile" 2>/dev/null | sort > "$TEMPDIR/libraries-$_pkgname" | ||||||
|     if ! diff_output="$(sdiff -s "$TEMPDIR/libraries-$_pkgname-old" "$TEMPDIR/libraries-$_pkgname")"; then |     if ! diff_output="$(sdiff -s "$TEMPDIR/libraries-$_pkgname-old" "$TEMPDIR/libraries-$_pkgname")"; then | ||||||
|         message="Sonames differ in $_pkgname!" |         message="Sonames differ in $_pkgname!" | ||||||
|         (( WARN )) && warning "$message" || msg "$message" |         if (( WARN )); then | ||||||
|  |             warning "$message" | ||||||
|  |         else | ||||||
|  |             msg "$message" | ||||||
|  |         fi | ||||||
|         printf "%s\n" "$diff_output" 2>&1 | tee "${pkgfile##*/}-checkpkg.log" |         printf "%s\n" "$diff_output" 2>&1 | tee "${pkgfile##*/}-checkpkg.log" | ||||||
|         changed=1 |         changed=1 | ||||||
|     else |     else | ||||||
|   | |||||||
| @@ -6,8 +6,6 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
| DATADIR=${DATADIR:-'@datadir@'} | DATADIR=${DATADIR:-'@datadir@'} | ||||||
| SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/pkg/util.sh | # shellcheck source=src/lib/pkg/util.sh | ||||||
| source "${LIBDIR}"/pkg/util.sh | source "${LIBDIR}"/pkg/util.sh | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| @@ -32,6 +30,7 @@ update_linksdb_cache(){ | |||||||
|     local cachedir url |     local cachedir url | ||||||
|     for repo in "${search[@]}"; do |     for repo in "${search[@]}"; do | ||||||
|         cachedir=${db_cache_dir}/linksdb/$repo |         cachedir=${db_cache_dir}/linksdb/$repo | ||||||
|  |         # shellcheck disable=SC2153 | ||||||
|         url=${REPOS_MIRROR}/$repo/os/${CARCH}/$repo.${linksdb_ext} |         url=${REPOS_MIRROR}/$repo/os/${CARCH}/$repo.${linksdb_ext} | ||||||
|         extract_db "$url" "$cachedir" |         extract_db "$url" "$cachedir" | ||||||
|     done |     done | ||||||
|   | |||||||
| @@ -39,7 +39,7 @@ umask 0022 | |||||||
| working_dir='' | working_dir='' | ||||||
| 
 | 
 | ||||||
| files=() | files=() | ||||||
| mount_args=("-B:/etc/hosts:/etc/hosts") | mount_args="-B:/etc/hosts:/etc/hosts" | ||||||
| 
 | 
 | ||||||
| usage() { | usage() { | ||||||
|     printf "Usage: %s [options] working-dir [run arguments]\n" "${0##*/}" |     printf "Usage: %s [options] working-dir [run arguments]\n" "${0##*/}" | ||||||
| @@ -72,7 +72,7 @@ while getopts ${opts} arg; do | |||||||
|         f) files+=("$OPTARG") ;; |         f) files+=("$OPTARG") ;; | ||||||
|         s) nosetarch=1 ;; |         s) nosetarch=1 ;; | ||||||
|         t) tmpfs_opts="$OPTARG" ;; |         t) tmpfs_opts="$OPTARG" ;; | ||||||
|         b) bindmounts="$OPTARG"; mount_args+=(${bindmounts}) ;; |         b) bindmounts="$OPTARG"; mount_args+=" ${bindmounts}" ;; | ||||||
|         h|?) usage ;; |         h|?) usage ;; | ||||||
|         *) error "invalid argument '%s'" "$arg"; usage ;; |         *) error "invalid argument '%s'" "$arg"; usage ;; | ||||||
|     esac |     esac | ||||||
| @@ -96,6 +96,7 @@ mapfile -t host_mirrors < <(pacman-conf --repo world Server 2> /dev/null | sed - | |||||||
| 
 | 
 | ||||||
| for host_mirror in "${host_mirrors[@]}"; do | for host_mirror in "${host_mirrors[@]}"; do | ||||||
|     if [[ $host_mirror == *file://* ]]; then |     if [[ $host_mirror == *file://* ]]; then | ||||||
|  |         # shellcheck disable=SC2016 | ||||||
|         host_mirror=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g') |         host_mirror=$(echo "$host_mirror" | sed -r 's#file://(/.*)/\$repo/os/\$arch#\1#g') | ||||||
|         for m in "$host_mirror"/pool/*/; do |         for m in "$host_mirror"/pool/*/; do | ||||||
|             in_array "$m" "${cache_dirs[@]}" || cache_dirs+=("$m") |             in_array "$m" "${cache_dirs[@]}" || cache_dirs+=("$m") | ||||||
| @@ -114,10 +115,10 @@ while read -r line; do | |||||||
|     done |     done | ||||||
| done < <(pacman-conf --config "${pacman_conf:-$working_dir/etc/pacman.conf}" --repo-list) | done < <(pacman-conf --config "${pacman_conf:-$working_dir/etc/pacman.conf}" --repo-list) | ||||||
| 
 | 
 | ||||||
| mount_args+=("-B:${cache_dirs[0]//:/\\:}:${cache_dirs[0]//:/\\:}") | mount_args+=" -B:${cache_dirs[0]//:/\\:}:${cache_dirs[0]//:/\\:}" | ||||||
| 
 | 
 | ||||||
| for cache_dir in "${cache_dirs[@]:1}"; do | for cache_dir in "${cache_dirs[@]:1}"; do | ||||||
|     mount_args+=("-Br:${cache_dir//:/\\:}:${cache_dir//:/\\:}") |     mount_args+=" -Br:${cache_dir//:/\\:}:${cache_dir//:/\\:}" | ||||||
| done | done | ||||||
| 
 | 
 | ||||||
| # {{{ functions | # {{{ functions | ||||||
| @@ -144,13 +145,13 @@ copy_hostconf () { | |||||||
| chroot_extra_mount() { | chroot_extra_mount() { | ||||||
|     chroot_add_resolv_conf "${working_dir}" |     chroot_add_resolv_conf "${working_dir}" | ||||||
| 
 | 
 | ||||||
|     for arg in "${mount_args[@]}"; do |     for arg in ${mount_args}; do | ||||||
|         local flag dest src |         local flag dest src | ||||||
|         flag=${arg%%:*} |         flag=${arg%%:*} | ||||||
|         dest=${arg##*:} |         dest=${arg##*:} | ||||||
|         src=${arg%:*} |         src=${arg%:*} | ||||||
|         src=${src#*:} |         src=${src#*:} | ||||||
|         chroot_mount "${src}" "${working_dir}${dest}" "${flag}" |         chroot_add_mount "${src}" "${working_dir}${dest}" "${flag}" | ||||||
|     done |     done | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| @@ -165,7 +166,7 @@ elif [[ $(cat "$working_dir/.artix-chroot") != "${CHROOTVERSION}" ]]; then | |||||||
|     die "chroot '%s' is not at version %s. Please rebuild." "$working_dir" "${CHROOTVERSION}" |     die "chroot '%s' is not at version %s. Please rebuild." "$working_dir" "${CHROOTVERSION}" | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
| chroot_api_mount "${working_dir}" "${tmpfs_opts}" || die "failed to setup API filesystems in chroot %s" "${working_dir}" | chroot_setup "${working_dir}" "${tmpfs_opts}" || die "failed to setup API filesystems in chroot %s" "${working_dir}" | ||||||
| 
 | 
 | ||||||
| chroot_extra_mount | chroot_extra_mount | ||||||
| 
 | 
 | ||||||
| @@ -4,12 +4,12 @@ | |||||||
|  |  | ||||||
| LIBDIR=${LIBDIR:-'@libdir@'} | LIBDIR=${LIBDIR:-'@libdir@'} | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/chroot.sh | # shellcheck source=src/lib/base/chroot.sh | ||||||
| source "${LIBDIR}"/base/chroot.sh | source "${LIBDIR}"/base/chroot.sh | ||||||
|  | # shellcheck source=src/lib/pkg/util.sh | ||||||
|  | source "${LIBDIR}"/pkg/util.sh | ||||||
|  |  | ||||||
| shopt -s nullglob | shopt -s nullglob | ||||||
|  |  | ||||||
| @@ -76,6 +76,7 @@ umask 0022 | |||||||
|  |  | ||||||
| ORIG_HOME=$HOME | ORIG_HOME=$HOME | ||||||
| IFS=: read -r _ _ _ _ _ HOME _ < <(getent passwd "${SUDO_USER:-$USER}") | IFS=: read -r _ _ _ _ _ HOME _ < <(getent passwd "${SUDO_USER:-$USER}") | ||||||
|  | # shellcheck source=config/makepkg/x86_64.conf | ||||||
| load_makepkg_config | load_makepkg_config | ||||||
| HOME=$ORIG_HOME | HOME=$ORIG_HOME | ||||||
|  |  | ||||||
|   | |||||||
| @@ -127,7 +127,7 @@ while (( $# )); do | |||||||
|             shift |             shift | ||||||
|             break |             break | ||||||
|         ;; |         ;; | ||||||
|         -*|--*) |         --*|-*) | ||||||
|             die "invalid argument: %s" "$1" |             die "invalid argument: %s" "$1" | ||||||
|         ;; |         ;; | ||||||
|         *) |         *) | ||||||
|   | |||||||
| @@ -1,73 +0,0 @@ | |||||||
| #!/bin/bash |  | ||||||
| # |  | ||||||
| # SPDX-License-Identifier: GPL-3.0-or-later |  | ||||||
|  |  | ||||||
| LIBDIR=${LIBDIR:-'@libdir@'} |  | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/message.sh |  | ||||||
| source "${LIBDIR}"/base/message.sh |  | ||||||
|  |  | ||||||
| usage() { |  | ||||||
|     cat <<- _EOF_ |  | ||||||
|         Usage: ${BASH_SOURCE[0]##*/} |  | ||||||
|  |  | ||||||
|         Export the PGP keys from a PKGBUILDs validpgpkeys array into the keys/pgp/ |  | ||||||
|         subdirectory. Useful for distributing packager validated source signing |  | ||||||
|         keys alongside PKGBUILDs. |  | ||||||
|  |  | ||||||
|         OPTIONS |  | ||||||
|             -h, --help      Show this help text |  | ||||||
| _EOF_ |  | ||||||
| } |  | ||||||
|  |  | ||||||
| # option checking |  | ||||||
| while (( $# )); do |  | ||||||
|     case $1 in |  | ||||||
|         -h|--help) usage; exit 0 ;; |  | ||||||
|         *) die "invalid argument: %s" "$1" ;; |  | ||||||
|     esac |  | ||||||
| done |  | ||||||
|  |  | ||||||
| if [[ ! -f PKGBUILD ]]; then |  | ||||||
|     die "This must be run a directory containing a PKGBUILD." |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| mapfile -t validpgpkeys < <( |  | ||||||
|     # shellcheck source=contrib/makepkg/PKGBUILD.proto |  | ||||||
|     . ./PKGBUILD |  | ||||||
|     if (( ${#validpgpkeys[@]} )); then |  | ||||||
|         printf "%s\n" "${validpgpkeys[@]}" |  | ||||||
|     fi |  | ||||||
| ) |  | ||||||
|  |  | ||||||
| msg "Exporting ${#validpgpkeys[@]} PGP keys..." |  | ||||||
| if (( ${#validpgpkeys[@]} == 0 )); then |  | ||||||
|     exit 0 |  | ||||||
| fi |  | ||||||
|  |  | ||||||
| trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT |  | ||||||
| TEMPDIR=$(mktemp -d --tmpdir export-pkgbuild-keys.XXXXXXXXXX) |  | ||||||
|  |  | ||||||
| mkdir -p keys/pgp |  | ||||||
| error=0 |  | ||||||
|  |  | ||||||
| for key in "${validpgpkeys[@]}"; do |  | ||||||
|     gpg --output "$TEMPDIR/$key.asc" --armor --export --export-options export-minimal "$key" 2>/dev/null |  | ||||||
|  |  | ||||||
|     # gpg does not give a non-zero return value if it fails to export... |  | ||||||
|     if [[ -f $TEMPDIR/$key.asc ]]; then |  | ||||||
|         msg2 "Exported $key" |  | ||||||
|         mv "$TEMPDIR/$key.asc" "keys/pgp/$key.asc" |  | ||||||
|     else |  | ||||||
|         if [[ -f keys/pgp/$key.asc ]]; then |  | ||||||
|             warning "Failed to update key: $key" |  | ||||||
|         else |  | ||||||
|             error "Key unavailable: $key" |  | ||||||
|             error=1 |  | ||||||
|         fi |  | ||||||
|     fi |  | ||||||
| done |  | ||||||
|  |  | ||||||
| if (( error )); then |  | ||||||
|     die "Failed to export all \'validpgpkeys\' entries." |  | ||||||
| fi |  | ||||||
| @@ -10,12 +10,12 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
| DATADIR=${DATADIR:-'@datadir@'} | DATADIR=${DATADIR:-'@datadir@'} | ||||||
| SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/chroot.sh | # shellcheck source=src/lib/base/chroot.sh | ||||||
| source "${LIBDIR}"/base/chroot.sh | source "${LIBDIR}"/base/chroot.sh | ||||||
|  | # shellcheck source=src/lib/pkg/util.sh | ||||||
|  | source "${LIBDIR}"/pkg/util.sh | ||||||
|  |  | ||||||
| declare -A buildinfo | declare -A buildinfo | ||||||
| declare -a buildenv buildopts installed installpkgs | declare -a buildenv buildopts installed installpkgs | ||||||
| @@ -133,7 +133,7 @@ while getopts 'dM:c:l:h' arg; do | |||||||
|         c) cache_dirs+=("$OPTARG") ;; |         c) cache_dirs+=("$OPTARG") ;; | ||||||
|         l) chroot="$OPTARG" ;; |         l) chroot="$OPTARG" ;; | ||||||
|         h) usage; exit 0 ;; |         h) usage; exit 0 ;; | ||||||
|         *|?) usage; exit 1 ;; |         ?|*) usage; exit 1 ;; | ||||||
|     esac |     esac | ||||||
| done | done | ||||||
| shift $((OPTIND - 1)) | shift $((OPTIND - 1)) | ||||||
| @@ -222,10 +222,12 @@ TEMPDIR=$(mktemp -d --tmpdir makerepropkg.XXXXXXXXXX) | |||||||
| makepkg_conf="${TEMPDIR}/makepkg.conf" | makepkg_conf="${TEMPDIR}/makepkg.conf" | ||||||
| # anything before buildtool support is pinned to the last none buildtool aware release | # anything before buildtool support is pinned to the last none buildtool aware release | ||||||
| if [[ -z "${BUILDTOOL}" ]]; then | if [[ -z "${BUILDTOOL}" ]]; then | ||||||
|     get_makepkg_conf "artools-pkg-0.28.2-1-any" "${CARCH}" "${makepkg_conf}" || exit 1 |     # shellcheck disable=SC2153 | ||||||
|  |     get_makepkg_conf "artools-pkg-0.31.7-1-any" "${CARCH}" "${makepkg_conf}" || exit 1 | ||||||
| # prefere to assume artools-pkg up until matching makepkg version so repository packages remain reproducible | # prefere to assume artools-pkg up until matching makepkg version so repository packages remain reproducible | ||||||
| elif [[ "${BUILDTOOL}" = makepkg ]] && (( $(vercmp "${BUILDTOOLVER}" 6.0.1) <= 0 )); then | elif [[ "${BUILDTOOL}" = makepkg ]] && (( $(vercmp "${BUILDTOOLVER}" 6.0.1) <= 0 )); then | ||||||
|     get_makepkg_conf "artools-pkg-0.28.2-1-any" "${CARCH}" "${makepkg_conf}" || exit 1 |     # shellcheck disable=SC2153 | ||||||
|  |     get_makepkg_conf "artools-pkg-0.31.7-1-any" "${CARCH}" "${makepkg_conf}" || exit 1 | ||||||
| # all artools-pkg builds | # all artools-pkg builds | ||||||
| elif [[ "${BUILDTOOL}" = artools ]] && get_makepkg_conf "${BUILDTOOL}-${BUILDTOOLVER}" "${makepkg_conf}"; then | elif [[ "${BUILDTOOL}" = artools ]] && get_makepkg_conf "${BUILDTOOL}-${BUILDTOOLVER}" "${makepkg_conf}"; then | ||||||
|     true |     true | ||||||
|   | |||||||
							
								
								
									
										99
									
								
								src/pkg/manage-pkgbuild-keys.in
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										99
									
								
								src/pkg/manage-pkgbuild-keys.in
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,99 @@ | |||||||
|  | #!/bin/bash | ||||||
|  | # | ||||||
|  | # SPDX-License-Identifier: GPL-3.0-or-later | ||||||
|  |  | ||||||
|  | LIBDIR=${LIBDIR:-'@libdir@'} | ||||||
|  |  | ||||||
|  | # shellcheck source=src/lib/base/message.sh | ||||||
|  | source "${LIBDIR}"/base/message.sh | ||||||
|  |  | ||||||
|  |  | ||||||
|  | usage() { | ||||||
|  |     cat <<- _EOF_ | ||||||
|  |         Usage: ${BASH_SOURCE[0]##*/} | ||||||
|  |  | ||||||
|  |         Export or import the PGP keys from a PKGBUILDs validpgpkeys array into/from the keys/pgp/ | ||||||
|  |         subdirectory. Useful for distributing packager validated source signing | ||||||
|  |         keys alongside PKGBUILDs. | ||||||
|  |  | ||||||
|  |         OPTIONS | ||||||
|  |             -i, --import    Import keys | ||||||
|  |             -e, --export    Export keys | ||||||
|  |             -h, --help      Show this help text | ||||||
|  | _EOF_ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | action='' | ||||||
|  | error=0 | ||||||
|  |  | ||||||
|  | # option checking | ||||||
|  | while (( $# )); do | ||||||
|  |     case $1 in | ||||||
|  |         -i|--import) action="import"; shift ;; | ||||||
|  |         -e|--export) action="export"; shift ;; | ||||||
|  |         -h|--help) usage; exit 0 ;; | ||||||
|  |         *) die "invalid argument: %s" "$1" ;; | ||||||
|  |     esac | ||||||
|  | done | ||||||
|  |  | ||||||
|  | if [[ ! -f PKGBUILD ]]; then | ||||||
|  |     die "This must be run a directory containing a PKGBUILD." | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | mapfile -t validpgpkeys < <( | ||||||
|  |     # shellcheck source=contrib/makepkg/PKGBUILD.proto | ||||||
|  |     . ./PKGBUILD | ||||||
|  |     if (( ${#validpgpkeys[@]} )); then | ||||||
|  |         printf "%s\n" "${validpgpkeys[@]}" | ||||||
|  |     fi | ||||||
|  | ) | ||||||
|  |  | ||||||
|  | if [[ "$action" == 'export' ]]; then | ||||||
|  |     msg "Exporting ${#validpgpkeys[@]} PGP keys..." | ||||||
|  |     if (( ${#validpgpkeys[@]} == 0 )); then | ||||||
|  |         exit 0 | ||||||
|  |     fi | ||||||
|  |  | ||||||
|  |     trap 'rm -rf $TEMPDIR' EXIT INT TERM QUIT | ||||||
|  |     TEMPDIR=$(mktemp -d --tmpdir export-pkgbuild-keys.XXXXXXXXXX) | ||||||
|  |  | ||||||
|  |     mkdir -p keys/pgp | ||||||
|  |  | ||||||
|  |     for key in "${validpgpkeys[@]}"; do | ||||||
|  |         gpg --output "$TEMPDIR/$key.asc" --armor --export --export-options export-minimal "$key" 2>/dev/null | ||||||
|  |  | ||||||
|  |         # gpg does not give a non-zero return value if it fails to export... | ||||||
|  |         if [[ -f $TEMPDIR/$key.asc ]]; then | ||||||
|  |             msg2 "Exported $key" | ||||||
|  |             mv "$TEMPDIR/$key.asc" "keys/pgp/$key.asc" | ||||||
|  |         else | ||||||
|  |             if [[ -f keys/pgp/$key.asc ]]; then | ||||||
|  |                 warning "Failed to update key: $key" | ||||||
|  |             else | ||||||
|  |                 error "Key unavailable: $key" | ||||||
|  |                 error=1 | ||||||
|  |             fi | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  | elif [[ "$action" == 'import' ]]; then | ||||||
|  |  | ||||||
|  |     msg "Ensuring required PGP keys are present..." | ||||||
|  |     for key in "${validpgpkeys[@]}"; do | ||||||
|  |         if ! gpg --list-keys "$key" &>/dev/null; then | ||||||
|  |             msg2 "Checking for $key..." | ||||||
|  |             if ! gpg --recv-keys "$key" || ! gpg --fingerprint "$key"; then | ||||||
|  |                 if [[ -f keys/pgp/$key.asc ]]; then | ||||||
|  |                     msg2 "Importing key from local..." | ||||||
|  |                     gpg --import "keys/pgp/$key.asc" | ||||||
|  |                 else | ||||||
|  |                     error "Key unavailable: $key" | ||||||
|  |                     error=1 | ||||||
|  |                 fi | ||||||
|  |             fi | ||||||
|  |         fi | ||||||
|  |     done | ||||||
|  | fi | ||||||
|  |  | ||||||
|  | if (( error )); then | ||||||
|  |     die "Failed to $action all \'validpgpkeys\' entries." | ||||||
|  | fi | ||||||
| @@ -20,6 +20,7 @@ umode='' | |||||||
| 
 | 
 | ||||||
| files=() | files=() | ||||||
| chroot_args=() | chroot_args=() | ||||||
|  | nosetarch=0 | ||||||
| 
 | 
 | ||||||
| usage() { | usage() { | ||||||
|     printf "Usage: %s [options] working-dir package-list...\n" "${0##*/}" |     printf "Usage: %s [options] working-dir package-list...\n" "${0##*/}" | ||||||
| @@ -177,7 +177,7 @@ prepare_chroot() { | |||||||
|     done |     done | ||||||
|  |  | ||||||
|     cat > "$copydir/etc/sudoers.d/builduser-pacman" <<EOF |     cat > "$copydir/etc/sudoers.d/builduser-pacman" <<EOF | ||||||
| builduser ALL = NOPASSWD: /usr/bin/pacman | builduser ALL=(ALL:ALL) NOPASSWD: /usr/bin/pacman | ||||||
| EOF | EOF | ||||||
|     chmod 440 "$copydir/etc/sudoers.d/builduser-pacman" |     chmod 440 "$copydir/etc/sudoers.d/builduser-pacman" | ||||||
|  |  | ||||||
| @@ -205,6 +205,7 @@ _chrootbuild() { | |||||||
|     # No coredumps |     # No coredumps | ||||||
|     ulimit -c 0 |     ulimit -c 0 | ||||||
|  |  | ||||||
|  |     # shellcheck disable=SC1091 | ||||||
|     . /etc/locale.conf |     . /etc/locale.conf | ||||||
|  |  | ||||||
|     # shellcheck source=/dev/null |     # shellcheck source=/dev/null | ||||||
| @@ -263,6 +264,7 @@ move_products() { | |||||||
|  |  | ||||||
|         # Fix broken symlink because of temporary chroot PKGDEST /pkgdest |         # Fix broken symlink because of temporary chroot PKGDEST /pkgdest | ||||||
|         if [[ "$PWD" != "$PKGDEST" && -L "$PWD/${pkgfile##*/}" ]]; then |         if [[ "$PWD" != "$PKGDEST" && -L "$PWD/${pkgfile##*/}" ]]; then | ||||||
|  |             # shellcheck disable=SC2226 | ||||||
|             ln -sf "$PKGDEST/${pkgfile##*/}" |             ln -sf "$PKGDEST/${pkgfile##*/}" | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
| @@ -275,6 +277,7 @@ move_products() { | |||||||
|  |  | ||||||
|         # Fix broken symlink because of temporary chroot SRCPKGDEST /srcpkgdest |         # Fix broken symlink because of temporary chroot SRCPKGDEST /srcpkgdest | ||||||
|         if [[ "$PWD" != "$SRCPKGDEST" && -L "$PWD/${s##*/}" ]]; then |         if [[ "$PWD" != "$SRCPKGDEST" && -L "$PWD/${s##*/}" ]]; then | ||||||
|  |             # shellcheck disable=SC2226 | ||||||
|             ln -sf "$SRCPKGDEST/${s##*/}" |             ln -sf "$SRCPKGDEST/${s##*/}" | ||||||
|         fi |         fi | ||||||
|     done |     done | ||||||
|   | |||||||
| @@ -6,10 +6,12 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| source "${LIBDIR}"/base/message.sh | source "${LIBDIR}"/base/message.sh | ||||||
| # shellcheck source=src/lib/base/yaml.sh | # shellcheck source=src/lib/pkg/yaml.sh | ||||||
| source "${LIBDIR}"/base/yaml.sh | source "${LIBDIR}"/pkg/yaml.sh | ||||||
|  |  | ||||||
|  | # shellcheck disable=1091 | ||||||
| source "${MAKEPKG_LIBRARY}"/util/pkgbuild.sh | source "${MAKEPKG_LIBRARY}"/util/pkgbuild.sh | ||||||
|  | # shellcheck disable=1091 | ||||||
| source "${MAKEPKG_LIBRARY}"/util/schema.sh | source "${MAKEPKG_LIBRARY}"/util/schema.sh | ||||||
|  |  | ||||||
| #{{{ functions | #{{{ functions | ||||||
| @@ -121,6 +123,7 @@ usage() { | |||||||
|     exit "$1" |     exit "$1" | ||||||
| } | } | ||||||
|  |  | ||||||
|  | # shellcheck source=config/makepkg/x86_64.conf | ||||||
| load_makepkg_config | load_makepkg_config | ||||||
|  |  | ||||||
| opts='h' | opts='h' | ||||||
|   | |||||||
| @@ -6,8 +6,6 @@ LIBDIR=${LIBDIR:-'@libdir@'} | |||||||
| DATADIR=${DATADIR:-'@datadir@'} | DATADIR=${DATADIR:-'@datadir@'} | ||||||
| SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | SYSCONFDIR=${SYSCONFDIR:-'@sysconfdir@/artools'} | ||||||
|  |  | ||||||
| # shellcheck source=src/lib/base/util.sh |  | ||||||
| source "${LIBDIR}"/base/util.sh |  | ||||||
| # shellcheck source=src/lib/pkg/util.sh | # shellcheck source=src/lib/pkg/util.sh | ||||||
| source "${LIBDIR}"/pkg/util.sh | source "${LIBDIR}"/pkg/util.sh | ||||||
| # shellcheck source=src/lib/base/message.sh | # shellcheck source=src/lib/base/message.sh | ||||||
| @@ -34,6 +32,7 @@ remove(){ | |||||||
|  |  | ||||||
| repo_action() { | repo_action() { | ||||||
|     local repo_path |     local repo_path | ||||||
|  |     # shellcheck disable=SC2153 | ||||||
|     repo_path=${REPOS_ROOT}/${dest_repo}/os/${CARCH} |     repo_path=${REPOS_ROOT}/${dest_repo}/os/${CARCH} | ||||||
|  |  | ||||||
|     local packages=() action func="$1" |     local packages=() action func="$1" | ||||||
|   | |||||||
| @@ -9,6 +9,7 @@ source "${LIBDIR}"/base/message.sh | |||||||
| # shellcheck source=src/lib/pkg/deploy.sh | # shellcheck source=src/lib/pkg/deploy.sh | ||||||
| source "${LIBDIR}"/pkg/deploy.sh | source "${LIBDIR}"/pkg/deploy.sh | ||||||
|  |  | ||||||
|  | # shellcheck source=config/makepkg/x86_64.conf | ||||||
| load_makepkg_config | load_makepkg_config | ||||||
|  |  | ||||||
| passfiles=("$@") | passfiles=("$@") | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user