From a4f315c72d47bb62d95c1db9ced45ecee6c48bef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Igor=20Pe=C4=8Dovnik?= Date: Mon, 21 Dec 2020 00:44:22 +0100 Subject: [PATCH] Add support for ZSH / TMUX / oh-my-zsh (#2478) * Add support for ZSH / TMUX / oh-my-zsh * Selecting default shell at 1st run * Install ZSH by default except on minimal image * Lets rather create armbian-zsh package * - fix remaining ZSH problems - add systemd timer to remove default desktop autologin feature - change DESKTOP_AUTOLOGIN to disabled by default * Few small improvements * Oneliner for revering all users back to BASH if package is uninstalled * Properly escape variables * Fixing chmod * More cryptic awk magic to fix permissions for all normal users that are getting zsh magic --- config/boards/pinebook-a64.conf | 1 - config/boards/pinebook-pro.wip | 1 - config/boards/teres-a64.conf | 1 - lib/compilation.sh | 87 +++++++++++++++++++ lib/distributions.sh | 18 +++- lib/main.sh | 7 ++ .../profile.d/armbian-check-first-login.sh | 2 +- .../system/armbian-disable-autologin.service | 8 ++ .../system/armbian-disable-autologin.timer | 8 ++ .../common/usr/lib/armbian/armbian-firstlogin | 48 ++++++++-- 10 files changed, 169 insertions(+), 12 deletions(-) create mode 100644 packages/bsp/common/lib/systemd/system/armbian-disable-autologin.service create mode 100644 packages/bsp/common/lib/systemd/system/armbian-disable-autologin.timer diff --git a/config/boards/pinebook-a64.conf b/config/boards/pinebook-a64.conf index 07069901d8..6f39b7f252 100644 --- a/config/boards/pinebook-a64.conf +++ b/config/boards/pinebook-a64.conf @@ -2,7 +2,6 @@ BOARD_NAME="Pinebook A64" BOARDFAMILY="sun50iw1" BOOTCONFIG="pinebook_defconfig" -DESKTOP_AUTOLOGIN="no" KERNEL_TARGET="legacy,current,dev" FULL_DESKTOP="yes" PACKAGE_LIST_DESKTOP_BOARD="xfce4-power-manager" diff --git a/config/boards/pinebook-pro.wip b/config/boards/pinebook-pro.wip index ace8e37a6f..1bd4f38abb 100644 --- a/config/boards/pinebook-pro.wip +++ b/config/boards/pinebook-pro.wip @@ -3,7 +3,6 @@ BOARD_NAME="Pinebook Pro" BOARDFAMILY="rockchip64" BOOTCONFIG="pinebook-pro-rk3399_defconfig" BOOT_FDT_FILE="rockchip/rk3399-pinebook-pro.dtb" -DESKTOP_AUTOLOGIN="no" KERNEL_TARGET="legacy,current,dev" FULL_DESKTOP="yes" PACKAGE_LIST_DESKTOP_BOARD="xfce4-power-manager" diff --git a/config/boards/teres-a64.conf b/config/boards/teres-a64.conf index 4d6bca48c9..ed5f35c4c1 100644 --- a/config/boards/teres-a64.conf +++ b/config/boards/teres-a64.conf @@ -2,7 +2,6 @@ BOARD_NAME="Teres A64" BOARDFAMILY="sun50iw1" BOOTCONFIG="teres_i_defconfig" -DESKTOP_AUTOLOGIN="no" KERNEL_TARGET="legacy,current,dev" FULL_DESKTOP="yes" PACKAGE_LIST_DESKTOP_BOARD="xfce4-power-manager" diff --git a/lib/compilation.sh b/lib/compilation.sh index 2ba3d9810c..399c2c6088 100644 --- a/lib/compilation.sh +++ b/lib/compilation.sh @@ -535,6 +535,93 @@ compile_firmware() +compile_armbian-zsh() +{ + + local tmp_dir armbian_zsh_dir + tmp_dir=$(mktemp -d) + chmod 700 ${tmp_dir} + trap "rm -rf \"${tmp_dir}\" ; exit 0" 0 1 2 3 15 + armbian_zsh_dir=armbian-zsh_${REVISION}_all + display_alert "Building deb" "armbian-zsh" "info" + + fetch_from_repo "https://github.com/robbyrussell/oh-my-zsh" "oh-my-zsh" "branch:master" + fetch_from_repo "https://github.com/mroth/evalcache" "evalcache" "branch:master" + + mkdir -p "${tmp_dir}/${armbian_zsh_dir}"/{DEBIAN,etc/skel/,etc/oh-my-zsh/,/etc/skel/.oh-my-zsh/cache} + + # set up control file + cat <<-END > "${tmp_dir}/${armbian_zsh_dir}"/DEBIAN/control + Package: armbian-zsh + Version: $REVISION + Architecture: all + Maintainer: $MAINTAINER <$MAINTAINERMAIL> + Depends: zsh, tmux + Section: utils + Priority: optional + Description: Armbian improved ZShell + END + + # set up post install script + cat <<-END > "${tmp_dir}/${armbian_zsh_dir}"/DEBIAN/postinst + #!/bin/sh + + # copy cache directory if not there yet + awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$6"/.oh-my-zsh"}' /etc/passwd | xargs -i sh -c 'test ! -d {} && cp -R --attributes-only /etc/skel/.oh-my-zsh {}' + awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$6"/.zshrc"}' /etc/passwd | xargs -i sh -c 'test ! -f {} && cp -R /etc/skel/.zshrc {}' + + # fix owner permissions in home directory + awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$1":"\$3" "\$6"/.oh-my-zsh"}' /etc/passwd | xargs -n2 chown -R + awk -F'[:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print ""\$1":"\$3" "\$6"/.zshrc"}' /etc/passwd | xargs -n2 chown -R + + # add support for bash profile + ! grep emulate /etc/zsh/zprofile >/dev/null && echo "emulate sh -c 'source /etc/profile'" >> /etc/zsh/zprofile + exit 0 + END + + # set up post remove script + cat <<-END > "${tmp_dir}/${armbian_zsh_dir}"/DEBIAN/postrm + #!/bin/sh + # change shell back to bash for future users + sed -i "s/^SHELL=.*/SHELL=\/usr\/bin\/bash/" /etc/default/useradd + sed -i "s/^DSHELL=.*/DSHELL=\/usr\/bin\/bash/" /etc/adduser.conf + # change to BASH shell for root and all normal users + awk -F'[/:]' '{if (\$3 >= 1000 && \$3 != 65534 || \$3 == 0) print \$1}' /etc/passwd | xargs -L1 chsh -s \$(grep /bash\$ /etc/shells | tail -1) + exit 0 + END + + cp -R "${SRC}"/cache/sources/oh-my-zsh "${tmp_dir}/${armbian_zsh_dir}"/etc/ + cp -R "${SRC}"/cache/sources/evalcache "${tmp_dir}/${armbian_zsh_dir}"/etc/oh-my-zsh/plugins + cp "${tmp_dir}/${armbian_zsh_dir}"/etc/oh-my-zsh/templates/zshrc.zsh-template "${tmp_dir}/${armbian_zsh_dir}"/etc/skel/.zshrc + + chmod -R g-w,o-w "${tmp_dir}/${armbian_zsh_dir}"/etc/oh-my-zsh/ + + # we have common settings + sed -i "s/^export ZSH=.*/export ZSH=\/etc\/oh-my-zsh/" "${tmp_dir}/${armbian_zsh_dir}"/etc/skel/.zshrc + + # user cache + sed -i "/^export ZSH=.*/a export ZSH_CACHE_DIR=~\/.oh-my-zsh\/cache" "${tmp_dir}/${armbian_zsh_dir}"/etc/skel/.zshrc + + # define theme + sed -i 's/^ZSH_THEME=.*/ZSH_THEME="mrtazz"/' "${tmp_dir}/${armbian_zsh_dir}"/etc/skel/.zshrc + + # disable prompt while update + sed -i 's/# DISABLE_UPDATE_PROMPT="true"/DISABLE_UPDATE_PROMPT="true"/g' "${tmp_dir}/${armbian_zsh_dir}"/etc/skel/.zshrc + + # define default plugins + sed -i 's/^plugins=.*/plugins=(evalcache git git-extras debian tmux screen history extract colorize web-search docker)/' "${tmp_dir}/${armbian_zsh_dir}"/etc/skel/.zshrc + + chmod 755 "${tmp_dir}/${armbian_zsh_dir}"/DEBIAN/{postrm,postinst} + + fakeroot dpkg -b "${tmp_dir}/${armbian_zsh_dir}" >/dev/null + rsync --remove-source-files -rq "${tmp_dir}/${armbian_zsh_dir}.deb" "${DEB_STORAGE}/" + rm -rf "${tmp_dir}" + +} + + + + compile_armbian-config() { diff --git a/lib/distributions.sh b/lib/distributions.sh index 77cd05b342..6f34f6f4dc 100644 --- a/lib/distributions.sh +++ b/lib/distributions.sh @@ -156,7 +156,7 @@ install_common() # display welcome message at first root login touch "${SDCARD}"/root/.not_logged_in_yet - if [[ ${DESKTOP_AUTOLOGIN} != no ]]; then + if [[ ${DESKTOP_AUTOLOGIN} == yes ]]; then # set desktop autologin touch "${SDCARD}"/root/.desktop_autologin fi @@ -309,6 +309,20 @@ install_common() fi fi + # install armbian-zsh + if [[ "${REPOSITORY_INSTALL}" != *armbian-zsh* ]]; then + if [[ $BUILD_MINIMAL != yes ]]; then + install_deb_chroot "${DEB_STORAGE}/armbian-zsh_${REVISION}_all.deb" + fi + else + if [[ $BUILD_MINIMAL != yes ]]; then + install_deb_chroot "armbian-zsh" "remote" + fi + fi + + # set default shell back to BASH and prompt for selection at first login + chroot "${SDCARD}" /bin/bash -c "chsh -s $(grep /bash$ /etc/shells | tail -1)" + # install kernel sources if [[ -f ${DEB_STORAGE}/${CHOSEN_KSRC}_${REVISION}_all.deb && $INSTALL_KSRC == yes ]]; then install_deb_chroot "${DEB_STORAGE}/${CHOSEN_KSRC}_${REVISION}_all.deb" @@ -323,7 +337,7 @@ install_common() if [[ $BSPFREEZE == yes ]]; then display_alert "Freezing Armbian packages" "$BOARD" "info" chroot "${SDCARD}" /bin/bash -c "apt-mark hold ${CHOSEN_KERNEL} ${CHOSEN_KERNEL/image/headers} \ - linux-u-boot-${BOARD}-${BRANCH} ${CHOSEN_KERNEL/image/dtb}" >> "${DEST}"/debug/install.log 2>&1 + linux-u-boot-${BOARD}-${BRANCH} ${CHOSEN_KERNEL/image/dtb}" >> "${DEST}"/debug/install.log 2>&1 fi # remove deb files diff --git a/lib/main.sh b/lib/main.sh index 6fd7482f81..0f3b019ce6 100644 --- a/lib/main.sh +++ b/lib/main.sh @@ -457,6 +457,13 @@ if [[ ! -f ${DEB_STORAGE}/armbian-config_${REVISION}_all.deb ]]; then fi +# Compile armbian-zsh if packed .deb does not exist or use the one from repository +if [[ ! -f ${DEB_STORAGE}/armbian-zsh_${REVISION}_all.deb ]]; then + + [[ "${REPOSITORY_INSTALL}" != *armbian-zsh* ]] && compile_armbian-zsh + +fi + # Compile armbian-firmware if packed .deb does not exist or use the one from repository if ! ls "${DEB_STORAGE}/armbian-firmware_${REVISION}_all.deb" 1> /dev/null 2>&1 || ! ls "${DEB_STORAGE}/armbian-firmware-full_${REVISION}_all.deb" 1> /dev/null 2>&1; then diff --git a/packages/bsp/common/etc/profile.d/armbian-check-first-login.sh b/packages/bsp/common/etc/profile.d/armbian-check-first-login.sh index 4ccf07a134..cdd7f145c6 100644 --- a/packages/bsp/common/etc/profile.d/armbian-check-first-login.sh +++ b/packages/bsp/common/etc/profile.d/armbian-check-first-login.sh @@ -8,5 +8,5 @@ # First login as root? if [ -w /root/ -a -f /root/.not_logged_in_yet ]; then - /usr/lib/armbian/armbian-firstlogin + bash /usr/lib/armbian/armbian-firstlogin fi diff --git a/packages/bsp/common/lib/systemd/system/armbian-disable-autologin.service b/packages/bsp/common/lib/systemd/system/armbian-disable-autologin.service new file mode 100644 index 0000000000..5e226ddffb --- /dev/null +++ b/packages/bsp/common/lib/systemd/system/armbian-disable-autologin.service @@ -0,0 +1,8 @@ +[Unit] +Description=Disable automated desktop login + +[Service] +Type=simple +ExecStart=rm -f /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf +TimeoutStopSec= 10 +ExecStop=systemctl disable armbian-disable-autologin.timer diff --git a/packages/bsp/common/lib/systemd/system/armbian-disable-autologin.timer b/packages/bsp/common/lib/systemd/system/armbian-disable-autologin.timer new file mode 100644 index 0000000000..27f1f4bd8b --- /dev/null +++ b/packages/bsp/common/lib/systemd/system/armbian-disable-autologin.timer @@ -0,0 +1,8 @@ +[Unit] +Description=Disable automated desktop login + +[Timer] +OnBootSec=10min + +[Install] +WantedBy=timers.target diff --git a/packages/bsp/common/usr/lib/armbian/armbian-firstlogin b/packages/bsp/common/usr/lib/armbian/armbian-firstlogin index df833a0450..3a15d5922f 100755 --- a/packages/bsp/common/usr/lib/armbian/armbian-firstlogin +++ b/packages/bsp/common/usr/lib/armbian/armbian-firstlogin @@ -32,6 +32,37 @@ do done } +set_shell() +{ + + optionsAudits=($(cat /etc/shells | grep "zsh\|/bash" | sed 's/\/bin\///g' | sed 's/\/usr//g' | uniq)) + USER_SHELL="bash" + + if [[ "${#optionsAudits[@]}" -gt 1 ]]; then + while : + do + i=1 + echo -e "\nChoose default system command shell:\n" + for o in "${optionsAudits[@]}"; do + echo "$i) $o" + let i++ + done + read -n1 -s reply + case $reply in + "1"|"${optionsAudits[0]}") USER_SHELL="${optionsAudits[0]}"; break;; + "2"|"${optionsAudits[1]}") USER_SHELL="${optionsAudits[1]}"; break;; + *) USER_SHELL="${optionsAudits[0]}"; break;; + esac + done + fi + chsh -s $(grep -iF "/$USER_SHELL" /etc/shells | tail -1) + echo -e "\nShell: \x1B[92m${USER_SHELL^^}\x1B[0m" + + # change shell for future users + sed -i "s/^SHELL=.*/SHELL=\/usr\/bin\/${USER_SHELL}/" /etc/default/useradd + sed -i "s/^DSHELL=.*/DSHELL=\/usr\/bin\/${USER_SHELL}/" /etc/adduser.conf + +} set_timezone_and_locales() { @@ -89,6 +120,7 @@ set_timezone_and_locales() sed -i "s/XKBLAYOUT=.*/XKBLAYOUT=\"$CCODE\"/" /etc/default/keyboard setupcon -k --force fi + fi } @@ -142,9 +174,9 @@ add_user() result="$(cracklib-check <<<"$password")" okay="$(awk -F': ' '{ print $2}' <<<"$result")" if [[ "$okay" == "OK" ]]; then - echo -e "\nPlease provide your real name (eg. John Doe): \c" - read -e RealName - adduser --quiet --disabled-password --shell /bin/bash --home /home/"$RealUserName" --gecos "$RealName" "$RealUserName" + echo -e "" + read -e -p "Please provide your real name: " -i "${RealUserName^}" RealName + adduser --quiet --disabled-password --home /home/"$RealUserName" --gecos "$RealName" "$RealUserName" (echo $first_input;echo $second_input;) | passwd "$RealUserName" >/dev/null 2>&1 for additionalgroup in sudo netdev audio video disk tty users games dialout plugdev input bluetooth systemd-journal ssh; do usermod -aG ${additionalgroup} ${RealUserName} 2>/dev/null @@ -236,6 +268,7 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then if [[ "$okay" == "OK" ]]; then (echo $first_input;echo $second_input;) | passwd root >/dev/null 2>&1 set_timezone_and_locales + set_shell break else echo -e "Rejected - \e[0;31m$okay.\x1B[0m Try again." @@ -249,7 +282,7 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then trap check_abort INT while [ -f "/root/.not_logged_in_yet" ]; do echo -e "\nCreating a new user account. Press to abort" - [ -n "$desktop_lightdm" ] && echo "Desktop environment will not be enabled if you abort the new user creation" + [ -n "$desktop_lightdm" ] && echo -e "\n\e[0;31mDesktop environment will not be enabled if you abort the new user creation\x1B[0m" add_user done trap - INT TERM EXIT @@ -278,7 +311,8 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then if [ -f /root/.desktop_autologin ]; then rm /root/.desktop_autologin else - (sleep 20; rm /etc/lightdm/lightdm.conf.d/22-armbian-autologin.conf) & + systemctl -q enable armbian-disable-autologin.timer + systemctl start armbian-disable-autologin.timer fi # logout if logged at console [[ -n $(who -la | grep root | grep tty1) ]] && exit 1 @@ -290,5 +324,7 @@ if [[ -f /root/.not_logged_in_yet && -n $(tty) ]]; then printf "\e[0;91mPlease reboot the system now \x1B[0m \n\n" fi fi - export TERM=linux + + # Change root user to ZSH in case selected + [[ ${USER_SHELL} == zsh ]] && exec zsh fi