initial commit

This commit is contained in:
udeved 2014-10-04 00:46:40 +02:00
parent 061c24007e
commit eaa787147e
27 changed files with 2684 additions and 0 deletions

86
Makefile Normal file
View file

@ -0,0 +1,86 @@
V=20141001
PREFIX = /usr/local
BINPROGS = \
checkpkg \
manjarobuild \
lddd \
finddeps \
find-libdeps \
signpkg \
signpkgs \
mkmanjaroroot \
makechrootpkg \
build-set \
build-set-helper
SYSCONFIGFILES = \
devtools.conf
SETS = \
sets/default.set \
sets/udev.set \
sets/nosystemd.set \
sets/openrc.set \
sets/openrc-nodeps.set
CONFIGFILES = \
makepkg-i686.conf \
makepkg-x86_64.conf \
pacman-default.conf \
pacman-mirrors.conf \
pacman-multilib.conf
MANJAROBUILD_LINKS = \
stable-i686-build \
stable-x86_64-build \
stable-multilib-build \
testing-i686-build \
testing-x86_64-build \
testing-multilib-build \
unstable-i686-build \
unstable-x86_64-build \
unstable-multilib-build
all: $(BINPROGS)
edit = sed -e "s|@pkgdatadir[@]|$(DESTDIR)$(PREFIX)/share/devtools|g" \
-e "s|@sysconfdir[@]|$(DESTDIR)$(SYSCONFDIR)/devtools|g"
%: %.in Makefile lib/common.sh
@echo "GEN $@"
@$(RM) "$@"
@m4 -P $@.in | $(edit) >$@
@chmod a-w "$@"
@chmod +x "$@"
clean:
rm -f $(BINPROGS)
install:
install -dm0755 $(DESTDIR)$(SYSCONFDIR)/devtools
install -m0644 ${SYSCONFIGFILES} $(DESTDIR)$(SYSCONFDIR)/devtools
install -dm0755 $(DESTDIR)$(SYSCONFDIR)/devtools/sets
install -m0644 ${SETS} $(DESTDIR)$(SYSCONFDIR)/devtools/sets
install -dm0755 $(DESTDIR)$(PREFIX)/bin
install -dm0755 $(DESTDIR)$(PREFIX)/share/devtools
install -m0755 ${BINPROGS} $(DESTDIR)$(PREFIX)/bin
install -m0644 ${CONFIGFILES} $(DESTDIR)$(PREFIX)/share/devtools
for l in ${MANJAROBUILD_LINKS}; do ln -sf manjarobuild $(DESTDIR)$(PREFIX)/bin/$$l; done
ln -sf find-libdeps $(DESTDIR)$(PREFIX)/bin/find-libprovides
uninstall:
for f in ${SYSCONFIGFILES}; do rm -f $(DESTDIR)$(SYSCONFDIR)/devtools/$$f; done
for f in ${SETS}; do rm -f $(DESTDIR)$(SYSCONFDIR)/devtools/sets/$$f; done
for f in ${BINPROGS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$f; done
for f in ${CONFIGFILES}; do rm -f $(DESTDIR)$(PREFIX)/share/devtools/$$f; done
for l in ${MANJAROBUILD_LINKS}; do rm -f $(DESTDIR)$(PREFIX)/bin/$$l; done
rm -f $(DESTDIR)$(PREFIX)/bin/find-libprovides
dist:
git archive --format=tar --prefix=devtools-$(V)/ $(V) | gzip -9 > devtools-$(V).tar.gz
gpg --detach-sign --use-agent devtools-$(V).tar.gz
.PHONY: all clean install uninstall dist

28
PKGBUILD Normal file
View file

@ -0,0 +1,28 @@
# Maintainer: Roland Singer <roland@manjaro.org>
pkgname=manjaro-tools
pkgver=20141004
pkgrel=1
pkgdesc='Tools for Manjaro Linux package maintainers'
arch=('any')
license=('GPL')
url='http://git.manjaro.org/core/devtools/'
depends=('namcap' 'openssh' 'subversion' 'rsync')
provides=('devtools')
backup=('etc/devtools/devtools.conf')
source=("git+https://github.com/udeved/manjaro-tools.git")
sha256sums=('SKIP')
pkgver() {
date +%Y%m%d
}
build() {
cd ${srcdir}/${pkgname}
make PREFIX=/usr SYSCONFDIR=/etc
}
package() {
cd ${srcdir}/${pkgname}
make SYSCONFDIR=/etc PREFIX=/usr DESTDIR=${pkgdir} install
}

290
basestrap.in Executable file
View file

@ -0,0 +1,290 @@
#!/bin/bash
#
# Assumptions:
# 1) User has partitioned, formatted, and mounted partitions on /mnt
# 2) Network is functional
# 3) Arguments passed to the script are valid pacman targets
# 4) A valid mirror appears in /etc/pacman.d/mirrorlist
#
shopt -s extglob
# generated from util-linux source: libmount/src/utils.c
declare -A pseudofs_types=([anon_inodefs]=1
[autofs]=1
[bdev]=1
[binfmt_misc]=1
[cgroup]=1
[configfs]=1
[cpuset]=1
[debugfs]=1
[devfs]=1
[devpts]=1
[devtmpfs]=1
[dlmfs]=1
[fuse.gvfs-fuse-daemon]=1
[fusectl]=1
[hugetlbfs]=1
[mqueue]=1
[nfsd]=1
[none]=1
[pipefs]=1
[proc]=1
[pstore]=1
[ramfs]=1
[rootfs]=1
[rpc_pipefs]=1
[securityfs]=1
[sockfs]=1
[spufs]=1
[sysfs]=1
[tmpfs]=1)
# generated from: pkgfile -vbr '/fsck\..+' | awk -F. '{ print $NF }' | sort
declare -A fsck_types=([cramfs]=1
[exfat]=1
[ext2]=1
[ext3]=1
[ext4]=1
[ext4dev]=1
[jfs]=1
[minix]=1
[msdos]=1
[reiserfs]=1
[vfat]=1
[xfs]=1)
out() { printf "$1 $2\n" "${@:3}"; }
error() { out "==> ERROR:" "$@"; } >&2
msg() { out "==>" "$@"; }
msg2() { out " ->" "$@";}
die() { error "$@"; exit 1; }
ignore_error() {
"$@" 2>/dev/null
return 0
}
in_array() {
local i
for i in "${@:2}"; do
[[ $1 = "$i" ]] && return
done
}
track_mount() {
if [[ -z $CHROOT_ACTIVE_MOUNTS ]]; then
CHROOT_ACTIVE_MOUNTS=()
trap 'chroot_umount' EXIT
fi
mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}")
}
mount_conditionally() {
local cond=$1; shift
if eval "$cond"; then
track_mount "$@"
fi
}
api_fs_mount() {
mount_conditionally "! mountpoint -q '$1'" "$1" "$1" --bind &&
track_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev &&
track_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro &&
ignore_error mount_conditionally "[[ -d '$1/sys/firmware/efi/efivars' ]]" \
efivarfs "$1/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev &&
track_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid &&
track_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec &&
track_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev &&
track_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 &&
track_mount tmp "$1/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid
}
chroot_umount() {
umount "${CHROOT_ACTIVE_MOUNTS[@]}"
}
valid_number_of_base() {
local base=$1 len=${#2} i=
for (( i = 0; i < len; i++ )); do
{ _=$(( $base#${2:i:1} )) || return 1; } 2>/dev/null
done
return 0
}
mangle() {
local i= chr= out=
unset {a..f} {A..F}
for (( i = 0; i < ${#1}; i++ )); do
chr=${1:i:1}
case $chr in
[[:space:]\\])
printf -v chr '%03o' "'$chr"
out+=\\
;;
esac
out+=$chr
done
printf '%s' "$out"
}
unmangle() {
local i= chr= out= len=$(( ${#1} - 4 ))
unset {a..f} {A..F}
for (( i = 0; i < len; i++ )); do
chr=${1:i:1}
case $chr in
\\)
if valid_number_of_base 8 "${1:i+1:3}" ||
valid_number_of_base 16 "${1:i+1:3}"; then
printf -v chr '%b' "${1:i:4}"
(( i += 3 ))
fi
;;
esac
out+=$chr
done
printf '%s' "$out${1:i}"
}
dm_name_for_devnode() {
read dm_name <"/sys/class/block/${1#/dev/}/dm/name"
if [[ $dm_name ]]; then
printf '/dev/mapper/%s' "$dm_name"
else
# don't leave the caller hanging, just print the original name
# along with the failure.
print '%s' "$1"
error 'Failed to resolve device mapper name for: %s' "$1"
fi
}
fstype_is_pseudofs() {
(( pseudofs_types["$1"] ))
}
fstype_has_fsck() {
(( fsck_types["$1"] ))
}
newroot=/mnt
hostcache=0
copykeyring=1
copymirrorlist=1
usage() {
cat <<EOF
usage: ${0##*/} [options] root [packages...]
Options:
-C config Use an alternate config file for pacman
-c Use the package cache on the host, rather than the target
-d Allow installation to a non-mountpoint directory
-G Avoid copying the host's pacman keyring to the target
-i Avoid auto-confirmation of package selections
-M Avoid copying the host's mirrorlist to the target
-h Print this help message
pacstrap installs packages to the specified new root directory. If no packages
are given, pacstrap defaults to the "base" group.
EOF
}
if [[ -z $1 || $1 = @(-h|--help) ]]; then
usage
exit $(( $# ? 0 : 1 ))
fi
(( EUID == 0 )) || die 'This script must be run with root privileges'
while getopts ':C:cdGiM' flag; do
case $flag in
C)
pacman_config=$OPTARG
;;
d)
directory=1
;;
c)
hostcache=1
;;
i)
interactive=1
;;
G)
copykeyring=0
;;
M)
copymirrorlist=0
;;
:)
die '%s: option requires an argument -- '\''%s'\' "${0##*/}" "$OPTARG"
;;
?)
die '%s: invalid option -- '\''%s'\' "${0##*/}" "$OPTARG"
;;
esac
done
shift $(( OPTIND - 1 ))
(( $# )) || die "No root directory specified"
newroot=$1; shift
pacman_args=("${@:-base}")
if (( ! hostcache )); then
pacman_args+=(--cachedir="$newroot/var/cache/pacman/pkg")
fi
if (( ! interactive )); then
pacman_args+=(--noconfirm)
fi
if [[ $pacman_config ]]; then
pacman_args+=(--config="$pacman_config")
fi
[[ -d $newroot ]] || die "%s is not a directory" "$newroot"
if ! mountpoint -q "$newroot" && (( ! directory )); then
die '%s is not a mountpoint!' "$newroot"
fi
# create obligatory directories
msg 'Creating install root at %s' "$newroot"
mkdir -m 0755 -p "$newroot"/var/{cache/pacman/pkg,lib/pacman,log} "$newroot"/{dev,run,etc}
mkdir -m 1777 -p "$newroot"/tmp
mkdir -m 0555 -p "$newroot"/{sys,proc}
# mount API filesystems
api_fs_mount "$newroot" || die "failed to setup API filesystems in new root"
msg 'Installing packages to %s' "$newroot"
if ! pacman -r "$newroot" -Sy "${pacman_args[@]}"; then
die 'Failed to install packages to new root'
fi
if (( copykeyring )); then
# if there's a keyring on the host, copy it into the new root, unless it exists already
if [[ -d /etc/pacman.d/gnupg && ! -d $newroot/etc/pacman.d/gnupg ]]; then
cp -a /etc/pacman.d/gnupg "$newroot/etc/pacman.d/"
fi
fi
if (( copymirrorlist )); then
# install the host's mirrorlist onto the new root
cp -a /etc/pacman.d/mirrorlist "$newroot/etc/pacman.d/"
fi
# vim: et ts=2 sw=2 ft=sh:

47
build-set-helper.in Normal file
View file

@ -0,0 +1,47 @@
#!/bin/bash
cp_profile_pkgs(){
for pkg in $(cat ${profiledir}/$1.set); do
cp_pkg $pkg
done
}
cp_pkg(){
msg2 "Copying $1 to ${pkgdir}"
cd $1
cp ${misc_args[*]} *.pkg.tar.xz ${pkgdir}
cd ..
}
cp_pkgs(){
msg "Copying packages ..."
eval "case ${profile} in
$profiles)
cp_profile_pkgs ${profile}
;;
*)
cp_pkg ${profile}
;;
esac"
msg "Finished copying"
}
repo_create(){
cd ${pkgdir}
repo-add ${pkgdir##*/}.db.tar.xz *.pkg.tar.xz
cd ..
}
cp_pkgs ${profile}
# if ${repo}; then
# cd ${pkgdir}
# repo_create
# cd ..
# fi
if ${sign}; then
cd ${pkgdir}
signpkgs
cd ..
fi

340
build-set.in Normal file
View file

@ -0,0 +1,340 @@
#!/bin/bash
m4_include(lib/common.sh)
get_profiles(){
local prof= temp=
for p in $(ls ${profiledir}/*.set);do
temp=${p##*/}
prof=${prof:-}${prof:+|}${temp%.set}
done
echo $prof
}
get_user(){
echo $(ls ${chrootdir} | cut -d' ' -f1 | grep -v root | grep -v lock)
}
chroot_clean(){
for copy in "${chrootdir}"/*; do
[[ -d "${copy}" ]] || continue
msg2 "Deleting chroot copy '$(basename "${copy}")'..."
exec 9>"${copy}.lock"
if ! flock -n 9; then
stat_busy "Locking chroot copy '${copy}'"
flock 9
stat_done
fi
if [[ "$(stat -f -c %T "${copy}")" == btrfs ]]; then
{ type -P btrfs && btrfs subvolume delete "${copy}"; } &>/dev/null
fi
rm -rf --one-file-system "${copy}"
done
exec 9>&-
rm -rf --one-file-system "${chrootdir}"
}
chroot_create(){
mkdir -p "${chrootdir}"
setarch ${arch} \
mkmanjaroroot ${mkmanjaroroot_args[*]} ${chrootdir}/root ${base_packages[*]} || abort
}
chroot_update(){
setarch "${arch}" \
mkmanjaroroot ${mkmanjaroroot_args[*]} -u ${chrootdir}/$(get_user) || abort
}
chroot_init(){
if [[ ! -d "${chrootdir}" ]]; then
msg "Creating chroot for [${branch}] (${arch})..."
chroot_create
elif ${clean_first};then
msg "Creating chroot for [${branch}] (${arch})..."
chroot_clean
chroot_create
else
msg "Updating chroot for [${branch}] (${arch})..."
chroot_update
fi
}
chroot_build_set(){
chroot_init
msg "Start building profile: [${profile}]"
for pkg in $(cat ${profiledir}/${profile}.set); do
cd $pkg
setarch ${arch} \
makechrootpkg ${makechrootpkg_args[*]} -- "${makepkg_args[*]}" || break
if [[ $pkg == 'eudev' ]]; then
local blacklist=('libsystemd')
pacman -Rdd "${blacklist[@]}" -r ${chrootdir}/$(get_user) --noconfirm
local temp
if [[ -z $PKGDEST ]];then
temp=$pkg
else
temp=$pkgdir/$pkg
fi
pacman -U $temp*${ARCH}*pkg*z -r ${chrootdir}/$(get_user) --noconfirm
fi
cd ..
done
msg "Finished building profile: [${profile}]"
}
chroot_build(){
cd ${profile}
chroot_init
setarch ${arch} \
makechrootpkg ${makechrootpkg_args[*]} -- "${makepkg_args[*]}" || abort
cd ..
}
display_build_set(){
msg "SETS:"
msg2 "profiles: $profiles"
msg2 "profile: $profile"
msg2 "is_profile: ${is_profile}"
if ${is_profile};then
msg "These packages will be built:"
local temp=$(cat ${profiledir}/${profile}.set)
for p in ${temp[@]}; do
msg2 "$p"
done
else
msg "This package will be built:"
msg2 "${profile}"
fi
}
run_pretend(){
eval "case ${profile} in
$profiles) is_profile=true ;;
*) is_profile=false ;;
esac"
display_build_set
exit 0
}
run(){
eval "case ${profile} in
$profiles) is_profile=true; display_build_set && chroot_build_set ;;
*) display_build_set && chroot_build ;;
esac"
}
#################################MAIN##########################################
export LC_MESSAGES=C
shopt -s nullglob
version=20141003
arch=$(uname -m)
pacman_conf_arch='default'
devtools_conf='@sysconfdir@/devtools.conf'
if [[ -f ${devtools_conf} ]]; then
. ${devtools_conf}
fi
if [[ -n ${branch} ]];then
branch=${branch}
else
branch='stable'
fi
if [[ -n ${profile} ]];then
profile=${profile}
else
profile='default'
fi
if [[ -n ${chroots} ]];then
chroots=${chroots}
else
chroots='/srv/manjarobuild'
fi
if [[ -n ${profiledir} ]];then
profiledir=${profiledir}
else
profiledir='@sysconfdir@/sets'
fi
if [[ -f ~/.makepkg.conf ]];then
. ~/.makepkg.conf
else
if [[ -r /etc/makepkg.conf ]]; then
. /etc/makepkg.conf
fi
fi
if [[ -n ${pkgdir} ]];then
pkgdir=${pkgdir}
else
pkgdir=$(pwd)/packages
fi
clean_first=false
namcap=false
sign=false
verbose=false
nosystemd=false
pretend=false
is_profile=false
clean_rundir=false
repo=false
base_packages=('base-devel')
mkmanjaroroot_args=()
makechrootpkg_args=()
makepkg_args=()
misc_args=()
profiles=$(get_profiles)
usage() {
echo "Usage: ${0##*/} [options] -- [makepkg_args]"
echo " -p <profile> Set profile or pkg [default ${profile}]"
echo " -a <arch> Set arch [default ${arch}]"
echo " -b <branch> Set branch [default ${branch}]"
echo " -r <dir> Chroots directory [default ${chroots}]"
echo " -c Clean chroot [default ${clean_first}]"
echo " -n Run namcap check [default ${namcap}]"
echo ' -s Sign packages'
echo ' -v Verbose'
echo " -x Use classic chroot instead of systemd-nspawn [default ${nosystemd}]"
echo ' Useful for testing if systemd is running to bypass autodetection'
echo " -q Pretend build [default ${pretend}]"
echo ' -w Wipe clean pkgbuild directory'
echo ' -y Add package to repo'
echo ' -h This help'
echo ''
echo ''
exit 1
}
opts='p:a:b:r:cnsvxqwyh'
while getopts "${opts}" arg; do
case "${arg}" in
p) profile="$OPTARG" ;;
a) arch="$OPTARG" ;;
b) branch="$OPTARG" ;;
r) chroots="$OPTARG" ;;
c) clean_first=true ;;
n) namcap=true;;
s) sign=true ;;
v) verbose=true ;;
x) nosystemd=true ;;
q) pretend=true; verbose=true ;;
w) clean_rundir=true ;;
y) repo=true ;;
h) usage ;;
esac
done
if [[ "$arch" == 'multilib' ]]; then
pacman_conf_arch='multilib'
arch='x86_64'
branch="${branch}-multilib"
base_packages+=('multilib-devel')
fi
pacman_conf="@pkgdatadir@/pacman-${pacman_conf_arch}.conf"
makepkg_conf="@pkgdatadir@/makepkg-${arch}.conf"
chrootdir=${chroots}/${branch}-${arch}
if ${nosystemd};then
mkmanjaroroot_args+=(-x)
fi
if ${namcap};then
makechrootpkg_args+=(-n)
fi
# if ${repo};then
# makechrootpkg_args+=(-d)
# fi
mkmanjaroroot_args+=(-C ${pacman_conf} -M ${makepkg_conf} -b ${branch})
makechrootpkg_args+=(-b ${branch} -r ${chrootdir})
makepkg_args+=("${*:$OPTIND}")
if ${verbose};then
msg "OPTARGS:"
msg2 "arch: $arch"
msg2 "branch: $branch"
msg2 "chroots: $chroots"
msg "PATHS:"
msg2 "chrootdir: $chrootdir"
msg2 "profiledir: $profiledir"
msg2 "pacman_conf: ${pacman_conf}"
msg2 "makepkg_conf: $makepkg_conf"
msg "mkmanjaroroot:"
msg2 "args: ${mkmanjaroroot_args[*]}"
msg "makechrootpkg:"
msg2 "args: ${makechrootpkg_args[*]}"
msg "makepkg:"
msg2 "args: ${makepkg_args[*]}"
msg "FLAGS:"
msg2 "clean_first: $clean_first"
msg2 "namcap: ${namcap}"
msg2 "sign: $sign"
msg2 "nosystemd: $nosystemd"
msg2 "clean_rundir: $clean_rundir"
msg2 "repo: ${repo}"
msg "PKG:"
msg2 "base_packages: ${base_packages[*]}"
msg2 "pkgdir: ${pkgdir}"
msg2 "PKGDEST: ${PKGDEST}"
misc_args+=(-v)
fi
if ${clean_rundir}; then
if ${pretend};then
msg "Files to be cleaned ${rundir} ..."
git clean -dfxn
else
msg "Cleaning ${rundir} ..."
if ${verbose};then
git clean -dfx
else
git clean -dfxq
fi
fi
fi
if [[ -n $PKGDEST ]];then
pkgdir=$PKGDEST
else
pkgdir=${pkgdir}/${arch}
mkdir -p ${misc_args[*]} ${pkgdir}
fi
if [[ $EUID != 0 ]]; then
die 'This script must be run as root.'
else
if ${pretend};then
run_pretend $@
else
run $@
fi
fi
. build-set-helper

83
checkpkg.in Normal file
View file

@ -0,0 +1,83 @@
#!/bin/bash
m4_include(lib/common.sh)
# Source makepkg.conf; fail if it is not found
if [[ -r '/etc/makepkg.conf' ]]; then
source '/etc/makepkg.conf'
else
die '/etc/makepkg.conf not found!'
fi
# Source user-specific makepkg.conf overrides
if [[ -r ~/.makepkg.conf ]]; then
source ~/.makepkg.conf
fi
if [[ ! -f PKGBUILD ]]; then
die 'This must be run in the directory of a built package.'
fi
. PKGBUILD
if [[ $arch == 'any' ]]; then
CARCH='any'
fi
STARTDIR=$(pwd)
TEMPDIR=$(mktemp -d --tmpdir checkpkg-script.XXXX)
cd "$TEMPDIR"
for _pkgname in "${pkgname[@]}"; do
pkgfile=${_pkgname}-$(get_full_version $_pkgname)-${CARCH}${PKGEXT}
if [[ -f "$STARTDIR/$pkgfile" ]]; then
ln -s "$STARTDIR/$pkgfile" "$pkgfile"
elif [[ -f "$PKGDEST/$pkgfile" ]]; then
ln -s "$PKGDEST/$pkgfile" "$pkgfile"
else
die "File \"$pkgfile\" doesn't exist"
fi
pkgurl=$(pacman -Spdd --print-format '%l' --noconfirm "$_pkgname")
if [[ $? -ne 0 ]]; then
die "Couldn't download previous package for $_pkgname."
fi
oldpkg=${pkgurl##*://*/}
if [[ ${oldpkg##*/} = ${pkgfile##*/} ]]; then
die "The built package ($_pkgname) is the one in the repo right now!"
fi
if [[ ! -f $oldpkg ]]; then
if [[ $pkgurl = file://* ]]; then
ln -s "${pkgurl#file://}" "${pkgurl##file://*/}"
elif [[ -f "$PKGDEST/$oldpkg" ]]; then
ln -s "$PKGDEST/$oldpkg" "$oldpkg"
elif [[ -f "$STARTDIR/$oldpkg" ]]; then
ln -s "$STARTDIR/$oldpkg" "$oldpkg"
else
curl -fsLC - --retry 3 --retry-delay 3 -o "$oldpkg" "$pkgurl"
fi
fi
bsdtar tf "$oldpkg" | sort > "filelist-$_pkgname-old"
bsdtar tf "$pkgfile" | sort > "filelist-$_pkgname"
sdiff -s "filelist-$_pkgname-old" "filelist-$_pkgname"
if diff "filelist-$_pkgname-old" "filelist-$_pkgname" | grep '\.so' > /dev/null 2>&1; then
mkdir -p pkg
cd pkg
bsdtar xf ../"$pkgfile" > /dev/null
diff "../filelist-$_pkgname-old" "../filelist-$_pkgname" | awk '/>.*\.so/{$1 = ""; print $0}' | while read i; do
echo "${i}: " "$(objdump -p "$i" | grep SONAME)"
done
cd ..
else
msg "No soname differences for $_pkgname."
fi
done
msg "Files saved to $TEMPDIR"

17
devtools.conf Normal file
View file

@ -0,0 +1,17 @@
# build-set config
# path to sets
# profiledir=/etc/devtools/sets
# default chroot path
# chroots=/srv/manjarobuild
# default branch
# branch=stable
# pkgdir where to copy pkgs
# If makepkg.conf has PGKDEST set, this path will be set to $PKGDEST
# pkgdir=
# default set; name without .set suffix
# profile=default

87
find-libdeps.in Normal file
View file

@ -0,0 +1,87 @@
#!/bin/bash
m4_include(lib/common.sh)
set -e
shopt -s extglob
IGNORE_INTERNAL=0
if [[ $1 = "--ignore-internal" ]]; then
IGNORE_INTERNAL=1
shift
fi
script_mode=${0##*/find-lib}
case $script_mode in
deps|provides) true;;
*) die "Unknown mode $script_mode" ;;
esac
if [[ -z $1 ]]; then
echo "${0##*/} [options] <package file|extracted package dir>"
echo "Options:"
echo " --ignore-internal ignore internal libraries"
exit 1
fi
if [[ -d $1 ]]; then
pushd $1 >/dev/null
else
setup_workdir
case ${script_mode} in
deps) bsdtar -C $WORKDIR -xf "$1";;
provides) bsdtar -C $WORKDIR -xf "$1" --include="*.so*";;
esac
pushd $WORKDIR >/dev/null
fi
process_sofile() {
# extract the library name: libfoo.so
soname="${sofile%.so?(+(.+([0-9])))}".so
# extract the major version: 1
soversion="${sofile##*\.so\.}"
if [[ "$soversion" = "$sofile" ]] && (($IGNORE_INTERNAL)); then
continue
fi
if ! in_array "${soname}=${soversion}-${soarch}" ${soobjects[@]}; then
# libfoo.so=1-64
echo "${soname}=${soversion}-${soarch}"
soobjects=(${soobjects[@]} "${soname}=${soversion}-${soarch}")
fi
}
case $script_mode in
deps) find_args="-perm -u+x";;
provides) find_args="-name *.so*";;
esac
find . -type f $find_args | while read filename; do
if [[ $script_mode = "provides" ]]; then
# ignore if we don't have a shared object
if ! LC_ALL=C readelf -h "$filename" 2>/dev/null | grep -q '.*Type:.*DYN (Shared object file).*'; then
continue
fi
fi
# get architecture of the file; if soarch is empty it's not an ELF binary
soarch=$(LC_ALL=C readelf -h "$filename" 2>/dev/null | sed -n 's/.*Class.*ELF\(32\|64\)/\1/p')
[[ -n $soarch ]] || continue
if [[ $script_mode = "provides" ]]; then
# get the string binaries link to: libfoo.so.1.2 -> libfoo.so.1
sofile=$(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -n 's/.*Library soname: \[\(.*\)\].*/\1/p')
[[ -z $sofile ]] && sofile="${filename##*/}"
process_sofile
elif [[ $script_mode = "deps" ]]; then
# process all libraries needed by the binary
for sofile in $(LC_ALL=C readelf -d "$filename" 2>/dev/null | sed -nr 's/.*Shared library: \[(.*)\].*/\1/p'); do
process_sofile
done
fi
done
popd >/dev/null

39
finddeps.in Normal file
View file

@ -0,0 +1,39 @@
#!/bin/bash
#
# finddeps - find packages that depend on a given depname
#
m4_include(lib/common.sh)
match=$1
if [[ -z $match ]]; then
echo 'Usage: finddeps <depname>'
echo ''
echo 'Find packages that depend on a given depname.'
echo 'Run this script from the top-level directory of your ABS tree.'
echo ''
exit 1
fi
find . -type d | while read d; do
if [[ -f "$d/PKGBUILD" ]]; then
unset pkgname depends makedepends optdepends
. "$d/PKGBUILD"
for dep in "${depends[@]}"; do
# lose the version comparator, if any
depname=${dep%%[<>=]*}
[[ $depname = $match ]] && echo "$d (depends)"
done
for dep in "${makedepends[@]}"; do
# lose the version comparator, if any
depname=${dep%%[<>=]*}
[[ $depname = $match ]] && echo "$d (makedepends)"
done
for dep in "${optdepends[@]/:*}"; do
# lose the version comaparator, if any
depname=${dep%%[<>=]*}
[[ $depname = $match ]] && echo "$d (optdepends)"
done
fi
done

358
fstabgen.in Executable file
View file

@ -0,0 +1,358 @@
#!/bin/bash
shopt -s extglob
# generated from util-linux source: libmount/src/utils.c
declare -A pseudofs_types=([anon_inodefs]=1
[autofs]=1
[bdev]=1
[binfmt_misc]=1
[cgroup]=1
[configfs]=1
[cpuset]=1
[debugfs]=1
[devfs]=1
[devpts]=1
[devtmpfs]=1
[dlmfs]=1
[fuse.gvfs-fuse-daemon]=1
[fusectl]=1
[hugetlbfs]=1
[mqueue]=1
[nfsd]=1
[none]=1
[pipefs]=1
[proc]=1
[pstore]=1
[ramfs]=1
[rootfs]=1
[rpc_pipefs]=1
[securityfs]=1
[sockfs]=1
[spufs]=1
[sysfs]=1
[tmpfs]=1)
# generated from: pkgfile -vbr '/fsck\..+' | awk -F. '{ print $NF }' | sort
declare -A fsck_types=([cramfs]=1
[exfat]=1
[ext2]=1
[ext3]=1
[ext4]=1
[ext4dev]=1
[jfs]=1
[minix]=1
[msdos]=1
[reiserfs]=1
[vfat]=1
[xfs]=1)
out() { printf "$1 $2\n" "${@:3}"; }
error() { out "==> ERROR:" "$@"; } >&2
msg() { out "==>" "$@"; }
msg2() { out " ->" "$@";}
die() { error "$@"; exit 1; }
ignore_error() {
"$@" 2>/dev/null
return 0
}
in_array() {
local i
for i in "${@:2}"; do
[[ $1 = "$i" ]] && return
done
}
track_mount() {
if [[ -z $CHROOT_ACTIVE_MOUNTS ]]; then
CHROOT_ACTIVE_MOUNTS=()
trap 'chroot_umount' EXIT
fi
mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}")
}
mount_conditionally() {
local cond=$1; shift
if eval "$cond"; then
track_mount "$@"
fi
}
api_fs_mount() {
mount_conditionally "! mountpoint -q '$1'" "$1" "$1" --bind &&
track_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev &&
track_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro &&
ignore_error mount_conditionally "[[ -d '$1/sys/firmware/efi/efivars' ]]" \
efivarfs "$1/sys/firmware/efi/efivars" -t efivarfs -o nosuid,noexec,nodev &&
track_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid &&
track_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec &&
track_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev &&
track_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 &&
track_mount tmp "$1/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid
}
chroot_umount() {
umount "${CHROOT_ACTIVE_MOUNTS[@]}"
}
valid_number_of_base() {
local base=$1 len=${#2} i=
for (( i = 0; i < len; i++ )); do
{ _=$(( $base#${2:i:1} )) || return 1; } 2>/dev/null
done
return 0
}
mangle() {
local i= chr= out=
unset {a..f} {A..F}
for (( i = 0; i < ${#1}; i++ )); do
chr=${1:i:1}
case $chr in
[[:space:]\\])
printf -v chr '%03o' "'$chr"
out+=\\
;;
esac
out+=$chr
done
printf '%s' "$out"
}
unmangle() {
local i= chr= out= len=$(( ${#1} - 4 ))
unset {a..f} {A..F}
for (( i = 0; i < len; i++ )); do
chr=${1:i:1}
case $chr in
\\)
if valid_number_of_base 8 "${1:i+1:3}" ||
valid_number_of_base 16 "${1:i+1:3}"; then
printf -v chr '%b' "${1:i:4}"
(( i += 3 ))
fi
;;
esac
out+=$chr
done
printf '%s' "$out${1:i}"
}
dm_name_for_devnode() {
read dm_name <"/sys/class/block/${1#/dev/}/dm/name"
if [[ $dm_name ]]; then
printf '/dev/mapper/%s' "$dm_name"
else
# don't leave the caller hanging, just print the original name
# along with the failure.
print '%s' "$1"
error 'Failed to resolve device mapper name for: %s' "$1"
fi
}
fstype_is_pseudofs() {
(( pseudofs_types["$1"] ))
}
fstype_has_fsck() {
(( fsck_types["$1"] ))
}
write_source() {
local src=$1 spec= label= uuid= comment=()
label=$(lsblk -rno LABEL "$1" 2>/dev/null)
uuid=$(lsblk -rno UUID "$1" 2>/dev/null)
# bind mounts do not have a UUID!
case $bytag in
'')
[[ $uuid ]] && comment=("UUID=$uuid")
[[ $label ]] && comment+=("LABEL=$(mangle "$label")")
;;
LABEL)
spec=$label
[[ $uuid ]] && comment=("$src" "UUID=$uuid")
;;
UUID)
spec=$uuid
comment=("$src")
[[ $label ]] && comment+=("LABEL=$(mangle "$label")")
;;
*)
[[ $uuid ]] && comment=("$1" "UUID=$uuid")
[[ $label ]] && comment+=("LABEL=$(mangle "$label")")
[[ $bytag ]] && spec=$(lsblk -rno "$bytag" "$1" 2>/dev/null)
;;
esac
[[ $comment ]] && printf '# %s\n' "${comment[*]}"
if [[ $spec ]]; then
printf '%-20s' "$bytag=$(mangle "$spec")"
else
printf '%-20s' "$(mangle "$src")"
fi
}
usage() {
cat <<EOF
usage: ${0##*/} [options] root
Options:
-L Use labels for source identifiers (shortcut for -t LABEL)
-p Avoid printing pseudofs mounts
-t TAG Use TAG for source identifiers
-U Use UUIDs for source identifiers (shortcut for -t UUID)
-h Print this help message
genfstab generates output suitable for addition to an fstab file based on the
devices mounted under the mountpoint specified by the given root.
EOF
}
if [[ -z $1 || $1 = @(-h|--help) ]]; then
usage
exit $(( $# ? 0 : 1 ))
fi
while getopts ':Lpt:U' flag; do
case $flag in
L)
bytag=LABEL
;;
U)
bytag=UUID
;;
p)
nopseudofs=1
;;
t)
bytag=${OPTARG^^}
;;
:)
die '%s: option requires an argument -- '\''%s'\' "${0##*/}" "$OPTARG"
;;
?)
die '%s: invalid option -- '\''%s'\' "${0##*/}" "$OPTARG"
;;
esac
done
shift $(( OPTIND - 1 ))
(( $# )) || die "No root directory specified"
root=$1; shift
if ! mountpoint -q "$root"; then
die "$root is not a mountpoint"
fi
# handle block devices
findmnt -Recvruno SOURCE,TARGET,FSTYPE,OPTIONS,FSROOT "$root" |
while read -r src target fstype opts fsroot; do
if (( nopseudofs )) && fstype_is_pseudofs "$fstype"; then
continue
fi
# default 5th and 6th columns
dump=0 pass=2
src=$(unmangle "$src")
target=$(unmangle "$target")
target=${target#$root}
if (( !foundroot )) && findmnt "$src" "$root" >/dev/null; then
# this is root. we can't possibly have more than one...
pass=1 foundroot=1
fi
# if there's no fsck tool available, then only pass=0 makes sense.
if ! fstype_has_fsck "$fstype"; then
pass=0
fi
if [[ $fsroot != / ]]; then
if [[ $fstype = btrfs ]]; then
opts+=,subvol=${fsroot#/}
else
# it's a bind mount
src=$(findmnt -funcevo TARGET "$src")$fsroot
if [[ $src -ef $target ]]; then
# 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,
# because this won't actually be a valid mount. Worst case, the user
# just re-adds it.
continue
fi
fstype=none
opts+=,bind
pass=0
fi
fi
# filesystem quirks
case $fstype in
fuseblk)
# well-behaved FUSE filesystems will report themselves as fuse.$fstype.
# this is probably NTFS-3g, but let's just make sure.
if ! newtype=$(lsblk -no FSTYPE "$src") || [[ -z $newtype ]]; then
# avoid blanking out fstype, leading to an invalid fstab
error 'Failed to derive real filesystem type for FUSE device on %s' "$target"
else
fstype=$newtype
fi
;;
esac
# write one line
write_source "$src"
printf '\t%-10s' "/$(mangle "${target#/}")" "$fstype" "$opts"
printf '\t%s %s' "$dump" "$pass"
printf '\n\n'
done
# handle swaps devices
{
# ignore header
read
while read -r device type _ _ prio; do
options=defaults
if [[ $prio != -1 ]]; then
options+=,pri=$prio
fi
# skip files marked deleted by the kernel
[[ $device = *'\040(deleted)' ]] && continue
if [[ $type = file ]]; then
printf '%-20s' "$device"
elif [[ $device = /dev/dm-+([0-9]) ]]; then
# device mapper doesn't allow characters we need to worry
# about being mangled, and it does the escaping of dashes
# for us in sysfs.
write_source "$(dm_name_for_devnode "$device")"
else
write_source "$(unmangle "$device")"
fi
printf '\t%-10s\t%-10s\t%-10s\t0 0\n\n' 'none' 'swap' "$options"
done
} </proc/swaps
# vim: et ts=2 sw=2 ft=sh:

48
lddd.in Normal file
View file

@ -0,0 +1,48 @@
#!/bin/bash
#
# lddd - find broken library links on your machine
#
m4_include(lib/common.sh)
ifs=$IFS
IFS="${IFS}:"
libdirs="/lib /usr/lib /usr/local/lib $(cat /etc/ld.so.conf.d/*)"
extras=
TEMPDIR=$(mktemp -d --tmpdir lddd-script.XXXX)
msg 'Go out and drink some tea, this will take a while :) ...'
# Check ELF binaries in the PATH and specified dir trees.
for tree in $PATH $libdirs $extras; do
msg2 "DIR $tree"
# Get list of files in tree.
files=$(find $tree -type f ! -name '*.a' ! -name '*.la' ! -name '*.py*' ! -name '*.txt' ! -name '*.h' ! -name '*.ttf' ! \
-name '*.rb' ! -name '*.ko' ! -name '*.pc' ! -name '*.enc' ! -name '*.cf' ! -name '*.def' ! -name '*.rules' ! -name \
'*.cmi' ! -name '*.mli' ! -name '*.ml' ! -name '*.cma' ! -name '*.cmx' ! -name '*.cmxa' ! -name '*.pod' ! -name '*.pm' \
! -name '*.pl' ! -name '*.al' ! -name '*.tcl' ! -name '*.bs' ! -name '*.o' ! -name '*.png' ! -name '*.gif' ! -name '*.cmo' \
! -name '*.cgi' ! -name '*.defs' ! -name '*.conf' ! -name '*_LOCALE' ! -name 'Compose' ! -name '*_OBJS' ! -name '*.msg' ! \
-name '*.mcopclass' ! -name '*.mcoptype')
IFS=$ifs
for i in $files; do
if (( $(file $i | grep -c 'ELF') != 0 )); then
# Is an ELF binary.
if (( $(ldd $i 2>/dev/null | grep -c 'not found') != 0 )); then
# Missing lib.
echo "$i:" >> $TEMPDIR/raw.txt
ldd $i 2>/dev/null | grep 'not found' >> $TEMPDIR/raw.txt
fi
fi
done
done
grep '^/' $TEMPDIR/raw.txt | sed -e 's/://g' >> $TEMPDIR/affected-files.txt
# invoke pacman
for i in $(cat $TEMPDIR/affected-files.txt); do
pacman -Qo $i | awk '{print $4,$5}' >> $TEMPDIR/pacman.txt
done
# clean list
sort -u $TEMPDIR/pacman.txt >> $TEMPDIR/possible-rebuilds.txt
msg "Files saved to $TEMPDIR"

132
lib/common.sh Normal file
View file

@ -0,0 +1,132 @@
# Avoid any encoding problems
export LANG=C
# check if messages are to be printed using color
unset ALL_OFF BOLD BLUE GREEN RED YELLOW
if [[ -t 2 ]]; then
# prefer terminal safe colored and bold text when tput is supported
if tput setaf 0 &>/dev/null; then
ALL_OFF="$(tput sgr0)"
BOLD="$(tput bold)"
BLUE="${BOLD}$(tput setaf 4)"
GREEN="${BOLD}$(tput setaf 2)"
RED="${BOLD}$(tput setaf 1)"
YELLOW="${BOLD}$(tput setaf 3)"
else
ALL_OFF="\e[1;0m"
BOLD="\e[1;1m"
BLUE="${BOLD}\e[1;34m"
GREEN="${BOLD}\e[1;32m"
RED="${BOLD}\e[1;31m"
YELLOW="${BOLD}\e[1;33m"
fi
fi
readonly ALL_OFF BOLD BLUE GREEN RED YELLOW
plain() {
local mesg=$1; shift
printf "${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
msg() {
local mesg=$1; shift
printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
msg2() {
local mesg=$1; shift
printf "${BLUE} ->${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
warning() {
local mesg=$1; shift
printf "${YELLOW}==> WARNING:${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
error() {
local mesg=$1; shift
printf "${RED}==> ERROR:${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
stat_busy() {
local mesg=$1; shift
printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}...${ALL_OFF}" >&2
}
stat_done() {
printf "${BOLD}done${ALL_OFF}\n" >&2
}
setup_workdir() {
[[ -z $WORKDIR ]] && WORKDIR=$(mktemp -d --tmpdir "${0##*/}.XXXXXXXXXX")
}
cleanup() {
[[ -n $WORKDIR ]] && rm -rf "$WORKDIR"
[[ $1 ]] && exit $1
}
abort() {
msg 'Aborting...'
cleanup 0
}
trap_abort() {
trap - EXIT INT QUIT TERM HUP
abort
}
trap_exit() {
trap - EXIT INT QUIT TERM HUP
cleanup
}
die() {
error "$*"
cleanup 1
}
trap 'trap_abort' INT QUIT TERM HUP
trap 'trap_exit' EXIT
##
# usage : in_array( $needle, $haystack )
# return : 0 - found
# 1 - not found
##
in_array() {
local needle=$1; shift
local item
for item in "$@"; do
[[ $item = $needle ]] && return 0 # Found
done
return 1 # Not Found
}
##
# usage : get_full_version( [$pkgname] )
# return : full version spec, including epoch (if necessary), pkgver, pkgrel
##
get_full_version() {
# set defaults if they weren't specified in buildfile
pkgbase=${pkgbase:-${pkgname[0]}}
epoch=${epoch:-0}
if [[ -z $1 ]]; then
if [[ $epoch ]] && (( ! $epoch )); then
echo $pkgver-$pkgrel
else
echo $epoch:$pkgver-$pkgrel
fi
else
for i in pkgver pkgrel epoch; do
local indirect="${i}_override"
eval $(declare -f package_$1 | sed -n "s/\(^[[:space:]]*$i=\)/${i}_override=/p")
[[ -z ${!indirect} ]] && eval ${indirect}=\"${!i}\"
done
if (( ! $epoch_override )); then
echo $pkgver_override-$pkgrel_override
else
echo $epoch_override:$pkgver_override-$pkgrel_override
fi
fi
}

5
lib/valid-tags.sh Normal file
View file

@ -0,0 +1,5 @@
_arch=(
i686
x86_64
any
)

339
makechrootpkg.in Normal file
View file

@ -0,0 +1,339 @@
#!/bin/bash
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
m4_include(lib/common.sh)
shopt -s nullglob
makepkg_args='-s --noconfirm -L'
repack=false
update_first=false
clean_first=false
install_pkg=
add_to_db=false
run_namcap=false
temp_chroot=false
chrootdir=
passeddir=
branch='stable'
declare -a install_pkgs
declare -i ret=0
copy=$USER
[[ -n $SUDO_USER ]] && copy=$SUDO_USER
[[ -z "$copy" || $copy = root ]] && copy=copy
src_owner=${SUDO_USER:-$USER}
usage() {
echo "Usage: ${0##*/} [options] -r <chrootdir> [--] [makepkg args]"
echo ' Run this script in a PKGBUILD dir to build a package inside a'
echo ' clean chroot. All unrecognized arguments passed to this script'
echo ' will be passed to makepkg.'
echo ''
echo ' The chroot dir consists of the following directories:'
echo ' <chrootdir>/{root, copy} but only "root" is required'
echo ' by default. The working copy will be created as needed'
echo ''
echo 'The chroot "root" directory must be created via the following'
echo 'command:'
echo ' mkmanjaroroot <chrootdir>/root base-devel'
echo ''
echo "Default makepkg args: $makepkg_args"
echo ''
echo 'Flags:'
echo '-h This help'
echo '-c Clean the chroot before building'
echo '-u Update the working copy of the chroot before building'
echo ' This is useful for rebuilds without dirtying the pristine'
echo ' chroot'
echo '-d Add the package to a local db at /repo after building'
echo '-r <dir> The chroot dir to use'
echo '-I <pkg> Install a package into the working copy of the chroot'
echo '-l <copy> The directory to use as the working copy of the chroot'
echo ' Useful for maintaining multiple copies'
echo " Default: $copy"
echo '-n Run namcap on the package'
echo '-T Build in a temporary directory'
echo '-b <branch> Set repository branch'
exit 1
}
while getopts 'hcudr:I:l:nTb:' arg; do
case "$arg" in
h) usage ;;
c) clean_first=true ;;
u) update_first=true ;;
d) add_to_db=true ;;
r) passeddir="$OPTARG" ;;
I) install_pkgs+=("$OPTARG") ;;
l) copy="$OPTARG" ;;
n) run_namcap=true; makepkg_args="$makepkg_args -i" ;;
T) temp_chroot=true; copy+="-$RANDOM" ;;
b) branch="$OPTARG" ;;
*) makepkg_args="$makepkg_args -$arg $OPTARG" ;;
esac
done
# Canonicalize chrootdir, getting rid of trailing /
chrootdir=$(readlink -e "$passeddir")
if [[ ${copy:0:1} = / ]]; then
copydir=$copy
else
copydir="$chrootdir/$copy"
fi
# Pass all arguments after -- right to makepkg
makepkg_args="$makepkg_args ${*:$OPTIND}"
# See if -R was passed to makepkg
for arg in ${*:$OPTIND}; do
if [[ $arg = -R ]]; then
repack=true
break
fi
done
if (( EUID )); then
die 'This script must be run as root.'
fi
if [[ ! -f PKGBUILD && -z "${install_pkgs[*]}" ]]; then
die 'This must be run in a directory containing a PKGBUILD.'
fi
if [[ ! -d $chrootdir ]]; then
die "No chroot dir defined, or invalid path '$passeddir'"
fi
if [[ ! -d $chrootdir/root ]]; then
die "Missing chroot dir root directory. Try using: mkmanjaroroot $chrootdir/root base-devel"
fi
umask 0022
# Detect chrootdir filesystem type
chroottype=$(stat -f -c %T "$chrootdir")
# Lock the chroot we want to use. We'll keep this lock until we exit.
# Note this is the same FD number as in mkmanjaroroot
exec 9>"$copydir.lock"
if ! flock -n 9; then
stat_busy "Locking chroot copy [$copy]"
flock 9
stat_done
fi
if [[ ! -d $copydir ]] || $clean_first; then
# Get a read lock on the root chroot to make
# sure we don't clone a half-updated chroot
exec 8>"$chrootdir/root.lock"
if ! flock -sn 8; then
stat_busy "Locking clean chroot"
flock -s 8
stat_done
fi
stat_busy "Creating clean working copy [$copy]"
if [[ "$chroottype" == btrfs ]]; then
if [[ -d $copydir ]]; then
btrfs subvolume delete "$copydir" >/dev/null ||
die "Unable to delete subvolume $copydir"
fi
btrfs subvolume snapshot "$chrootdir/root" "$copydir" >/dev/null ||
die "Unable to create subvolume $copydir"
else
mkdir -p "$copydir"
rsync -a --delete -q -W -x "$chrootdir/root/" "$copydir"
fi
stat_done
# Drop the read lock again
exec 8>&-
fi
if [[ -n "${install_pkgs[*]}" ]]; then
for install_pkg in "${install_pkgs[@]}"; do
pkgname="${install_pkg##*/}"
cp "$install_pkg" "$copydir/$pkgname"
mkmanjaroroot -b "${branch}" -r "pacman -U /$pkgname --noconfirm" "$copydir"
(( ret += !! $? ))
rm "$copydir/$pkgname"
done
# If there is no PKGBUILD we have done
[[ -f PKGBUILD ]] || exit $ret
fi
$update_first && mkmanjaroroot -b "${branch}" -u "$copydir"
mkdir -p "$copydir/build"
# Remove anything in there UNLESS -R (repack) was passed to makepkg
$repack || rm -rf "$copydir"/build/*
# Read .makepkg.conf and .gnupg/pubring.gpg even if called via sudo
if [[ -n $SUDO_USER ]]; then
SUDO_HOME="$(eval echo ~$SUDO_USER)"
makepkg_conf="$SUDO_HOME/.makepkg.conf"
if [[ -r "$SUDO_HOME/.gnupg/pubring.gpg" ]]; then
install -D "$SUDO_HOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg"
fi
else
makepkg_conf="$HOME/.makepkg.conf"
if [[ -r "$HOME/.gnupg/pubring.gpg" ]]; then
install -D "$HOME/.gnupg/pubring.gpg" "$copydir/build/.gnupg/pubring.gpg"
fi
fi
# Get SRC/PKGDEST from makepkg.conf
if [[ -f $makepkg_conf ]]; then
eval $(grep '^SRCDEST=' "$makepkg_conf")
eval $(grep '^PKGDEST=' "$makepkg_conf")
eval $(grep '^MAKEFLAGS=' "$makepkg_conf")
eval $(grep '^PACKAGER=' "$makepkg_conf")
fi
[[ -z $SRCDEST ]] && eval $(grep '^SRCDEST=' /etc/makepkg.conf)
[[ -z $PKGDEST ]] && eval $(grep '^PKGDEST=' /etc/makepkg.conf)
[[ -z $MAKEFLAGS ]] && eval $(grep '^MAKEFLAGS=' /etc/makepkg.conf)
[[ -z $PACKAGER ]] && eval $(grep '^PACKAGER=' /etc/makepkg.conf)
# Use PKGBUILD directory if PKGDEST or SRCDEST don't exist
[[ -d $PKGDEST ]] || PKGDEST=.
[[ -d $SRCDEST ]] || SRCDEST=.
mkdir -p "$copydir/pkgdest"
if ! grep -q 'PKGDEST="/pkgdest"' "$copydir/etc/makepkg.conf"; then
echo 'PKGDEST="/pkgdest"' >> "$copydir/etc/makepkg.conf"
fi
mkdir -p "$copydir/srcdest"
if ! grep -q 'SRCDEST="/srcdest"' "$copydir/etc/makepkg.conf"; then
echo 'SRCDEST="/srcdest"' >> "$copydir/etc/makepkg.conf"
fi
if [[ -n $MAKEFLAGS ]]; then
sed -i '/^MAKEFLAGS=/d' "$copydir/etc/makepkg.conf"
echo "MAKEFLAGS='${MAKEFLAGS}'" >> "$copydir/etc/makepkg.conf"
fi
if [[ -n $PACKAGER ]]; then
sed -i '/^PACKAGER=/d' "$copydir/etc/makepkg.conf"
echo "PACKAGER='${PACKAGER}'" >> "$copydir/etc/makepkg.conf"
fi
# Set target CARCH as it might be used within the PKGBUILD to select correct sources
eval $(grep '^CARCH=' "$copydir/etc/makepkg.conf")
export CARCH
# Copy PKGBUILD and sources
cp PKGBUILD "$copydir/build/"
(
source PKGBUILD
for file in "${source[@]}"; do
file="${file%%::*}"
file="${file##*://*/}"
if [[ -f $file ]]; then
cp "$file" "$copydir/srcdest/"
elif [[ -f $SRCDEST/$file ]]; then
cp "$SRCDEST/$file" "$copydir/srcdest/"
fi
done
# Find all changelog and install files, even inside functions
for i in 'changelog' 'install'; do
while read -r file; do
# evaluate any bash variables used
eval file=\"$(sed 's/^\(['\''"]\)\(.*\)\1$/\2/' <<< "$file")\"
[[ -f $file ]] && cp "$file" "$copydir/build/"
done < <(sed -n "s/^[[:space:]]*$i=//p" PKGBUILD)
done
)
chown -R nobody "$copydir"/{build,pkgdest,srcdest}
cat > "$copydir/etc/sudoers.d/nobody-pacman" <<EOF
Defaults env_keep += "HOME"
nobody ALL = NOPASSWD: /usr/bin/pacman
EOF
chmod 440 "$copydir/etc/sudoers.d/nobody-pacman"
# This is a little gross, but this way the script is recreated every time in the
# working copy
cat >"$copydir/chrootbuild" <<EOF
#!/bin/bash
. /etc/profile
export HOME=/build
cd /build
sudo -u nobody makepkg $makepkg_args || exit 1
if $run_namcap; then
pacman -S --needed --noconfirm namcap
for pkgfile in /build/PKGBUILD /pkgdest/*.pkg.tar.?z; do
echo "Checking \${pkgfile##*/}"
sudo -u nobody namcap "\$pkgfile" 2>&1 | tee "/build/\${pkgfile##*/}-namcap.log"
done
fi
exit 0
EOF
chmod +x "$copydir/chrootbuild"
if mkmanjaroroot -b "${branch}" -r "/chrootbuild" "$copydir"; then
for pkgfile in "$copydir"/pkgdest/*.pkg.tar.?z; do
if $add_to_db; then
mkdir -p "$copydir/repo"
pushd "$copydir/repo" >/dev/null
cp "$pkgfile" .
repo-add repo.db.tar.gz "${pkgfile##*/}"
popd >/dev/null
fi
chown "$src_owner" "$pkgfile"
mv "$pkgfile" "$PKGDEST"
done
for l in "$copydir"/build/*-{build,check,namcap,package,package_*}.log; do
chown "$src_owner" "$l"
[[ -f $l ]] && mv "$l" .
done
else
# Just in case. We returned 1, make sure we fail
ret=1
fi
for f in "$copydir"/srcdest/*; do
chown "$src_owner" "$f"
mv "$f" "$SRCDEST"
done
if $temp_chroot; then
stat_busy "Removing temporary directoy [$copy]"
if [[ "$chroottype" == btrfs ]]; then
btrfs subvolume delete "$copydir" >/dev/null ||
die "Unable to delete subvolume $copydir"
else
# avoid change of filesystem in case of an umount failure
rm --recursive --force --one-file-system "$copydir" ||
die "Unable to delete $copydir"
fi
# remove lock file
rm --force "$copydir.lock"
stat_done
elif (( ret != 0 )); then
die "Build failed, check $copydir/build"
else
true
fi

138
makepkg-i686.conf Normal file
View file

@ -0,0 +1,138 @@
#
# /etc/makepkg.conf
#
#########################################################################
# SOURCE ACQUISITION
#########################################################################
#
#-- The download utilities that makepkg should use to acquire sources
# Format: 'protocol::agent'
DLAGENTS=('ftp::/usr/bin/curl -fC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
'http::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
'https::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
'rsync::/usr/bin/rsync --no-motd -z %u %o'
'scp::/usr/bin/scp -C %u %o')
# Other common tools:
# /usr/bin/snarf
# /usr/bin/lftpget -c
# /usr/bin/wget
#########################################################################
# ARCHITECTURE, COMPILE FLAGS
#########################################################################
#
CARCH="i686"
CHOST="i686-pc-linux-gnu"
#-- Compiler and Linker Flags
# -march (or -mcpu) builds exclusively for an architecture
# -mtune optimizes for an architecture, but builds for whole processor family
CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-march=i686 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"
CXXFLAGS="-march=i686 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
#-- Make Flags: change this for DistCC/SMP systems
#MAKEFLAGS="-j2"
#-- Debugging flags
DEBUG_CFLAGS="-g -fvar-tracking-assignments"
DEBUG_CXXFLAGS="-g -fvar-tracking-assignments"
#########################################################################
# BUILD ENVIRONMENT
#########################################################################
#
# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign)
# A negated environment option will do the opposite of the comments below.
#
#-- fakeroot: Allow building packages as a non-root user
#-- distcc: Use the Distributed C/C++/ObjC compiler
#-- color: Colorize output messages
#-- ccache: Use ccache to cache compilation
#-- check: Run the check() function if present in the PKGBUILD
#-- sign: Generate PGP signature file
#
BUILDENV=(fakeroot !distcc color !ccache check !sign)
#
#-- If using DistCC, your MAKEFLAGS will also need modification. In addition,
#-- specify a space-delimited list of hosts running in the DistCC cluster.
#DISTCC_HOSTS=""
#
#-- Specify a directory for package building.
#BUILDDIR=/tmp/makepkg
#########################################################################
# GLOBAL PACKAGE OPTIONS
# These are default values for the options=() settings
#########################################################################
#
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug)
# A negated option will do the opposite of the comments below.
#
#-- strip: Strip symbols from binaries/libraries
#-- docs: Save doc directories specified by DOC_DIRS
#-- libtool: Leave libtool (.la) files in packages
#-- staticlibs: Leave static library (.a) files in packages
#-- emptydirs: Leave empty directories in packages
#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip
#-- purge: Remove files specified by PURGE_TARGETS
#-- upx: Compress binary executable files using UPX
#-- debug: Add debugging flags as specified in DEBUG_* variables
#
OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !upx !debug)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5)
#-- Options to be used when stripping binaries. See `man strip' for details.
STRIP_BINARIES="--strip-all"
#-- Options to be used when stripping shared libraries. See `man strip' for details.
STRIP_SHARED="--strip-unneeded"
#-- Options to be used when stripping static libraries. See `man strip' for details.
STRIP_STATIC="--strip-debug"
#-- Manual (man and info) directories to compress (if zipman is specified)
MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info})
#-- Doc directories to remove (if !docs is specified)
DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc})
#-- Files to be removed from all packages (if purge is specified)
PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#########################################################################
# PACKAGE OUTPUT
#########################################################################
#
# Default: put built package and cached source in build directory
#
#-- Destination: specify a fixed directory where all packages will be placed
#PKGDEST=/home/packages
#-- Source cache: specify a fixed directory where source files will be cached
#SRCDEST=/home/sources
#-- Source packages: specify a fixed directory where all src packages will be placed
#SRCPKGDEST=/home/srcpackages
#-- Packager: name/email of the person or organization building packages
#PACKAGER="John Doe <john@doe.com>"
#-- Specify a key to use for package signing
#GPGKEY=""
#########################################################################
# COMPRESSION DEFAULTS
#########################################################################
#
COMPRESSGZ=(gzip -c -f -n)
COMPRESSBZ2=(bzip2 -c -f)
COMPRESSXZ=(xz -c -z -)
COMPRESSLRZ=(lrzip -q)
COMPRESSLZO=(lzop -q)
COMPRESSZ=(compress -c -f)
#########################################################################
# EXTENSION DEFAULTS
#########################################################################
#
# WARNING: Do NOT modify these variables unless you know what you are
# doing.
#
PKGEXT='.pkg.tar.xz'
SRCEXT='.src.tar.gz'
# vim: set ft=sh ts=2 sw=2 et:

138
makepkg-x86_64.conf Normal file
View file

@ -0,0 +1,138 @@
#
# /etc/makepkg.conf
#
#########################################################################
# SOURCE ACQUISITION
#########################################################################
#
#-- The download utilities that makepkg should use to acquire sources
# Format: 'protocol::agent'
DLAGENTS=('ftp::/usr/bin/curl -fC - --ftp-pasv --retry 3 --retry-delay 3 -o %o %u'
'http::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
'https::/usr/bin/curl -fLC - --retry 3 --retry-delay 3 -o %o %u'
'rsync::/usr/bin/rsync --no-motd -z %u %o'
'scp::/usr/bin/scp -C %u %o')
# Other common tools:
# /usr/bin/snarf
# /usr/bin/lftpget -c
# /usr/bin/wget
#########################################################################
# ARCHITECTURE, COMPILE FLAGS
#########################################################################
#
CARCH="x86_64"
CHOST="x86_64-unknown-linux-gnu"
#-- Compiler and Linker Flags
# -march (or -mcpu) builds exclusively for an architecture
# -mtune optimizes for an architecture, but builds for whole processor family
CPPFLAGS="-D_FORTIFY_SOURCE=2"
CFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"
CXXFLAGS="-march=x86-64 -mtune=generic -O2 -pipe -fstack-protector --param=ssp-buffer-size=4"
LDFLAGS="-Wl,-O1,--sort-common,--as-needed,-z,relro"
#-- Make Flags: change this for DistCC/SMP systems
#MAKEFLAGS="-j2"
#-- Debugging flags
DEBUG_CFLAGS="-g -fvar-tracking-assignments"
DEBUG_CXXFLAGS="-g -fvar-tracking-assignments"
#########################################################################
# BUILD ENVIRONMENT
#########################################################################
#
# Defaults: BUILDENV=(fakeroot !distcc color !ccache check !sign)
# A negated environment option will do the opposite of the comments below.
#
#-- fakeroot: Allow building packages as a non-root user
#-- distcc: Use the Distributed C/C++/ObjC compiler
#-- color: Colorize output messages
#-- ccache: Use ccache to cache compilation
#-- check: Run the check() function if present in the PKGBUILD
#-- sign: Generate PGP signature file
#
BUILDENV=(fakeroot !distcc color !ccache check !sign)
#
#-- If using DistCC, your MAKEFLAGS will also need modification. In addition,
#-- specify a space-delimited list of hosts running in the DistCC cluster.
#DISTCC_HOSTS=""
#
#-- Specify a directory for package building.
#BUILDDIR=/tmp/makepkg
#########################################################################
# GLOBAL PACKAGE OPTIONS
# These are default values for the options=() settings
#########################################################################
#
# Default: OPTIONS=(strip docs libtool staticlibs emptydirs zipman purge !upx !debug)
# A negated option will do the opposite of the comments below.
#
#-- strip: Strip symbols from binaries/libraries
#-- docs: Save doc directories specified by DOC_DIRS
#-- libtool: Leave libtool (.la) files in packages
#-- staticlibs: Leave static library (.a) files in packages
#-- emptydirs: Leave empty directories in packages
#-- zipman: Compress manual (man and info) pages in MAN_DIRS with gzip
#-- purge: Remove files specified by PURGE_TARGETS
#-- upx: Compress binary executable files using UPX
#-- debug: Add debugging flags as specified in DEBUG_* variables
#
OPTIONS=(strip docs !libtool !staticlibs emptydirs zipman purge !upx !debug)
#-- File integrity checks to use. Valid: md5, sha1, sha256, sha384, sha512
INTEGRITY_CHECK=(md5)
#-- Options to be used when stripping binaries. See `man strip' for details.
STRIP_BINARIES="--strip-all"
#-- Options to be used when stripping shared libraries. See `man strip' for details.
STRIP_SHARED="--strip-unneeded"
#-- Options to be used when stripping static libraries. See `man strip' for details.
STRIP_STATIC="--strip-debug"
#-- Manual (man and info) directories to compress (if zipman is specified)
MAN_DIRS=({usr{,/local}{,/share},opt/*}/{man,info})
#-- Doc directories to remove (if !docs is specified)
DOC_DIRS=(usr/{,local/}{,share/}{doc,gtk-doc} opt/*/{doc,gtk-doc})
#-- Files to be removed from all packages (if purge is specified)
PURGE_TARGETS=(usr/{,share}/info/dir .packlist *.pod)
#########################################################################
# PACKAGE OUTPUT
#########################################################################
#
# Default: put built package and cached source in build directory
#
#-- Destination: specify a fixed directory where all packages will be placed
#PKGDEST=/home/packages
#-- Source cache: specify a fixed directory where source files will be cached
#SRCDEST=/home/sources
#-- Source packages: specify a fixed directory where all src packages will be placed
#SRCPKGDEST=/home/srcpackages
#-- Packager: name/email of the person or organization building packages
#PACKAGER="John Doe <john@doe.com>"
#-- Specify a key to use for package signing
#GPGKEY=""
#########################################################################
# COMPRESSION DEFAULTS
#########################################################################
#
COMPRESSGZ=(gzip -c -f -n)
COMPRESSBZ2=(bzip2 -c -f)
COMPRESSXZ=(xz -c -z -)
COMPRESSLRZ=(lrzip -q)
COMPRESSLZO=(lzop -q)
COMPRESSZ=(compress -c -f)
#########################################################################
# EXTENSION DEFAULTS
#########################################################################
#
# WARNING: Do NOT modify these variables unless you know what you are
# doing.
#
PKGEXT='.pkg.tar.xz'
SRCEXT='.src.tar.gz'
# vim: set ft=sh ts=2 sw=2 et:

248
mkmanjaroroot.in Normal file
View file

@ -0,0 +1,248 @@
#!/bin/bash
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 2 of the License.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
m4_include(lib/common.sh)
CHROOT_VERSION='v3'
RUN=''
NOCOPY='n'
working_dir=''
branch='stable'
APPNAME=$(basename "${0}")
# check for systemd running on build system
if [[ -d /run/systemd ]];then
nosystemd=false
else
nosystemd=true
fi
# usage: usage <exitvalue>
usage() {
echo "Usage: ${APPNAME} [options] working-dir [package-list | app]"
echo ' options:'
echo ' -r <app> Run "app" within the context of the chroot'
echo ' -u Update the chroot via pacman'
echo ' -C <file> Location of a pacman config file'
echo ' -M <file> Location of a makepkg config file'
echo ' -S <file> Location of a pacman-mirrors config file'
echo ' -n Do not copy config files into the chroot'
echo ' -c <dir> Set pacman cache'
echo ' -b <branch> Set repository branch'
echo ' -x Use classic chroot instead of systemd-nspawn'
echo ' -h This message'
exit 1
}
while getopts 'r:ufnxhC:M:S:c:b:' arg; do
case "${arg}" in
r) RUN="$OPTARG" ;;
u) RUN='pacman -Syu --noconfirm' ;;
C) pac_conf="$OPTARG" ;;
M) makepkg_conf="$OPTARG" ;;
n) NOCOPY='y' ;;
c) cache_dir="$OPTARG" ;;
b) branch="$OPTARG" ;;
S) mirrors_conf="$OPTARG" ;;
x) nosystemd=true ;;
h|?) usage ;;
*) error "invalid argument '${arg}'"; usage ;;
esac
done
if (( $EUID != 0 )); then
die 'This script must be run as root.'
fi
shift $(($OPTIND - 1))
if [[ -z $RUN ]] && (( $# < 2 )); then
die 'You must specify a directory and one or more packages.'
elif (( $# < 1 )); then
die 'You must specify a directory.'
fi
working_dir="$(readlink -f ${1})"
shift 1
[[ -z $working_dir ]] && die 'Please specify a working directory.'
if [[ -z $cache_dir ]]; then
cache_dirs=($(pacman -v $cache_conf 2>&1 | grep '^Cache Dirs:' | sed 's/Cache Dirs:\s*//g'))
else
cache_dirs=(${cache_dir})
fi
# Get host mirror
host_mirror=$(pacman -Sddp extra/devtools 2>/dev/null | sed -E "s#(.*/)(.*/)extra/.*#\1${branch}/\$repo/\$arch#")
if echo "${host_mirror}" | grep -q 'file://'; then
host_mirror_path=$(echo "${host_mirror}" | sed -E 's#file://(/.*)/\$repo/\$arch#\1#g')
fi
# {{{ functions
build_mount_args() {
local p
declare -g mount_args=()
if [[ -n $host_mirror_path ]]; then
printf -v p '%q' "$host_mirror_path"
mount_args+=(--bind-ro="$p")
fi
printf -v p '%q' "${cache_dirs[0]}"
mount_args+=(--bind="$p")
for cache_dir in ${cache_dirs[@]:1}; do
printf -v p '%q' "$cache_dir"
mount_args+=(--bind-ro="$p")
done
}
copy_hostconf () {
cp -a /etc/pacman.d/gnupg "${working_dir}/etc/pacman.d"
echo "Server = ${host_mirror}" > ${working_dir}/etc/pacman.d/mirrorlist
sed -i -e "s|^.*Branch=.*|Branch=${branch}|" ${working_dir}/etc/pacman-mirrors.conf
if [[ -n $pac_conf && $NOCOPY = 'n' ]]; then
cp ${pac_conf} ${working_dir}/etc/pacman.conf
fi
if [[ -n $makepkg_conf && $NOCOPY = 'n' ]]; then
cp ${makepkg_conf} ${working_dir}/etc/makepkg.conf
fi
if [[ -n $mirrors_conf && $NOCOPY = 'n' ]]; then
cp ${mirrors_conf} ${working_dir}/etc/pacman-mirrors.conf
sed -i -e "s|^.*Branch=.*|Branch=${branch}|" ${working_dir}/etc/pacman-mirrors.conf
fi
sed -r "s|^#?\\s*CacheDir.+|CacheDir = $(echo -n ${cache_dirs[@]})|g" -i ${working_dir}/etc/pacman.conf
}
chroot_lock () {
# Only reopen the FD if it wasn't handed to us
if [[ $(readlink -f /dev/fd/9) != "${working_dir}.lock" ]]; then
exec 9>"${working_dir}.lock"
fi
# Lock the chroot. Take note of the FD number.
if ! flock -n 9; then
stat_busy "Locking chroot"
flock 9
stat_done
fi
}
track_mount() {
if [[ -z $CHROOT_ACTIVE_MOUNTS ]]; then
CHROOT_ACTIVE_MOUNTS=()
trap 'chroot_umount' EXIT
fi
mount "$@" && CHROOT_ACTIVE_MOUNTS=("$2" "${CHROOT_ACTIVE_MOUNTS[@]}")
}
mount_conditionally() {
local cond=$1; shift
if eval "$cond"; then
track_mount "$@"
fi
}
api_fs_mount() {
mount_conditionally "! mountpoint -q '$1'" "$1" "$1" --bind &&
track_mount proc "$1/proc" -t proc -o nosuid,noexec,nodev &&
track_mount sys "$1/sys" -t sysfs -o nosuid,noexec,nodev,ro &&
track_mount udev "$1/dev" -t devtmpfs -o mode=0755,nosuid &&
track_mount devpts "$1/dev/pts" -t devpts -o mode=0620,gid=5,nosuid,noexec &&
track_mount shm "$1/dev/shm" -t tmpfs -o mode=1777,nosuid,nodev &&
track_mount run "$1/run" -t tmpfs -o nosuid,nodev,mode=0755 &&
track_mount tmp "$1/tmp" -t tmpfs -o mode=1777,strictatime,nodev,nosuid
track_mount /etc/resolv.conf "$1/etc/resolv.conf" --bind
track_mount ${cache_dirs[0]} "$1/${cache_dirs[0]}" --bind
}
chroot_umount() {
umount "${CHROOT_ACTIVE_MOUNTS[@]}"
}
chroot_run() {
local dir=$1
shift
if ${nosystemd};then
chroot "${dir}" "${@}"
else
systemd-nspawn -D "${dir}" "${mount_args[@]}" -- ${@} 2>/dev/null
fi
}
# }}}
umask 0022
if [[ -n $RUN ]]; then
# run chroot {{{
#Sanity check
if [[ ! -f "${working_dir}/.manjaro-chroot" ]]; then
die "'${working_dir}' does not appear to be a Manjaro chroot."
elif [[ $(cat "${working_dir}/.manjaro-chroot") != ${CHROOT_VERSION} ]]; then
die "'${working_dir}' is not compatible with ${APPNAME} version ${CHROOT_VERSION}. Please rebuild."
fi
chroot_lock
if ${nosystemd};then
api_fs_mount "${working_dir}"
else
build_mount_args
fi
copy_hostconf
chroot_run "${working_dir}" ${RUN}
# }}}
else
# {{{ build chroot
if [[ -e $working_dir ]]; then
die "Working directory '${working_dir}' already exists"
fi
mkdir -p "${working_dir}"
if [[ "$(stat -f -c %T "${working_dir}")" == btrfs ]]; then
rmdir "${working_dir}"
if ! btrfs subvolume create "${working_dir}"; then
die "Couldn't create subvolume for '${working_dir}'"
fi
chmod 0755 "${working_dir}"
fi
chroot_lock
pacargs=("${cache_dirs[@]/#/--cachedir=}")
if [[ -n $pac_conf ]]; then
pacargs+=("--config=${pac_conf}")
fi
if ! pacstrap -GMcd "${working_dir}" "${pacargs[@]}" "$@"; then
die 'Failed to install all packages'
fi
printf '%s.UTF-8 UTF-8\n' en_US de_DE > "${working_dir}/etc/locale.gen"
chroot_run "${working_dir}" locale-gen
echo 'LANG=C' > "${working_dir}/etc/locale.conf"
copy_hostconf
echo "${CHROOT_VERSION}" > "${working_dir}/.manjaro-chroot"
# }}}
fi

86
pacman-default.conf Normal file
View file

@ -0,0 +1,86 @@
#
# /etc/pacman.conf
#
# See the pacman.conf(5) manpage for option and repository directives
#
# GENERAL OPTIONS
#
[options]
# The following paths are commented out with their default values listed.
# If you wish to use different paths, uncomment and update the paths.
#RootDir = /
#DBPath = /var/lib/pacman/
#CacheDir = /var/cache/pacman/pkg/
#LogFile = /var/log/pacman.log
#GPGDir = /etc/pacman.d/gnupg/
HoldPkg = pacman glibc
#XferCommand = /usr/bin/curl -C - -f %u > %o
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#CleanMethod = KeepInstalled
#UseDelta = 0.7
Architecture = auto
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
#IgnorePkg =
#IgnoreGroup =
#NoUpgrade =
#NoExtract =
# Misc options
#UseSyslog
#Color
#TotalDownload
# We cannot check disk space from within a chroot environment
#CheckSpace
#VerbosePkgLists
# By default, pacman accepts packages signed by keys that its local keyring
# trusts (see pacman-key and its man page), as well as unsigned packages.
SigLevel = Required DatabaseOptional
LocalFileSigLevel = Optional
#RemoteFileSigLevel = Required
# NOTE: You must run `pacman-key --init` before first using pacman; the local
# keyring can then be populated with the keys of all official Manjaro Linux
# packagers with `pacman-key --populate archlinux manjaro`.
#
# REPOSITORIES
# - can be defined here or included from another file
# - pacman will search repositories in the order defined here
# - local/custom mirrors can be added here or in separate files
# - repositories listed first will take precedence when packages
# have identical names, regardless of version number
# - URLs will have $repo replaced by the name of the current repo
# - URLs will have $arch replaced by the name of the architecture
#
# Repository entries are of the format:
# [repo-name]
# Server = ServerName
# Include = IncludePath
#
# The header [repo-name] is crucial - it must be present and
# uncommented to enable the repo.
#
# The testing repositories are disabled by default. To enable, uncomment the
# repo name header and Include lines. You can add preferred servers immediately
# after the header, and they will be used before the default mirrors.
[core]
Include = /etc/pacman.d/mirrorlist
[extra]
Include = /etc/pacman.d/mirrorlist
[community]
Include = /etc/pacman.d/mirrorlist
# An example of a custom package repository. See the pacman manpage for
# tips on creating your own repositories.
#[custom]
#SigLevel = Optional TrustAll
#Server = file:///home/custompkgs

21
pacman-mirrors.conf Normal file
View file

@ -0,0 +1,21 @@
##
## /etc/pacman-mirrors.conf
##
## Branch Pacman should use (stable, testing, unstable)
Branch=stable
## Generation method
## 1) rank - rank mirrors depending on their access time
## 2) random - randomly generate the output mirrorlist
Method=rank
## Specify to use only mirrors from a specific country
## Disabled by default
# OnlyCountry=Germany
## Input mirrorlist directory
MirrorlistsDir="/etc/pacman.d/mirrors"
## Output mirrorlist
OutputMirrorlist="/etc/pacman.d/mirrorlist"

92
pacman-multilib.conf Normal file
View file

@ -0,0 +1,92 @@
#
# /etc/pacman.conf
#
# See the pacman.conf(5) manpage for option and repository directives
#
# GENERAL OPTIONS
#
[options]
# The following paths are commented out with their default values listed.
# If you wish to use different paths, uncomment and update the paths.
#RootDir = /
#DBPath = /var/lib/pacman/
#CacheDir = /var/cache/pacman/pkg/
#LogFile = /var/log/pacman.log
#GPGDir = /etc/pacman.d/gnupg/
HoldPkg = pacman glibc
#XferCommand = /usr/bin/curl -C - -f %u > %o
#XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u
#CleanMethod = KeepInstalled
#UseDelta = 0.7
Architecture = auto
# Pacman won't upgrade packages listed in IgnorePkg and members of IgnoreGroup
#IgnorePkg =
#IgnoreGroup =
#NoUpgrade =
#NoExtract =
# Misc options
#UseSyslog
#Color
#TotalDownload
# We cannot check disk space from within a chroot environment
#CheckSpace
#VerbosePkgLists
# By default, pacman accepts packages signed by keys that its local keyring
# trusts (see pacman-key and its man page), as well as unsigned packages.
SigLevel = Required DatabaseOptional
LocalFileSigLevel = Optional
#RemoteFileSigLevel = Required
# NOTE: You must run `pacman-key --init` before first using pacman; the local
# keyring can then be populated with the keys of all official Manjaro Linux
# packagers with `pacman-key --populate archlinux manjaro`.
#
# REPOSITORIES
# - can be defined here or included from another file
# - pacman will search repositories in the order defined here
# - local/custom mirrors can be added here or in separate files
# - repositories listed first will take precedence when packages
# have identical names, regardless of version number
# - URLs will have $repo replaced by the name of the current repo
# - URLs will have $arch replaced by the name of the architecture
#
# Repository entries are of the format:
# [repo-name]
# Server = ServerName
# Include = IncludePath
#
# The header [repo-name] is crucial - it must be present and
# uncommented to enable the repo.
#
# The testing repositories are disabled by default. To enable, uncomment the
# repo name header and Include lines. You can add preferred servers immediately
# after the header, and they will be used before the default mirrors.
[core]
Include = /etc/pacman.d/mirrorlist
[extra]
Include = /etc/pacman.d/mirrorlist
[community]
Include = /etc/pacman.d/mirrorlist
# If you want to run 32 bit applications on your x86_64 system,
# enable the multilib repositories as required here.
[multilib]
Include = /etc/pacman.d/mirrorlist
# An example of a custom package repository. See the pacman manpage for
# tips on creating your own repositories.
#[custom]
#SigLevel = Optional TrustAll
#Server = file:///home/custompkgs

2
sets/default.set Normal file
View file

@ -0,0 +1,2 @@
linux314
mhwd

14
sets/nosystemd.set Normal file
View file

@ -0,0 +1,14 @@
eudev
upower-pm-utils
eudev-systemdcompat
sysvinit
polkit-consolekit
consolekit
openrc-base
openrc-desktop
openrc-misc
openrc-net
openrc-devel
keyboardctl-openrc
networkmanager-openrc
manjaro-openrc

5
sets/openrc-nodeps.set Normal file
View file

@ -0,0 +1,5 @@
openrc-desktop
openrc-misc
openrc-net
openrc-devel
manjaro-openrc

6
sets/openrc.set Normal file
View file

@ -0,0 +1,6 @@
sysvinit
polkit-consolekit
consolekit
openrc-base
keyboardctl-openrc
networkmanager-openrc

3
sets/udev.set Normal file
View file

@ -0,0 +1,3 @@
eudev
upower-pm-utils
eudev-systemdcompat

29
signpkg Executable file
View file

@ -0,0 +1,29 @@
#!/bin/bash
err() {
ALL_OFF="\e[1;0m"
BOLD="\e[1;1m"
RED="${BOLD}\e[1;31m"
local mesg=$1; shift
printf "${RED}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
msg() {
ALL_OFF="\e[1;0m"
BOLD="\e[1;1m"
GREEN="${BOLD}\e[1;32m"
local mesg=$1; shift
printf "${GREEN}==>${ALL_OFF}${BOLD} ${mesg}${ALL_OFF}\n" "$@" >&2
}
. /etc/makepkg.conf
if [ ! -e "$1" ]; then
err "Package '$1' does not exists!"
exit 1
fi
msg "Signing package '$1' with key ${GPGKEY}..."
gpg --detach-sign --use-agent -u "${GPGKEY}" "$1"

3
signpkgs Executable file
View file

@ -0,0 +1,3 @@
#!/bin/bash
find . -maxdepth 1 -name '*.pkg.tar.xz' -exec signpkg {} \;