]> git.wh0rd.org Git - home.git/blob - .bin/custom-chroot
check $ID rather than writable root
[home.git] / .bin / custom-chroot
1 #!/bin/bash -e
2
3 bootstrap() {
4         [[ $(id -u) -eq 0 ]] || exec sudo env -uUNSHARE HOME="$HOME" "$0" "$@"
5
6         if [[ -z ${UNSHARE} ]] ; then
7                 mount_args=
8                 if type -P unshare >&/dev/null ; then
9                         UNSHARE=true exec unshare -m -- "$0" "$@"
10                 fi
11         else
12                 mount_args='-n'
13         fi
14         unset UNSHARE
15 }
16
17 maybe_mount() {
18         local src=/$1 dst=${chroot}/${2:-$1}
19         [[ -d ${src} ]] || return 0
20         if ! mkdir -p "${dst}" ; then
21                 [[ -w ${chroot} ]] && exit 1 || return 0
22         fi
23         grep -sq "${dst}" /proc/mounts || mount ${mount_args} --bind "${src}" "${dst}"
24 }
25
26 get_type() {
27         case $(file "$1") in
28         *x86-64*)         echo x86_64;;
29         *"Intel 80386"*)  echo i386;;
30         *32-bit*PowerPC*) echo ppc;;
31         *64-bit*PowerPC*) echo ppc64;;
32         *32-bit*S/390*)   echo s390;;
33         *64-bit*S/390*)   echo s390x;;
34         esac
35 }
36
37 init_chroot() {
38         [[ -w . ]] || return 0
39
40         if [[ ! -L etc/mtab ]] ; then
41                 ln -sfT /proc/mounts etc/mtab
42         fi
43         local f dst
44         local etc=(
45                 hosts
46                 locale.gen
47                 localtime
48                 resolv.conf
49         )
50         local home=(
51                 .inputrc
52                 .gdbinit
53                 .gitconfig
54                 .nanorc
55         )
56         for f in \
57                 $(printf 'etc/%s ' "${etc[@]}") \
58         ; do
59                 if [[ -e /${f} ]] ; then
60                         cp "/${f}" "${f}"
61                 fi
62         done
63         for f in "${home[@]}" ; do
64                 df="root/${f}"
65                 f="${HOME}/${f}"
66                 if [[ -e ${f} ]] ; then
67                         cp "${f}" "${df}"
68                 fi
69         done
70
71         f="${HOME}/.profile.d/aliases.sh"
72         if [[ -e ${f} ]] ; then
73                 cat "${f}" > root/.bash_profile
74         fi
75 }
76
77 usage() {
78         cat <<-EOF
79         Usage: ${0##*/} [options] [program to run]
80
81         Sets up common mount points and then chroots in and runs a program.
82         If no program is specified, then launch a login shell.
83
84         Options:
85           -u          Unmount all paths in the chroot
86           -m <path>   Add path to mount list
87           -d <dir>    Use <dir> as chroot (defaults to ${0%/*})
88           -h          This help screen
89         EOF
90         exit
91 }
92
93 main() {
94         bootstrap "$@"
95
96         local mounts=( proc sys tmp dev dev/pts dev/shm usr/portage usr/portage/distfiles usr/local/src )
97
98         local chroot=${0%/*}
99         case ${chroot} in
100         .) chroot=${PWD} ;;
101         ./*) chroot=${PWD}/${chroot#./} ;;
102         esac
103
104         local cmd
105         while [[ -n $1 ]] ; do
106                 case $1 in
107                 -u) cmd='umount' ;;
108                 -m) mounts+=( "$2" ); shift ;;
109                 -d) chroot=$(realpath "$2"); shift ;;
110                 -h) usage ;;
111                 -*) echo "${0##*/}: unknown option $1"; exit 1 ;;
112                 *)  break ;;
113                 esac
114                 shift
115         done
116         cd "${chroot}"
117
118         case ${cmd} in
119         umount) exec "${0%/*}/umount-tree" -y "${chroot}" ;;
120         esac
121
122         local m
123         for m in "${mounts[@]}" ; do
124                 maybe_mount ${m}
125         done
126
127         init_chroot
128
129         local setarch
130         if type -P setarch &>/dev/null ; then
131                 local bin_dst=$(get_type bin/bash)
132                 if [[ -n ${bin_dst} ]] ; then
133                         setarch="setarch ${bin_dst}"
134                 fi
135         fi
136
137         unset LS_COLORS # format changes over time
138         [[ $# -eq 0 ]] && set -- env HOME=/root /bin/bash -l
139         exec \
140                 ${setarch} \
141                 chroot "${chroot}" \
142                 "$@"
143 }
144
145 main "$@"