diff --git a/.gitignore b/.gitignore index cdb5da7..8241071 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,10 @@ /shells-kernel/ /shells-kernel-*.tar.bz2 +/work/ *_test.qcow2 +*.squashfs +*.pid *.shells *.qcow2 +*.tar.xz /rbdconv/ diff --git a/README.md b/README.md index 1c0615a..b03f42e 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,12 @@ This repository includes scripts used for building Linux images used on Shells™. +To run these scripts you need to have relevant packages installed on your machine: + + sudo apt install git qemu qemu-utils qemu-system php8.1 debootstrap squashfs-tools jq + +After which you clone this repo and run the build (and test scripts). + # build_image.sh This script will build an image for a given distibution. diff --git a/build_image.sh b/build_image.sh index d9a7fce..9fc9e77 100755 --- a/build_image.sh +++ b/build_image.sh @@ -11,6 +11,8 @@ set -e . oscfg/gentoo.sh . oscfg/fedora.sh . oscfg/opensuse.sh +. oscfg/centos.sh +. oscfg/deepin.sh dodistro() { if [ -f "$1-$DATE.qcow2" ]; then @@ -36,6 +38,16 @@ dodistro() { opensuse-*) opensuse_distro "$1" ;; + centos-*) + centos_distro "$1" + ;; + deepin-*) + deepin_distro "$1" + ;; + kali-*) + . oscfg/kali.sh + kali_distro "$1" + ;; *) echo "unsupported distro $1" ;; diff --git a/known_linux_fixes.md b/known_linux_fixes.md new file mode 100644 index 0000000..d847f04 --- /dev/null +++ b/known_linux_fixes.md @@ -0,0 +1,47 @@ +# Known Linux Fixes + +Fixes for one image will sometimes work for another image if they share the same DE, base distribution, or other supporting software. These are some example fixes that may work, so it's worth looking through this if you're setting up a new image or debugging a common issue with an existing one. + +## gdm3 + +Disable Wayland (SPICE doesn't work well with Wayland, xorg is preferred): +``` +sed -i "/\[daemon]/a WaylandEnable=false" "$WORK/etc/gdm3/custom.conf" +``` + +## GNOME + +Disabling sleep, suspend, and hibernating: +``` +run systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target +``` + +## KDE + +Disable locking: +``` +cat >"$WORK/etc/skel/.config/kscreenlockerrc" <> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf +echo autologin-user-timeout=0 >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf +echo session-cleanup-script=pkill -P1 -fx /usr/sbin/lightdm >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf +``` + +## PulseAudio + +Fix sound being muted by default: +``` +cat <<'EOF' >>"$WORK/etc/pulse/default.pa" +set-sink-volume 0 32768 +set-sink-mute 0 0 +EOF +``` diff --git a/official_images.txt b/official_images.txt index 5cba468..4636edd 100644 --- a/official_images.txt +++ b/official_images.txt @@ -1,7 +1,13 @@ -debian-buster-gnome-desktop -debian-buster-ssh-server -fedora-33-server -fedora-33-workstation-product +debian-bullseye-gnome-desktop +debian-bullseye-ssh-server +debian-bullseye-mx-linux-desktop +debian-bookworm-gnome-desktop +debian-bookworm-ssh-server +debian-bookworm-mx-linux-desktop +debian-trixie-gnome-desktop +debian-trixie-ssh-server +fedora-35-server +fedora-35-workstation-product manjaro-desktop manjaro-gnome-desktop manjaro-kde-desktop @@ -12,3 +18,20 @@ ubuntu-focal-openssh-server ubuntu-focal-ubuntu-desktop ubuntu-focal-xubuntu-desktop ubuntu-focal-rescue +ubuntu-focal-mint-cinnamon-desktop +ubuntu-jammy-mint-cinnamon-desktop +ubuntu-noble-mint-cinnamon-desktop +ubuntu-jammy-openssh-server +ubuntu-jammy-ubuntu-desktop +ubuntu-jammy-rescue +ubuntu-noble-kde-neon-desktop +ubuntu-noble-openssh-server +ubuntu-noble-ubuntu-desktop +ubuntu-noble-rescue +ubuntu-plucky-openssh-server +ubuntu-plucky-ubuntu-desktop +ubuntu-plucky-rescue +opensuse-leap-gnome-desktop +opensuse-leap-kde-desktop +opensuse-tumbleweed-gnome-desktop +opensuse-tumbleweed-kde-desktop diff --git a/os_requirements.md b/os_requirements.md index 4e0f561..689c896 100644 --- a/os_requirements.md +++ b/os_requirements.md @@ -4,8 +4,13 @@ If you want to submit and/or maintain distribution of your choice for official S * No password for users (we disable the passwords, enabled passwordless sudo and passwordless polkit auth in firstrun script, so keep that in mind). * Set user to autologin (we try to achieve this in firstrun script but if you see difference not applying for your OS, be sure to do it). * Disable power saving (screensavers, sleep, automatic logout etc). -* Disable logout option. * Be sure to have in your image spice-vdagent and qemu-guest-agent. +* Either disable logout or make it so users can't get stuck if they do log out (make sure they auto-login again immediately or they can click a login button / press enter to get logged in again). +* Disable sleep button if one exists (or make it do a no-op). We want to avoid images freezing up when the sleep button gets pressed. +* Disable lock button, or make it so that if the user does click it they can simply move the mouse or click to escape. +* Make sure the OS gets all latest updates when the image gets built. If your image requires a special update command (for example [pkcon](https://neon.kde.org/faq#command-to-update)) then make sure that is being run. +* Sound should work out of the box and not be muted. +* Be sure to have `https://github.com/Shells-com/shells-helper` installed on the image, so that notifications will be passed to the Shell host. ## Naming diff --git a/oscfg/centos.sh b/oscfg/centos.sh new file mode 100644 index 0000000..fda8292 --- /dev/null +++ b/oscfg/centos.sh @@ -0,0 +1,149 @@ +#!/bin/sh + +centos_distro() { + # centos-xxx + + case "$1" in + *-yumbase) + # centos-7.9.2009-yumbase + local VERSION="$(echo "$1" | cut -f2 -d-)" + # grab min from docker + docker_prepare centos "$VERSION" + + # we might be good with this, but actually not. + # Let's use this base docker centos image to build a proper centos image. + + echo 'nameserver 8.8.8.8' >"$WORK/etc/resolv.conf" + echo 'nameserver 8.8.4.4' >>"$WORK/etc/resolv.conf" + mkdir "$WORK/new-root" + run rpm --root /new-root --initdb + run yumdownloader --destdir=/var/tmp centos-release + run rpm --root /new-root -ivh --nodeps /var/tmp/centos-release*rpm + run yum --installroot=/new-root update + run yum -y --installroot=/new-root install @core + mkdir -p "$WORK/new-root/dev" + for foo in tty-c-5-0 console-c-5-1 zero-c-1-5 ptmx-c-5-2 fuse-c-10-229 random-c-1-8 urandom-c-1-9; do + mknod -m 666 "$WORK/new-root/dev/"${foo//-/ } + done + chroot "$WORK/new-root" yum clean all + + echo "Generating centos-$VERSION-yumbase.tar.xz" + tar cJf "centos-$VERSION-yumbase-$DATE.tar.xz" -C "$WORK/new-root" . + + # perform prepare here so finalize makes something good + prepare "centos-$VERSION-yumbase-$DATE.tar.xz" + ;; + *-dnfbase) + local VERSION="$(echo "$1" | cut -f2 -d-)" + # grab min from docker + docker_prepare centos "$VERSION" + + # we might be good with this, but actually not. + # Let's use this base docker centos image to build a proper centos image. + + echo 'nameserver 8.8.8.8' >"$WORK/etc/resolv.conf" + echo 'nameserver 8.8.4.4' >>"$WORK/etc/resolv.conf" + run dnf -y --installroot=/new-root --releasever="$VERSION" group install minimal-environment + chroot "$WORK/new-root" dnf clean all + + echo "Generating centos-$VERSION-dnfbase.tar.xz" + tar cJf "centos-$VERSION-dnfbase-$DATE.tar.xz" -C "$WORK/new-root" . + + # perform prepare here so finalize makes something good + prepare "centos-$VERSION-dnfbase-$DATE.tar.xz" + ;; + *) + # use latest pre-build dnfbase image + # centos-7.9-dnfbase + local VERSION="$(echo "$1" | cut -f2 -d-)" + + case $VERSION in + 7.9.2009) + getfile centos-7.9.2009-yumbase-20230603.tar.xz 7fabf1472b65ee4768945a966d8baf1bf48ceb365a4c51d60c83176088c865e7 + prepare centos-7.9.2009-yumbase-20230603.tar.xz + ;; + *) + echo "unsupported centos version: $VERSION" + exit 1 + esac + centos_cfg "$1" + ;; + esac +} + +centos_cfg() { + local VERSION="$(echo "$1" | cut -f2 -d-)" + local GROUP="$(echo "$1" | cut -f3- -d-)" + local DNF=dnf + case $VERSION in + 7*) + DNF=yum + echo 'NETWORKING=yes' >"$WORK/etc/sysconfig/network" + ;; + esac + + echo 'nameserver 8.8.8.8' >"$WORK/etc/resolv.conf" + echo 'nameserver 8.8.4.4' >>"$WORK/etc/resolv.conf" + + # make sudo available without password (default for key auth) + #mkdir -p "$WORK/etc/sudoers.d" + echo "%shellsmgmt ALL=(ALL) NOPASSWD: ALL" > "$WORK/etc/sudoers.d/01-shells" + chmod 440 "$WORK/etc/sudoers.d/01-shells" + + if [ $DNF == dnf ]; then + run $DNF upgrade --refresh -y + else + run $DNF upgrade -y + fi + + case $GROUP in + server) + run $DNF -y install @server-product + # setup systemd to boot to the right runlevel + echo -n "Setting default runlevel to multiuser text mode" + rm -f "${WORK}/etc/systemd/system/default.target" + ln -s /lib/systemd/system/multi-user.target "${WORK}/etc/systemd/system/default.target" + echo . + ;; + *) + # perform dnf install + # see for groups: https://docs.centosproject.org/en-US/quick-docs/switching-desktop-environments/ + # example: custom-environment (default centos command line) → centos-33-custom + run $DNF -y install "@${GROUP}-environment" + ;; + esac + + # install qemu agent & NetworkManager + run $DNF install -y qemu-guest-agent NetworkManager + + case "$GROUP" in + *-desktop|workstation-product|developer-workstation) + run $DNF install -y spice-vdagent spice-webdavd + run systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target + esac + + # remove ssh key files if any + rm -f "$WORK/etc/ssh"/ssh_host_* || true + + # add shells-helper to /etc/skel + if [ ! -f "$WORK/etc/skel/.bin/shells-helper" ]; then + mkdir -p "$WORK/etc/skel/.bin" + local O="$PWD" + cd "$WORK/etc/skel/.bin" + curl -s https://raw.githubusercontent.com/KarpelesLab/make-go/master/get.sh | /bin/sh -s shells-helper + cd "$O" + fi + + # new .xprofile file + echo "#!/bin/sh" >"$WORK/etc/skel/.xprofile" + echo "xset s off" >>"$WORK/etc/skel/.xprofile" + echo 'while true; do $HOME/.bin/shells-helper >/dev/null 2>&1; sleep 30; done &' >>"$WORK/etc/skel/.xprofile" + echo >>"$WORK/etc/skel/.xprofile" + chmod +x "$WORK/etc/skel/.xprofile" + + # add firstrun + add_firstrun NetworkManager-wait-online.service + do_linux_config + + run $DNF clean all +} diff --git a/oscfg/debian.sh b/oscfg/debian.sh index 5d48b74..82580b2 100644 --- a/oscfg/debian.sh +++ b/oscfg/debian.sh @@ -10,20 +10,30 @@ debian_distro() { # for example: debian-buster-base create_empty - debootstrap --include=wget,curl,net-tools,rsync,openssh-server,sudo $SUITE "$WORK" + debootstrap --include=wget,curl,net-tools,rsync,openssh-server,sudo,psmisc $SUITE "$WORK" + + # mount tmpfs for apt cache to avoid cleanup later + mkdir -p "$WORK/var/cache/apt/archives" + mount -t tmpfs tmpfs "$WORK/var/cache/apt/archives" # make sudo available without password (default for key auth) echo "%shellsmgmt ALL=(ALL) NOPASSWD: ALL" > "$WORK/etc/sudoers.d/01-shells" chmod 440 "$WORK/etc/sudoers.d/01-shells" + SECURITY="$SUITE-security" + if [ x"$SUITE" = x"buster" ]; then + # naming scheme until buster was different + SECURITY="$SUITE/updates" + fi + # build sources.list (add backports?) # see: https://wiki.debian.org/SourcesList cat >"$WORK/etc/apt/sources.list" <"$WORK/etc/default/zramswap" <"$WORK/etc/apt/sources.list.d/mx.list" <>"$WORK/etc/pulse/default.pa" +set-sink-volume 0 32768 +set-sink-mute 0 0 +EOF ;; esac @@ -127,7 +192,7 @@ EOF do_linux_config # create script to disable gnome screensaver stuff - if [ -f "$WORK/usr/bin/gsettings" ]; then + if [ -f "$WORK/usr/bin/gnome-session" ]; then if [ -d "$WORK/usr/share/backgrounds" ]; then # install wallpaper cp "$RESDIR/shells_bg.png" "$WORK/usr/share/backgrounds/shells_bg.png" @@ -174,7 +239,7 @@ idle-activation-enabled=false [org/gnome/desktop/lockdown] disable-lock-screen=true -disable-log-out=true +#disable-log-out=true [org/gnome/desktop/session] idle-delay=uint32 0 @@ -183,12 +248,459 @@ idle-delay=uint32 0 picture-uri='file:////usr/share/backgrounds/shells_bg.png' [org/gnome/desktop/interface] -gtk-theme='Material-Black-Blueberry-3.36' -icon-theme='Material-Black-Blueberry-3.36' +#icon-theme='Material-Black-Blueberry-3.36' EOF fi + + case "$TASKSEL" in + mx-linux-desktop) + case $SUITE in + buster) + MX_VERS="19.3" + MX_CODENAME="patito feo" + MX_DATE="March 31, 2021" + ;; + bullseye) + MX_VERS="21.3" + MX_CODENAME="wildflower" + MX_DATE="October 21, 2021" + ;; + bookworm) + MX_VERS="23.6" + MX_CODENAME="libretto" + MX_DATE="March 31, 2025" # probably + ;; + esac + + cat >"$WORK/etc/apt/apt.conf" <"$WORK/etc/lsb-release" <"$WORK/etc/mx-version" <"$WORK/etc/adduser.conf" +# /etc/adduser.conf: `adduser' configuration. +# See adduser(8) and adduser.conf(5) for full documentation. + +# The DSHELL variable specifies the default login shell on your +# system. +DSHELL=/bin/bash + +# The DHOME variable specifies the directory containing users' home +# directories. +DHOME=/home + +# If GROUPHOMES is "yes", then the home directories will be created as +# /home/groupname/user. +GROUPHOMES=no + +# If LETTERHOMES is "yes", then the created home directories will have +# an extra directory - the first letter of the user name. For example: +# /home/u/user. +LETTERHOMES=no + +# The SKEL variable specifies the directory containing "skeletal" user +# files; in other words, files such as a sample .profile that will be +# copied to the new user's home directory when it is created. +SKEL=/etc/skel + +# FIRST_SYSTEM_[GU]ID to LAST_SYSTEM_[GU]ID inclusive is the range for UIDs +# for dynamically allocated administrative and system accounts/groups. +# Please note that system software, such as the users allocated by the base-passwd +# package, may assume that UIDs less than 100 are unallocated. +FIRST_SYSTEM_UID=100 +LAST_SYSTEM_UID=999 + +FIRST_SYSTEM_GID=100 +LAST_SYSTEM_GID=999 + +# FIRST_[GU]ID to LAST_[GU]ID inclusive is the range of UIDs of dynamically +# allocated user accounts/groups. +FIRST_UID=1000 +LAST_UID=29999 + +FIRST_GID=1000 +LAST_GID=29999 + +# The USERGROUPS variable can be either "yes" or "no". If "yes" each +# created user will be given their own group to use as a default. If +# "no", each created user will be placed in the group whose gid is +# USERS_GID (see below). +USERGROUPS=yes + +# If USERGROUPS is "no", then USERS_GID should be the GID of the group +# `users' (or the equivalent group) on your system. +USERS_GID=100 + +# If DIR_MODE is set, directories will be created with the specified +# mode. Otherwise the default mode 0755 will be used. +DIR_MODE=0755 + +# If SETGID_HOME is "yes" home directories for users with their own +# group the setgid bit will be set. This was the default for +# versions << 3.13 of adduser. Because it has some bad side effects we +# no longer do this per default. If you want it nevertheless you can +# still set it here. +SETGID_HOME=no + +# If QUOTAUSER is set, a default quota will be set from that user with +# `edquota -p QUOTAUSER newuser' +QUOTAUSER="" + +# If SKEL_IGNORE_REGEX is set, adduser will ignore files matching this +# regular expression when creating a new home directory +SKEL_IGNORE_REGEX="dpkg-(old|new|dist|save)" + +# Set this if you want the --add_extra_groups option to adduser to add +# new users to other groups. +# This is the list of groups that new non-system users will be added to +# Default: +EXTRA_GROUPS="dialout dip fuse cdrom audio video plugdev users floppy netdev scanner lp lpadmin sudo vboxsf" + +# If ADD_EXTRA_GROUPS is set to something non-zero, the EXTRA_GROUPS +# option above will be default behavior for adding new, non-system users +ADD_EXTRA_GROUPS=1 + + +# check user and group names also against this regular expression. +#NAME_REGEX="^[a-z][-a-z0-9_]*\$" +EOF + + cat <<'EOF' >"$WORK/etc/bash.bashrc" +# System-wide .bashrc file for interactive bash(1) shells. + +# To enable the settings / commands in this file for login shells as well, +# this file has to be sourced in /etc/profile. + +# If not running interactively, don't do anything +[ -z "$PS1" ] && return + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "${debian_chroot:-}" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, overwrite the one in /etc/profile) +#PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +PS1='${debian_chroot:+($debian_chroot)}\[\033[01;31m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' + +# Commented out, don't overwrite xterm -T "title" -n "icontitle" by default. +# If this is an xterm set the title to user@host:dir +#case "$TERM" in +#xterm*|rxvt*) +# PROMPT_COMMAND='echo -ne "\033]0;${USER}@${HOSTNAME}: ${PWD}\007"' +# ;; +#*) +# ;; +#esac + +# enable bash completion in interactive shells +#if ! shopt -oq posix; then +# if [ -f /usr/share/bash-completion/bash_completion ]; then +# . /usr/share/bash-completion/bash_completion +# elif [ -f /etc/bash_completion ]; then +# . /etc/bash_completion +# fi +#fi + +# if the command-not-found package is installed, use it +if [ -x /usr/lib/command-not-found -o -x /usr/share/command-not-found/command-not-found ]; then + function command_not_found_handle { + # check because c-n-f could've been removed in the meantime + if [ -x /usr/lib/command-not-found ]; then + /usr/lib/command-not-found -- "$1" + return $? + elif [ -x /usr/share/command-not-found/command-not-found ]; then + /usr/share/command-not-found/command-not-found -- "$1" + return $? + else + printf "%s: command not found\n" "$1" >&2 + return 127 + fi + } +fi + +#apt-get +alias agu="apt-get update" +alias agd="apt-get dist-upgrade" +alias agc="apt-get clean" +alias ag="apt-get update;apt-get dist-upgrade" +EOF + + mkdir -p "$WORK/etc/default" + cat <<'EOF' >"$WORK/etc/default/console-setup" +# CONFIGURATION FILE FOR SETUPCON + +# Consult the console-setup(5) manual page. + +ACTIVE_CONSOLES="/dev/tty[1-6]" + +CHARMAP="UTF-8" - # cleanup apt - run apt-get clean +CODESET="guess" +FONTFACE="Terminus" +FONTSIZE="12x6" + +VIDEOMODE= + +# The following is an example how to use a braille font +# FONT='lat9w-08.psf.gz brl-8x8.psf' +EOF + + cat <<'EOF' >"$WORK/etc/skel/.bashrc" +# ~/.bashrc: executed by bash(1) for non-login shells. +# see /usr/share/doc/bash/examples/startup-files (in the package bash-doc) +# for examples + +# If not running interactively, don't do anything +[ -z "$PS1" ] && return + +# don't put duplicate lines in the history. See bash(1) for more options +# don't overwrite GNU Midnight Commander's setting of `ignorespace'. +HISTCONTROL=$HISTCONTROL${HISTCONTROL+:}ignoredups +# ... or force ignoredups and ignorespace +HISTCONTROL=ignoreboth + +# append to the history file, don't overwrite it +shopt -s histappend + +# for setting history length see HISTSIZE and HISTFILESIZE in bash(1) + +# check the window size after each command and, if necessary, +# update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# make less more friendly for non-text input files, see lesspipe(1) +#[ -x /usr/bin/lesspipe ] && eval "$(SHELL=/bin/sh lesspipe)" + +# set variable identifying the chroot you work in (used in the prompt below) +if [ -z "$debian_chroot" ] && [ -r /etc/debian_chroot ]; then + debian_chroot=$(cat /etc/debian_chroot) +fi + +# set a fancy prompt (non-color, unless we know we "want" color) +case "$TERM" in + xterm-color) color_prompt=yes;; +esac + +# uncomment for a colored prompt, if the terminal has the capability; turned +# off by default to not distract the user: the focus in a terminal window +# should be on the output of commands, not on the prompt +# force_color_prompt=yes + +if [ -n "$force_color_prompt" ]; then + if [ -x /usr/bin/tput ] && tput setaf 1 >&/dev/null; then + # We have color support; assume it's compliant with Ecma-48 + # (ISO/IEC-6429). (Lack of such support is extremely rare, and such + # a case would tend to support setf rather than setaf.) + color_prompt=yes + else + color_prompt= + fi +fi + +if [ "$color_prompt" = yes ]; then + PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ ' +else + PS1='${debian_chroot:+($debian_chroot)}\u@\h:\w\$ ' +fi +unset color_prompt force_color_prompt + +red='\[\e[0;31m\]' +RED='\[\e[1;31m\]' +blue='\[\e[0;34m\]' +BLUE='\[\e[1;34m\]' +cyan='\[\e[0;36m\]' +CYAN='\[\e[1;36m\]' +green='\[\e[0;32m\]' +GREEN='\[\e[1;32m\]' +yellow='\[\e[0;33m\]' +YELLOW='\[\e[1;33m\]' +PURPLE='\[\e[1;35m\]' +purple='\[\e[0;35m\]' +nc='\[\e[0m\]' + +if [ "$UID" = 0 ]; then + PS1="$red\u$nc@$red\H$nc:$CYAN\w$nc\\n$red#$nc " +else + PS1="$PURPLE\u$nc@$CYAN\H$nc:$GREEN\w$nc\\n$GREEN\$$nc " +fi +# enable color support of ls and also add handy aliases +if [ -x /usr/bin/dircolors ]; then + test -r ~/.dircolors && eval "$(dircolors -b ~/.dircolors)" || eval "$(dircolors -b)" + alias ls='ls --color=auto' + #alias dir='dir --color=auto' + #alias vdir='vdir --color=auto' + + #alias grep='grep --color=auto' + #alias fgrep='fgrep --color=auto' + #alias egrep='egrep --color=auto' +fi + +# some more ls aliases +alias ll='ls -lh' +alias la='ls -A' +alias l='ls -CF' + +# Alias definitions. +# You may want to put all your additions into a separate file like +# ~/.bash_aliases, instead of adding them here directly. +# See /usr/share/doc/bash-doc/examples in the bash-doc package. + +if [ -f ~/.bash_aliases ]; then + . ~/.bash_aliases +fi + +# Default parameter to send to the "less" command +# -R: show ANSI colors correctly; -i: case insensitive search +LESS="-R -i" + +# enable programmable completion features (you don't need to enable +# this, if it's already enabled in /etc/bash.bashrc and /etc/profile +# sources /etc/bash.bashrc). +if [ -f /etc/bash_completion ] && ! shopt -oq posix; then + . /etc/bash_completion +fi + +# Add sbin directories to PATH. This is useful on systems that have sudo +echo $PATH | grep -Eq "(^|:)/sbin(:|)" || PATH=$PATH:/sbin +echo $PATH | grep -Eq "(^|:)/usr/sbin(:|)" || PATH=$PATH:/usr/sbin + +# If this is an xterm set the title to user@host:dir +case "$TERM" in +xterm*|rxvt*) + PS1="\[\e]0;${debian_chroot:+($debian_chroot)}\u@\h: \w\a\]$PS1" + ;; +*) + ;; +esac +EOF + + cat <<'EOF' >"$WORK/etc/skel/.inputrc" +"\e[A": history-search-backward +"\e[B": history-search-forward +EOF + + mkdir -p "$WORK/etc/skel/.local/share/applications" + cat <<'EOF' >"$WORK/etc/skel/.local/share/applications/compton.desktop" +[Desktop Entry] +Version=1.0 +Type=Application +Name=compton +GenericName=X compositor +Comment=A X compositor +Categories=Utility; +TryExec=compton +Exec=compton +Icon=compton +Keywords=x;x11;compositor; +NoDisplay=true +# Thanks to quequotion for providing this file! +EOF + + cat <<'EOF' >"$WORK/etc/skel/.local/share/applications/compton-conf.desktop" +[Desktop Entry] +Type=Application +Name=Window Effects +GenericName=Compton Configuration +Comment=Configure Compton window effects +TryExec=compton-conf +Exec=compton-conf +Icon=preferences-system-windows +Categories=Settings;DesktopSettings;Qt;LXQt; + +Name[de]=Fenstereffekte +GenericName[de]=Compton Konfiguration +Comment[de]=Konfiguriere Compton-Fenstereffekte +Name[fr]=Effets des fenêtres +GenericName[fr]=Paramétrage de Compton +Comment[fr]=Paramétrage de Compton (effets des fenêtres) +Name[hu]=Ablakhatások +GenericName[hu]=Compton beállítás +Comment[hu]=Compton-ablakhatások beállítása +Name[it]=Effetti delle finestre +Comment[it]=Configura gli effetti delle finestre di Compton +Name[ja]=ウインドウ効果 +GenericName[ja]=Comptonの設定 +Comment[ja]=Comptonのウインドウ効果の設定 +Name[pt]=Efeitos de janelas +GenericName[pt]=Configuração do Compton +Comment[pt]=Configurar os efeitos de janelas +Name[ru]=Эффекты окна +GenericName[ru]=Настройка Compton +Comment[ru]=Настроить эффекты окна Compton +NoDisplay=true +EOF + + mkdir -p "$WORK/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/" + cat >"$WORK/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-session.xml" < + + + + + + + + + + + +EOF + + cat >"$WORK/etc/skel/.config/xfce4/xfconf/xfce-perchannel-xml/xfce4-power-manager.xml" < + + + + + + + + + + + + + + + + + + + + + + + + +EOF + + cat <<'EOF' >>"$WORK/etc/pulse/default.pa" +set-sink-volume 0 32768 +set-sink-mute 0 0 +EOF + + ;; + esac + + # update apt cache + run apt-get update } diff --git a/oscfg/deepin.sh b/oscfg/deepin.sh new file mode 100644 index 0000000..e179f32 --- /dev/null +++ b/oscfg/deepin.sh @@ -0,0 +1,159 @@ +#!/bin/sh + +deepin_distro() { + local SUITE="apricot" + + case "$1" in + *-base) + create_empty + # hack for deepin, debootstrap does not support deepin, some packages need to be replaced. + debootstrap --include=wget,curl,net-tools,rsync,openssh-server,sudo buster "$WORK" https://mirrors.ustc.edu.cn/debian/ + + # mount tmpfs for apt cache to avoid cleanup later + mkdir -p "$WORK/var/cache/apt/archives" + mount -t tmpfs tmpfs "$WORK/var/cache/apt/archives" + + # make sudo available without password (default for key auth) + echo "%shellsmgmt ALL=(ALL) NOPASSWD: ALL" >"$WORK/etc/sudoers.d/01-shells" + chmod 440 "$WORK/etc/sudoers.d/01-shells" + + DEBIAN_FRONTEND=noninteractive run apt install ca-certificates -y + + cat >"$WORK/etc/apt/sources.list" <"$WORK/etc/default/locale" + export LANG=en_US.UTF-8 + run apt update + DEBIAN_FRONTEND=noninteractive run apt install deepin-keyring -y + DEBIAN_FRONTEND=noninteractive run apt install base-files bash -y + + cat >"$WORK/etc/apt/sources.list" <"$WORK/etc/apt/sources.list.d/printer.list" <"$WORK/etc/apt/sources.list.d/appstore.list" <"$WORK/etc/netplan/config.yaml" <"$WORK/etc/skel/.profile" + echo "xset s off" >>"$WORK/etc/skel/.profile" + echo 'while true; do $HOME/.bin/shells-helper >/dev/null 2>&1; sleep 30; done &' >>"$WORK/etc/skel/.profile" + echo >>"$WORK/etc/skel/.profile" + chmod +x "$WORK/etc/skel/.profile" + + # add firstrun + add_firstrun NetworkManager-wait-online.service + do_linux_config + + if [ -f "$WORK/usr/bin/gsettings" ]; then + # setup wine mime type + mkdir -p "$WORK/etc/skel/.local/share/applications" + cat >"$WORK/etc/skel/.local/share/applications/wine.desktop" <"$WORK/etc/skel/.local/share/applications/mimeapps.list" <"$WORK/etc/resolv.conf" echo 'nameserver 8.8.4.4' >>"$WORK/etc/resolv.conf" @@ -70,7 +83,8 @@ fedora_cfg() { case "$GROUP" in *-desktop|workstation-product|developer-workstation) - run dnf install -y spice-vdagent spice-webdavd + run dnf install -y spice-vdagent spice-webdavd + run systemctl mask sleep.target suspend.target hibernate.target hybrid-sleep.target esac # remove ssh key files if any diff --git a/oscfg/gentoo.sh b/oscfg/gentoo.sh index dd67e17..99c737b 100644 --- a/oscfg/gentoo.sh +++ b/oscfg/gentoo.sh @@ -1,30 +1,39 @@ #!/bin/sh gentoo_distro() { - # fetch stage3 - local STAGE3="$(curl -s -L https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/latest-stage3.txt | grep -v '^#' | head -n 1 | awk '{ print $1 }')" + gentoo_cfg "$1" +} + +gentoo_prepare() { + # fetch stage3 for the specified config + local STAGE3="$(curl -s -L https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/latest-stage3.txt | grep -v '^#' | grep "stage3-amd64-$1" | head -n 1 | awk '{ print $1 }')" local STAGE3_NAME="$(basename "$STAGE3")" - echo "Donwloading $STAGE3_NAME ..." - curl -# -o "$STAGE3_NAME" "https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/$STAGE3" + if [ ! -f "$STAGE3_NAME" ]; then + echo "Downloading $STAGE3_NAME ..." + curl -# -L -o "${STAGE3_NAME}~" "https://bouncer.gentoo.org/fetch/root/all/releases/amd64/autobuilds/$STAGE3" + mv -f "${STAGE3_NAME}~" "${STAGE3_NAME}" + fi prepare "$STAGE3_NAME" - gentoo_cfg "$1" + echo 'nameserver 8.8.8.8' >"$WORK/etc/resolv.conf" + echo 'nameserver 8.8.4.4' >>"$WORK/etc/resolv.conf" + run emerge-webrsync } gentoo_cfg() { # sync emerge (can take some time) - run emerge-webrsync - case "$1" in gentoo-xfce-desktop) - run eselect profile set default/linux/amd64/17.1/desktop + gentoo_prepare desktop-openrc + #run eselect profile set default/linux/amd64/23.0/desktop echo "INPUT_DEVICES=\"libinput synaptics\"" >>"$WORK/etc/portage/make.conf" echo "VIDEO_CARDS=\"qxl\"" >>"$WORK/etc/portage/make.conf" - run emerge -j`nproc` xfce-base/xfce4-meta x11-terms/xfce4-terminal - run emerge -j`nproc` xfce-extra/xfce4-pulseaudio-plugin xfce-extra/xfce4-taskmanager x11-themes/xfwm4-themes app-office/orage app-editors/mousepad xfce-extra/xfce4-power-manager x11-terms/xfce4-terminal xfce-base/thunar - run emerge -j`nproc` x11-misc/slim + run emerge -j"$(nproc)" app-admin/sudo net-misc/openssh + run emerge -j"$(nproc)" xfce-base/xfce4-meta x11-terms/xfce4-terminal + run emerge -j"$(nproc)" xfce-extra/xfce4-pulseaudio-plugin xfce-extra/xfce4-taskmanager x11-themes/xfwm4-themes app-office/orage app-editors/mousepad xfce-extra/xfce4-power-manager x11-terms/xfce4-terminal xfce-base/thunar + run emerge -j"$(nproc)" x11-misc/slim sed -i -e 's/^DISPLAYMANAGER=.*/DISPLAYMANAGER="slim"/' "$WORK/etc/conf.d/xdm" echo XSESSION=\"Xfce4\" > "$WORK/etc/env.d/90xsession" @@ -32,5 +41,14 @@ gentoo_cfg() { run rc-update add dbus default run rc-update add xdm default ;; + gentoo-ssh-server) + gentoo_prepare openrc + run emerge -j"$(nproc)" app-admin/sudo net-misc/openssh + + run rc-update add ssh default + ;; esac + + # make sudo available without password (default for key auth) + echo "%shellsmgmt ALL=(ALL) NOPASSWD: ALL" > "$WORK/etc/sudoers.d/01-shells" & chmod 440 "$WORK/etc/sudoers.d/01-shells" } diff --git a/oscfg/kali.sh b/oscfg/kali.sh new file mode 100644 index 0000000..be65beb --- /dev/null +++ b/oscfg/kali.sh @@ -0,0 +1,69 @@ +#!/bin/sh + +kali_distro() { + docker_prepare "kalilinux/kali-last-release" latest + + # mount tmpfs for apt cache to avoid cleanup later + mkdir -p "$WORK/var/cache/apt/archives" + mount -t tmpfs tmpfs "$WORK/var/cache/apt/archives" + + kali_cfg "$1" +} + +# configure an existing kali linux install +kali_cfg() { + # make sure / is 0755 + chmod 0755 "${WORK}" + + # add some resolvers + echo "nameserver 8.8.8.8" >>"$WORK/etc/resolv.conf" + echo "nameserver 8.8.4.4" >>"$WORK/etc/resolv.conf" + + run apt update + DEBIAN_FRONTEND=noninteractive run apt full-upgrade -y + DEBIAN_FRONTEND=noninteractive run apt-get -y install wget curl net-tools rsync openssh-server sudo psmisc + + # make sudo available without password (default for key auth) + echo "%shellsmgmt ALL=(ALL) NOPASSWD: ALL" > "$WORK/etc/sudoers.d/01-shells" & chmod 440 "$WORK/etc/sudoers.d/01-shells" + + # https://www.kali.org/docs/general-use/metapackages/ + + case "$1" in + kali-ssh-server) + DEBIAN_FRONTEND=noninteractive run apt-get -y install kali-linux-headless + ;; + kali-desktop) + DEBIAN_FRONTEND=noninteractive run apt-get -y install kali-linux-default + ;; + kali-xfce-desktop) + DEBIAN_FRONTEND=noninteractive run apt-get -y install kali-desktop-xfce + ;; + *) + echo "invalid kali image" + exit 1 + ;; + esac + + # add shells-helper to /etc/skel + if [ ! -f "$WORK/etc/skel/.bin/shells-helper" ]; then + mkdir -p "$WORK/etc/skel/.bin" + local O="$PWD" + cd "$WORK/etc/skel/.bin" + curl -s https://raw.githubusercontent.com/KarpelesLab/make-go/master/get.sh | /bin/sh -s shells-helper + cd "$O" + fi + + if [ ! -f "$WORK/etc/localtime" ]; then + ln -sf "/usr/share/zoneinfo/UTC" "$WORK/etc/localtime" + fi + + add_firstrun NetworkManager-wait-online.service + do_linux_config + + # new .xprofile file + echo "#!/bin/sh" >"$WORK/etc/skel/.xprofile" + echo "xset s off" >>"$WORK/etc/skel/.xprofile" + echo 'while true; do $HOME/.bin/shells-helper >/dev/null 2>&1; sleep 30; done &' >>"$WORK/etc/skel/.xprofile" + echo >>"$WORK/etc/skel/.xprofile" + chmod +x "$WORK/etc/skel/.xprofile" +} diff --git a/oscfg/manjaro.sh b/oscfg/manjaro.sh index fc30a04..e636da7 100644 --- a/oscfg/manjaro.sh +++ b/oscfg/manjaro.sh @@ -1,8 +1,7 @@ #!/bin/sh manjaro_distro() { - getfile manjaro-base-20200119.tar.xz 218bcdfe8998624180993ac4a86971b585700ce5a5076b913a24cea32efbdf47 - prepare manjaro-base-20200119.tar.xz + docker_prepare "manjarolinux/base" latest manjaro_cfg "$1" } @@ -27,12 +26,12 @@ manjaro_cfg() { case "$1" in manjaro-desktop) run pacman -S --noconfirm glibc-locales xfce4 ttf-dejavu accountsservice xfce4-goodies xfce4-pulseaudio-plugin mugshot engrampa catfish screenfetch network-manager-applet noto-fonts noto-fonts-cjk - run pacman -S --noconfirm manjaro-xfce-settings-shells manjaro-release manjaro-firmware manjaro-system manjaro-hello manjaro-application-utility manjaro-documentation-en manjaro-browser-settings nano inxi wallpaper-manjaro-shells + run pacman -S --noconfirm manjaro-xfce-settings-shells manjaro-release manjaro-system manjaro-hello manjaro-browser-settings nano inxi wallpaper-manjaro-shells run pacman -S --noconfirm firefox thunderbird run pacman -S --noconfirm onlyoffice-desktopeditors run pacman -S --noconfirm pulseaudio pavucontrol - run pacman -S --noconfirm xf86-input-libinput xf86-video-qxl-debian xorg-server xorg-mkfontscale xorg-xkill phodav spice-vdagent - run pacman -S --noconfirm pamac-gtk pamac-snap-plugin pamac-flatpak-plugin + run pacman -S --noconfirm xf86-input-libinput xf86-video-qxl xorg-server xorg-mkfontscale xorg-xkill phodav spice-vdagent + run pacman -S --noconfirm pamac-gtk3 pamac-snap-plugin pamac-flatpak-plugin xdg-desktop-portal-gtk run systemctl enable apparmor snapd snapd.apparmor sed -i -e 's|show-command-switchuser=true|show-command-switchuser=false|g' $WORK/etc/skel/.config/xfce4/panel/whiskermenu*.rc sed -i -e 's|show-command-logout=true|show-command-logout=false|g' $WORK/etc/skel/.config/xfce4/panel/whiskermenu*.rc @@ -71,22 +70,15 @@ EOF ;; manjaro-kde-desktop) run pacman -S --noconfirm glibc-locales plasma-meta ark dolphin dolphin-plugins kate kcalc kfind okular kget libktorrent kdenetwork-filesharing kio-extras konsole konversation ksystemlog kwalletmanager gwenview spectacle kdegraphics-thumbnailers ffmpegthumbs ruby kimageformats qt5-imageformats systemd-kcm yakuake vlc oxygen-icons kaccounts-providers - run pacman -S --noconfirm manjaro-kde-settings-shells manjaro-release manjaro-firmware manjaro-system manjaro-hello manjaro-application-utility manjaro-documentation-en manjaro-browser-settings sddm-breath2-theme nano inxi illyria-wallpaper wallpapers-juhraya wallpapers-2018 manjaro-wallpapers-18.0 + run pacman -S --noconfirm manjaro-kde-settings manjaro-release manjaro-system manjaro-hello manjaro-browser-settings nano inxi run pacman -S --noconfirm firefox thunderbird run pacman -S --noconfirm onlyoffice-desktopeditors run pacman -S --noconfirm pulseaudio pavucontrol - run pacman -S --noconfirm xf86-input-libinput xf86-video-qxl-debian xorg-server xorg-mkfontscale xorg-xkill phodav spice-vdagent - run pacman -S --noconfirm pamac-gtk pamac-snap-plugin pamac-flatpak-plugin pamac-tray-icon-plasma xdg-desktop-portal xdg-desktop-portal-kde + run pacman -S --noconfirm xf86-input-libinput xf86-video-qxl xorg-server xorg-mkfontscale xorg-xkill phodav spice-vdagent + run pacman -S --noconfirm pamac-gtk3 pamac-snap-plugin pamac-flatpak-plugin pamac-tray-icon-plasma xdg-desktop-portal-kde run systemctl enable sddm run systemctl enable apparmor snapd snapd.apparmor sed -i -e 's|#%PAM-1.0|#%PAM-1.0\nauth sufficient pam_succeed_if.so user ingroup shellsmgmt|' $WORK/etc/pam.d/sddm - cat > "$WORK/etc/sddm.conf.d/manjaro-theme.conf" < "$WORK/etc/skel/.config/kdesurc" printf "\n[Daemon]\nAutolock=false\n" >> "$WORK/etc/skel/.config/kscreenlockerrc" cat >> "$WORK/etc/skel/.config/kdeglobals" <"$WORK/run/netconfig/resolv.conf" - echo 'nameserver 8.8.4.4' >>"$WORK/run/netconfig/resolv.conf" + if [ -L "$WORK/etc/resolv.conf" ]; then + echo 'nameserver 8.8.8.8' >"$WORK/run/netconfig/resolv.conf" + echo 'nameserver 8.8.4.4' >>"$WORK/run/netconfig/resolv.conf" + else + echo 'nameserver 8.8.8.8' >"$WORK/etc/resolv.conf" + echo 'nameserver 8.8.4.4' >>"$WORK/etc/resolv.conf" + fi # refresh/update + run zypper repos + # force import of NVIDIA:repo-non-free as it doesn't happen automatically + run zypper --gpg-auto-import-keys ref -f 'NVIDIA:repo-non-free' run zypper -n ref run zypper -n dup } @@ -153,18 +166,30 @@ opensuse_cfg() { if [ "$DESKTOP" == "gnome" ]; then cat >>"$WORK/usr/share/glib-2.0/schemas/30-Shells.gschema.override" < "$WORK/etc/pam.d/gnomesu-pam" <> "$WORK/etc/skel/.config/kdeglobals" <"$WORK/etc/skel/.config/kscreenlockerrc" <"$WORK/etc/skel/.config/kdesurc" < "$WORK/etc/sudoers.d/01-shells" @@ -22,9 +33,9 @@ ubuntu_distro() { deb http://archive.ubuntu.com/ubuntu $SUITE main restricted universe multiverse ###### Ubuntu Update Repos -deb http://archive.ubuntu.com/ubuntu/ $SUITE-security main restricted universe multiverse -deb http://archive.ubuntu.com/ubuntu/ $SUITE-updates main restricted universe multiverse -deb http://archive.ubuntu.com/ubuntu/ $SUITE-backports main restricted universe multiverse +deb http://security.ubuntu.com/ubuntu $SUITE-security main restricted universe multiverse +deb http://archive.ubuntu.com/ubuntu $SUITE-updates main restricted universe multiverse +deb http://archive.ubuntu.com/ubuntu $SUITE-backports main restricted universe multiverse EOF echo 'LANG=en_US.UTF-8' >"$WORK/etc/default/locale" @@ -32,7 +43,7 @@ EOF # perform apt get update (download cache) run apt-get update DEBIAN_FRONTEND=noninteractive run apt-get dist-upgrade -y - DEBIAN_FRONTEND=noninteractive run apt-get install -y locales-all ubuntu-release-upgrader-core python3-distro-info kmod qemu-guest-agent + DEBIAN_FRONTEND=noninteractive run apt-get install -y locales-all python3-distro-info kmod qemu-guest-agent bash-completion nano ubuntu-release-upgrader-core ;; *) # start from base @@ -42,6 +53,11 @@ EOF fi prepare "ubuntu-$SUITE-base" + + # mount tmpfs for apt cache to avoid cleanup later + mkdir -p "$WORK/var/cache/apt/archives" + mount -t tmpfs tmpfs "$WORK/var/cache/apt/archives" + ubuntu_cfg "$1" ;; esac @@ -54,17 +70,44 @@ ubuntu_cfg() { run apt-get update DEBIAN_FRONTEND=noninteractive run apt-get dist-upgrade -y + + #add swap + DEBIAN_FRONTEND=noninteractive run apt-get install -y zram-tools + + cat >"$WORK/etc/default/zramswap" <"$WORK/etc/apt/preferences.d/mesa-amber" <<'EOF' +Package: libglapi-amber libgl1-amber-dri mesa-amber* +Pin: release * +Pin-Priority: -1 +EOF + ;; + esac + + case "$TASKSEL" in kde-neon-desktop) DEBIAN_FRONTEND=noninteractive run apt-get install -y gnupg - curl -s https://archive.neon.kde.org/public.key | run apt-key add - - echo "deb http://archive.neon.kde.org/user focal main" >"$WORK/etc/apt/sources.list.d/kde-neon.list" + # Use modern signed-by method instead of deprecated apt-key + mkdir -p "$WORK/etc/apt/keyrings" + curl -s https://archive.neon.kde.org/public.key | gpg --dearmor > "$WORK/etc/apt/keyrings/neon-archive-keyring.gpg" + echo "deb [signed-by=/etc/apt/keyrings/neon-archive-keyring.gpg] http://archive.neon.kde.org/user $SUITE main" >"$WORK/etc/apt/sources.list.d/kde-neon.list" run apt-get update + DEBIAN_FRONTEND=noninteractive run apt-get install -y neon-settings + DEBIAN_FRONTEND=noninteractive run apt-get full-upgrade -y DEBIAN_FRONTEND=noninteractive run apt-get install -y neon-desktop + run pkcon update -y mkdir -p "$WORK/etc/skel/.config" cat >> "$WORK/etc/skel/.config/kdeglobals" <"$WORK/etc/skel/.config/kscreenlockerrc" <"$WORK/etc/apt/sources.list.d/linux-mint.list" + # Use modern signed-by method instead of deprecated apt-key + mkdir -p "$WORK/etc/apt/keyrings" + curl -s 'https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x302F0738F465C1535761F965A6616109451BBBF2' | gpg --dearmor > "$WORK/etc/apt/keyrings/linuxmint-keyring.gpg" + echo "deb [signed-by=/etc/apt/keyrings/linuxmint-keyring.gpg] http://packages.linuxmint.com $MINT_CODENAME main upstream import backport" >"$WORK/etc/apt/sources.list.d/linux-mint.list" cat >> "$WORK/etc/apt/preferences.d/official-package-repositories.pref" < EOF + mkdir -p "$WORK/etc/systemd/logind.conf.d" + cat >"$WORK/etc/systemd/logind.conf.d/20-kill-user-processes.conf" <"$WORK/etc/netplan/config.yaml" <>"$WORK/etc/skel/.xprofile" <>"$WORK/etc/dconf/profile/user" < "$WORK/etc/skel/.config/dconf/user.txt" + + cat >>"$WORK/etc/skel/.config/dconf/user.txt" <> "$WORK/etc/skel/.xprofile" <.config +make prepare +make modules_prepare + +echo "Setting up symlink..." +ln -snf "$PWD" $MODPATH/build diff --git a/res/shells_bg.png b/res/shells_bg.png index 90fceb8..734b600 100644 Binary files a/res/shells_bg.png and b/res/shells_bg.png differ diff --git a/scripts/base.sh b/scripts/base.sh index ba3571a..256a872 100644 --- a/scripts/base.sh +++ b/scripts/base.sh @@ -1,10 +1,11 @@ #!/bin/bash -if [ -d "/shells/software/qemu/bin" ]; then - export PATH="/shells/software/qemu/bin:$PATH" +if [ -d "/shells/software/qemu-8.2.9/bin" ]; then + export PATH="/shells/software/qemu-8.2.9/bin:$PATH" fi -QEMUIMG="$(which qemu-img)" -QEMUNBD="$(which qemu-nbd)" +QEMUIMG="$(command -v qemu-img)" +QEMUSD="$(command -v qemu-storage-daemon)" +NBDCL="$(command -v nbd-client)" # various settings NBD="/dev/nbd2" @@ -12,6 +13,7 @@ RESDIR="$PWD/res" SCRIPTSDIR="$PWD/scripts" TMPIMG="work$$.qcow2" API_PREFIX="https://ws.atonline.com/_special/rest/" +BLOCKSIZE=512 if [ -d /shells ]; then WORK="/shells/work" @@ -28,9 +30,11 @@ DATE=$(date +'%Y%m%d') perform_clean() { if [ -d "$WORK" ]; then fuser --kill --ismountpoint --mount "$WORK" && sleep 1 || true - umount 2>/dev/null "$WORK/proc" "$WORK/sys" "$WORK/dev" || umount 2>/dev/null -l "$WORK/proc" "$WORK/sys" "$WORK/dev" || true + umount 2>/dev/null "$WORK/var/cache/apt/archives" || true + umount 2>/dev/null "$WORK/proc" "$WORK/sys" "$WORK/dev/pts" "$WORK/dev" || umount 2>/dev/null -l "$WORK/proc" "$WORK/sys" "$WORK/dev" || true umount 2>/dev/null "$WORK" || true - "$QEMUNBD" 2>/dev/null -d "$NBD" || true + "$NBDCL" 2>/dev/null -d "$NBD" || true + killall qemu-storage-daemon || true # should be empty after umount rmdir "$WORK" fi @@ -39,9 +43,14 @@ perform_clean() { create_empty() { perform_clean - "$QEMUIMG" create -f qcow2 "$TMPIMG" 8G - "$QEMUNBD" -c "$NBD" -f qcow2 "$TMPIMG" - parted --script -a optimal -- "$NBD" mklabel msdos mkpart primary ext4 1MiB -2048s + echo "Creating and partitionning $TMPIMG..." + "$QEMUIMG" create -f qcow2 "$TMPIMG" 10G + "$QEMUSD" --daemonize --pidfile qemusd.$$.pid --blockdev "driver=qcow2,file.driver=file,file.filename=$TMPIMG,node-name=disk0" --nbd-server addr.type=unix,addr.path=/tmp/nbd.sock --export type=nbd,id=exp0,node-name=disk0,name=disk0,writable=on + "$NBDCL" -unix /tmp/nbd.sock -N disk0 -b "$BLOCKSIZE" "$NBD" + sleep 0.5 + parted --script -a optimal -- "$NBD" mklabel gpt mkpart primary ext4 1MiB -2048s + sleep 0.5 # wait for /dev to update + echo "Formatting and mounting..." mkfs.ext4 -L root "$NBD"p1 mkdir "$WORK" mount "$NBD"p1 "$WORK" @@ -69,7 +78,8 @@ prepare() { # mount mkdir "$WORK" - "$QEMUNBD" -c "$NBD" -f qcow2 "$TMPIMG" + "$QEMUSD" --daemonize --pidfile qemusd.$$.pid --blockdev "driver=qcow2,file.driver=file,file.filename=$TMPIMG,node-name=disk0" --nbd-server addr.type=unix,addr.path=/tmp/nbd.sock --export type=nbd,id=exp0,node-name=disk0,name=disk0,writable=on + "$NBDCL" -unix /tmp/nbd.sock -N disk0 -b "$BLOCKSIZE" "$NBD" sleep 1 mount "$NBD"p1 "$WORK" else @@ -79,7 +89,9 @@ prepare() { # mount proc, sys, dev mount -t proc proc "$WORK/proc" mount -t sysfs sys "$WORK/sys" - mount -o bind /dev "$WORK/dev" + mount -t devtmpfs udev "$WORK/dev" + mkdir -p "$WORK/dev/pts" + mount -t devpts devpts "$WORK/dev/pts" # prevent service activation (will be deleted by finalize) echo -e '#!/bin/sh\nexit 101' >"$WORK/usr/sbin/policy-rc.d" @@ -122,32 +134,39 @@ EOF # making sure we have no remaining process fuser --kill --ismountpoint --mount "$WORK" && sleep 1 || true - umount "$WORK/proc" "$WORK/sys" "$WORK/dev" || umount -l "$WORK/proc" "$WORK/sys" "$WORK/dev" || true + # unmount all mounts under $WORK (in reverse order, deepest first) + grep " $WORK/" /proc/self/mounts | cut -d' ' -f2 | sort -r | while read mnt; do + umount "$mnt" 2>/dev/null || umount -l "$mnt" 2>/dev/null || true + done - # build squashfs image if requested NOW - if [ x"$MKSQUASHFS" != x ]; then - mksquashfs "$WORK" "$1-$DATE.squashfs" -comp xz -noappend -progress - fi + # build squashfs image + mksquashfs "$WORK" "$1-$DATE.squashfs" -comp xz -noappend -progress echo "Syncing..." umount "$WORK" - "$QEMUNBD" -d "$NBD" + "$NBDCL" -d "$NBD" + sleep 0.5 + if [ -f qemusd.$$.pid ]; then + kill $(cat qemusd.$$.pid ) + sleep 0.5 + fi - echo "Converting image..." - # somehow qemuimg cannot output to stdout - "$QEMUIMG" convert -f qcow2 -O raw "work$$.qcow2" "$1-$DATE.raw" - # keep result too + "$QEMUIMG" convert -c -p -f qcow2 -O qcow2 "work$$.qcow2" "$1-$DATE.qcow2" mv -f "work$$.qcow2" "$1.qcow2" if [ ! -d rbdconv ]; then # grab rbdconv git clone https://github.com/Shells-com/rbdconv.git fi + # need to convert to raw file first so that raw-to-rbd.php can get the filesize first + "$QEMUIMG" convert -f qcow2 -O raw "$1-$DATE.qcow2" "$1-$DATE.raw" php rbdconv/raw-to-rbd.php "$1-$DATE.raw" | xz -z -9 -T $(nproc --ignore=4) -v >"$1-$DATE.shells" rm -f "$1-$DATE.raw" + go run github.com/KarpelesLab/rest/cli/restupload@latest -api Shell/OS:uploadOfficialImage -params "blocksize=$BLOCKSIZE" "$1-$DATE.qcow2" "$1-$DATE.squashfs" "$1-$DATE.shells" + # complete, list the file - ls -la "$1-$DATE.shells" + ls -la "$1-$DATE.qcow2" } add_firstrun() { @@ -158,7 +177,7 @@ add_firstrun() { local AFTER="$1" if [ x"$AFTER" = x ]; then # can also be NetworkManager-wait-online.service - AFTER="systemd-networkd-wait-online.service" + AFTER="network-online.target" fi if [ -d "$WORK/usr/lib/systemd/system" ]; then @@ -186,5 +205,8 @@ WantedBy=sysinit.target EOF # enable run systemctl enable cloud-firstrun + else + echo "No systemd found!" + exit 1 fi } diff --git a/scripts/docker.sh b/scripts/docker.sh index 079f3b5..a6f5069 100644 --- a/scripts/docker.sh +++ b/scripts/docker.sh @@ -6,30 +6,22 @@ docker_get() { # $1 $2 # for example: docker_get fedora 33 - if [ -f "docker_$1_$2.tar.xz" ]; then + local NAME_SAN=`echo "$1" | sed -e 's#/#_#g'` + + if [ -f "docker_${NAME_SAN}_$2.tar.xz" ]; then return fi echo "Grabbing $1:$2 from docker..." docker pull "$1:$2" - local NAME_SAN=`echo "$1" | sed -e 's#/#_#g'` - echo "Extracting..." - DOCKERTMP="docker$$" - mkdir "$DOCKERTMP" - docker save "$1:$2" | tar -xC "$DOCKERTMP" - local LAYER="$(find "$DOCKERTMP" -mindepth 1 -type d \! -name 'lost+found')" - if [ $(echo "$LAYER" | wc -l) -eq 1 ]; then - # all good - mv "$LAYER/layer.tar" "docker_${NAME_SAN}_$2.tar" - rm -fr "$DOCKERTMP" - xz -z -9 -T 16 -v "docker_${NAME_SAN}_$2.tar" - else - rm -fr "$DOCKERTMP" - echo "Failed to extract: image contains more than one layer" - exit 1 - fi + # Create a throwaway container and export its merged rootfs + cid=$(docker create --platform=linux/amd64 "$1:$2") + docker export "$cid" -o "docker_${NAME_SAN}_$2.tar" + docker rm "$cid" + + xz -z -9 -T 16 -v "docker_${NAME_SAN}_$2.tar" } docker_prepare() { diff --git a/scripts/firstrun.sh b/scripts/firstrun.sh index 50bce40..7237b03 100755 --- a/scripts/firstrun.sh +++ b/scripts/firstrun.sh @@ -29,6 +29,7 @@ if [ x"$SYSTEM_UUID" = x"bdef7bde-f7bd-ef7b-def7-bdef7bdef7bd" ]; then SHELLS_USERNAME="test" SHELLS_SSH="" SHELLS_TZ="UTC" + SHELLS_LOCALE="en-US" SHELLS_SHADOW='' SHELLS_CMD="" else @@ -40,6 +41,7 @@ else SHELLS_USERNAME="$(curl -s -H "X-shells-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/username")" SHELLS_SSH="$(curl -s -H "X-shells-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/public-keys/*/openssh-key")" SHELLS_TZ="$(curl -s -H "X-shells-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/timezone")" + SHELLS_LOCALE="$(curl -s -H "X-shells-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/locale")" SHELLS_SHADOW='' SHELLS_CMD="$(curl -s -H "X-shells-metadata-token: $TOKEN" "http://169.254.169.254/latest/meta-data/firstrun")" fi @@ -94,9 +96,10 @@ if [ x"$SHELLS_USERNAME" != x ]; then [[ -d /run/openrc ]] && sed -i -e 's/^.*minimum-vt=.*/minimum-vt=7/' /etc/lightdm/lightdm.conf.d/70-xubuntu.conf gpasswd -a "${SHELLS_USERNAME}" autologin echo [SeatDefaults] > /etc/lightdm/lightdm.conf.d/70-xubuntu.conf + echo user-session=xubuntu >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf echo autologin-user=${SHELLS_USERNAME} >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf echo autologin-user-timeout=0 >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf - echo user-session=xubuntu >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf + echo session-cleanup-script=pkill -P1 -fx /usr/sbin/lightdm >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf echo pam-autologin-service=lightdm-autologin >> /etc/lightdm/lightdm.conf.d/70-xubuntu.conf echo "auth sufficient pam_succeed_if.so user ingroup nopasswdlogin" >> /etc/pam.d/lightdm groupadd -r nopasswdlogin @@ -133,6 +136,7 @@ if [ x"$SHELLS_USERNAME" != x ]; then sed -i "/\[daemon]/a AutomaticLoginEnable=True" /etc/gdm3/custom.conf elif [ -f /etc/gdm3/daemon.conf ]; then # replace "# AutomaticLogin" → " AutomaticLogin = xxx" #Debian has daemon.conf instead of custom.conf + sed -i "/\[daemon]/a WaylandEnable=false" "/etc/gdm3/daemon.conf" sed -i -r -e "s/#( *)AutomaticLogin/\1AutomaticLogin/;s/AutomaticLogin =.*/AutomaticLogin = $SHELLS_USERNAME/" "/etc/gdm3/daemon.conf" fi if [ -f /etc/gdm/custom.conf ]; then diff --git a/scripts/linux.sh b/scripts/linux.sh index ab72f89..06cf184 100644 --- a/scripts/linux.sh +++ b/scripts/linux.sh @@ -7,7 +7,7 @@ do_linux_config() { do_linux_init_config() { # initial config for all linux installs - cat "$WORK/etc/group" | grep -q ^shellsmgmt: || run groupadd shellsmgmt + cat "$WORK/etc/group" | grep -q ^shellsmgmt: || run /usr/sbin/groupadd shellsmgmt } do_linux_polkit_config() { diff --git a/scripts/qemu.sh b/scripts/qemu.sh index fe5e0b6..66e75ba 100644 --- a/scripts/qemu.sh +++ b/scripts/qemu.sh @@ -32,7 +32,7 @@ doqemu() { exit 1 esac - local QEMUSYS="$(which "qemu-system-$ARCH")" + local QEMUSYS="$(command -v "qemu-system-$ARCH")" OPTS=( -name guest=shell-xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx,debug-threads=on @@ -57,11 +57,12 @@ doqemu() { -device pcie-root-port,port=0x14,chassis=7,id=pci.7,bus=pcie.0,addr=0x2.0x4 -device pcie-root-port,port=0x15,chassis=2,id=pci3.1,bus=pcie.0,multifunction=on,addr=0x3 -device qemu-xhci,p2=8,p3=8,id=usb,bus=pci.4,addr=0x0 + #-device nec-usb-xhci,p2=8,p3=8,id=usb,bus=pci.4,addr=0x0 -device usb-ehci,bus=pci.2,addr=0x2,id=ehci -device virtio-serial-pci,id=virtio-serial0,bus=pci.5,addr=0x0 -blockdev "{\"driver\":\"file\",\"filename\":\"$DISK\",\"node-name\":\"libvirt-1-storage\",\"auto-read-only\":true,\"discard\":\"unmap\"}" -blockdev '{"node-name":"libvirt-1-format","read-only":false,"driver":"qcow2","file":"libvirt-1-storage"}' - -device virtio-blk-pci,bus=pci.6,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1 + -device virtio-blk-pci,bus=pci.6,addr=0x0,drive=libvirt-1-format,id=virtio-disk0,bootindex=1,logical_block_size=$BLOCKSIZE,physical_block_size=$BLOCKSIZE,min_io_size=$BLOCKSIZE,opt_io_size=1048576 -netdev user,id=hostnet0,hostfwd=tcp::10022-:22 #-netdev socket,id=hostnet0,connect=:4221 -device virtio-net-pci,netdev=hostnet0,id=net0,mac=d2:89:f4:90:ee:76,bus=pci.3,addr=0x0 @@ -76,7 +77,7 @@ doqemu() { -chardev vc,id=ttyUSB1 -device usb-serial,chardev=ttyUSB1,id=serialu1,bus=usb.0,port=3 - -chardev socket,id=charchannel0,path=/tmp/qga.sock,server,nowait + -chardev socket,id=charchannel0,path=/tmp/qga.sock,server=on,wait=off -device virtserialport,bus=virtio-serial0.0,nr=1,chardev=charchannel0,id=channel0,name=org.qemu.guest_agent.0 -chardev spicevmc,id=charchannel1,name=vdagent -device virtserialport,bus=virtio-serial0.0,nr=2,chardev=charchannel1,id=channel1,name=com.redhat.spice.0 @@ -89,6 +90,7 @@ doqemu() { -device "$VIDEO,id=video0,bus=pcie.0,addr=0x1" -device intel-hda,id=sound0,bus=pci.2,addr=0x1 -device hda-duplex,id=sound0-codec0,bus=sound0.0,cad=0 + -audio driver=none #-chardev spicevmc,id=charredir0,name=usbredir #-device usb-redir,chardev=charredir0,id=redir0,bus=usb.0,port=2 #-chardev spicevmc,id=charredir1,name=usbredir @@ -114,9 +116,9 @@ qemukernel() { if [ -f shells-kernel/guest-linux-x86_64/release.txt ]; then KVER="$(cat shells-kernel/guest-linux-x86_64/release.txt)" fi - if [ x"$KVER" != x"5.10.31-shells" ]; then - getfile shells-kernel-5.10.31-fe0a4ff.tar.bz2 fe0a4ff57894e8413930824394589282dbc5ff4c379ad1b207a60333dfedad6f - tar xjf shells-kernel-5.10.31-fe0a4ff.tar.bz2 + if [ x"$KVER" != x"6.12.47-shells" ]; then + getfile shells-kernel-6.12.47-9171e9f.tar.bz2 9171e9fb4e0519f266b3106a6d2257168f7babca2705ea4ddd37f4981d66410c + tar xjf shells-kernel-6.12.47-9171e9f.tar.bz2 fi if [ x"$ARCH" = x ]; then