├── README.md └── to-gentoo /README.md: -------------------------------------------------------------------------------- 1 | # to-gentoo 2 | 3 | To run it: 4 | `bash <(curl -Ss 'https://raw.githubusercontent.com/oglueck/to-gentoo/master/to-gentoo')` 5 | 6 | to-gentoo is a bash script that you can run on any pre-installed Linux distribution. It will replace the current system with a basic Gentoo system. If all goes well you have a fully working Gentoo system when the script finishes without even rebooting. 7 | 8 | The basic Gentoo system is first installed in a subdirectory (/gentoo). When finished, your existing system is moved to an different subdirectory (/orig) and the Gentoo system is moved to the root filesystem. 9 | 10 | Some files are not touched by this script however. 11 | 12 | In fact only the following directories will be replaced with the Gentoo versions: 13 | - etc 14 | - lib (lib32, lib64) 15 | - var 16 | - usr 17 | - sbin 18 | - bin 19 | 20 | Specifically the following directories will not be touched and will be kept: 21 | - /root 22 | - /home 23 | - /boot 24 | - /opt 25 | - /mnt 26 | - all technical directories: /dev, /proc, /sys, /tmp 27 | 28 | To make transition a bit smoother, the following things will be kept / migrated to Gentoo: 29 | - bootloader, the kernel and its modules in /lib/modules 30 | - firmware in /lib/firmware (you can replace it with sys-kernel/linux-firmware later) 31 | - file system layout and /etc/fstab 32 | - the root password 33 | - users and groups with IDs above 999 34 | - everything in /usr/local 35 | - the hostname 36 | - DNS config from /etc/resolv.conf 37 | - timezone 38 | 39 | Preconditions: 40 | - a modern x86\_64 Linux in single-user mode 41 | - about 8GB of free space on the / filesystem 42 | - direct Internet connection: proxies don't work properly 43 | 44 | How basic is the installed Gentoo system? 45 | A current Stage-3 system with current Portage repository is installed. So it is quite uptodate and can easily be brought to a fully patched level by running: 46 | ``` 47 | emerge -uavD world 48 | ``` 49 | Where to continue the installation? 50 | You can simply continue working through the [Gentoo Handbook](https://wiki.gentoo.org/wiki/Handbook:AMD64/Full/Installation#Choosing_the_right_profile) where Portage is configured and a profile is chosen. 51 | 52 | What are the essential tasks? 53 | - You should probably compile and install a new kernel 54 | - Create a new initramfs (aka initrd) and install grub and its config 55 | - Install syslog-ng and cronie and all other software you might need 56 | - Migrate anything you need from the old system which is found in /orig 57 | - free up space by removing the old system 58 | 59 | When something goes wrong 60 | In the worst case the script will fail in a state where your system has (partially) been moved to /orig or /gentoo has partially been moved to the root filesystem. In that case the system is not functional. Boot from [System Rescue CD](https://www.system-rescue-cd.org), mount the root filesystem and move the folders back in place manually. Then reboot. 61 | 62 | Known issues 63 | - When the script ends the original init system (sysvinit, systemd) is still running. 64 | Especially systemd doesn't like when we remove its files from under its feet. So it will no longer work correctly and espcially will not shutdown smoothly. So for systemd you can call sync and then power down the system. 65 | -------------------------------------------------------------------------------- /to-gentoo: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # Converts a random Linux installation to Gentoo 3 | 4 | # crash early 5 | set -e 6 | 7 | export LANG=C 8 | 9 | # see https://www.gentoo.org/downloads/mirrors/ 10 | #MIRROR="https://mirror.init7.net/gentoo/" 11 | MIRROR="http://distfiles.gentoo.org/" 12 | GENTOO="/gentoo" 13 | OLD="/orig" 14 | 15 | # check preconditions 16 | if [ "$(uname -s)" != "Linux" ]; then 17 | echo "Only Linux can be converted. Your system is $(uname -s)." >&2 18 | exit 1 19 | fi 20 | 21 | if [ "$(uname -m)" != "x86_64" ]; then 22 | echo "Only x86_64 is supported. Your system is $(uname -m)." >&2 23 | exit 1 24 | fi 25 | 26 | if [ "$(whoami)" != "root" ]; then 27 | echo "The script needs to be run as root. You are $(whoami)." >&2 28 | exit 1 29 | fi 30 | 31 | for f in sed tar wget curl grep awk mount umount bash; do 32 | which "${f}" >/dev/null || { 33 | echo "${f} missing. Please install." >&2 34 | exit 1 35 | } 36 | done 37 | 38 | for f in sed tar grep awk bash; do 39 | if [ "$(basename $(readlink -f $(which ${f})))" = "busybox" ]; then 40 | echo "binary $(which $f) is from BusyBox, please install the real (GNU) version" >&2 41 | exit 1 42 | fi 43 | done 44 | 45 | for f in mount; do 46 | if [ "$(basename $(readlink -f $(which ${f})))" = "bbsuid" ]; then 47 | echo "binary $(which $f) is from BusyBox, please install the version from util-linux" >&2 48 | exit 1 49 | fi 50 | done 51 | 52 | RUNLEVEL="" 53 | which runlevel &>/dev/null && RUNLEVEL="$(runlevel | cut -d ' ' -f 2)" 54 | if [ -z "${RUNLEVEL}" ]; then 55 | which rc-status &>/dev/null && RUNLEVEL="$(rc-status -r)" 56 | fi 57 | if [ -z "${RUNLEVEL}" ]; then 58 | which systemctl &>/dev/null && RUNLEVEL="systemd" 59 | fi 60 | case "${RUNLEVEL}" in 61 | S | unknown | single | systemd | 1) 62 | ;; 63 | 64 | *) 65 | echo "Please run this script from single-user mode: init s or openrc single or append single to kernel cmd line" >&2 66 | exit 1 67 | ;; 68 | esac 69 | 70 | FREE=$(df -m / | sed '1d' | awk '{ print $4; }') 71 | MIN=8000 72 | if [ "${FREE}" -lt "${MIN}" ]; then 73 | echo "No enough free disk space. Need ${MIN}K, there is only ${FREE}K" >&2 74 | exit 1 75 | fi 76 | 77 | STAGE3=$(curl -s "${MIRROR}releases/amd64/autobuilds/latest-stage3-amd64-openrc.txt" | grep stage3-amd64-openrc | cut -d ' ' -f 1) 78 | if [ -z "${STAGE3}" ]; then 79 | echo "Is the network up and DNS works?" >&2 80 | exit 1 81 | fi 82 | 83 | echo "Installing Gentoo base system into ${GENTOO}. Old system will be moved to ${OLD}." 84 | mkdir "${GENTOO}" 85 | mkdir "${OLD}" 86 | cd "${GENTOO}" 87 | 88 | echo "Downloading ${STAGE3}..." 89 | wget "${MIRROR}releases/amd64/autobuilds/${STAGE3}" 90 | 91 | STAGE3=$(ls -1 *.tar.xz) 92 | echo "Unpacking ${STAGE3}" 93 | tar xpf "${STAGE3}" --xattrs 94 | rm "${STAGE3}" 95 | 96 | echo "Copying stuff from existing system:" 97 | # root password 98 | echo " - root password" 99 | sed -i '/^root:/ d' etc/shadow 100 | grep ^root: /etc/shadow >>etc/shadow 101 | # extra users and groups 102 | awk -F: '$3 > 999 && $3 < 65000 { print $0; }' /etc/passwd >>etc/passwd 103 | awk -F: '$3 > 999 && $3 < 65000 { print $0; }' /etc/group >>etc/group 104 | awk -F: '$3 > 999 && $3 < 65000 { print $1; }' /etc/passwd | while read N; do 105 | echo " - user ${N}" 106 | grep "^${N}:" /etc/shadow >>etc/shadow 107 | done 108 | echo " - /usr/local" 109 | cp -ra /usr/local/* usr/local/ || true 110 | echo " - SSH keys" 111 | cp -a /etc/ssh/*key* etc/ssh || true 112 | echo " - kernel modules" 113 | cp -ra /lib/modules lib/ || true 114 | echo " - firmware" 115 | cp -ra /lib/firmware lib/ || true 116 | echo " - hostname" 117 | echo "hostname=$(hostname)" >etc/conf.d/hostname 118 | cp /etc/hosts etc/ 119 | echo " - DNS config" 120 | cp -L "/etc/resolv.conf" etc/ || cp /etc/resolv.conf etc/ 121 | echo " - timezone" 122 | cp -L "/etc/localtime" etc/ || cp /etc/localtime etc/ 123 | echo " - fstab" 124 | cp -L "/etc/fstab" etc/ || cp /etc/fstab etc/ 125 | 126 | 127 | if [ -L /dev/shm ]; then 128 | # Gentoo requires /dev/shm to be its own tmpfs 129 | rm /dev/shm 130 | mkdir /dev/shm 131 | mount -t tmpfs -o nosuid,nodev,noexec shm /dev/shm 132 | chmod 1777 /dev/shm 133 | fi 134 | 135 | if [ -e "${GENTOO}/bin/busybox" ]; then 136 | echo "using static busybox from Gentoo to run mv" 137 | cp "${GENTOO}/bin/busybox" /tmp 138 | MYMV="/tmp/busybox mv" 139 | elif [ -e /bin/mv ]; then 140 | echo "Creating a working standalone mv" 141 | MV=$(mktemp -d) 142 | cp /bin/mv "${MV}" 143 | ldd /bin/mv | sed "s/\t//" | while read f ; do 144 | g=$(echo "${f}" | cut -d' ' -f 3) 145 | f=$(echo "${f}" | cut -d' ' -f 1) 146 | if [ "${f}" == "linux-vdso.so.1" ] || 147 | [ "${f}" == "linux-gate.so.1" ]; then 148 | continue 149 | fi 150 | 151 | if [ -e "${f}" ]; then 152 | cp "${f}" "${MV}" 153 | elif [ -e "/${g}" ]; then 154 | cp "${g}" "${MV}" 155 | fi 156 | done 157 | # glibc, musl are supported here 158 | MYMV="${MV}/ld-*-x86?64.so.? --library-path ${MV} ${MV}/mv" 159 | else 160 | echo "missing /bin/mv" >&2 161 | exit 1 162 | fi 163 | 164 | # test it 165 | touch /tmp/a 166 | ${MYMV} /tmp/a /tmp/b 167 | if [ ! -e /tmp/b ]; then 168 | echo "didn't manage to create a working standalone mv" >&2 169 | echo "This doesn't work as expected:" >&2 170 | echo "${MYMV}" 171 | exit 1 172 | fi 173 | rm /tmp/b 174 | 175 | echo "Now switching over your installation!" 176 | DIRS="etc lib lib32 lib64 var usr sbin bin" 177 | cd / 178 | 179 | # FIXME deal with systems that mount /var/run tmpfs 180 | 181 | echo "moving to ${OLD}/:" 182 | [ -e /linuxrc ] && mv /linuxrc "${OLD}/" 183 | for d in ${DIRS}; do 184 | echo " - ${d}" 185 | [ -e "${d}" -o -L "${d}" ] && ${MYMV} "${d}" "${OLD}/" 186 | done 187 | 188 | echo "replacing with Gentoo:" 189 | for d in ${DIRS}; do 190 | echo " - ${d}" 191 | [ -d "${GENTOO}/${d}" ] && ${MYMV} "${GENTOO}/${d}" . 192 | done 193 | 194 | source /etc/profile 195 | hash -r 196 | 197 | echo "Cleaning up" 198 | rm -rf "/tmp/busybox" 199 | rm -rf "${GENTOO}" 200 | 201 | echo "Downloading Portage tree snapshot" 202 | mkdir -p /etc/portage/repos.conf 203 | cp /usr/share/portage/config/repos.conf /etc/portage/repos.conf/gentoo.conf 204 | emerge-webrsync 205 | emerge --sync 206 | emerge -v --noreplace net-misc/netifrc net-misc/dhcpcd 207 | rc-update add sshd default 208 | 209 | echo "Symlinking net.lo" 210 | ip link show up | awk '/^[0-9][0-9]?:/ && $2 != "lo:" { print $2; }' | cut -d: -f1 | while read f ; do 211 | cd /etc/init.d/ 212 | echo " - ${f}" 213 | ln -s net.lo net.${f} 214 | done 215 | 216 | grep -q '^root:!' /etc/shadow && { 217 | echo "root account is disabled. Gentoo uses root. Please set a password." 218 | passwd 219 | } 220 | chsh -s /bin/bash 221 | 222 | echo "Your old system is in ${OLD}. Remove manually." 223 | echo "Keeping your kernel and /boot. Please review..." 224 | echo "You are now running Gentoo!" 225 | echo "Please run now: source /etc/profile" 226 | echo "It is advisable to install a new kernel and install and configure grub." 227 | echo "DONE! You should reboot afterwards." 228 | --------------------------------------------------------------------------------