mirror of
https://github.com/philmmanjaro/alma.git
synced 2025-12-06 19:29:21 +01:00
[presets] add steamos files
This commit is contained in:
256
presets/steam/steamos/bin/gamescope-session
Executable file
256
presets/steam/steamos/bin/gamescope-session
Executable file
@@ -0,0 +1,256 @@
|
||||
#!/bin/bash
|
||||
|
||||
##
|
||||
## Session globals
|
||||
##
|
||||
export SDL_VIDEO_MINIMIZE_ON_FOCUS_LOSS=0
|
||||
|
||||
export HOMETEST_DESKTOP=1
|
||||
export HOMETEST_DESKTOP_SESSION=plasma
|
||||
|
||||
export STEAM_USE_MANGOAPP=1
|
||||
export MANGOHUD_CONFIGFILE=$(mktemp /tmp/mangohud.XXXXXXXX)
|
||||
export MANGOAPP=1
|
||||
|
||||
export STEAM_USE_DYNAMIC_VRS=1
|
||||
export RADV_FORCE_VRS_CONFIG_FILE=$(mktemp /tmp/radv_vrs.XXXXXXXX)
|
||||
|
||||
# Initially write no_display to our config file
|
||||
# so we don't get mangoapp showing up before Steam initializes
|
||||
# on OOBE and stuff.
|
||||
mkdir -p "$(dirname "$MANGOHUD_CONFIGFILE")"
|
||||
echo "no_display" > "$MANGOHUD_CONFIGFILE"
|
||||
|
||||
# Prepare our initial VRS config file
|
||||
# for dynamic VRS in Mesa.
|
||||
mkdir -p "$(dirname "$RADV_FORCE_VRS_CONFIG_FILE")"
|
||||
echo "1x1" > "$RADV_FORCE_VRS_CONFIG_FILE"
|
||||
|
||||
# Let's try this across the board to see if it breaks anything
|
||||
# Helps performance in HZD, Cyberpunk, at least
|
||||
# Expose 8 physical cores, instead of 4c/8t
|
||||
export WINE_CPU_TOPOLOGY=8:0,1,2,3,4,5,6,7
|
||||
|
||||
# To expose vram info from radv's patch we're including
|
||||
export WINEDLLOVERRIDES=dxgi=n
|
||||
|
||||
# Workaround for steam getting killed immediatly during reboot
|
||||
# See: jupiter/tasks/-/issues/280
|
||||
export STEAMOS_STEAM_REBOOT_SENTINEL="/tmp/steamos-reboot-sentinel"
|
||||
if [[ -e "$STEAMOS_STEAM_REBOOT_SENTINEL" ]]; then
|
||||
rm -f "$STEAMOS_STEAM_REBOOT_SENTINEL"
|
||||
/usr/bin/steamos-polkit-helpers/steamos-reboot-now
|
||||
sudo -n reboot
|
||||
fi
|
||||
|
||||
# Workaround for steam getting killed immediatly during shutdown
|
||||
# Same idea as reboot sentinel above
|
||||
export STEAMOS_STEAM_SHUTDOWN_SENTINEL="/tmp/steamos-shutdown-sentinel"
|
||||
if [[ -e "$STEAMOS_STEAM_SHUTDOWN_SENTINEL" ]]; then
|
||||
rm -f "$STEAMOS_STEAM_SHUTDOWN_SENTINEL"
|
||||
/usr/bin/steamos-polkit-helpers/steamos-poweroff-now
|
||||
sudo -n poweroff
|
||||
fi
|
||||
|
||||
# Enable volume key management via steam for this session
|
||||
export STEAM_ENABLE_VOLUME_HANDLER=1
|
||||
|
||||
# Have SteamRT's xdg-open send http:// and https:// URLs to Steam
|
||||
export SRT_URLOPEN_PREFER_STEAM=1
|
||||
|
||||
# Disable automatic audio device switching in steam, now handled by wireplumber
|
||||
export STEAM_DISABLE_AUDIO_DEVICE_SWITCHING=1
|
||||
|
||||
# Enable support for xwayland isolation per-game in Steam
|
||||
export STEAM_MULTIPLE_XWAYLANDS=1
|
||||
|
||||
# We have the Mesa integration for the fifo-based dynamic fps-limiter
|
||||
export STEAM_GAMESCOPE_DYNAMIC_FPSLIMITER=1
|
||||
|
||||
# Don't wait for buffers to idle on the client side before sending them to gamescope
|
||||
export vk_xwayland_wait_ready=false
|
||||
|
||||
# Set input method modules for Qt/GTK that will show the Steam keyboard
|
||||
export QT_IM_MODULE=steam
|
||||
export GTK_IM_MODULE=Steam
|
||||
|
||||
# TODO!
|
||||
# Bring this back when gamescope side is more complete
|
||||
#
|
||||
# Remove vsync handling from Xwayland, we handle it in gamescope
|
||||
#export vblank_mode=0
|
||||
#export MESA_VK_WSI_PRESENT_MODE=immediate
|
||||
|
||||
# To play nice with the short term callback-based limiter for now
|
||||
export GAMESCOPE_LIMITER_FILE=$(mktemp /tmp/gamescope-limiter.XXXXXXXX)
|
||||
|
||||
export XCURSOR_THEME=steam
|
||||
|
||||
# Workaround for Steam login issue while Steam client change propagates out of Beta
|
||||
touch ~/.steam/root/config/SteamAppData.vdf || true
|
||||
|
||||
export STEAM_UPDATEUI_PNG_BACKGROUND=/usr/share/steamos/steamos.png
|
||||
|
||||
ulimit -n 524288
|
||||
|
||||
# Create run directory file for startup and stats sockets
|
||||
# shellcheck disable=SC2030 # (broken warning)
|
||||
tmpdir="$([[ -n ${XDG_RUNTIME_DIR+x} ]] && mktemp -p "$XDG_RUNTIME_DIR" -d -t gamescope.XXXXXXX)"
|
||||
socket="${tmpdir:+$tmpdir/startup.socket}"
|
||||
stats="${tmpdir:+$tmpdir/stats.pipe}"
|
||||
# Fail early if we don't have a proper runtime directory setup
|
||||
# shellcheck disable=SC2031 # (broken warning)
|
||||
if [[ -z $tmpdir || -z ${XDG_RUNTIME_DIR+x} ]]; then
|
||||
echo >&2 "!! Failed to find run directory in which to create stats session sockets (is \$XDG_RUNTIME_DIR set?)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# 1048576 = 1M - passing it like that omits the 'M' suffix - xargs removes whitespace
|
||||
free_disk_space_megs=$(df ~/ --output=avail -B1048576 | sed -n '2 p' | xargs)
|
||||
minimum_free_disk_space_needed_megs=500
|
||||
|
||||
if [[ "$free_disk_space_megs" -lt "$minimum_free_disk_space_needed_megs" ]]; then
|
||||
echo >&2 "gamescope-session: not enough disk space to proceed, trying to find game to delete"
|
||||
|
||||
find ~/.local/share/Steam/steamapps/common/ -mindepth 1 -maxdepth 1 -type d -printf "%T@ %p\0" | sort -n -z | while IFS= read -r -d $'\0' line; do
|
||||
timestamp=${line%% *}
|
||||
game_folder=${line#* }
|
||||
|
||||
[[ -d $game_folder ]] || continue
|
||||
|
||||
acf=$(grep -F -- "$(basename -- "$game_folder")" ~/.local/share/Steam/steamapps/*.acf | grep \"installdir\" | cut -d: -f1)
|
||||
[[ -e "$acf" ]] || continue
|
||||
|
||||
echo >&2 "gamescope-session: deleting $(basename "$game_folder")"
|
||||
appid=$(basename "$acf" | cut -d_ -f2 | cut -d. -f1)
|
||||
|
||||
# TODO leave a note for Steam to display UI to explain what happened, if this logic stays
|
||||
# intentionally leave compatdata; could be unclouded save files there
|
||||
rm -rf --one-file-system -- "$game_folder" "$acf" ~/.local/share/Steam/steamapps/shadercache/"$appid"
|
||||
|
||||
free_disk_space_megs=$(df ~/ --output=avail -B1048576 | sed -n '2 p' | xargs)
|
||||
[[ "$free_disk_space_megs" -lt "$minimum_free_disk_space_needed_megs" ]] || break
|
||||
done
|
||||
fi
|
||||
|
||||
export GAMESCOPE_STATS="$stats"
|
||||
mkfifo -- "$stats"
|
||||
mkfifo -- "$socket"
|
||||
|
||||
# Attempt to claim global session if we're the first one running (e.g. /run/1000/gamescope)
|
||||
linkname="gamescope-stats"
|
||||
# shellcheck disable=SC2031 # (broken warning)
|
||||
sessionlink="${XDG_RUNTIME_DIR:+$XDG_RUNTIME_DIR/}${linkname}" # Account for XDG_RUNTIME_DIR="" (notfragileatall)
|
||||
lockfile="$sessionlink".lck
|
||||
exec 9>"$lockfile" # Keep as an fd such that the lock lasts as long as the session if it is taken
|
||||
if flock -n 9 && rm -f "$sessionlink" && ln -sf "$tmpdir" "$sessionlink"; then
|
||||
# Took the lock. Don't blow up if those commands fail, though.
|
||||
echo >&2 "Claimed global gamescope stats session at \"$sessionlink\""
|
||||
else
|
||||
echo >&2 "!! Failed to claim global gamescope stats session"
|
||||
fi
|
||||
|
||||
gamescope \
|
||||
--generate-drm-mode fixed \
|
||||
--xwayland-count 2 \
|
||||
-w 1280 -h 800 \
|
||||
--default-touch-mode 4 \
|
||||
--hide-cursor-delay 3000 \
|
||||
--max-scale 2 \
|
||||
--fade-out-duration 200 \
|
||||
-e -R "$socket" -T "$stats" \
|
||||
-O '*',eDP-1 \
|
||||
--cursor-hotspot 5,3 --cursor /usr/share/steamos/steamos-cursor.png \
|
||||
&
|
||||
gamescope_pid="$!"
|
||||
|
||||
if read -r -t 3 response_x_display response_wl_display <> "$socket"; then
|
||||
export DISPLAY="$response_x_display"
|
||||
export GAMESCOPE_WAYLAND_DISPLAY="$response_wl_display"
|
||||
# We're done!
|
||||
else
|
||||
kill -9 "$gamescope_pid"
|
||||
wait
|
||||
exit 0
|
||||
# SDDM will restart us
|
||||
fi
|
||||
|
||||
xbindkeys -f /etc/xbindkeysrc
|
||||
|
||||
steamargs=("-steamos3" "-steampal" "-steamdeck" "-gamepadui")
|
||||
|
||||
# steamargs+=("-steamfs")
|
||||
|
||||
(while true; do
|
||||
/usr/lib/hwsupport/power-button-handler.py
|
||||
done) &
|
||||
|
||||
|
||||
short_session_tracker_file="/tmp/steamos-short-session-tracker"
|
||||
short_session_duration=60
|
||||
short_session_count_before_reset=3
|
||||
SECONDS=0
|
||||
|
||||
short_session_count=$(< "$short_session_tracker_file" wc -l)
|
||||
|
||||
if [[ "$short_session_count" -ge "$short_session_count_before_reset" ]]; then
|
||||
# TODO could detect if we're in the devkit case below and undo that instead
|
||||
# instead of resetting the wrong thing
|
||||
# also could print full list of files and sizes in the Steam dir and save as a diagnostic report
|
||||
echo >&2 "gamescope-session: detected broken Steam, bootstrapping from OS copy..."
|
||||
mkdir -p ~/.local/share/Steam
|
||||
# remove some caches and stateful things known to cause Steam to fail to start if corrupt
|
||||
rm -rf --one-file-system ~/.local/share/Steam/config/widevine
|
||||
# restore clean copy of binaries from RO partition
|
||||
tar xf /usr/lib/steam/bootstraplinux_ubuntu12_32.tar.xz -C ~/.local/share/Steam
|
||||
# rearm
|
||||
rm "$short_session_tracker_file"
|
||||
fi
|
||||
|
||||
if [[ -x $HOME/devkit-game/devkit-steam ]]; then
|
||||
mangoapp &
|
||||
"$HOME"/devkit-game/devkit-steam "${steamargs[@]}"
|
||||
else
|
||||
mangoapp &
|
||||
steam "${steamargs[@]}"
|
||||
fi
|
||||
|
||||
if [[ "$SECONDS" -lt "$short_session_duration" ]]; then
|
||||
echo "frog" >> "$short_session_tracker_file"
|
||||
else
|
||||
rm "$short_session_tracker_file"
|
||||
fi
|
||||
|
||||
# Ask gamescope to exit nicely
|
||||
kill $gamescope_pid
|
||||
|
||||
# Start a background sleep for five seconds because we don't trust it
|
||||
sleep 5 &
|
||||
sleep_pid=$!
|
||||
|
||||
# Wait for gamescope or the sleep to finish for timeout purposes
|
||||
ret=0
|
||||
wait -n $gamescope_pid $sleep_pid || ret=$?
|
||||
|
||||
# If we get a SIGTERM/etc while waiting this happens. Proceed to kill -9 everything but complain
|
||||
if [[ $ret = 127 ]]; then
|
||||
echo >&2 "gamescope-session: Interrupted while waiting on teardown, force-killing remaining tasks"
|
||||
fi
|
||||
|
||||
# Kill all remaining jobs and warn if unexpected things are in there (should be just sleep_pid, unless gamescope failed
|
||||
# to exit in time or we hit the interrupt case above)
|
||||
for job in $(jobs -p); do
|
||||
# Warn about unexpected things
|
||||
if [[ $ret != 127 && $job = "$gamescope_pid" ]]; then
|
||||
echo >&2 "gamescope-session: gamescope timed out while exiting, killing"
|
||||
elif [[ $ret != 127 && $job != "$sleep_pid" ]]; then
|
||||
echo >&2 "gamescope-session: unexpected background pid $job at teardown: "
|
||||
# spew some debug about it
|
||||
ps -p "$job" >&2
|
||||
fi
|
||||
kill -9 "$job"
|
||||
done
|
||||
|
||||
# This should just be waiting on kill -9'd things. Another signal will cause us to give up, but we should be a little
|
||||
# stubborn about not letting the session die with gamescope holding on to things.
|
||||
wait
|
||||
12
presets/steam/steamos/bin/gamescope-wayland-teardown-workaround
Executable file
12
presets/steam/steamos/bin/gamescope-wayland-teardown-workaround
Executable file
@@ -0,0 +1,12 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
TARGETS=('/bin/bash /usr/bin/gamescope-session'
|
||||
'/usr/bin/kwin_x11')
|
||||
|
||||
for target in "${TARGETS[@]}"; do
|
||||
for processtree in $(pgrep -xf "$target" || true); do
|
||||
kill -- "-$processtree"
|
||||
done
|
||||
done
|
||||
246
presets/steam/steamos/bin/pacman-db-upgrade
Executable file
246
presets/steam/steamos/bin/pacman-db-upgrade
Executable file
@@ -0,0 +1,246 @@
|
||||
#!/usr/bin/bash -e
|
||||
#
|
||||
# pacman-db-upgrade - upgrade the local pacman db to a newer format
|
||||
#
|
||||
# Copyright (c) 2010-2021 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# Avoid creating world-unreadable files
|
||||
umask 022
|
||||
|
||||
# gettext initialization
|
||||
export TEXTDOMAIN='pacman-scripts'
|
||||
export TEXTDOMAINDIR='/usr/share/locale'
|
||||
|
||||
declare -r myver='6.0.1'
|
||||
|
||||
LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
|
||||
|
||||
# Import libmakepkg
|
||||
source "$LIBRARY"/util/message.sh
|
||||
source "$LIBRARY"/util/parseopts.sh
|
||||
|
||||
usage() {
|
||||
printf "pacman-db-upgrade (pacman) %s\n" "${myver}"
|
||||
echo
|
||||
printf -- "$(gettext "Upgrade the local pacman database to a newer format")\n"
|
||||
echo
|
||||
printf -- "$(gettext "Usage: %s [options]")\n" "$0"
|
||||
echo
|
||||
printf -- "$(gettext "options:")\n"
|
||||
printf -- "$(gettext " -d, --dbpath <path> set an alternate database location")\n"
|
||||
printf -- "$(gettext " -h, --help show this help message and exit")\n"
|
||||
printf -- "$(gettext " -r, --root <path> set an alternate installation root")\n"
|
||||
printf -- "$(gettext " -V, --version show version information and exit")\n"
|
||||
printf -- "$(gettext " --config <path> set an alternate configuration file")\n"
|
||||
printf -- "$(gettext " --nocolor disable colorized output messages")\n"
|
||||
echo
|
||||
}
|
||||
|
||||
version() {
|
||||
printf "pacman-db-upgrade (pacman) %s\n" "$myver"
|
||||
printf -- "Copyright (c) 2010-2021 Pacman Development Team <pacman-dev@archlinux.org>.\n"
|
||||
printf '\n'
|
||||
printf -- "$(gettext "\
|
||||
This is free software; see the source for copying conditions.\n\
|
||||
There is NO WARRANTY, to the extent permitted by law.\n")"
|
||||
}
|
||||
|
||||
die() {
|
||||
error "$@"
|
||||
exit 1
|
||||
}
|
||||
|
||||
die_r() {
|
||||
rm -f "$lockfile"
|
||||
die "$@"
|
||||
}
|
||||
|
||||
resolve_dir() {
|
||||
local d="$(cd "$1"; pwd -P)"
|
||||
[[ $d == */ ]] || d+=/
|
||||
printf "%s" "$d"
|
||||
}
|
||||
|
||||
# PROGRAM START
|
||||
|
||||
# determine whether we have gettext; make it a no-op if we do not
|
||||
if ! type gettext &>/dev/null; then
|
||||
gettext() {
|
||||
echo "$@"
|
||||
}
|
||||
fi
|
||||
|
||||
USE_COLOR='y'
|
||||
|
||||
OPT_SHORT="d:hr:V"
|
||||
OPT_LONG=('config:' 'dbpath:' 'help' 'nocolor' 'root:' 'version')
|
||||
if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
|
||||
exit 1 # E_INVALID_OPTION
|
||||
fi
|
||||
set -- "${OPTRET[@]}"
|
||||
unset OPT_SHORT OPT_LONG OPTRET
|
||||
|
||||
while true; do
|
||||
case "$1" in
|
||||
--config) shift; conffile="$1" ;;
|
||||
-d|--dbpath) shift; dbroot="$1" ;;
|
||||
-r|--root) shift; pacroot="$1" ;;
|
||||
-h|--help) usage; exit 0 ;;
|
||||
--nocolor) USE_COLOR='n' ;;
|
||||
-V|--version) version; exit 0 ;;
|
||||
--) shift; break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
conffile=${conffile:-/etc/pacman.conf}
|
||||
[[ -z $pacroot ]] && pacroot=$(pacman-conf --config="$conffile" rootdir)
|
||||
[[ -z $dbroot ]] && dbroot=$(pacman-conf --config="$conffile" --rootdir="$pacroot" dbpath)
|
||||
|
||||
# check if messages are to be printed using color
|
||||
if [[ -t 2 && $USE_COLOR != "n" ]]; then
|
||||
colorize
|
||||
else
|
||||
unset ALL_OFF BOLD BLUE GREEN RED YELLOW
|
||||
fi
|
||||
|
||||
if [[ ! -d $dbroot ]]; then
|
||||
die "$(gettext "%s does not exist or is not a directory.")" "$dbroot"
|
||||
fi
|
||||
|
||||
if [[ ! -d $dbroot/local ]]; then
|
||||
die "$(gettext "%s is not a pacman database directory.")" "$dbroot"
|
||||
fi
|
||||
|
||||
if [[ ! -w $dbroot ]]; then
|
||||
die "$(gettext "You must have correct permissions to upgrade the database.")"
|
||||
fi
|
||||
|
||||
# strip any trailing slash from our dbroot
|
||||
dbroot="${dbroot%/}"
|
||||
# form the path to our lockfile location
|
||||
lockfile="${dbroot}/db.lck"
|
||||
|
||||
# make sure pacman isn't running
|
||||
if [[ -f $lockfile ]]; then
|
||||
die "$(gettext "Pacman lock file was found. Cannot run while pacman is running.")"
|
||||
fi
|
||||
# do not let pacman run while we do this
|
||||
touch "$lockfile"
|
||||
|
||||
if [[ -f "${dbroot}"/local/ALPM_DB_VERSION ]]; then
|
||||
db_version=$(cat "${dbroot}"/local/ALPM_DB_VERSION)
|
||||
fi
|
||||
|
||||
if [[ -z "$db_version" ]]; then
|
||||
# pacman-3.4 to 3.5 upgrade - merge depends into desc
|
||||
if [[ $(find "$dbroot"/local -name depends) ]]; then
|
||||
msg "$(gettext "Pre-3.5 database format detected - upgrading...")"
|
||||
for i in "$dbroot"/local/*; do
|
||||
if [[ -f "$i"/depends ]]; then
|
||||
cat "$i"/depends >> "$i"/desc
|
||||
rm "$i"/depends
|
||||
fi
|
||||
done
|
||||
msg "$(gettext "Done.")"
|
||||
fi
|
||||
|
||||
# pacman 4.1 to 4.2 upgrade - remove directory symlink support
|
||||
msg "$(gettext "Pre-4.2 database format detected - upgrading...")"
|
||||
|
||||
dirlist=()
|
||||
|
||||
unset GREP_OPTIONS
|
||||
while IFS= read -r dir; do
|
||||
dirlist+=("${pacroot}${dir%/}")
|
||||
done < <(grep -h '/$' "$dbroot"/local/*/files | sort -ru)
|
||||
|
||||
mapfile -t dirlist < <(
|
||||
for dir in "${dirlist[@]}"; do
|
||||
[[ -L "$dir" ]] && echo "$dir"
|
||||
done)
|
||||
|
||||
if [[ ${#dirlist[@]} != 0 ]]; then
|
||||
pacroot="$(resolve_dir "$pacroot")"
|
||||
|
||||
for dir in "${dirlist[@]}"; do
|
||||
realdir="$(resolve_dir "$dir")"
|
||||
|
||||
# verify realdir is inside root
|
||||
if [[ ${realdir:0:${#pacroot}} != "$pacroot" ]]; then
|
||||
warning "$(gettext "symlink '%s' points outside pacman root, manual repair required")" "$dir"
|
||||
continue
|
||||
fi
|
||||
|
||||
# convert to an appropriate form for the replacement
|
||||
olddir="${dir:${#pacroot}}/"
|
||||
newdir="${realdir:${#pacroot}}"
|
||||
|
||||
# construct the parents of the new directory
|
||||
parents=""
|
||||
parent="$(dirname "$newdir")"
|
||||
while [[ $parent != "." ]]; do
|
||||
parents+="$parent/\n"
|
||||
parent="$(dirname "$parent")"
|
||||
done
|
||||
|
||||
for f in "$dbroot"/local/*/files; do
|
||||
awk -v "olddir=$olddir" -v "newdir=$newdir" -v "parents=$parents" '
|
||||
function print_path(path) {
|
||||
if (path != "" && !(path in seen)) {
|
||||
seen[path] = 1
|
||||
print path
|
||||
}
|
||||
}
|
||||
BEGIN {
|
||||
oldlen = length(olddir) + 1
|
||||
file = substr(newdir, 0, length(newdir) - 1)
|
||||
}
|
||||
{
|
||||
if ($0 == "") {
|
||||
# end of section, clear seen paths and print as-is
|
||||
for ( i in seen ) {
|
||||
delete seen[i]
|
||||
}
|
||||
print
|
||||
} else if ($0 == olddir) {
|
||||
# replace symlink with its target, including parents
|
||||
split(parents, paths, "\n")
|
||||
for (i in paths) {
|
||||
print_path(paths[i])
|
||||
}
|
||||
print_path(newdir)
|
||||
} else if ($0 == file) {
|
||||
# newdir already existed as a file, skip it
|
||||
} else if (index($0, olddir) == 1) {
|
||||
# update paths that were under olddir
|
||||
print_path(newdir substr($0, oldlen))
|
||||
} else {
|
||||
# print everything else as-is
|
||||
print_path($0)
|
||||
}
|
||||
}' "$f" > "$f.tmp"
|
||||
mv "$f.tmp" "$f"
|
||||
done
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
echo "9" > "$dbroot"/local/ALPM_DB_VERSION
|
||||
|
||||
# remove the lock file
|
||||
rm -f "$lockfile"
|
||||
741
presets/steam/steamos/bin/pacman-key
Executable file
741
presets/steam/steamos/bin/pacman-key
Executable file
@@ -0,0 +1,741 @@
|
||||
#!/usr/bin/bash
|
||||
#
|
||||
# pacman-key - manages pacman's keyring
|
||||
# Based on apt-key, from Debian
|
||||
#
|
||||
# Copyright (c) 2010-2021 Pacman Development Team <pacman-dev@archlinux.org>
|
||||
#
|
||||
# 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; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
|
||||
# gettext initialization
|
||||
export TEXTDOMAIN='pacman-scripts'
|
||||
export TEXTDOMAINDIR='/usr/share/locale'
|
||||
|
||||
declare -r myver="6.0.1"
|
||||
|
||||
LIBRARY=${LIBRARY:-'/usr/share/makepkg'}
|
||||
|
||||
# Import libmakepkg
|
||||
source "$LIBRARY"/util/message.sh
|
||||
source "$LIBRARY"/util/parseopts.sh
|
||||
|
||||
# Options
|
||||
ADD=0
|
||||
DELETE=0
|
||||
EDITKEY=0
|
||||
EXPORT=0
|
||||
FINGER=0
|
||||
IMPORT=0
|
||||
IMPORT_TRUSTDB=0
|
||||
INIT=0
|
||||
KEYSERVER=''
|
||||
LISTKEYS=0
|
||||
LISTSIGS=0
|
||||
LSIGNKEY=0
|
||||
POPULATE=0
|
||||
RECEIVE=0
|
||||
REFRESH=0
|
||||
UPDATEDB=0
|
||||
USE_COLOR='y'
|
||||
VERIFY=0
|
||||
VERBOSE=0
|
||||
|
||||
usage() {
|
||||
printf "pacman-key (pacman) %s\n" ${myver}
|
||||
echo
|
||||
printf -- "$(gettext "Usage: %s [options] operation [targets]")\n" $(basename $0)
|
||||
echo
|
||||
printf -- "$(gettext "Manage pacman's list of trusted keys")\n"
|
||||
echo
|
||||
printf -- "$(gettext "Operations:")\n"
|
||||
printf -- "$(gettext " -a, --add Add the specified keys (empty for stdin)")\n"
|
||||
printf -- "$(gettext " -d, --delete Remove the specified keyids")\n"
|
||||
printf -- "$(gettext " -e, --export Export the specified or all keyids")\n"
|
||||
printf -- "$(gettext " -f, --finger List fingerprint for specified or all keyids")\n"
|
||||
printf -- "$(gettext " -l, --list-keys List the specified or all keys")\n"
|
||||
printf -- "$(gettext " -r, --recv-keys Fetch the specified keyids")\n"
|
||||
printf -- "$(gettext " -u, --updatedb Update the trustdb of pacman")\n"
|
||||
printf -- "$(gettext " -v, --verify Verify the file(s) specified by the signature(s)")\n"
|
||||
printf -- "$(gettext " --edit-key Present a menu for key management task on keyids")\n"
|
||||
printf -- "$(gettext " --import Imports pubring.gpg from dir(s)")\n"
|
||||
printf -- "$(gettext " --import-trustdb Imports ownertrust values from trustdb.gpg in dir(s)")\n"
|
||||
printf -- "$(gettext " --init Ensure the keyring is properly initialized")\n"
|
||||
printf -- "$(gettext " --list-sigs List keys and their signatures")\n"
|
||||
printf -- "$(gettext " --lsign-key Locally sign the specified keyid")\n"
|
||||
printf -- "$(gettext " --populate Reload the default keys from the (given) keyrings\n\
|
||||
in '%s'")\n" "/usr/share/pacman/keyrings"
|
||||
printf -- "$(gettext " --refresh-keys Update specified or all keys from a keyserver")\n"
|
||||
printf -- "$(gettext " --verbose Show extra information")\n"
|
||||
echo
|
||||
printf -- "$(gettext "Options:")\n"
|
||||
printf -- "$(gettext " --config <file> Use an alternate config file (instead of\n\
|
||||
'%s')")\n" "/etc/pacman.conf"
|
||||
printf -- "$(gettext " --gpgdir <dir> Set an alternate directory for GnuPG (instead\n\
|
||||
of '%s')")\n" "/etc/pacman.d/gnupg"
|
||||
printf -- "$(gettext " --keyserver <server-url> Specify a keyserver to use if necessary")\n"
|
||||
echo
|
||||
printf -- "$(gettext " -h, --help Show this help message and exit")\n"
|
||||
printf -- "$(gettext " -V, --version Show program version")\n"
|
||||
}
|
||||
|
||||
version() {
|
||||
printf "pacman-key (pacman) %s\n" "${myver}"
|
||||
printf -- "Copyright (c) 2010-2021 Pacman Development Team <pacman-dev@archlinux.org>.\n"
|
||||
printf '\n'
|
||||
printf -- "$(gettext "\
|
||||
This is free software; see the source for copying conditions.\n\
|
||||
There is NO WARRANTY, to the extent permitted by law.\n")"
|
||||
}
|
||||
|
||||
# read the config file "$1" which has key=value pairs, and return the key which
|
||||
# matches "$2". the equals sign between pairs may be surrounded by any amount
|
||||
# of whitespace. Optionally, "$3" can be specified which is the default value
|
||||
# when no key is found.
|
||||
get_from() {
|
||||
while IFS='=' read -r key value; do
|
||||
[[ -z $key || ${key:0:1} = '#' ]] && continue
|
||||
|
||||
if [[ ${key%% *} = "$2" && -n ${value##* } ]]; then
|
||||
echo "${value##* }"
|
||||
return 0
|
||||
fi
|
||||
done < "$1"
|
||||
if [[ -n "$3" ]]; then
|
||||
printf '%s\n' "$3"
|
||||
return 0
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
key_lookup_from_name() {
|
||||
local ids
|
||||
|
||||
mapfile -t ids < \
|
||||
<("${GPG_PACMAN[@]}" --search-keys --batch --with-colons "$1" 2>/dev/null |
|
||||
awk -F: '$1 == "pub" { print $2 }')
|
||||
|
||||
# only return success on non-ambiguous lookup
|
||||
case ${#ids[*]} in
|
||||
0)
|
||||
error "$(gettext "Failed to lookup key by name:") %s" "$name"
|
||||
return 1
|
||||
;;
|
||||
1)
|
||||
printf '%s' "${ids[0]}"
|
||||
return 0
|
||||
;;
|
||||
*)
|
||||
error "$(gettext "Key name is ambiguous:") %s" "$name"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
generate_master_key() {
|
||||
# Generate the master key, which will be in both pubring and secring
|
||||
msg "$(gettext "Generating pacman master key. This may take some time.")"
|
||||
|
||||
"${GPG_PACMAN[@]}" --gen-key --batch <<EOF
|
||||
%echo Generating pacman keyring master key...
|
||||
Key-Type: RSA
|
||||
Key-Length: 4096
|
||||
Key-Usage: sign
|
||||
Name-Real: Pacman Keyring Master Key
|
||||
Name-Email: pacman@localhost
|
||||
Expire-Date: 0
|
||||
%no-protection
|
||||
%commit
|
||||
%echo Done
|
||||
EOF
|
||||
}
|
||||
|
||||
secret_keys_available() {
|
||||
"${GPG_PACMAN[@]}" -K --with-colons | wc -l
|
||||
}
|
||||
|
||||
# Adds the given gpg.conf option if it is not present in the file.
|
||||
# Note that if we find it commented out, we won't add the option.
|
||||
# args: $1 conffile, $2 option-name, $3 (optional) option-value
|
||||
add_gpg_conf_option() {
|
||||
local conffile=$1; shift
|
||||
# looking for the option 'bare', only leading spaces or # chars allowed,
|
||||
# followed by at least one space and any other text or the end of line.
|
||||
if ! grep -q "^[[:space:]#]*$*\([[:space:]].*\)*$" "$conffile" &>/dev/null; then
|
||||
printf '%s\n' "$*" >> "$conffile"
|
||||
fi
|
||||
}
|
||||
|
||||
check_keyids_exist() {
|
||||
local ret=0
|
||||
for key in "$@"; do
|
||||
# Verify if the key exists in pacman's keyring
|
||||
if ! "${GPG_PACMAN[@]}" --list-keys "$key" &>/dev/null ; then
|
||||
error "$(gettext "The key identified by %s could not be found locally.")" "$key"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
if (( ret )); then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
key_is_lsigned() {
|
||||
secret_key=$("${GPG_PACMAN[@]}" --with-colons --list-secret-key --quiet | awk -F : 'NR==1 {print $5}')
|
||||
while IFS=: read -r type valid _ _ sign_key _; do
|
||||
if [[ $type != "sig" || $valid != "!" ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ "$sign_key" == "$secret_key" ]]; then
|
||||
return 0
|
||||
fi
|
||||
done < <("${GPG_PACMAN[@]}" --with-colons --check-signatures --quiet "$1")
|
||||
return 1
|
||||
}
|
||||
|
||||
key_is_revoked() {
|
||||
while IFS=: read -r type _ _ _ _ _ _ _ _ _ _ flags _; do
|
||||
if [[ $type != "pub" ]]; then
|
||||
continue
|
||||
fi
|
||||
if [[ $flags == *"D"* ]]; then
|
||||
return 0
|
||||
fi
|
||||
done < <("${GPG_PACMAN[@]}" --with-colons --list-key --quiet "$1")
|
||||
return 1
|
||||
}
|
||||
|
||||
initialize() {
|
||||
local conffile keyserv
|
||||
# Check for simple existence rather than for a directory as someone
|
||||
# may want to use a symlink here
|
||||
[[ -e ${PACMAN_KEYRING_DIR} ]] || mkdir -p -m 755 "${PACMAN_KEYRING_DIR}"
|
||||
|
||||
# keyring files
|
||||
[[ -f ${PACMAN_KEYRING_DIR}/pubring.gpg ]] || touch ${PACMAN_KEYRING_DIR}/pubring.gpg
|
||||
[[ -f ${PACMAN_KEYRING_DIR}/secring.gpg ]] || touch ${PACMAN_KEYRING_DIR}/secring.gpg
|
||||
[[ -f ${PACMAN_KEYRING_DIR}/trustdb.gpg ]] || "${GPG_PACMAN[@]}" --update-trustdb
|
||||
chmod 644 ${PACMAN_KEYRING_DIR}/{pubring,trustdb}.gpg
|
||||
chmod 600 ${PACMAN_KEYRING_DIR}/secring.gpg
|
||||
|
||||
# gpg.conf
|
||||
conffile="${PACMAN_KEYRING_DIR}/gpg.conf"
|
||||
[[ -f $conffile ]] || touch "$conffile"
|
||||
chmod 644 "$conffile"
|
||||
add_gpg_conf_option "$conffile" 'no-greeting'
|
||||
add_gpg_conf_option "$conffile" 'no-permission-warning'
|
||||
add_gpg_conf_option "$conffile" 'lock-never'
|
||||
add_gpg_conf_option "$conffile" 'keyserver-options' 'timeout=10'
|
||||
add_gpg_conf_option "$conffile" 'keyserver-options' 'import-clean'
|
||||
|
||||
local gpg_ver=$(gpg --version | awk '{print $3; exit}')
|
||||
if (( $(vercmp "$gpg_ver" 2.2.17) >= 0 )); then
|
||||
add_gpg_conf_option "$conffile" 'keyserver-options' 'no-self-sigs-only'
|
||||
fi
|
||||
|
||||
# gpg-agent.conf
|
||||
agent_conffile="${PACMAN_KEYRING_DIR}/gpg-agent.conf"
|
||||
[[ -f $agent_conffile ]] || touch "$agent_conffile"
|
||||
chmod 644 "$agent_conffile"
|
||||
add_gpg_conf_option "$agent_conffile" 'disable-scdaemon'
|
||||
|
||||
# set up a private signing key (if none available)
|
||||
if [[ $(secret_keys_available) -lt 1 ]]; then
|
||||
generate_master_key
|
||||
UPDATEDB=1
|
||||
fi
|
||||
}
|
||||
|
||||
check_keyring() {
|
||||
if [[ ! -r ${PACMAN_KEYRING_DIR}/pubring.gpg || \
|
||||
! -r ${PACMAN_KEYRING_DIR}/trustdb.gpg ]]; then
|
||||
error "$(gettext "You do not have sufficient permissions to read the %s keyring.")" "pacman"
|
||||
msg "$(gettext "Use '%s' to correct the keyring permissions.")" "pacman-key --init"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( (EXPORT || FINGER || LIST || VERIFY) && EUID != 0 )); then
|
||||
if ! grep -q "^[[:space:]]*lock-never[[:space:]]*$" ${PACMAN_KEYRING_DIR}/gpg.conf &>/dev/null; then
|
||||
error "$(gettext "You do not have sufficient permissions to run this command.")"
|
||||
msg "$(gettext "Use '%s' to correct the keyring permissions.")" "pacman-key --init"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if (( LSIGNKEY || POPULATE )); then
|
||||
if [[ $(secret_keys_available) -lt 1 ]]; then
|
||||
error "$(gettext "There is no secret key available to sign with.")"
|
||||
msg "$(gettext "Use '%s' to generate a default secret key.")" "pacman-key --init"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
populate_keyring() {
|
||||
local KEYRING_IMPORT_DIR='/usr/share/pacman/keyrings'
|
||||
|
||||
local keyring KEYRINGIDS=("$@")
|
||||
local ret=0
|
||||
if (( ${#KEYRINGIDS[*]} == 0 )); then
|
||||
# get list of all available keyrings
|
||||
shopt -s nullglob
|
||||
KEYRINGIDS=("$KEYRING_IMPORT_DIR"/*.gpg)
|
||||
shopt -u nullglob
|
||||
KEYRINGIDS=("${KEYRINGIDS[@]##*/}")
|
||||
KEYRINGIDS=("${KEYRINGIDS[@]%.gpg}")
|
||||
if (( ${#KEYRINGIDS[*]} == 0 )); then
|
||||
error "$(gettext "No keyring files exist in %s.")" "$KEYRING_IMPORT_DIR"
|
||||
ret=1
|
||||
fi
|
||||
else
|
||||
# verify listed keyrings exist
|
||||
for keyring in "${KEYRINGIDS[@]}"; do
|
||||
if [[ ! -f "$KEYRING_IMPORT_DIR/$keyring.gpg" ]]; then
|
||||
error "$(gettext "The keyring file %s does not exist.")" "$KEYRING_IMPORT_DIR/$keyring.gpg"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if (( ret )); then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Variable used for iterating on keyrings
|
||||
local keys key_id
|
||||
|
||||
# Add keys from requested keyrings
|
||||
for keyring in "${KEYRINGIDS[@]}"; do
|
||||
msg "$(gettext "Appending keys from %s.gpg...")" "$keyring"
|
||||
"${GPG_PACMAN[@]}" --quiet --import "${KEYRING_IMPORT_DIR}/${keyring}.gpg"
|
||||
done
|
||||
|
||||
# Read the trusted key IDs to an array. Because this is an ownertrust
|
||||
# file, we know we have the full 40 hex digit fingerprint values.
|
||||
# Format of ownertrust dump file:
|
||||
# 40CHARFINGERPRINTXXXXXXXXXXXXXXXXXXXXXXX:6:
|
||||
# 40CHARFINGERPRINTXXXXXXXXXXXXXXXXXXXXXXX:5:
|
||||
local -A trusted_ids
|
||||
for keyring in "${KEYRINGIDS[@]}"; do
|
||||
if [[ -s "${KEYRING_IMPORT_DIR}/${keyring}-trusted" ]]; then
|
||||
while IFS=: read key_id _; do
|
||||
# skip blank lines, comments; these are valid in this file
|
||||
[[ -z $key_id || ${key_id:0:1} = \# ]] && continue
|
||||
|
||||
if key_is_lsigned "$key_id" ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
# Mark this key to be lsigned
|
||||
trusted_ids[$key_id]=$keyring
|
||||
done < "${KEYRING_IMPORT_DIR}/${keyring}-trusted"
|
||||
fi
|
||||
done
|
||||
|
||||
local -A revoked_ids
|
||||
for keyring in "${KEYRINGIDS[@]}"; do
|
||||
if [[ -s $KEYRING_IMPORT_DIR/$keyring-revoked ]]; then
|
||||
while read -r key_id; do
|
||||
if key_is_revoked "$key_id" ; then
|
||||
continue
|
||||
fi
|
||||
|
||||
revoked_ids["$key_id"]=1
|
||||
done <"$KEYRING_IMPORT_DIR/$keyring-revoked"
|
||||
fi
|
||||
done
|
||||
|
||||
if (( ${#trusted_ids[@]} > 0 )); then
|
||||
msg "$(gettext "Locally signing trusted keys in keyring...")"
|
||||
lsign_keys "${!trusted_ids[@]}"
|
||||
msg "$(gettext "Importing owner trust values...")"
|
||||
for keyring in "${KEYRINGIDS[@]}"; do
|
||||
if [[ -s "${KEYRING_IMPORT_DIR}/${keyring}-trusted" ]]; then
|
||||
"${GPG_PACMAN[@]}" --import-ownertrust "${KEYRING_IMPORT_DIR}/${keyring}-trusted"
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if (( ${#revoked_ids[@]} > 0 )); then
|
||||
local key_count=0
|
||||
msg "$(gettext "Disabling revoked keys in keyring...")"
|
||||
for key_id in "${!revoked_ids[@]}"; do
|
||||
if (( VERBOSE )); then
|
||||
msg2 "$(gettext "Disabling key %s...")" "${key_id}"
|
||||
fi
|
||||
printf 'disable\nquit\n' | LANG=C "${GPG_PACMAN[@]}" --command-fd 0 --quiet --batch --edit-key "${key_id}" 2>/dev/null
|
||||
key_count=$((key_count+1))
|
||||
done
|
||||
if (( key_count )); then
|
||||
msg2 "$(gettext "Disabled %s keys.")" "${key_count}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
add_keys() {
|
||||
if ! "${GPG_PACMAN[@]}" --quiet --batch --import "$@" ; then
|
||||
error "$(gettext "A specified keyfile could not be added to the keyring.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
delete_keys() {
|
||||
check_keyids_exist "$@"
|
||||
if ! "${GPG_PACMAN[@]}" --quiet --batch --delete-key --yes "$@" ; then
|
||||
error "$(gettext "A specified key could not be removed from the keyring.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
edit_keys() {
|
||||
check_keyids_exist "$@"
|
||||
local ret=0
|
||||
for key in "$@"; do
|
||||
if ! "${GPG_PACMAN[@]}" --edit-key "$key" ; then
|
||||
error "$(gettext "The key identified by %s could not be edited.")" "$key"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
if (( ret )); then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
export_keys() {
|
||||
check_keyids_exist "$@"
|
||||
if ! "${GPG_PACMAN[@]}" --armor --export "$@" ; then
|
||||
error "$(gettext "A specified key could not be exported from the keyring.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
finger_keys() {
|
||||
check_keyids_exist
|
||||
if ! "${GPG_PACMAN[@]}" --batch --fingerprint "$@" ; then
|
||||
error "$(gettext "The fingerprint of a specified key could not be determined.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
import_trustdb() {
|
||||
local importdir
|
||||
local ret=0
|
||||
for importdir in "$@"; do
|
||||
if [[ -f "${importdir}/trustdb.gpg" ]]; then
|
||||
gpg --homedir "${importdir}" --export-ownertrust | \
|
||||
"${GPG_PACMAN[@]}" --import-ownertrust -
|
||||
if (( PIPESTATUS )); then
|
||||
error "$(gettext "%s could not be imported.")" "${importdir}/trustdb.gpg"
|
||||
ret=1
|
||||
fi
|
||||
else
|
||||
error "$(gettext "File %s does not exist and could not be imported.")" "${importdir}/trustdb.gpg"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
if (( ret )); then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
import() {
|
||||
local importdir
|
||||
local ret=0
|
||||
for importdir in "$@"; do
|
||||
if [[ -f "${importdir}/pubring.gpg" ]]; then
|
||||
if ! "${GPG_PACMAN[@]}" --quiet --batch --import "${importdir}/pubring.gpg" ; then
|
||||
error "$(gettext "%s could not be imported.")" "${importdir}/pubring.gpg"
|
||||
ret=1
|
||||
fi
|
||||
else
|
||||
error "$(gettext "File %s does not exist and could not be imported.")" "${importdir}/pubring.gpg"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
if (( ret )); then
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
list_keys() {
|
||||
check_keyids_exist
|
||||
if ! "${GPG_PACMAN[@]}" --batch --list-keys "$@" ; then
|
||||
error "$(gettext "A specified key could not be listed.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
list_sigs() {
|
||||
check_keyids_exist
|
||||
if ! "${GPG_PACMAN[@]}" --batch --list-sigs "$@" ; then
|
||||
error "$(gettext "A specified signature could not be listed.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
lsign_keys() {
|
||||
check_keyids_exist
|
||||
|
||||
local ret=0
|
||||
local key_count=0
|
||||
for key_id in "$@"; do
|
||||
if (( VERBOSE )); then
|
||||
msg2 "$(gettext "Locally signing key %s...")" "${key_id}"
|
||||
fi
|
||||
# we cannot use --yes here as gpg would still ask for confirmation if a key has more than one uid
|
||||
printf 'y\ny\n' | LANG=C "${GPG_PACMAN[@]}" --command-fd 0 --quiet --batch --lsign-key "${key_id}" 2>/dev/null
|
||||
if (( PIPESTATUS[1] )); then
|
||||
error "$(gettext "%s could not be locally signed.")" "${key_id}"
|
||||
ret=1
|
||||
fi
|
||||
key_count=$((key_count+1))
|
||||
done
|
||||
|
||||
if (( ret )); then
|
||||
exit 1
|
||||
fi
|
||||
if (( key_count )); then
|
||||
msg2 "$(gettext "Locally signed %s keys.")" "${key_count}"
|
||||
fi
|
||||
}
|
||||
|
||||
receive_keys() {
|
||||
local ret=0 name id keyids emails
|
||||
|
||||
# if the key is not a hex ID, do a lookup
|
||||
for name; do
|
||||
if [[ $name = ?(0x)+([0-9a-fA-F]) ]]; then
|
||||
keyids+=("$name")
|
||||
elif [[ $name = *@*.* ]]; then
|
||||
emails+=("$name")
|
||||
elif id=$(key_lookup_from_name "$name"); then
|
||||
keyids+=("$id")
|
||||
fi
|
||||
done
|
||||
|
||||
(( ${#keyids[*]}+${#emails[*]} > 0 )) || exit 1
|
||||
|
||||
if (( ${#emails[*]} > 0 )) && \
|
||||
! "${GPG_PACMAN[@]}" --auto-key-locate clear,nodefault,wkd,keyserver \
|
||||
--locate-key "${emails[@]}" ; then
|
||||
error "$(gettext "Remote key not fetched correctly from WKD or keyserver.")"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
if (( ${#keyids[*]} > 0 )) && ! "${GPG_PACMAN[@]}" --recv-keys "${keyids[@]}" ; then
|
||||
error "$(gettext "Remote key not fetched correctly from keyserver.")"
|
||||
ret=1
|
||||
fi
|
||||
|
||||
exit $ret
|
||||
}
|
||||
|
||||
refresh_keys() {
|
||||
local ret=0 ids masterkey emails
|
||||
|
||||
check_keyids_exist "$@"
|
||||
|
||||
# don't try to refresh the user's local masterkey
|
||||
masterkey="$("${GPG_PACMAN[@]}" --list-keys --with-colons pacman@localhost |
|
||||
awk -F: '$1 == "pub" { print $5 }')"
|
||||
|
||||
mapfile -t ids < \
|
||||
<("${GPG_PACMAN[@]}" --list-keys --with-colons "$@" |
|
||||
awk -F: '$1 == "pub" { print $5 }' | grep -vx "$masterkey")
|
||||
|
||||
for id in "${ids[@]}"; do
|
||||
mapfile -t emails < \
|
||||
<("${GPG_PACMAN[@]}" --list-keys --list-options show-only-fpr-mbox "$id" |
|
||||
awk '{print $2 }')
|
||||
|
||||
# first try looking up the key in a WKD (only works by email address)
|
||||
for email in "${emails[@]}"; do
|
||||
"${GPG_PACMAN[@]}" --locate-external-keys "$email" && break
|
||||
done
|
||||
|
||||
# if no key was found, fall back to using the keyservers (with the key fingerprint instead)
|
||||
if (( $? )) && ! "${GPG_PACMAN[@]}" --refresh-keys "$id"; then
|
||||
error "$(gettext "Could not update key: %s")" "$id"
|
||||
ret=1
|
||||
fi
|
||||
done
|
||||
|
||||
exit $ret
|
||||
}
|
||||
|
||||
verify_sig() {
|
||||
local ret=0 sig=$1 file=$2
|
||||
if [[ -z $file && -f ${sig%.*} ]]; then
|
||||
file=${sig%.*}
|
||||
fi
|
||||
if [[ -n $file ]]; then
|
||||
local files=("$sig" "$file")
|
||||
msg "Checking %s... (detached)" "$sig"
|
||||
else
|
||||
local files=("$sig")
|
||||
msg "Checking %s... (embedded)" "$sig"
|
||||
fi
|
||||
if grep -q 'BEGIN PGP SIGNATURE' "$sig"; then
|
||||
error "$(gettext "Cannot use armored signatures for packages: %s")" "$sig"
|
||||
exit 1
|
||||
fi
|
||||
if ! "${GPG_PACMAN[@]}" --status-fd 1 --verify "${files[@]}" | grep -qE '^\[GNUPG:\] TRUST_(FULLY|ULTIMATE).*$'; then
|
||||
error "$(gettext "The signature identified by %s could not be verified.")" "$sig"
|
||||
ret=1
|
||||
fi
|
||||
exit $ret
|
||||
}
|
||||
|
||||
updatedb() {
|
||||
msg "$(gettext "Updating trust database...")"
|
||||
if ! "${GPG_PACMAN[@]}" --batch --check-trustdb ; then
|
||||
error "$(gettext "Trust database could not be updated.")"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# PROGRAM START
|
||||
if ! type gettext &>/dev/null; then
|
||||
gettext() {
|
||||
echo "$@"
|
||||
}
|
||||
fi
|
||||
|
||||
OPT_SHORT="adefhlruvV"
|
||||
OPT_LONG=('add' 'config:' 'delete' 'edit-key' 'export' 'finger' 'gpgdir:'
|
||||
'help' 'import' 'import-trustdb' 'init' 'keyserver:' 'list-keys' 'list-sigs'
|
||||
'lsign-key' 'nocolor' 'populate' 'recv-keys' 'refresh-keys' 'updatedb'
|
||||
'verbose' 'verify' 'version')
|
||||
if ! parseopts "$OPT_SHORT" "${OPT_LONG[@]}" -- "$@"; then
|
||||
exit 1 # E_INVALID_OPTION
|
||||
fi
|
||||
set -- "${OPTRET[@]}"
|
||||
unset OPT_SHORT OPT_LONG OPTRET
|
||||
|
||||
if [[ $1 == "--" ]]; then
|
||||
usage
|
||||
exit 0
|
||||
fi
|
||||
|
||||
while (( $# )); do
|
||||
case $1 in
|
||||
-a|--add) ADD=1 UPDATEDB=1 ;;
|
||||
--config) shift; CONFIG=$1 ;;
|
||||
-d|--delete) DELETE=1 UPDATEDB=1 ;;
|
||||
--edit-key) EDITKEY=1 UPDATEDB=1 ;;
|
||||
-e|--export) EXPORT=1 ;;
|
||||
-f|--finger) FINGER=1 ;;
|
||||
--gpgdir) shift; PACMAN_KEYRING_DIR=$1 ;;
|
||||
--import) IMPORT=1 UPDATEDB=1 ;;
|
||||
--import-trustdb) IMPORT_TRUSTDB=1 UPDATEDB=1 ;;
|
||||
--init) INIT=1 ;;
|
||||
--keyserver) shift; KEYSERVER=$1 ;;
|
||||
-l|--list-keys) LISTKEYS=1 ;;
|
||||
--list-sigs) LISTSIGS=1 ;;
|
||||
--lsign-key) LSIGNKEY=1 UPDATEDB=1 ;;
|
||||
--nocolor) USE_COLOR='n';;
|
||||
--populate) POPULATE=1 UPDATEDB=1 ;;
|
||||
-r|--recv-keys) RECEIVE=1 UPDATEDB=1 ;;
|
||||
--refresh-keys) REFRESH=1 ;;
|
||||
-u|--updatedb) UPDATEDB=1 ;;
|
||||
--verbose) VERBOSE=1 ;;
|
||||
-v|--verify) VERIFY=1 ;;
|
||||
|
||||
-h|--help) usage; exit 0 ;;
|
||||
-V|--version) version; exit 0 ;;
|
||||
|
||||
--) shift; break ;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
# check if messages are to be printed using color
|
||||
if [[ -t 2 && $USE_COLOR != "n" ]]; then
|
||||
colorize
|
||||
else
|
||||
unset ALL_OFF BOLD BLUE GREEN RED YELLOW
|
||||
fi
|
||||
|
||||
if ! type -p gpg >/dev/null; then
|
||||
error "$(gettext "Cannot find the %s binary required for all %s operations.")" "gpg" "pacman-key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if (( (ADD || DELETE || EDITKEY || IMPORT || IMPORT_TRUSTDB || INIT || LSIGNKEY || POPULATE || RECEIVE || REFRESH || UPDATEDB) && EUID != 0 )); then
|
||||
error "$(gettext "%s needs to be run as root for this operation.")" "pacman-key"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
CONFIG=${CONFIG:-/etc/pacman.conf}
|
||||
if [[ ! -r "${CONFIG}" ]]; then
|
||||
error "$(gettext "%s configuration file '%s' not found.")" "pacman" "$CONFIG"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# if PACMAN_KEYRING_DIR isn't assigned, try to get it from the config
|
||||
# file, falling back on a hard default
|
||||
PACMAN_KEYRING_DIR=${PACMAN_KEYRING_DIR:-$(pacman-conf --config="$CONFIG" gpgdir)}
|
||||
|
||||
GPG_PACMAN=(gpg --homedir "${PACMAN_KEYRING_DIR}" --no-permission-warning)
|
||||
if [[ -n ${KEYSERVER} ]]; then
|
||||
GPG_PACMAN+=(--keyserver "${KEYSERVER}")
|
||||
fi
|
||||
|
||||
# check only a single operation has been given
|
||||
# don't include UPDATEDB in here as other opts can induce it
|
||||
numopt=$(( ADD + DELETE + EDITKEY + EXPORT + FINGER + IMPORT + IMPORT_TRUSTDB +
|
||||
INIT + LISTKEYS + LISTSIGS + LSIGNKEY + POPULATE + RECEIVE + REFRESH + VERIFY ))
|
||||
|
||||
case $numopt in
|
||||
0)
|
||||
if (( ! UPDATEDB )); then
|
||||
error "$(gettext "no operation specified (use -h for help)")"
|
||||
exit 1
|
||||
fi
|
||||
;;
|
||||
[!1])
|
||||
error "$(gettext "Multiple operations specified.")"
|
||||
msg "$(gettext "Please run %s with each operation separately.")" "pacman-key"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
# check for targets where needed
|
||||
if (( (ADD || DELETE || EDIT || IMPORT || IMPORT_TRUSTDB ||
|
||||
LSIGNKEY || RECEIVE || VERIFY) && $# == 0 )); then
|
||||
error "$(gettext "No targets specified")"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
(( ! INIT )) && check_keyring
|
||||
|
||||
(( ADD )) && add_keys "$@"
|
||||
(( DELETE )) && delete_keys "$@"
|
||||
(( EDITKEY )) && edit_keys "$@"
|
||||
(( EXPORT )) && export_keys "$@"
|
||||
(( FINGER )) && finger_keys "$@"
|
||||
(( IMPORT )) && import "$@"
|
||||
(( IMPORT_TRUSTDB)) && import_trustdb "$@"
|
||||
(( INIT )) && initialize
|
||||
(( LISTKEYS )) && list_keys "$@"
|
||||
(( LISTSIGS )) && list_sigs "$@"
|
||||
(( LSIGNKEY )) && lsign_keys "$@"
|
||||
(( POPULATE )) && populate_keyring "$@"
|
||||
(( RECEIVE )) && receive_keys "$@"
|
||||
(( REFRESH )) && refresh_keys "$@"
|
||||
(( VERIFY )) && verify_sig "$@"
|
||||
|
||||
(( UPDATEDB )) && updatedb
|
||||
|
||||
exit 0
|
||||
242
presets/steam/steamos/bin/pacman-system-update
Executable file
242
presets/steam/steamos/bin/pacman-system-update
Executable file
@@ -0,0 +1,242 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) 2020 Gaël PORTAY
|
||||
#
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
#
|
||||
# https://www.freedesktop.org/software/systemd/man/systemd.offline-updates.html
|
||||
|
||||
set -e
|
||||
set -u
|
||||
set -o pipefail
|
||||
|
||||
VERSION="1.1"
|
||||
|
||||
opts=(--noconfirm --noprogressbar --cachedir /var/lib/system-update)
|
||||
while [[ "$#" -ne 0 ]]
|
||||
do
|
||||
if [[ "$1" =~ (-h|--help) ]]
|
||||
then
|
||||
echo "Usage: ${0##*/} [--now] [--force] [--] [pacman-extra-flags]"
|
||||
exit 0
|
||||
elif [[ "$1" =~ (-V|--version) ]]
|
||||
then
|
||||
echo "$VERSION"
|
||||
exit
|
||||
elif [[ "$1" == "--now" ]]
|
||||
then
|
||||
now=true
|
||||
elif [[ "$1" == "--force" ]]
|
||||
then
|
||||
force=true
|
||||
elif [[ "$1" == "--" ]]
|
||||
then
|
||||
shift
|
||||
break
|
||||
else
|
||||
echo "$1: Invalid argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -z "${now:-}" ]]
|
||||
then
|
||||
if [[ ! -e /system-update ]] || [[ "${force:-}" ]]
|
||||
then
|
||||
echo ":: Preparing offline system updates..."
|
||||
mkdir -p /var/lib/system-update
|
||||
pacman "${opts[@]}" --downloadonly -Syu "$@"
|
||||
|
||||
mapfile -t pkgs < <(find /var/lib/system-update -name "*.pkg.tar.*")
|
||||
if [[ "${#pkgs[@]}" -eq 0 ]]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
ln -sf /var/lib/system-update /system-update
|
||||
if [[ "$#" -gt 0 ]]
|
||||
then
|
||||
echo "$@" >/var/lib/system-update/.flags
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ":: Please reboot the machine to trigger the offline system updates."
|
||||
if [[ -e /var/lib/system-update/.flags ]]
|
||||
then
|
||||
cat /var/lib/system-update/.flags
|
||||
fi
|
||||
exit
|
||||
fi
|
||||
|
||||
# As the first step, an update service should check if the /system-update
|
||||
# symlink points to the location used by that update service. In case it does
|
||||
# not exist or points to a different location, the service must exit without
|
||||
# error.
|
||||
if [[ ! -L /system-update ]] ||
|
||||
[[ "$(readlink -f /system-update)" != "/var/lib/system-update" ]]
|
||||
then
|
||||
echo ":: No offline system updates prepared."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Make sure to remove the /system-update symlink as early as possible in the
|
||||
# update script to avoid reboot loops in case the update fails.
|
||||
rm -f /system-update
|
||||
|
||||
progress() {
|
||||
if plymouth --ping 2>/dev/null
|
||||
then
|
||||
plymouth system-update --progress="$1"
|
||||
fi
|
||||
|
||||
echo -n "$1 "
|
||||
}
|
||||
|
||||
if [[ -r /var/lib/system-update/.flags ]]
|
||||
then
|
||||
read -r -a extraflags < <(cat /var/lib/system-update/.flags)
|
||||
if [[ "${#extraflags[@]}" -gt 0 ]]
|
||||
then
|
||||
set -- "$@" "${extraflags[@]}"
|
||||
fi
|
||||
rm -f /var/lib/system-update/.flags
|
||||
fi
|
||||
|
||||
# If your script succeeds you should trigger the reboot in your own code, for
|
||||
# example by invoking logind's Reboot() call or calling systemctl reboot. See
|
||||
# logind dbus API for details.
|
||||
# shellcheck disable=SC2154
|
||||
trap 'ret="$?"; trap - 0; if [ "$ret" -eq 0 ]; then systemctl reboot; return "$ret"; fi' 0 INT
|
||||
|
||||
if plymouth --ping 2>/dev/null
|
||||
then
|
||||
plymouth change-mode --system-upgrade
|
||||
plymouth system-update --progress=0
|
||||
fi
|
||||
|
||||
i=0
|
||||
step=
|
||||
while read -r -a words
|
||||
do
|
||||
# empty line: skip it!
|
||||
if [[ "${#words[@]}" -eq 0 ]]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
# the pacman steps:
|
||||
# :: Synchronizing package databases...
|
||||
# :: Starting full system upgrade...
|
||||
# :: Proceed with installation? [Y/n]
|
||||
# :: Retrieving packages...
|
||||
# :: Running pre-transaction hooks...
|
||||
# :: Processing package changes...
|
||||
# :: Running post-transaction hooks...
|
||||
if [[ "${words[0]}" =~ :: ]]
|
||||
then
|
||||
i=0
|
||||
step="${words[*]:1}"
|
||||
if [[ "$step" == "Synchronizing package databases..." ]] ||
|
||||
[[ "$step" == "Retrieving packages..." ]] ||
|
||||
[[ "$step" == "Running pre-transaction hooks..." ]] ||
|
||||
[[ "$step" == "Running post-transaction hooks..." ]]
|
||||
then
|
||||
echo "$step"
|
||||
fi
|
||||
continue
|
||||
fi
|
||||
|
||||
# nothing to do: exit early!
|
||||
if [[ "${words[0]}" == "there is nothing to do" ]]
|
||||
then
|
||||
echo "Nothing to do, rebooting..."
|
||||
break
|
||||
fi
|
||||
|
||||
# :: Starting full system upgrade...
|
||||
# resolving dependencies...
|
||||
# looking for conflicting packages...
|
||||
#
|
||||
# Packages (4) pkg1 pkg2 pkg3 pkg4
|
||||
#
|
||||
# Total Download Size: ##.## MiB
|
||||
# Total Installed Size: ##.## MiB
|
||||
# Net Upgrade Size: ##.## MiB
|
||||
#
|
||||
if [[ "${words[0]}" == "Packages" ]]
|
||||
then
|
||||
# Packages (4) (...)
|
||||
if [[ "${words[1]}" =~ ^\([0-9]+\)$ ]]
|
||||
then
|
||||
count="${words[1]:1:$((${#words[1]}-2))}"
|
||||
fi
|
||||
# :: Retrieving packages...
|
||||
# downloading pkg...
|
||||
# :: Processing package changes...
|
||||
# upgrading pkg...
|
||||
elif [[ "${words[0]}" =~ ^(downloading|installing|upgrading)$ ]] &&
|
||||
[[ "$step" != "Synchronizing package databases..." ]]
|
||||
then
|
||||
i="$((i+1))"
|
||||
processing="${words[0]:0:1}"
|
||||
processing="${processing^^}"
|
||||
processing+="${words[0]:1}"
|
||||
if [[ -z "${count:-}" ]]
|
||||
then
|
||||
echo "$processing ${words[1]}"
|
||||
continue
|
||||
elif [[ "${words[0]}" == downloading ]]
|
||||
then
|
||||
echo "$processing ${words[1]} ($i/$count)"
|
||||
continue
|
||||
fi
|
||||
|
||||
progress "$((20+(60*i)/count))"
|
||||
echo "$processing ${words[1]} ($i/$count)"
|
||||
continue
|
||||
# :: Running pre-transaction hooks...
|
||||
# ( #/##) Doing something...
|
||||
# (##/##) Doing another thing...
|
||||
# :: Running post-transaction hooks...
|
||||
# (#/#) Doing a last thing...
|
||||
elif [[ "$step" == "Running pre-transaction hooks..." ]] ||
|
||||
[[ "$step" == "Running post-transaction hooks..." ]]
|
||||
then
|
||||
# ( #/##) (...): remove the parasite space.
|
||||
if [[ "${words[0]}" == "(" ]]
|
||||
then
|
||||
words[1]="${words[0]}${words[1]}"
|
||||
words[0]=
|
||||
words=("${words[@]:1}")
|
||||
fi
|
||||
|
||||
if ! [[ "${words[0]}" =~ ^\([0-9]+/[0-9]+\)$ ]]
|
||||
then
|
||||
echo "${words[*]}"
|
||||
continue
|
||||
fi
|
||||
|
||||
if [[ "$step" == "Running pre-transaction hooks..." ]]
|
||||
then
|
||||
base=0
|
||||
else
|
||||
base=80
|
||||
fi
|
||||
|
||||
val="${words[0]:1:$((${#words[0]}-2))}"
|
||||
progress "$((base+20*${val// /}))"
|
||||
echo "${words[*]:1} ${words[0]}"
|
||||
continue
|
||||
fi
|
||||
done < <(pacman "${opts[@]}" -Su "$@")
|
||||
rm -f /var/lib/system-update/*.pkg.tar.*
|
||||
|
||||
if plymouth --ping 2>/dev/null
|
||||
then
|
||||
plymouth change-mode --boot-up
|
||||
plymouth display-message --text="Rebooting..."
|
||||
fi
|
||||
|
||||
echo "Rebooting..."
|
||||
sleep 5s
|
||||
46
presets/steam/steamos/bin/startplasma-steamos-oneshot
Executable file
46
presets/steam/steamos/bin/startplasma-steamos-oneshot
Executable file
@@ -0,0 +1,46 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
die() { echo >&2 "!! $*"; exit 1; }
|
||||
|
||||
SENTINEL_FILE="steamos-session-select"
|
||||
SENTINEL_VALUE="plasma-steamos-oneshot.desktop"
|
||||
|
||||
# If we proceed, execute this
|
||||
CHAINED_SESSION="/usr/bin/startplasma-x11"
|
||||
# If we decide the sentinel is consumed, execute this command instead and fail
|
||||
RESTORE_SESSION=(steamos-session-select) # No arguments restores the session
|
||||
|
||||
# Find or check config sentinel
|
||||
check_sentinel()
|
||||
{
|
||||
if [[ -z ${HOME+x} ]]; then
|
||||
echo >&2 "$0: No \$HOME variable!"
|
||||
# Rather than break we'll just launch plasma and hope for the best?
|
||||
return 0
|
||||
fi
|
||||
|
||||
local config_dir="${XDG_CONF_DIR:-"$HOME/.config"}"
|
||||
(
|
||||
cd "$HOME"
|
||||
cd "$config_dir"
|
||||
sentinel_value="$(cat "$SENTINEL_FILE")"
|
||||
[[ $sentinel_value = "$SENTINEL_VALUE" ]] || return 1
|
||||
rm "$SENTINEL_FILE"
|
||||
) || return 1 # If we couldn't read the value or it wasn't what we wanted
|
||||
|
||||
# Found value and removed it, we're good to continue
|
||||
return 0
|
||||
}
|
||||
|
||||
if check_sentinel; then
|
||||
# We found and consumed the oneshot sentinel, proceed to launch plasma
|
||||
echo >&2 "$0: Found and removed sentinel file for one-shot plasma, proceeding to launch"
|
||||
exec "$CHAINED_SESSION"
|
||||
else
|
||||
echo >&2 "$0: Sentinel value not found, executing session-select to restore session"
|
||||
"${RESTORE_SESSION[@]}" || echo >&2 "$0: !! Failed to restore previous session, executing chained session"
|
||||
# Session restore should've stopped us, if it is broken at least let plasma continue to open
|
||||
exec "$CHAINED_SESSION"
|
||||
fi
|
||||
18
presets/steam/steamos/bin/steamos-boot-install
Executable file
18
presets/steam/steamos/bin/steamos-boot-install
Executable file
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020-2021 Collabora Ltd.
|
||||
# Copyright © 2020-2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
# This is a simple wrapper that provides backwards compatibility to the renamed steamos-finalize-install
|
||||
source "${BASH_SOURCE%/*}"/steamos-finalize-install "$@";
|
||||
177
presets/steam/steamos/bin/steamos-chroot
Executable file
177
presets/steam/steamos/bin/steamos-chroot
Executable file
@@ -0,0 +1,177 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2019-2020 Collabora Ltd.
|
||||
# Copyright © 2019-2020 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
DISK= # --disk=
|
||||
PARTSET= # --partset=
|
||||
|
||||
SYMLINKS_DIR=/dev/disk/by-partsets
|
||||
|
||||
[ -e /usr/lib/steamos/steamos-partitions-lib ] && \
|
||||
. /usr/lib/steamos/steamos-partitions-lib || \
|
||||
{ echo "Failed to source '/usr/lib/steamos/steamos-partitions-lib'"; exit 1; }
|
||||
|
||||
# Helpers
|
||||
|
||||
fail() { echo >&2 "$@"; exit 1; }
|
||||
|
||||
usage() {
|
||||
local status=${1-2}
|
||||
|
||||
if [ $status -ne 0 ]; then
|
||||
exec >&2
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Usage: $(basename $0) [--disk=DISK] --partset=A|B|self|other -- COMMAND"
|
||||
echo
|
||||
echo "Run COMMAND in a chroot. The chroot is SteamOS specific, which means"
|
||||
echo "that the various SteamOS partitions are mounted within the chroot."
|
||||
echo
|
||||
echo "There are two use-cases for this command:"
|
||||
echo
|
||||
echo "1. Chroot into the 'other' SteamOS, useful for atomic update. For example:"
|
||||
echo
|
||||
echo " $(basename $0) --partset other -- COMMAND"
|
||||
echo
|
||||
echo "2. Chroot into another SteamOS install, on another disk. For example:"
|
||||
echo
|
||||
echo " $(basename $0) --disk /dev/sdb --partset A -- COMMAND"
|
||||
echo
|
||||
echo "The second mode works if SteamOS is installed alone on the disk, however"
|
||||
echo "if there are other partitions on the disk then it's not guaranteed to work."
|
||||
echo "This is because we rely on partition labels to find SteamOS partitions and"
|
||||
echo "setup the chroot. This is too fragile, and if we're unlucky there could be"
|
||||
echo "another partition that doesn't belong to SteamOS but uses the same partition"
|
||||
echo "label."
|
||||
echo
|
||||
|
||||
exit $status
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage 0
|
||||
;;
|
||||
-d|--disk)
|
||||
shift
|
||||
[ "${1:-}" ] || usage 1
|
||||
DISK=$1
|
||||
shift
|
||||
;;
|
||||
-p|--partset)
|
||||
shift
|
||||
[ "${1:-}" ] || usage 1
|
||||
PARTSET=$1
|
||||
shift
|
||||
;;
|
||||
--)
|
||||
shift
|
||||
break
|
||||
;;
|
||||
*)
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ "$PARTSET" ] || usage 1
|
||||
|
||||
# Find devices
|
||||
|
||||
ESP_DEVICE=
|
||||
EFI_DEVICE=
|
||||
ROOTFS_DEVICE=
|
||||
|
||||
if [ "$DISK" ]; then
|
||||
# A disk was provided, which means that we're chrooting into another
|
||||
# SteamOS install. We do our best to 'guess' the partitions, ie. we
|
||||
# mostly rely on partition labels. This is OK if SteamOS is alone on
|
||||
# this disk, but it's fragile if it's installed along another OS.
|
||||
[ -b "$DISK" ] || fail "'$DISK' is not a block device"
|
||||
ROOTFS_DEVICE=$(get_device_by_partlabel $DISK rootfs-$PARTSET)
|
||||
EFI_DEVICE=$(get_device_by_partlabel $DISK efi-$PARTSET)
|
||||
VAR_DEVICE=$(get_device_by_partlabel $DISK var-$PARTSET)
|
||||
ESP_DEVICE=$(get_device_by_partlabel $DISK esp)
|
||||
if [ -z "$ESP_DEVICE" ]; then
|
||||
ESP_DEVICE=$(get_device_by_typeuuid $DISK \
|
||||
c12a7328-f81f-11d2-ba4b-00a0c93ec93b)
|
||||
fi
|
||||
else
|
||||
# No disk was provided, which means that we're chrooting into the
|
||||
# 'other' install, A or B. We can find these partitions reliably
|
||||
# using the existing symlinks.
|
||||
ROOTFS_DEVICE=$(realpath $SYMLINKS_DIR/$PARTSET/rootfs)
|
||||
EFI_DEVICE=$(realpath $SYMLINKS_DIR/$PARTSET/efi)
|
||||
ESP_DEVICE=$(realpath $SYMLINKS_DIR/shared/esp)
|
||||
VAR_DEVICE=$(realpath $SYMLINKS_DIR/$PARTSET/var)
|
||||
fi
|
||||
|
||||
[ -b "$ROOTFS_DEVICE" ] || fail "'$ROOTFS_DEVICE' is not a block device"
|
||||
[ -b "$EFI_DEVICE" ] || fail "'$EFI_DEVICE' is not a block device"
|
||||
[ -b "$ESP_DEVICE" ] || fail "'$ESP_DEVICE' is not a block device"
|
||||
[ -b "$VAR_DEVICE" ] || fail "'$VAR_DEVICE' is not a block device"
|
||||
|
||||
# Do the job
|
||||
|
||||
prepare_chroot_at() {
|
||||
|
||||
local dir=$1
|
||||
|
||||
mount -o ro "$ROOTFS_DEVICE" $dir
|
||||
mount --bind /dev $dir/dev
|
||||
mount --bind /proc $dir/proc
|
||||
mount --bind /run $dir/run
|
||||
mount --bind /sys $dir/sys
|
||||
mount --bind /sys/firmware/efi/efivars $dir/sys/firmware/efi/efivars
|
||||
mount -t tmpfs -o size=128M tmpfs $dir/tmp
|
||||
mount "$EFI_DEVICE" $dir/efi
|
||||
mount "$ESP_DEVICE" $dir/esp
|
||||
mount "$VAR_DEVICE" $dir/var
|
||||
if [ -d $dir/var/boot ]; then
|
||||
mount --bind $dir/var/boot $dir/boot
|
||||
fi
|
||||
}
|
||||
|
||||
cleanup_chroot_at() {
|
||||
|
||||
local dir=$1
|
||||
|
||||
if mountpoint -q $dir/boot; then
|
||||
umount $dir/boot || :
|
||||
fi
|
||||
umount $dir/var || :
|
||||
umount $dir/esp || :
|
||||
umount $dir/efi || :
|
||||
umount $dir/tmp || :
|
||||
umount $dir/sys/firmware/efi/efivars || :
|
||||
umount -R $dir/sys || :
|
||||
umount $dir/run || :
|
||||
umount -R $dir/proc || :
|
||||
umount $dir/dev || :
|
||||
umount $dir || :
|
||||
|
||||
rmdir $dir
|
||||
}
|
||||
|
||||
CHROOTDIR=$(mktemp -d)
|
||||
trap "cleanup_chroot_at $CHROOTDIR" EXIT
|
||||
|
||||
prepare_chroot_at $CHROOTDIR
|
||||
chroot $CHROOTDIR "$@"
|
||||
1
presets/steam/steamos/bin/steamos-critical
Symbolic link
1
presets/steam/steamos/bin/steamos-critical
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
1
presets/steam/steamos/bin/steamos-debug
Symbolic link
1
presets/steam/steamos/bin/steamos-debug
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
1
presets/steam/steamos/bin/steamos-emergency
Symbolic link
1
presets/steam/steamos/bin/steamos-emergency
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
1
presets/steam/steamos/bin/steamos-error
Symbolic link
1
presets/steam/steamos/bin/steamos-error
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
90
presets/steam/steamos/bin/steamos-factory-reset
Executable file
90
presets/steam/steamos/bin/steamos-factory-reset
Executable file
@@ -0,0 +1,90 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2019-2021 Collabora Ltd.
|
||||
# Copyright © 2019-2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
FORCE=0 # --force
|
||||
|
||||
FACTORY_RESET_CONFIG_DIR=/esp/efi/steamos/factory-reset
|
||||
|
||||
[ -e /usr/lib/steamos/steamos-partitions-lib ] && \
|
||||
. /usr/lib/steamos/steamos-partitions-lib || \
|
||||
{ echo "Failed to source '/usr/lib/steamos/steamos-partitions-lib'"; exit 1; }
|
||||
|
||||
usage() {
|
||||
local status=${1-2}
|
||||
|
||||
if [ $status -ne 0 ]; then
|
||||
exec >&2
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Usage: $(basename $0) [OPTIONS]"
|
||||
echo
|
||||
echo "Factory reset of SteamOS, wipe out the data partitions."
|
||||
echo
|
||||
echo "This script records the partitions to be reset in:"
|
||||
echo " $FACTORY_RESET_CONFIG_DIR"
|
||||
echo "On reboot the initrd scrubs them and does a first-boot setup."
|
||||
echo
|
||||
|
||||
exit $status
|
||||
}
|
||||
|
||||
ask() {
|
||||
local message="$1 [y/n] "
|
||||
local answer=
|
||||
|
||||
while read -r -t 0; do
|
||||
read -n 256 -r -s
|
||||
done
|
||||
|
||||
while true; do
|
||||
read -p "$message" answer
|
||||
case "$answer" in
|
||||
[Yy]|YES|Yes|yes) return 0;;
|
||||
[Nn]|NO|No|no) return 1;;
|
||||
*) echo "Please answer yes or no.";;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage 0
|
||||
;;
|
||||
*)
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
echo
|
||||
echo "You're about to perform a factory reset of your SteamOS install!"
|
||||
echo
|
||||
echo "The data partitions will be erased, all your personal data will be lost."
|
||||
echo "Then the system will reboot, and you'll be back to a pristine SteamOS install."
|
||||
echo
|
||||
if ! ask "Do you want to continue?"; then
|
||||
echo "Alright buddy. Come back when you feel ready."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if steamos-factory-reset-config "$FACTORY_RESET_CONFIG_DIR"; then
|
||||
reboot
|
||||
fi
|
||||
43
presets/steam/steamos/bin/steamos-factory-reset-config
Executable file
43
presets/steam/steamos/bin/steamos-factory-reset-config
Executable file
@@ -0,0 +1,43 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2021 Collabora Ltd.
|
||||
# Copyright © 2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -eu
|
||||
|
||||
SYMLINKS_DIR=/dev/disk/by-partsets
|
||||
FACTORY_RESET_CONFIG_DIR=/esp/efi/steamos/factory-reset
|
||||
HOME_DEVICE=$SYMLINKS_DIR/all/home
|
||||
ESP_DEVICE=$SYMLINKS_DIR/all/esp
|
||||
|
||||
cdir=${1:-$FACTORY_RESET_CONFIG_DIR}
|
||||
wdir=$(mktemp -t -d rest-conf-XXXXXXXXXX)
|
||||
dev=
|
||||
opts=
|
||||
|
||||
for dev in $SYMLINKS_DIR/all/efi-*; do
|
||||
echo EFI $dev $(readlink -f $dev) > ${wdir}/${dev##*/}.cfg
|
||||
done
|
||||
|
||||
for dev in $SYMLINKS_DIR/all/var-*; do
|
||||
opts=$(tune2fs -l "$dev" | sed -n 's/^Filesystem features:\s*//p')
|
||||
echo VAR $dev $(readlink -f $dev) "$opts" > ${wdir}/${dev##*/}.cfg
|
||||
done
|
||||
|
||||
opts=$(tune2fs -l "$HOME_DEVICE" | sed -n 's/^Filesystem features:\s*//p')
|
||||
echo HOME $HOME_DEVICE $(readlink -f $HOME_DEVICE) "$opts" > ${wdir}/home.cfg
|
||||
|
||||
mkdir -p "$cdir"
|
||||
mv "${wdir}"/* "$cdir"
|
||||
rmdir "$wdir"
|
||||
1
presets/steam/steamos/bin/steamos-fatal
Symbolic link
1
presets/steam/steamos/bin/steamos-fatal
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
195
presets/steam/steamos/bin/steamos-finalize-install
Executable file
195
presets/steam/steamos/bin/steamos-finalize-install
Executable file
@@ -0,0 +1,195 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright ©2022 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
function usage
|
||||
{
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} [--roothash=HASH] [--no-bootloaders] [--no-kernel] [--no-migrate]
|
||||
|
||||
Perform post-update migration steps before marking the new installation ready.
|
||||
Install boot artifacts on your device.
|
||||
EOF
|
||||
}
|
||||
|
||||
# Install boot artifacts
|
||||
function install_bootloaders
|
||||
{
|
||||
if [[ ! "${no_bootloaders:-}" ]]
|
||||
then
|
||||
typeset ident
|
||||
ident=$(steamos-bootconf this-image)
|
||||
# fallback if there are no bootconfs in /esp, so we can't determine our image name
|
||||
if [[ -z ${ident} ]]
|
||||
then
|
||||
rootdsk=$(findmnt --noheadings -o PARTLABEL / )
|
||||
ident=${rootdsk#rootfs-}
|
||||
fi
|
||||
|
||||
if [[ -z ${ident} ]]
|
||||
then
|
||||
echo "Failed to determine new boot identifier"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
steamcl-install
|
||||
if mountpoint -q /boot
|
||||
then
|
||||
grub-install
|
||||
else
|
||||
echo "Warning: Skipping installation artifacts to /boot!" >&2
|
||||
grub-mkimage
|
||||
fi
|
||||
|
||||
if [[ ! -e /efi/SteamOS ]]
|
||||
then
|
||||
mkdir -p /efi/SteamOS
|
||||
fi
|
||||
|
||||
if [[ ! -e /esp/SteamOS/conf/${ident}.conf ]]
|
||||
then
|
||||
echo "Initializing boot configuration at /esp/SteamOS/conf for ${ident}"
|
||||
mkdir -p /esp/SteamOS/conf
|
||||
steamos-bootconf --conf-dir /esp/SteamOS/conf create --image ${ident}
|
||||
fi
|
||||
|
||||
# we want to know our buildid
|
||||
. /etc/os-release ||:
|
||||
# mostly just a nice-to-have, but it also resolves a condition where an empty conf doesn't get updated
|
||||
steamos-bootconf --conf-dir /esp/SteamOS/conf config --image ${ident} --set comment "${BUILD_ID:-}"
|
||||
fi
|
||||
|
||||
if [[ ! "${no_kernel:-}" ]]
|
||||
then
|
||||
mapfile -t moduledirs < <(ls -1d /usr/lib/steamos/modules/* 2>/dev/null)
|
||||
for moduledir in "${moduledirs[@]}"
|
||||
do
|
||||
if ! read -r pkgbase > /dev/null 2>&1 < "$moduledir/pkgbase"
|
||||
then
|
||||
# if the kernel has no pkgbase, we skip it
|
||||
continue
|
||||
fi
|
||||
|
||||
kver="${moduledir##*/}"
|
||||
install -Dm644 "/usr/share/factory/var/lib/modules/$kver/vmlinuz" "/boot/vmlinuz-$pkgbase"
|
||||
mkdir -p "/var/lib/modules/$kver"
|
||||
cp -a "/usr/share/factory/var/lib/modules/$kver" "/var/lib/modules/"
|
||||
dracut --force --hostonly "/boot/initramfs-$pkgbase.img" "$kver"
|
||||
dracut --force --no-hostonly "/boot/initramfs-$pkgbase-fallback.img" "$kver"
|
||||
done
|
||||
fi
|
||||
if [[ "${roothash:-}" ]]
|
||||
then
|
||||
mkdir -p /efi/SteamOS
|
||||
echo "$roothash" >/efi/SteamOS/roothash
|
||||
fi
|
||||
mapfile -t linux < <(ls -1 /boot/vmlinuz-* 2>/dev/null)
|
||||
if [[ "${#linux[*]}" -eq 0 ]]
|
||||
then
|
||||
echo "Warning: /boot: No such vmlinuz!" >&2
|
||||
fi
|
||||
mapfile -t initramfs < <(ls -1 /boot/initramfs-*.img 2>/dev/null)
|
||||
if [[ "${#initramfs[*]}" -eq 0 ]]
|
||||
then
|
||||
echo "Warning: /boot: No such initramfs!" >&2
|
||||
fi
|
||||
mapfile -t modules < <(ls -d1 /usr/lib/modules/* 2>/dev/null)
|
||||
if [[ "${#modules[*]}" -eq 0 ]]
|
||||
then
|
||||
echo "Warning: /usr/lib/modules: No such modules!" >&2
|
||||
fi
|
||||
update-grub
|
||||
}
|
||||
|
||||
function in_chroot
|
||||
{
|
||||
local proc_root;
|
||||
local root;
|
||||
if ! proc_root="$(stat --printf "%d %i" /proc/1/root/ 2>/dev/null)" || ! root="$(stat --printf "%d %i" / 2>/dev/null)"; then
|
||||
return 1;
|
||||
fi;
|
||||
test "$proc_root" != "$root"
|
||||
}
|
||||
|
||||
# Migrate configuration before booting new image.
|
||||
# Currently:
|
||||
# Convert wifi system connections to a form that iwd can handle
|
||||
#
|
||||
function migrate_network
|
||||
{
|
||||
# remove properties used by NetworkManager that are not permitted by iwd:
|
||||
find /var/lib/overlays/etc/upper/NetworkManager/system-connections/ -type f -name \*.nmconnection -print0 | while read -r -d $'\0' file;
|
||||
do
|
||||
if grep -q '^type=wifi' "$file"
|
||||
then
|
||||
sed -i 's/^\(mac-address\|interface-name\|permissions\|bssid\)=.*//' "$file" ||:
|
||||
fi
|
||||
done
|
||||
|
||||
# when converting from early OS builds, we may not have masked out NetworkManager ephemeral files
|
||||
rm -f /var/lib/NetworkManager/*
|
||||
}
|
||||
|
||||
while [[ "$#" -ne 0 ]]
|
||||
do
|
||||
if [[ "$1" =~ ^(-h|--help)$ ]]
|
||||
then
|
||||
usage
|
||||
exit
|
||||
elif [[ "$1" =~ ^(--roothash)$ ]]
|
||||
then
|
||||
shift
|
||||
roothash="$1"
|
||||
elif [[ "$1" =~ ^(--no-bootloaders)$ ]]
|
||||
then
|
||||
no_bootloaders=1
|
||||
elif [[ "$1" =~ ^(--no-kernel)$ ]]
|
||||
then
|
||||
no_kernel=1
|
||||
elif [[ "$1" =~ ^(--no-boot-install)$ ]]
|
||||
then
|
||||
no_boot_install=1
|
||||
elif [[ "$1" =~ ^(--no-migrate)$ ]]
|
||||
then
|
||||
no_migrate=1
|
||||
elif [[ "$1" =~ ^(-f|--force)$ ]]
|
||||
then
|
||||
force_migrate=1
|
||||
else
|
||||
usage
|
||||
echo "$1: Too many arguments" >&2
|
||||
exit 1
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ ! ${no_migrate:-} ]]
|
||||
then
|
||||
if in_chroot || [[ ${force_migrate:-} ]]
|
||||
then
|
||||
migrate_network
|
||||
else
|
||||
echo "Skipping configuration migration steps as this is not running in a chroot."
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ! ${no_boot_install:-} ]]
|
||||
then
|
||||
install_bootloaders
|
||||
fi
|
||||
|
||||
1
presets/steam/steamos/bin/steamos-halt
Symbolic link
1
presets/steam/steamos/bin/steamos-halt
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-reboot
|
||||
1
presets/steam/steamos/bin/steamos-info
Symbolic link
1
presets/steam/steamos/bin/steamos-info
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
132
presets/steam/steamos/bin/steamos-logger
Executable file
132
presets/steam/steamos/bin/steamos-logger
Executable file
@@ -0,0 +1,132 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020 Collabora Ltd.
|
||||
# Copyright © 2020 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} [options] [<message>]
|
||||
|
||||
Echoes the message to standard output.
|
||||
|
||||
It displays the text message if splash screen is running.
|
||||
|
||||
The splash screen is cleared if message is empty.
|
||||
|
||||
Options:
|
||||
-h, --help this help message
|
||||
-l, --log-level LEVEL the level of logs
|
||||
|
||||
LEVELS
|
||||
Valid levels: emergency alert critical error warning notice info debug.
|
||||
EOF
|
||||
}
|
||||
|
||||
declare -A LOG_LEVEL
|
||||
LOG_LEVEL[emergency]="0"
|
||||
LOG_LEVEL[fatal]="1"
|
||||
LOG_LEVEL[critical]="2"
|
||||
LOG_LEVEL[error]="3"
|
||||
LOG_LEVEL[warning]="4"
|
||||
LOG_LEVEL[notice]="5"
|
||||
LOG_LEVEL[info]="6"
|
||||
LOG_LEVEL[debug]="7"
|
||||
|
||||
declare -A LOG_LEVEL_PREFIX
|
||||
LOG_LEVEL_PREFIX[emergency]="<0>"
|
||||
LOG_LEVEL_PREFIX[fatal]="<1>"
|
||||
LOG_LEVEL_PREFIX[critical]="<2>"
|
||||
LOG_LEVEL_PREFIX[error]="<3>"
|
||||
LOG_LEVEL_PREFIX[warning]="<4>"
|
||||
LOG_LEVEL_PREFIX[notice]="<5>"
|
||||
LOG_LEVEL_PREFIX[info]="<6>"
|
||||
LOG_LEVEL_PREFIX[debug]="<7>"
|
||||
|
||||
declare -A PLYMOUTH_PREFIX
|
||||
PLYMOUTH_PREFIX[emergency]="Emergency: "
|
||||
PLYMOUTH_PREFIX[fatal]="Fatal: "
|
||||
PLYMOUTH_PREFIX[critical]="Critical: "
|
||||
PLYMOUTH_PREFIX[error]="Error: "
|
||||
PLYMOUTH_PREFIX[warning]="Warning: "
|
||||
if [[ ${STEAMOS_DEBUG:-} ]]
|
||||
then
|
||||
PLYMOUTH_PREFIX[notice]="Notice: "
|
||||
PLYMOUTH_PREFIX[info]="Info: "
|
||||
PLYMOUTH_PREFIX[debug]="Debug: "
|
||||
fi
|
||||
|
||||
if [[ "${0##*/}" != steamos-logger ]]
|
||||
then
|
||||
log_level="${0##*/}"
|
||||
log_level="${log_level#steamos-}"
|
||||
else
|
||||
log_level="notice"
|
||||
fi
|
||||
|
||||
while [[ "$#" -ne 0 ]]
|
||||
do
|
||||
if [[ "$1" =~ ^(-h|--help) ]]
|
||||
then
|
||||
usage
|
||||
exit
|
||||
elif [[ "$1" =~ ^(-l|--log-level) ]]
|
||||
then
|
||||
shift
|
||||
|
||||
if [[ "$#" -eq 0 ]] || [[ -z ${LOG_LEVEL_PREFIX[$1]:-} ]]
|
||||
then
|
||||
echo "${!LOG_LEVEL_PREFIX[@]}"
|
||||
if [[ "$#" -eq 0 ]]
|
||||
then
|
||||
exit 0
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
|
||||
log_level="$1"
|
||||
else
|
||||
break
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if plymouth --ping &&
|
||||
{ [[ ${STEAMOS_DEBUG:-} ]] ||
|
||||
[[ "${LOG_LEVEL[$log_level]}" -lt "${LOG_LEVEL[info]}" ]]; }
|
||||
then
|
||||
prefix="${PLYMOUTH_PREFIX[$log_level]:-}"
|
||||
if [[ ${prefix:-} ]]
|
||||
then
|
||||
text="$prefix"
|
||||
fi
|
||||
text+="${*:-}"
|
||||
|
||||
plymouth display-message --text="$text"
|
||||
unset prefix text
|
||||
fi
|
||||
|
||||
if [[ "$#" -eq 0 ]]
|
||||
then
|
||||
exit
|
||||
fi
|
||||
|
||||
if ! [[ -t 1 ]]
|
||||
then
|
||||
prefix="${LOG_LEVEL_PREFIX[$log_level]:-}"
|
||||
fi
|
||||
|
||||
exec printf "%s%s\n" "${prefix:-}" "${*:-}"
|
||||
150
presets/steam/steamos/bin/steamos-ls
Executable file
150
presets/steam/steamos/bin/steamos-ls
Executable file
@@ -0,0 +1,150 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2021 Collabora Ltd.
|
||||
# Copyright © 2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
declare -r esp_parttype=c12a7328-f81f-11d2-ba4b-00a0c93ec93b
|
||||
declare -r efi_parttype=ebd0a0a2-b9e5-4433-87c0-68b6b72699c7
|
||||
declare -r lsblk_cols=PATH,PARTTYPE,PARTUUID,PARTLABEL
|
||||
|
||||
MOUNTDIR="${MOUNTDIR:-/mnt}"
|
||||
OUTPUTS=("path" "partuuid" "partlabel" "label" "boot-requested-at" "boot-other"
|
||||
"boot-other-disabled" "boot-attempts" "boot-count" "boot-time"
|
||||
"image-invalid" "update" "update-disabled" "update-window-start"
|
||||
"update-window-end" "loader" "partitions" "comment")
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
${0##*/} [options] [<device> ...]
|
||||
|
||||
List bootconf parameters about SteamOS devices.
|
||||
|
||||
Options:
|
||||
-o, --output <list> output columns
|
||||
EOF
|
||||
}
|
||||
|
||||
opts=()
|
||||
while [[ "$#" -ne 0 ]]
|
||||
do
|
||||
if [[ "$1" =~ ^(-h|--help)$ ]]
|
||||
then
|
||||
usage
|
||||
exit 0
|
||||
elif [[ "$1" =~ ^(-o|--output)$ ]]
|
||||
then
|
||||
shift
|
||||
if [[ "$1" == "help" ]]
|
||||
then
|
||||
echo "${OUTPUTS[@]}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
IFS=, read -r -a output <<<"$1"
|
||||
elif [[ "$1" == -- ]]
|
||||
then
|
||||
shift
|
||||
break
|
||||
else
|
||||
opts+=("$1")
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
|
||||
esp_path=
|
||||
mapfile -t espdev < <(lsblk --noheadings --output $lsblk_cols)
|
||||
for dev in "${espdev[@]}"
|
||||
do
|
||||
read -r path parttype partuuid partlabel <<<"$dev"
|
||||
[[ "${parttype:-}" == $esp_parttype ]] || continue
|
||||
# We need this check in case there are other OSes installed with
|
||||
# esp_parttype tagged partitions of their own:
|
||||
[[ "${partlabel:-}" == esp ]] || continue
|
||||
esp_path=$path
|
||||
break
|
||||
done
|
||||
|
||||
mapfile -t devices < <(lsblk --noheadings --output $lsblk_cols "${opts[@]}" "$@")
|
||||
for dev in "${devices[@]}"
|
||||
do
|
||||
read -r path parttype partuuid partlabel <<<"$dev"
|
||||
[[ "${parttype:-}" == $efi_parttype ]] || continue
|
||||
|
||||
image_ident=
|
||||
case $partlabel in
|
||||
efi-*)
|
||||
image_ident=${partlabel#efi-};
|
||||
;;
|
||||
esac
|
||||
|
||||
[[ -n "${image_ident}" ]] || continue;
|
||||
|
||||
if ! mount -oro "$esp_path" ${MOUNTDIR}
|
||||
then
|
||||
echo "Warning: $path: No such mountable device" >&2
|
||||
continue
|
||||
fi
|
||||
trap "umount ${MOUNTDIR}" 0
|
||||
|
||||
cfgs=()
|
||||
if [[ -e "$MOUNTDIR/SteamOS/conf/${image_ident}.conf" ]]
|
||||
then
|
||||
mapfile -t cfgs <"$MOUNTDIR/SteamOS/conf/${image_ident}.conf"
|
||||
fi
|
||||
|
||||
# FIXME: Small delay to avoid umount exiting with EBUSY
|
||||
while ! umount "$MOUNTDIR"
|
||||
do
|
||||
sleep 0.01
|
||||
done 2>/dev/null
|
||||
trap - 0
|
||||
|
||||
[[ "${#cfgs[@]}" -ne 0 ]] || continue
|
||||
|
||||
if [[ ! "${output[@]:-}" ]]
|
||||
then
|
||||
printf "$path@/SteamOS/bootconf: %s\n" "${cfgs[@]}"
|
||||
continue
|
||||
fi
|
||||
|
||||
vals=()
|
||||
cfgs+=("path: $path")
|
||||
cfgs+=("partuuid: $partuuid")
|
||||
cfgs+=("partlabel: $partlabel")
|
||||
for i in "${output[@]}"
|
||||
do
|
||||
val=
|
||||
for cfg in "${cfgs[@]}"
|
||||
do
|
||||
read -r p v <<<"$cfg"
|
||||
p="${p%:}"
|
||||
[[ "$i" == "$p" ]] || continue
|
||||
|
||||
val="$v"
|
||||
break
|
||||
done
|
||||
|
||||
if [[ ! "$val" ]] && [[ "${FS:- }" == " " ]]
|
||||
then
|
||||
val="-"
|
||||
fi
|
||||
|
||||
vals+=("$val")
|
||||
done
|
||||
( IFS="${FS:- }"; printf "%s" "${vals[*]}"; printf "\n" )
|
||||
done
|
||||
258
presets/steam/steamos/bin/steamos-mount
Executable file
258
presets/steam/steamos/bin/steamos-mount
Executable file
@@ -0,0 +1,258 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020 Collabora Ltd.
|
||||
# Copyright © 2020 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} [-o fs-options] DEVICE MOUNTPOINT
|
||||
${0##*/} -u MOUNTPOINT
|
||||
|
||||
Mount all the SteamOS filesystems on MOUNTPOINT using the DEVICE partitions.
|
||||
|
||||
Options:
|
||||
-o, --options <list> comma-separated list of mount options
|
||||
-u umount
|
||||
-h, --help display this help
|
||||
|
||||
Options for disk:
|
||||
partset=<self|other|A|B|dev>
|
||||
explicitly specifies partset
|
||||
noesp no mount /esp
|
||||
noefi no mount /efi
|
||||
novar no mount /var (implies nooverlay and noboot)
|
||||
nohome no mount /home (implies nooffload)
|
||||
nooffload no bind-mount offloaded directories
|
||||
nooverlay no mount overlayed /etc
|
||||
noboot no bind-mount /boot
|
||||
EOF
|
||||
}
|
||||
|
||||
partset="${partset:-other}"
|
||||
while [[ "$#" -ne 0 ]]
|
||||
do
|
||||
if [[ "$1" =~ ^(-h|--help)$ ]]
|
||||
then
|
||||
usage
|
||||
exit
|
||||
elif [[ "$1" =~ ^(-u)$ ]]
|
||||
then
|
||||
unmount=1
|
||||
elif [[ "$1" =~ ^(-o) ]]
|
||||
then
|
||||
if [[ "$1" == "-o" ]]
|
||||
then
|
||||
shift
|
||||
opt="$1"
|
||||
elif [[ "$1" =~ ^-o= ]]
|
||||
then
|
||||
opt="${1/-o=/}"
|
||||
else
|
||||
opt="${1/-o/}"
|
||||
fi
|
||||
|
||||
IFS=, read -a opts <<<"$opt"
|
||||
for opt in "${opts[@]}"
|
||||
do
|
||||
if [[ "${opt%%=*}" = "$opt" ]]
|
||||
then
|
||||
opt+="=1"
|
||||
fi
|
||||
eval "$(echo "$opt")"
|
||||
done
|
||||
elif [[ "${dev:-}" ]] || ( [[ -n "${unmount:-}" ]] && [[ "${mnt:-}" ]] )
|
||||
then
|
||||
usage
|
||||
echo "$1: Too many arguments" >&2
|
||||
exit 1
|
||||
elif [[ ! "${mnt:-}" ]]
|
||||
then
|
||||
mnt="$1"
|
||||
else
|
||||
dev="$mnt"
|
||||
mnt="$1"
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ ! "${mnt:-}" ]]
|
||||
then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Unmount all partitions
|
||||
if [[ "${unmount:-}" ]]
|
||||
then
|
||||
exec umount -R "$mnt"
|
||||
fi
|
||||
|
||||
# Mount all partitions
|
||||
if [[ ! "${dev:-}" ]]
|
||||
then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Get the list of partitions
|
||||
case "${partset:-other}" in
|
||||
A|B|dev)
|
||||
PARTITIONS=("efi-$partset" "rootfs-$partset" "var-$partset")
|
||||
;;
|
||||
*)
|
||||
if [[ ! -d "/dev/disk/by-partsets/$partset" ]]
|
||||
then
|
||||
echo "$partset: No such partset" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mapfile -t PARTITIONS < <(blkid -s PARTLABEL -o value "/dev/disk/by-partsets/$partset"/*)
|
||||
;;
|
||||
esac
|
||||
PARTITIONS+=("esp" "home")
|
||||
|
||||
# Get the devices
|
||||
mapfile -t devs < <(sfdisk -o "device,name" -l "$dev" | sed -n '/Device/,/^$/{//d;p}')
|
||||
declare -A devices
|
||||
for dev in "${devs[@]}"
|
||||
do
|
||||
read -r -a device < <(echo "$dev")
|
||||
if [[ ${#device[@]} -lt 2 ]]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
# check if the device is a SteamOS partition using the GPT partition label:
|
||||
for part in "${PARTITIONS[@]}"
|
||||
do
|
||||
if [[ "$part" == "${device[1]}" ]]
|
||||
then
|
||||
devices[${device[1]}]="${device[0]}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
done
|
||||
|
||||
for dev in "${!devices[@]}"
|
||||
do
|
||||
case "$dev" in
|
||||
esp)
|
||||
esp="${devices[$dev]}"
|
||||
;;
|
||||
efi-*)
|
||||
efi="${devices[$dev]}"
|
||||
;;
|
||||
rootfs-*)
|
||||
rootfs="${devices[$dev]}"
|
||||
;;
|
||||
var-*)
|
||||
var="${devices[$dev]}"
|
||||
;;
|
||||
home)
|
||||
home="${devices[$dev]}"
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! "${esp:-}" ]]
|
||||
then
|
||||
# Get the first EFI System Partition
|
||||
mapfile -t esps < <(sfdisk -o "device,uuid,type" -l "$dev" | sed -n '/Device/,/^$/{//d;/EFI System$/p}')
|
||||
for dev in "${esps[@]}"
|
||||
do
|
||||
read -r -a device < <(echo "$dev")
|
||||
if [[ ${#device[@]} -lt 2 ]]
|
||||
then
|
||||
continue
|
||||
fi
|
||||
|
||||
esp="${device[0]}"
|
||||
break
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ ! "${noesp:-}" ]] && [[ ! "${esp:-}" ]]
|
||||
then
|
||||
echo "esp: No such device" >&2
|
||||
exit 1
|
||||
elif [[ ! "${noefi:-}" ]] && [[ ! "${efi:-}" ]]
|
||||
then
|
||||
echo "efi: No such device" >&2
|
||||
exit 1
|
||||
elif [[ ! "${rootfs:-}" ]]
|
||||
then
|
||||
echo "rootfs: No such device" >&2
|
||||
exit 1
|
||||
elif [[ ! "${novar:-}" ]] && [[ ! "${var:-}" ]]
|
||||
then
|
||||
echo "var: No such device" >&2
|
||||
exit 1
|
||||
elif [[ ! "${nohome:-}" ]] && [[ ! "${home:-}" ]]
|
||||
then
|
||||
echo "home: No such device" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Mount partset
|
||||
mount "$rootfs" "$mnt"
|
||||
trap 'umount -R "$mnt"' 0
|
||||
if [[ ! "${nohome:-}" ]]
|
||||
then
|
||||
mount "$home" "$mnt/home"
|
||||
fi
|
||||
if [[ ! "${novar:-}" ]]
|
||||
then
|
||||
mount "$var" "$mnt/var"
|
||||
fi
|
||||
if [[ ! "${noefi:-}" ]]
|
||||
then
|
||||
mount "$efi" "$mnt/efi"
|
||||
fi
|
||||
if [[ ! "${noesp:-}" ]]
|
||||
then
|
||||
mount "$esp" "$mnt/esp"
|
||||
fi
|
||||
|
||||
# Mount offload
|
||||
if [[ ! "${nohome:-}" ]] && [[ ! "${nooverlay:-}" ]]
|
||||
then
|
||||
for i in /opt /root /srv /usr/lib/debug /usr/local
|
||||
do
|
||||
mount --bind "$mnt/home/.steamos/offload$i" "$mnt$i"
|
||||
done
|
||||
if [[ ! "${novar:-}" ]]
|
||||
then
|
||||
for i in /var/cache/pacman /var/lib/docker /var/lib/flatpak /var/lib/systemd/coredump /var/log /var/tmp
|
||||
do
|
||||
mount --bind "$mnt/home/.steamos/offload$i" "$mnt$i"
|
||||
done
|
||||
fi
|
||||
fi
|
||||
|
||||
# Mount overlay
|
||||
if [[ ! "${novar:-}" ]] && [[ ! "${nooverlay:-}" ]]
|
||||
then
|
||||
mount -t overlay -o "lowerdir=$mnt/etc,upperdir=$mnt/var/lib/overlays/etc/upper,workdir=$mnt/var/lib/overlays/etc/work" none "$mnt/etc"
|
||||
fi
|
||||
|
||||
# Mount boot
|
||||
if [[ ! "${novar:-}" ]] && [[ ! "${noboot:-}" ]]
|
||||
then
|
||||
mount --bind "$mnt/var/boot" "$mnt/boot"
|
||||
fi
|
||||
trap - 0
|
||||
1
presets/steam/steamos/bin/steamos-notice
Symbolic link
1
presets/steam/steamos/bin/steamos-notice
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
204
presets/steam/steamos/bin/steamos-partsets
Executable file
204
presets/steam/steamos/bin/steamos-partsets
Executable file
@@ -0,0 +1,204 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2019-2020 Collabora Ltd.
|
||||
# Copyright © 2019-2020 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
OUTDIR= # $1
|
||||
DEVICES= # --devices=
|
||||
|
||||
[ -e /usr/lib/steamos/steamos-partitions-lib ] && \
|
||||
. /usr/lib/steamos/steamos-partitions-lib || \
|
||||
{ echo "Failed to source '/usr/lib/steamos/steamos-partitions-lib'"; exit 1; }
|
||||
|
||||
# Helpers
|
||||
|
||||
log () { echo >&2 "$@"; }
|
||||
fail() { echo >&2 "$@"; exit 1; }
|
||||
|
||||
usage() {
|
||||
local status=${1-2}
|
||||
|
||||
if [ $status -ne 0 ]; then
|
||||
exec >&2
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "Usage: $(basename $0) [--devices 'efi esp-A esp-B ...'] OUTDIR"
|
||||
echo
|
||||
echo "In the output directory, this script creates 4 files that define the SteamOS"
|
||||
echo "partition definitions: all, self, other, shared."
|
||||
echo
|
||||
echo "The output directory should not exist."
|
||||
echo
|
||||
echo "This program starts off the / mountpoint, and from there it guesses the disk"
|
||||
echo "on which SteamOS is installed, if the current root partition belongs to A or B,"
|
||||
echo "and then which partitions belong to 'self', 'other' or 'shared'."
|
||||
echo
|
||||
echo "It is assumed that all partitions on the disk belong to SteamOS, unless you"
|
||||
echo "use --devices to provide a space-separated list of partitions. In such case,"
|
||||
echo "only the partitions that belong to this list are kept."
|
||||
echo
|
||||
echo "This program should be used during the build of a SteamOS disk image,"
|
||||
echo "and also when SteamOS is installed to another disk. Apart from that,"
|
||||
echo "I don't see any other use-cases."
|
||||
echo
|
||||
|
||||
exit $status
|
||||
}
|
||||
|
||||
# Handle arguments
|
||||
|
||||
while [ $# -gt 0 ]; do
|
||||
case "$1" in
|
||||
-h|--help)
|
||||
usage 0
|
||||
;;
|
||||
--devices)
|
||||
shift
|
||||
DEVICES=$1
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
if ! [ "$OUTDIR" ]; then OUTDIR=$1; shift; continue; fi
|
||||
usage 1
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
[ -n "$OUTDIR" ] || fail "Too few argument"
|
||||
|
||||
# Get to know who we are: A, B or dev?
|
||||
|
||||
ROOTDEV=$(find_device_for_mountpoint_deep '/')
|
||||
[ -b "$ROOTDEV" ] || fail "Failed to get device for '/'"
|
||||
|
||||
ROOTLABEL=$(get_partlabel "$ROOTDEV")
|
||||
[ "$ROOTLABEL" ] || fail "Failed to get partition label for '$ROOTDEV'"
|
||||
|
||||
SELF=$(get_partition_set "$ROOTLABEL")
|
||||
[ "$SELF" ] || fail "Failed to determine partition set for label '$ROOTLABEL'"
|
||||
|
||||
OTHER=
|
||||
case "$SELF" in
|
||||
(A) OTHER=B;;
|
||||
(B) OTHER=A;;
|
||||
esac
|
||||
[ "$OTHER" ] || [ "$SELF" == "dev" ] || fail "Failed to determine 'other' for self=$SELF"
|
||||
|
||||
# Get the disk on which SteamOS lives
|
||||
|
||||
DISK=$(get_parent_device "$ROOTDEV")
|
||||
[ -b "$DISK" ] || fail "Failed to get disk for root device '$ROOTDEV'"
|
||||
|
||||
# We know everything, let's go
|
||||
|
||||
log "SteamOS root device: $ROOTDEV ($ROOTLABEL)"
|
||||
log "SteamOS disk : $DISK"
|
||||
log "A/B/dev status : self=$SELF, other=$OTHER"
|
||||
log "Creating partition definitions in $OUTDIR ..."
|
||||
|
||||
[ -e "$OUTDIR" ] && fail "'$OUTDIR' already exists"
|
||||
mkdir -p "$OUTDIR"
|
||||
|
||||
while read device partuuid typeuuid partlabel; do
|
||||
|
||||
# NOTE that 'type-uuid' and 'name' might not be set, and that break us.
|
||||
# Ie. if type-uuid is not set, but name is set, then we end up with
|
||||
# name assigned to typeuuid, which is problematic.
|
||||
#
|
||||
# Well it's not that bad, as we expect caller to provide a list of
|
||||
# partitions in case there's more than one OS on the disk, and all
|
||||
# those partitions belong to SteamOS (so we know that we set all
|
||||
# those fields), EXCEPT for the ESP, which is shared with other OS.
|
||||
#
|
||||
# So we identify the ESP based on the typeuuid, which means that we
|
||||
# must take care that sfdisk outputs the typeuuid before the label,
|
||||
# in case there's no label set.
|
||||
|
||||
# If a device list was provided by caller, accept only those,
|
||||
# otherwise assume all devices on the disk belong to SteamOS.
|
||||
accepted=0
|
||||
if [ -z "$DEVICES" ]; then
|
||||
accepted=1
|
||||
else
|
||||
for d in $DEVICES; do
|
||||
if [ "$d" == "$device" ]; then
|
||||
accepted=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [ $accepted -eq 0 ]; then
|
||||
log "Discarding partition '$device' ($partlabel), not part of SteamOS"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Hack for ESP, as it's the only one which doesn't belong to
|
||||
# SteamOS, hence we can't control the name. So we identify it
|
||||
# using the type uuid, and pretend that the name is 'esp'.
|
||||
if [ "${typeuuid,,}" == c12a7328-f81f-11d2-ba4b-00a0c93ec93b ]; then
|
||||
partlabel=esp
|
||||
fi
|
||||
|
||||
if [ ! "$partlabel" ]; then
|
||||
log "Discarding partition '$device', label is empty"
|
||||
continue
|
||||
fi
|
||||
|
||||
# Guess partition set (A, B or dev) and linkname from label.
|
||||
partset=$(get_partition_set "$partlabel")
|
||||
linkname=$(get_partition_linkname "$partlabel")
|
||||
partuuid=${partuuid,,}
|
||||
group=
|
||||
|
||||
# Find the group, based on partset
|
||||
case "$partset" in
|
||||
("")
|
||||
group=shared
|
||||
;;
|
||||
("$SELF")
|
||||
group=self
|
||||
echo "$linkname $partuuid" >> "$OUTDIR/$partset"
|
||||
if [ "$SELF" == "dev" ]; then
|
||||
echo "$linkname $partuuid" >> "$OUTDIR/dev"
|
||||
fi
|
||||
;;
|
||||
("$OTHER")
|
||||
group=other
|
||||
echo "$linkname $partuuid" >> "$OUTDIR/$partset"
|
||||
;;
|
||||
("dev")
|
||||
group=dev
|
||||
;;
|
||||
("A")
|
||||
group=A
|
||||
;;
|
||||
("B")
|
||||
group=B
|
||||
;;
|
||||
(*)
|
||||
log "Discarding partition '$partlabel' with unexpected suffix '$partset'"
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
|
||||
# Add to partition definition files
|
||||
echo "$linkname $partuuid" >> "$OUTDIR/$group"
|
||||
echo "$partlabel $partuuid" >> "$OUTDIR/all"
|
||||
|
||||
done < <(sfdisk -ql -o device,uuid,type-uuid,name "$DISK" | tail +2)
|
||||
1
presets/steam/steamos/bin/steamos-poweroff
Symbolic link
1
presets/steam/steamos/bin/steamos-poweroff
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-reboot
|
||||
145
presets/steam/steamos/bin/steamos-readonly
Executable file
145
presets/steam/steamos/bin/steamos-readonly
Executable file
@@ -0,0 +1,145 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020-2021 Collabora Ltd.
|
||||
# Copyright © 2020-2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
declare -r ROOTDEV=/dev/disk/by-partsets/self/rootfs
|
||||
|
||||
# default and future guess
|
||||
fstype=btrfs
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} enable|disable|status
|
||||
|
||||
Enable or disable read-only on the current running SteamOS.
|
||||
EOF
|
||||
}
|
||||
|
||||
# mark root partition writable
|
||||
read_write_extfs() {
|
||||
tune2fs -O ^read-only "$ROOTDEV"
|
||||
mount -o remount,rw /
|
||||
}
|
||||
read_write_btrfs() {
|
||||
mount -o remount,rw /
|
||||
btrfs property set / ro false
|
||||
}
|
||||
read_write() {
|
||||
if ! status >/dev/null; then
|
||||
echo "Warning: The rootfs is already read-write!" >&2
|
||||
echo " Nothing is performed." >&2
|
||||
return
|
||||
fi
|
||||
read_write_$fstype
|
||||
}
|
||||
|
||||
#
|
||||
# mark root partition read-only
|
||||
read_only_btrfs() {
|
||||
btrfs property set / ro true
|
||||
}
|
||||
read_only_extfs() {
|
||||
mount -o remount,ro /
|
||||
tune2fs -O read-only "$ROOTDEV"
|
||||
}
|
||||
read_only() {
|
||||
if status >/dev/null; then
|
||||
echo "Warning: The rootfs is already read-only!" >&2
|
||||
echo " Nothing is performed." >&2
|
||||
return
|
||||
fi
|
||||
sync /
|
||||
read_only_$fstype
|
||||
}
|
||||
|
||||
status_extfs() {
|
||||
if tune2fs -l "$ROOTDEV" | grep -q '^Filesystem features: .*read-only.*$'
|
||||
then
|
||||
echo "enabled"
|
||||
return
|
||||
else
|
||||
echo "disabled"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
status_btrfs() {
|
||||
prop_val=$(btrfs property get / ro)
|
||||
if [[ $prop_val = "ro=true" ]]
|
||||
then
|
||||
echo "enabled"
|
||||
else
|
||||
echo "disabled"
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
status() {
|
||||
status_$fstype
|
||||
}
|
||||
|
||||
|
||||
toggle() {
|
||||
if status >/dev/null
|
||||
then
|
||||
read_write
|
||||
else
|
||||
read_only
|
||||
fi
|
||||
status
|
||||
}
|
||||
|
||||
# determine file system type and set the fstype variable used above
|
||||
get_fstype() {
|
||||
declare -r FSTYPE=$(findmnt -fn --output FSTYPE /)
|
||||
case "$FSTYPE" in
|
||||
ext4)
|
||||
fstype=extfs
|
||||
;;
|
||||
btrfs)
|
||||
fstype=btrfs
|
||||
;;
|
||||
*)
|
||||
echo "Unrecognized root filesystem type $FSTYPE"
|
||||
exit 1
|
||||
esac
|
||||
}
|
||||
|
||||
# Ideally status will be root-free, alas tune2fs (ext4 rootfs)
|
||||
# does not like that.
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "$(basename $0) needs to be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
get_fstype
|
||||
|
||||
case "${1:-}" in
|
||||
disable)
|
||||
read_write
|
||||
;;
|
||||
enable)
|
||||
read_only
|
||||
;;
|
||||
toggle)
|
||||
toggle
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
esac
|
||||
216
presets/steam/steamos/bin/steamos-reboot
Executable file
216
presets/steam/steamos/bin/steamos-reboot
Executable file
@@ -0,0 +1,216 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020-2021 Collabora Ltd.
|
||||
# Copyright © 2020-2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -o pipefail
|
||||
set -u
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
${0##*/} [OPTIONS...] [ARG]
|
||||
|
||||
Reboot SteamOS.
|
||||
|
||||
Options:
|
||||
--next XXXX
|
||||
Set BootNext to XXXX (Boothex or Label)
|
||||
to boot on XXXX at next boot
|
||||
See efibootmgr --bootnext usage
|
||||
Same as --reboot-to-firmware-entry XXXX
|
||||
--factory-reset
|
||||
Perform factory reset at shutdown
|
||||
--update
|
||||
Set mode update to update at next boot
|
||||
--update-other
|
||||
Set mode update-other to update other at next boot
|
||||
--reboot-other
|
||||
Set mode reboot-other to boot on other at next boot
|
||||
--reboot-to-firmware-entry ENTRY
|
||||
Set firmware entry at next boot
|
||||
--reboot-to-bootloader-menu TIMEOUT
|
||||
Set timeout in sec and enter menu at next boot
|
||||
--reboot-to-bootloader-entry ENTRY
|
||||
Set bootloader entry at next boot
|
||||
--reboot-to-firmware-setup
|
||||
Set OS indications to enter firmware setup at next boot
|
||||
--list-firmware-entries
|
||||
List firmware entries
|
||||
--list-bootloader-entries
|
||||
List bootloader entries
|
||||
EOF
|
||||
"${0##*/steamos-}" --help | sed -n '/^Options:/,//{//d;p}'
|
||||
}
|
||||
|
||||
prompt() {
|
||||
if [[ ! -t 0 ]]
|
||||
then
|
||||
return 0
|
||||
fi
|
||||
|
||||
while true
|
||||
do
|
||||
echo -n "$* " >&2
|
||||
read -r resp _
|
||||
resp="${resp:-no}"
|
||||
|
||||
case "${resp,,}" in
|
||||
yes) return 0;;
|
||||
n|no) return 1;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
get_efivar_str() {
|
||||
cat "/sys/firmware/efi/efivars/$1" | dd bs=1 skip=4 status=none | \
|
||||
iconv -t ASCII -f UTF-16LE | tr '\0' '\n'
|
||||
}
|
||||
|
||||
get_efivar_hex() {
|
||||
local hex
|
||||
|
||||
read -r hex < <(od -An -tx8 -N8 -j4 "/sys/firmware/efi/efivars/$1")
|
||||
echo "0x$hex"
|
||||
}
|
||||
|
||||
set_efivar_hex() {
|
||||
local file
|
||||
local fmt
|
||||
local hex
|
||||
|
||||
hex="$(printf "%016x" "$2")"
|
||||
fmt="\x07\x00\x00\x00"
|
||||
fmt+="\x${hex:14:2}\x${hex:12:2}\x${hex:10:2}\x${hex:8:2}"
|
||||
fmt+="\x${hex:6:2}\x${hex:4:2}\x${hex:2:2}\x${hex:0:2}"
|
||||
|
||||
file="$1.$$"
|
||||
printf "$fmt" >"$file"
|
||||
trap "rm -f $file" 0
|
||||
}
|
||||
|
||||
set_efivar_ascii() {
|
||||
local file
|
||||
|
||||
file="$1.$$"
|
||||
touch "$file"
|
||||
trap "rm -f $file" 0
|
||||
printf "\x07\x00\x00\x00" >"$file"
|
||||
iconv -t utf-16le <<<"$2" | tr '\n' '\0' >>"$file"
|
||||
|
||||
cp "$file" "/sys/firmware/efi/efivars/$1"
|
||||
rm -f "$file"
|
||||
trap - 0
|
||||
}
|
||||
|
||||
opts=()
|
||||
while [[ "$#" -ne 0 ]]
|
||||
do
|
||||
if [[ "$1" =~ ^(-h|--help)$ ]]
|
||||
then
|
||||
usage
|
||||
exit 0
|
||||
elif [[ "$1" =~ ^--factory-reset$ ]]
|
||||
then
|
||||
if ! prompt "Are you sure to perform factory-reset [no/yes]?"
|
||||
then
|
||||
echo "Abort!" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
steamos-factory-reset-config /esp/efi/steamos/factory-reset
|
||||
/usr/bin/steamos-set-bootmode reboot
|
||||
elif [[ "$1" =~ ^--update$ ]] || [[ "$1" =~ ^--(update|reboot)-other$ ]]
|
||||
then
|
||||
/usr/bin/steamos-set-bootmode ${1:2}
|
||||
elif [[ "$1" =~ ^--next$ ]]
|
||||
then
|
||||
shift
|
||||
if [[ ! "${1:-}" ]]
|
||||
then
|
||||
usage
|
||||
echo "Error: Too few argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ "$1" =~ ^Boot[0-9A-Fa-F]{4,4}$ ]]
|
||||
then
|
||||
next="$1"
|
||||
else
|
||||
mapfile -t entries < <(efibootmgr | sed -n '/^Boot[0-9A-Fa-f]\{4,4\}./p')
|
||||
for entry in "${entries[@]}"
|
||||
do
|
||||
if [[ "$1" == "${entry:10}" ]]
|
||||
then
|
||||
next="${entry:0:8}"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
if [[ "${next:-}" ]]
|
||||
then
|
||||
efibootmgr -n "${next:4}"
|
||||
else
|
||||
echo "Warning: $1: No Such BootEntry" >&2
|
||||
fi
|
||||
elif [[ "$1" =~ ^--reboot-to-bootloader-menu$ ]]
|
||||
then
|
||||
shift
|
||||
if [[ ! "${1:-}" ]]
|
||||
then
|
||||
usage
|
||||
echo "Error: Too few argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ascii="$(($1 * 1000000))"
|
||||
set_efivar_ascii "LoaderConfigTimeoutOneShot-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f" "$ascii"
|
||||
unset ascii
|
||||
elif [[ "$1" =~ ^--reboot-to-bootloader-entry$ ]]
|
||||
then
|
||||
shift
|
||||
if [[ ! "${1:-}" ]]
|
||||
then
|
||||
usage
|
||||
echo "Error: Too few argument" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set_efivar_ascii "LoaderEntryOneShot-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f" "$1"
|
||||
elif [[ "$1" =~ ^--reboot-to-firmware-setup$ ]]
|
||||
then
|
||||
shift
|
||||
|
||||
hex="$(get_efivar_hex "OsIndicationsSupported-8be4df61-93ca-11d2-aa0d-00e098032b8c")"
|
||||
hex="$((hex|1))"
|
||||
set_efivar_hex "OsIndications-8be4df61-93ca-11d2-aa0d-00e098032b8c" "$hex"
|
||||
unset hex
|
||||
elif [[ "$1" =~ ^--list-firmware-entries$ ]]
|
||||
then
|
||||
efibootmgr | sed -n '/^Boot[0-9A-Fa-f]\{4,4\}. /s,\(Boot[0-9A-Fa-f]\{4\,4\}\). \(.*\),\1\n\2,p' \
|
||||
| sed '/^$/d' \
|
||||
| sort -u
|
||||
exit 0
|
||||
elif [[ "$1" =~ ^--list-bootloader-entries$ ]]
|
||||
then
|
||||
get_efivar_str "LoaderEntries-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f"
|
||||
exit 0
|
||||
else
|
||||
opts+=("$1")
|
||||
fi
|
||||
shift
|
||||
done
|
||||
|
||||
exec "${0##*/steamos-}" "${opts[@]}"
|
||||
36
presets/steam/steamos/bin/steamos-select-branch
Executable file
36
presets/steam/steamos/bin/steamos-select-branch
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
BRANCH_PATH="/var/lib/steamos-branch"
|
||||
|
||||
if [[ "$#" = 1 ]]; then
|
||||
case "$1" in
|
||||
"-c")
|
||||
branch=$(cat "$BRANCH_PATH" 2> /dev/null || echo "rel")
|
||||
case "$branch" in
|
||||
"rel" | "rc" | "beta" | "bc" | "main")
|
||||
echo "$branch"
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
echo "unknown branch name in $BRANCH_PATH: $branch" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
;;
|
||||
"-l")
|
||||
echo rel
|
||||
echo rc
|
||||
echo beta
|
||||
echo bc
|
||||
echo main
|
||||
exit 0
|
||||
;;
|
||||
"rel" | "rc" | "beta" | "bc" | "main")
|
||||
echo "$1" > "$BRANCH_PATH"
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
echo "Usage: steamos-select-branch <-c|-l|rel|rc|beta|bc|main>" 1>&2
|
||||
84
presets/steam/steamos/bin/steamos-session-select
Executable file
84
presets/steam/steamos/bin/steamos-session-select
Executable file
@@ -0,0 +1,84 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
die() { echo >&2 "!! $*"; exit 1; }
|
||||
|
||||
# FIXME Purge old files and use this one
|
||||
|
||||
# File this script will modify, in addition to (potentially) the per-user sentinel file
|
||||
CONF_FILE="/etc/sddm.conf.d/zz-steamos-autologin.conf"
|
||||
|
||||
SENTINEL_FILE="steamos-session-select"
|
||||
|
||||
# For sanity this shipped file must be present, to ensure we're still on a normal-looking steamos setup.
|
||||
CHECK_FILE="/etc/sddm.conf.d/steamos.conf"
|
||||
|
||||
session="${1:-gamescope}"
|
||||
|
||||
session_launcher=""
|
||||
create_sentinel=""
|
||||
session_uses_x11=""
|
||||
|
||||
case "$session" in
|
||||
plasma-wayland-persistent)
|
||||
session_launcher="plasmawayland.desktop"
|
||||
;;
|
||||
plasma-persistent)
|
||||
session_launcher="plasma.desktop"
|
||||
session_uses_x11=1
|
||||
;;
|
||||
plasma)
|
||||
session_launcher="plasma-steamos-oneshot.desktop"
|
||||
create_sentinel=1
|
||||
session_uses_x11=1
|
||||
;;
|
||||
gamescope)
|
||||
session_launcher="gamescope-wayland.desktop"
|
||||
;;
|
||||
*)
|
||||
echo >&2 "!! Unrecognized session '$session'"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ "$2" == "--sentinel-created" ]]; then
|
||||
SENTINEL_CREATED=1
|
||||
fi
|
||||
|
||||
# Update config sentinel
|
||||
if [[ -z $SENTINEL_CREATED ]]; then
|
||||
[[ -n ${HOME+x} ]] || die "No \$HOME variable"
|
||||
config_dir="${XDG_CONF_DIR:-"$HOME/.config"}"
|
||||
(
|
||||
cd "$HOME"
|
||||
mkdir -p "$config_dir"
|
||||
cd "$config_dir"
|
||||
echo "$session_launcher" > "$SENTINEL_FILE"
|
||||
)
|
||||
|
||||
# If we were executed as a session user and then re-execute as root below, we don't want to set root's sentinel too
|
||||
export SENTINEL_CREATED=1
|
||||
echo "Updated user selected session to $session_launcher"
|
||||
fi
|
||||
|
||||
# Become root
|
||||
if [[ $EUID != 0 ]]; then
|
||||
exec pkexec "$(realpath $0)" "$session" --sentinel-created
|
||||
exit 1
|
||||
fi
|
||||
|
||||
{
|
||||
if [[ -n $session_uses_x11 ]]; then
|
||||
# Default is Wayland
|
||||
echo "[General]"
|
||||
echo "DisplayServer=X11"
|
||||
fi
|
||||
echo "[Autologin]"
|
||||
echo "Session=$session_launcher"
|
||||
} > "$CONF_FILE"
|
||||
|
||||
echo "Updated system autologin session to $session_launcher"
|
||||
systemctl reset-failed sddm
|
||||
systemctl restart sddm
|
||||
echo "Restarted SDDM"
|
||||
113
presets/steam/steamos/bin/steamos-settings-importer
Executable file
113
presets/steam/steamos/bin/steamos-settings-importer
Executable file
@@ -0,0 +1,113 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020-2021 Collabora Ltd.
|
||||
# Copyright © 2020-2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
SETTINGS_DIR=/efi/settings
|
||||
|
||||
# Copy steam-settings files from /efi/steam-settings to /home/steamos/.steam-settings/ folder.
|
||||
if [ -d /efi/steam-settings ]; then
|
||||
# Create target folder if it doesn't exist
|
||||
mkdir -p /home/steamos/.steam-settings
|
||||
# Copy all settings files to .steam-settings
|
||||
cp /efi/steam-settings/* /home/steamos/.steam-settings
|
||||
# Change the owner so steam client can read the files.
|
||||
chown -R steamos:steamos /home/steamos/.steam-settings
|
||||
fi
|
||||
|
||||
if ! [ -d $SETTINGS_DIR ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Make sure to consume the settings dir, whatever happens
|
||||
trap "rm -fr $SETTINGS_DIR" EXIT
|
||||
|
||||
# Import user settings
|
||||
if [ -f $SETTINGS_DIR/settings.conf ]; then
|
||||
|
||||
. $SETTINGS_DIR/settings.conf
|
||||
|
||||
if [ "$LOCALE" ]; then
|
||||
echo "Setting locale: $LOCALE"
|
||||
localectl set-locale $LOCALE
|
||||
fi
|
||||
|
||||
if [ "$TZ" ]; then
|
||||
echo "Setting timezone: $TZ"
|
||||
timedatectl set-timezone $TZ
|
||||
fi
|
||||
|
||||
if [ "$KEYBOARD" ]; then
|
||||
KBDLAYOUT=$(echo $KEYBOARD | cut -d ':' -f 1)
|
||||
|
||||
KBDMODEL="pc105"
|
||||
case "$KBDLAYOUT" in
|
||||
"jp" )
|
||||
KBDMODEL="jp106"
|
||||
;;
|
||||
esac
|
||||
|
||||
KBDVARIANT=""
|
||||
if grep -q ':' <<< "$KEYBOARD"; then
|
||||
KBDVARIANT=$(echo $KEYBOARD | cut -d ':' -f 2)
|
||||
fi
|
||||
|
||||
echo "Setting keyboard: layout=$KBDLAYOUT, model=$KBDMODEL, variant=$KBDVARIANT (from '$KEYBOARD')"
|
||||
localectl set-x11-keymap $KBDLAYOUT $KBDMODEL $KBDVARIANT
|
||||
|
||||
# Make sure X will start with the right keyboard layout
|
||||
mkdir -p /etc/X11/xorg.conf.d
|
||||
cat > /etc/X11/xorg.conf.d/00-keyboard.conf << EOF
|
||||
# Read and parsed by systemd-localed. It's probably wise not to edit this file
|
||||
# manually too freely.
|
||||
Section "InputClass"
|
||||
Identifier "system-keyboard"
|
||||
MatchIsKeyboard "on"
|
||||
Option "XkbLayout" "$KBDLAYOUT"
|
||||
Option "XkbModel" "$KBDMODEL"
|
||||
Option "XkbVariant" "$KBDVARIANT"
|
||||
EndSection
|
||||
EOF
|
||||
|
||||
# Make sure the layout is applied to all ttys
|
||||
# XXX No setupcon on ArchLinux, I guess we need something else,
|
||||
# like loadkeys?
|
||||
if command -v setupcon >/dev/null 2>&1; then
|
||||
setupcon
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
# Import steam libraries
|
||||
if [ -f $SETTINGS_DIR/steamlibtab ]; then
|
||||
echo "Setting steamlibtab:"
|
||||
cat $SETTINGS_DIR/steamlibtab | tee --append /etc/steamlibtab
|
||||
systemctl daemon-reload
|
||||
systemctl restart local-fs.target
|
||||
fi
|
||||
|
||||
# Import network configuration
|
||||
if [ -d $SETTINGS_DIR/network-connections ]; then
|
||||
echo "Installing network configuration"
|
||||
mkdir -p /etc/NetworkManager/system-connections
|
||||
install -v -m 0600 $SETTINGS_DIR/network-connections/* /etc/NetworkManager/system-connections/
|
||||
fi
|
||||
|
||||
# Mark setup as complete to prevent initial setup from running
|
||||
mkdir -p /var/lib/calamares-steamos
|
||||
touch /var/lib/calamares-steamos/initial_setup_complete
|
||||
rm -f /etc/sddm.conf.d/calamares-initial-setup.conf \
|
||||
/root/.config/kwinrulesrc \
|
||||
/root/.xsessions/steamos-initial-setup.desktop
|
||||
|
||||
170
presets/steam/steamos/bin/steamos-update
Executable file
170
presets/steam/steamos/bin/steamos-update
Executable file
@@ -0,0 +1,170 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -eu
|
||||
|
||||
##
|
||||
## This script must match the API the temporary Steam UI updater wants of us, including this file
|
||||
##
|
||||
|
||||
unset tmpdir
|
||||
cleanup() { rm -rf /tmp/steamos-update.pid; [[ -z ${tmpdir-} ]] || rm -rf --one-file-system -- "$tmpdir"; }
|
||||
trap cleanup EXIT
|
||||
touch /tmp/steamos-update.pid
|
||||
info() { echo >&2 "$*"; }
|
||||
die() { info "!! $*"; exit 1; }
|
||||
|
||||
|
||||
checkmode=""
|
||||
error=""
|
||||
beta=""
|
||||
debug=""
|
||||
|
||||
while [[ $# -ge 1 ]]; do
|
||||
case "$1" in
|
||||
"check") checkmode=1 ;;
|
||||
"--beta") beta=1 ;;
|
||||
"-d") debug=1 ;;
|
||||
*)
|
||||
error=1
|
||||
info "Unknown option \"$1\""
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if [[ -n $error ]]; then
|
||||
echo >&2 "!! Usage: $0 [check]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
atomupd_args=(--manifest "/usr/share/steamos-update/manifest-0.json")
|
||||
[[ -n $debug ]] && atomupd_args+=(-d)
|
||||
|
||||
# Determine which branches to check.
|
||||
check_rel=0
|
||||
check_rc=0
|
||||
check_beta=0
|
||||
check_bc=0
|
||||
check_main=0
|
||||
|
||||
if [[ -n $beta ]]; then
|
||||
info "'--beta' is deprecated; use 'steamos-select-branch beta' then 'steamos-update'"
|
||||
check_beta=1
|
||||
else
|
||||
branch_path="/var/lib/steamos-branch"
|
||||
branch=$(cat "$branch_path" 2> /dev/null || echo "rel")
|
||||
case "$branch" in
|
||||
"rel")
|
||||
check_rel=1
|
||||
;;
|
||||
"rc")
|
||||
check_rel=1
|
||||
check_rc=1
|
||||
;;
|
||||
"beta")
|
||||
check_beta=1
|
||||
;;
|
||||
"bc")
|
||||
check_beta=1
|
||||
check_bc=1
|
||||
;;
|
||||
"main")
|
||||
check_main=1
|
||||
;;
|
||||
*)
|
||||
echo "unknown branch name in $branch_path: $branch" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Get the buildid for each variant.
|
||||
get_buildid () {
|
||||
if [[ $1 = 0 ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
query="$(sudo steamos-atomupd-client "${atomupd_args[@]}" --variant="$2" --query-only)"
|
||||
if [[ -z $query ]]; then
|
||||
info "Failed to check for updates"
|
||||
exit 1 # Unknown failure
|
||||
fi
|
||||
|
||||
jq -r '.minor.candidates[0].image.buildid | select(type == "string")' <<< "$query"
|
||||
}
|
||||
|
||||
buildid_rel="$(get_buildid $check_rel steamdeck)"
|
||||
buildid_rc="$(get_buildid $check_rc steamdeck-rc)"
|
||||
buildid_beta="$(get_buildid $check_beta steamdeck-beta)"
|
||||
buildid_bc="$(get_buildid $check_bc steamdeck-bc)"
|
||||
buildid_main="$(get_buildid $check_main steamdeck-main)"
|
||||
|
||||
if [[ -n $debug ]]; then
|
||||
info "buildid_rel=$buildid_rel"
|
||||
info "buildid_rc=$buildid_rc"
|
||||
info "buildid_beta=$buildid_beta"
|
||||
info "buildid_bc=$buildid_bc"
|
||||
info "buildid_main=$buildid_main"
|
||||
fi
|
||||
|
||||
# Choose the variant with the newest buildid.
|
||||
chosen_buildid=""
|
||||
chosen_variant=""
|
||||
|
||||
if [[ "$buildid_rel" > "$chosen_buildid" ]]; then
|
||||
chosen_buildid="$buildid_rel"
|
||||
chosen_variant="steamdeck"
|
||||
fi
|
||||
if [[ "$buildid_rc" > "$chosen_buildid" ]]; then
|
||||
chosen_buildid="$buildid_rc"
|
||||
chosen_variant="steamdeck-rc"
|
||||
fi
|
||||
if [[ "$buildid_beta" > "$chosen_buildid" ]]; then
|
||||
chosen_buildid="$buildid_beta"
|
||||
chosen_variant="steamdeck-beta"
|
||||
fi
|
||||
if [[ "$buildid_bc" > "$chosen_buildid" ]]; then
|
||||
chosen_buildid="$buildid_bc"
|
||||
chosen_variant="steamdeck-bc"
|
||||
fi
|
||||
if [[ "$buildid_main" > "$chosen_buildid" ]]; then
|
||||
chosen_buildid="$buildid_main"
|
||||
chosen_variant="steamdeck-main"
|
||||
fi
|
||||
|
||||
if [[ -z "$chosen_variant" ]]; then
|
||||
info "No update available"
|
||||
exit 7
|
||||
fi
|
||||
|
||||
manifest_path="/etc/steamos-atomupd/manifest.json"
|
||||
current_buildid=$(jq -r .buildid < "$manifest_path")
|
||||
if [[ "$current_buildid" = "$chosen_buildid" ]]; then
|
||||
info "No update available"
|
||||
exit 7
|
||||
fi
|
||||
|
||||
if [[ -n $debug ]]; then
|
||||
info "chosen_buildid=$chosen_buildid"
|
||||
info "chosen_variant=$chosen_variant"
|
||||
fi
|
||||
|
||||
# Update is available
|
||||
info "Update available"
|
||||
|
||||
# Check mode, return success for update available
|
||||
if [[ -n ${checkmode-} ]]; then
|
||||
echo "$chosen_buildid"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Not check mode. Update!
|
||||
do_atomupd() { sudo steamos-atomupd-client "${atomupd_args[@]}" --variant="$chosen_variant" "$@"; }
|
||||
|
||||
if do_atomupd; then
|
||||
info "Applied an update"
|
||||
exit 0
|
||||
else
|
||||
info "Update failed"
|
||||
exit 1
|
||||
fi
|
||||
69
presets/steam/steamos/bin/steamos-update-os
Executable file
69
presets/steam/steamos/bin/steamos-update-os
Executable file
@@ -0,0 +1,69 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2019-2020 Collabora Ltd.
|
||||
# Copyright © 2019-2020 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -e
|
||||
set -u
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} now [ATOMUPD-OPTIONS]
|
||||
${0##*/} after-reboot
|
||||
${0##*/} -h|--help
|
||||
EOF
|
||||
}
|
||||
|
||||
update_now() {
|
||||
if ! steamos-atomupd-client "$@"; then
|
||||
echo "SteamOS cannot be updated!" >&2
|
||||
sleep 5s
|
||||
fi
|
||||
|
||||
if grep -q 'systemd.unit=steamos-update-os.target' /proc/cmdline; then
|
||||
steamos-logger "Rebooting in 5 seconds...";
|
||||
sleep 5s
|
||||
reboot
|
||||
else
|
||||
echo "Reboot to run the new version of SteamOS." >&2
|
||||
fi
|
||||
}
|
||||
|
||||
update_after_reboot() {
|
||||
/usr/sbin/steamos-set-bootmode update-other
|
||||
echo "Reboot to start the update of SteamOS." >&2
|
||||
}
|
||||
|
||||
if [[ $# -eq 0 ]]; then
|
||||
usage
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "$1" in
|
||||
(now)
|
||||
shift
|
||||
update_now "$@"
|
||||
;;
|
||||
(after-reboot)
|
||||
shift
|
||||
update_after_reboot
|
||||
;;
|
||||
(-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
(*)
|
||||
usage
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
144
presets/steam/steamos/bin/steamos-verity
Executable file
144
presets/steam/steamos/bin/steamos-verity
Executable file
@@ -0,0 +1,144 @@
|
||||
#!/bin/bash
|
||||
# -*- mode: sh; indent-tabs-mode: nil; sh-basic-offset: 4; -*-
|
||||
# vim: et sts=4 sw=4
|
||||
|
||||
# SPDX-License-Identifier: LGPL-2.1+
|
||||
#
|
||||
# Copyright © 2020-2021 Collabora Ltd.
|
||||
# Copyright © 2020-2021 Valve Corporation.
|
||||
#
|
||||
# This file is part of steamos-customizations.
|
||||
#
|
||||
# steamos-customizations is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU Lesser General Public License as
|
||||
# published by the Free Software Foundation; either version 2.1 of the License,
|
||||
# or (at your option) any later version.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
declare -r ROOTDEV=/dev/disk/by-partsets/self/rootfs
|
||||
declare -r VERITYDEV=/dev/disk/by-partsets/self/verity
|
||||
declare -r HASHFILE=/efi/SteamOS/roothash
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: ${0##*/} enable|disable|status|verify
|
||||
|
||||
Enable or disable the block level verification on the current running SteamOS.
|
||||
EOF
|
||||
}
|
||||
|
||||
mapper_root_mounted() {
|
||||
grep -q '^/dev/mapper/root / ' /proc/mounts
|
||||
}
|
||||
|
||||
read_write() {
|
||||
steamos-readonly disable
|
||||
|
||||
if mapper_root_mounted
|
||||
then
|
||||
echo "Warning: The rootfs is still read-only!" >&2
|
||||
echo " Reboot to complete setup." >&2
|
||||
return
|
||||
fi
|
||||
rm -f "$HASHFILE"
|
||||
sync /
|
||||
}
|
||||
|
||||
read_only() {
|
||||
if mapper_root_mounted
|
||||
then
|
||||
echo "Warning: The rootfs is already read-only!" >&2
|
||||
echo " Nothing is performed." >&2
|
||||
return
|
||||
fi
|
||||
|
||||
local block_size=$(blkid -o value -s BLOCK_SIZE "$ROOTDEV")
|
||||
|
||||
steamos-readonly enable
|
||||
|
||||
veritysetup format --data-block-size "$block_size" --hash-block-size "$block_size" \
|
||||
"$ROOTDEV" "$VERITYDEV" | \
|
||||
tee /dev/stderr | \
|
||||
sed -n 's,^Root hash:[[:blank:]]\+\([[:xdigit:]]\{64\}\)$,\1,p' > "$HASHFILE"
|
||||
|
||||
echo "Reboot to complete setup." >&2
|
||||
}
|
||||
|
||||
status() {
|
||||
local filesystem_is_readonly
|
||||
local device_is_readonly
|
||||
local roothash
|
||||
|
||||
if mapper_root_mounted
|
||||
then
|
||||
device_is_readonly=yes
|
||||
fi
|
||||
|
||||
if steamos-readonly status >/dev/null
|
||||
then
|
||||
filesystem_is_readonly=yes
|
||||
fi
|
||||
|
||||
if [[ -e "$HASHFILE" ]]
|
||||
then
|
||||
roothash="$(cat $HASHFILE)"
|
||||
fi
|
||||
|
||||
if [[ "${roothash:-}" ]] && [[ "${device_is_readonly:-}" ]] && [[ "${filesystem_is_readonly:-}" ]]
|
||||
then
|
||||
echo "enabled"
|
||||
return
|
||||
fi
|
||||
|
||||
# XXX: this seems off
|
||||
if [[ ! "${roothash:-}" ]] && [[ ! "${filesystem_is_readonly:-}" ]]
|
||||
then
|
||||
echo "disabled"
|
||||
return 1
|
||||
elif [[ ! "${roothash:-}" ]] && [[ ! "${filesystem_is_readonly:-}" ]]
|
||||
then
|
||||
echo "disabled${device_is_readonly:+ (after reboot)}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "unknown"
|
||||
echo "- device-is-read-only: ${device_is_readonly:-no}"
|
||||
echo "- filesystem-is-read-only: ${filesystem_is_readonly:-no}"
|
||||
echo "- roothash: ${roothash:-none}"
|
||||
return 1
|
||||
}
|
||||
|
||||
verify() {
|
||||
if [[ ! -e "$HASHFILE" ]]
|
||||
then
|
||||
return 1
|
||||
fi
|
||||
|
||||
veritysetup verify "$ROOTDEV" "$VERITYDEV" "$(cat $HASHFILE)"
|
||||
}
|
||||
|
||||
# Ideally status will be root-free, alas steamos-readonly status
|
||||
# does not like that.
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "$(basename $0) needs to be run as root"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
case "${1:-}" in
|
||||
disable)
|
||||
read_write
|
||||
;;
|
||||
enable)
|
||||
read_only
|
||||
;;
|
||||
status)
|
||||
status
|
||||
;;
|
||||
verify)
|
||||
verify
|
||||
;;
|
||||
*)
|
||||
usage
|
||||
exit 1
|
||||
esac
|
||||
1
presets/steam/steamos/bin/steamos-warning
Symbolic link
1
presets/steam/steamos/bin/steamos-warning
Symbolic link
@@ -0,0 +1 @@
|
||||
steamos-logger
|
||||
Reference in New Issue
Block a user