Streamline the installer for fresh Arch installs
This commit is contained in:
1 parent
501d066e64
commit
d59725f193
14 files changed
+234
-44
No files matched your search
@@ -59,6 +59,17 @@ and nothing to re-apply after somebody else's release.
|
|||||||
|
|
||||||
## Install
|
## Install
|
||||||
|
|
||||||
|
On a fresh Arch install, logged in as your own user with sudo and a network
|
||||||
|
connection:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
curl -fsSL https://git.sirblob.co/SirBlob/blomarchy/raw/branch/main/bootstrap.sh | bash
|
||||||
|
```
|
||||||
|
|
||||||
|
`bootstrap.sh` installs `git`, clones this repository to `~/dotfiles` (or
|
||||||
|
`BLOB_CHECKOUT_DIR`), and runs `install.sh`, passing any flags through with
|
||||||
|
`bash -s -- --autologin`.
|
||||||
|
|
||||||
`BLOB_PATH` is a symlink to this checkout, so `bin/`, `shell/`, `themes/` and
|
`BLOB_PATH` is a symlink to this checkout, so `bin/`, `shell/`, `themes/` and
|
||||||
`default/` are always the working tree and edits are live. Only the handful of
|
`default/` are always the working tree and edits are live. Only the handful of
|
||||||
files that must sit under `~/.config` get copied.
|
files that must sit under `~/.config` get copied.
|
||||||
@@ -75,6 +86,7 @@ It runs these steps, in this order, and every one of them is idempotent:
|
|||||||
|
|
||||||
| Step | What it does |
|
| Step | What it does |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
| 0. Preflight | stops if run as root, off Arch, without working sudo, or offline, warns when another network manager is enabled next to NetworkManager, and keeps sudo alive for the whole run |
|
||||||
| 1. Directories | creates the 19 directories the shell and scripts expect, before anything writes into them |
|
| 1. Directories | creates the 19 directories the shell and scripts expect, before anything writes into them |
|
||||||
| 2. `BLOB_PATH` | symlinks `~/.local/share/blob` to this checkout |
|
| 2. `BLOB_PATH` | symlinks `~/.local/share/blob` to this checkout |
|
||||||
| 3. Packages | installs what is missing from `packages/`, bootstrapping `yay` first on a machine that has no AUR helper |
|
| 3. Packages | installs what is missing from `packages/`, bootstrapping `yay` first on a machine that has no AUR helper |
|
||||||
@@ -85,7 +97,10 @@ It runs these steps, in this order, and every one of them is idempotent:
|
|||||||
| 8. System services | enables NetworkManager, resolved, bluetooth, cups, avahi, docker, power-profiles-daemon, and oomd, masks `NetworkManager-wait-online`, sets the boot splash to `branding/blob_boot.png`, and sets GRUB up with every other installed OS in its menu |
|
| 8. System services | enables NetworkManager, resolved, bluetooth, cups, avahi, docker, power-profiles-daemon, and oomd, masks `NetworkManager-wait-online`, sets the boot splash to `branding/blob_boot.png`, and sets GRUB up with every other installed OS in its menu |
|
||||||
| 9. Login screen | installs the session entry and the SDDM config, enables `sddm.service`, and sets the default target to `graphical.target` |
|
| 9. Login screen | installs the session entry and the SDDM config, enables `sddm.service`, and sets the default target to `graphical.target` |
|
||||||
| 10. Reload | reloads systemd, restarts the running user services, and in a running session re-renders the theme, reloads Hyprland, and restarts the Blob shell |
|
| 10. Reload | reloads systemd, restarts the running user services, and in a running session re-renders the theme, reloads Hyprland, and restarts the Blob shell |
|
||||||
| 11. Launch | starts the login screen, so the desktop comes up without a reboot |
|
| 11. Launch | offers a reboot, or starts the login screen straight away if you decline |
|
||||||
|
|
||||||
|
Output is grouped into sections, and every warning is repeated in a summary at
|
||||||
|
the end so a failed AUR build is not lost in the scroll.
|
||||||
|
|
||||||
Step 9 is the one a plain Arch install cannot do without: SDDM's stock Wayland
|
Step 9 is the one a plain Arch install cannot do without: SDDM's stock Wayland
|
||||||
greeter runs on `weston`, which Blob does not install, so the greeter is pointed
|
greeter runs on `weston`, which Blob does not install, so the greeter is pointed
|
||||||
|
|||||||
Executable
+32
@@ -0,0 +1,32 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
repo_url="${BLOB_REPO_URL:-https://git.sirblob.co/SirBlob/blomarchy.git}"
|
||||||
|
repo_branch="${BLOB_REPO_BRANCH:-main}"
|
||||||
|
checkout_dir="${BLOB_CHECKOUT_DIR:-$HOME/dotfiles}"
|
||||||
|
|
||||||
|
if (( EUID == 0 )); then
|
||||||
|
echo "Run this as your own user, not as root. It asks for sudo when it needs it." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v pacman &>/dev/null; then
|
||||||
|
echo "pacman not found; Blob installs on Arch Linux only." >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! command -v git &>/dev/null; then
|
||||||
|
echo "Installing git"
|
||||||
|
sudo pacman -Syu --needed --noconfirm git
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ -d $checkout_dir/.git ]]; then
|
||||||
|
echo "Updating $checkout_dir"
|
||||||
|
git -C "$checkout_dir" pull --ff-only
|
||||||
|
else
|
||||||
|
echo "Cloning $repo_url into $checkout_dir"
|
||||||
|
git clone --branch "$repo_branch" "$repo_url" "$checkout_dir"
|
||||||
|
fi
|
||||||
|
|
||||||
|
exec "$checkout_dir/install.sh" "$@" </dev/tty
|
||||||
+22
-6
@@ -8,8 +8,10 @@ with `--check`.
|
|||||||
|
|
||||||
| Path | Role |
|
| Path | Role |
|
||||||
| --- | --- |
|
| --- | --- |
|
||||||
|
| `bootstrap.sh` | one-command install on a bare machine: installs git, clones, runs `install.sh` |
|
||||||
| `install.sh` | flags and the order the steps run in |
|
| `install.sh` | flags and the order the steps run in |
|
||||||
| `install/helpers/lib.sh` | reporting, file copies, unit queries |
|
| `install/helpers/lib.sh` | reporting, sections, the warning summary, file copies, unit queries |
|
||||||
|
| `install/steps/preflight.sh` | the checks that stop a run early, and the sudo keepalive |
|
||||||
| `install/helpers/as-root.sh` | `as_root`, a no-op when already root |
|
| `install/helpers/as-root.sh` | `as_root`, a no-op when already root |
|
||||||
| `install/steps/directories.sh` | the directories the shell and scripts expect |
|
| `install/steps/directories.sh` | the directories the shell and scripts expect |
|
||||||
| `install/steps/packages.sh` | repo and AUR packages, and the yay bootstrap |
|
| `install/steps/packages.sh` | repo and AUR packages, and the yay bootstrap |
|
||||||
@@ -23,6 +25,16 @@ with `--check`.
|
|||||||
|
|
||||||
## Steps
|
## Steps
|
||||||
|
|
||||||
|
0. **Preflight** stops before anything is written when the installer is run as
|
||||||
|
root (it installs into `$HOME`, and `makepkg` refuses to build as root), when
|
||||||
|
`pacman` is missing, when `sudo` does not accept the user, or when
|
||||||
|
`archlinux.org` cannot be reached and packages are wanted. It warns when
|
||||||
|
`systemd-networkd`, `iwd`, `dhcpcd` or `netctl` is enabled, because
|
||||||
|
NetworkManager is enabled below and two network managers fight over the same
|
||||||
|
interface after a reboot. `archinstall`'s "copy ISO network config" option
|
||||||
|
leaves exactly that behind. Once sudo is accepted it is refreshed every
|
||||||
|
minute in the background, so a long AUR build does not stop halfway for a
|
||||||
|
password.
|
||||||
1. **Directories** are created first, because nothing below can write into a
|
1. **Directories** are created first, because nothing below can write into a
|
||||||
directory that is not there: `~/.config/blob`, `~/.config/systemd/user/app.slice.d`,
|
directory that is not there: `~/.config/blob`, `~/.config/systemd/user/app.slice.d`,
|
||||||
`~/.local/state/blob`, `~/.local/share` and `~/.cache/blob`. A fresh Arch
|
`~/.local/state/blob`, `~/.local/share` and `~/.cache/blob`. A fresh Arch
|
||||||
@@ -32,9 +44,10 @@ with `--check`.
|
|||||||
create the parent of a link, so this step makes `~/.local/share` itself rather
|
create the parent of a link, so this step makes `~/.local/share` itself rather
|
||||||
than assuming step 1 ran.
|
than assuming step 1 ran.
|
||||||
3. **Packages** come from `packages/blob.packages` and
|
3. **Packages** come from `packages/blob.packages` and
|
||||||
`packages/blob-aur.packages`. A machine with no AUR helper gets `yay-bin`
|
`packages/blob-aur.packages`. Repo packages go in with a full
|
||||||
built once with `makepkg`. A failed batch refreshes the databases and retries,
|
`pacman -Syu`, never a partial upgrade. A machine with no AUR helper gets
|
||||||
then falls back to one package at a time, so a single name that no longer
|
`yay-bin` built once with `makepkg`. A failed batch upgrades the system on
|
||||||
|
its own, then falls back to one package at a time, so a single name that no longer
|
||||||
resolves cannot cost you the other hundred and the config, service and login
|
resolves cannot cost you the other hundred and the config, service and login
|
||||||
steps below. See [packages.md](packages.md).
|
steps below. See [packages.md](packages.md).
|
||||||
4. **Config** is copied into `~/.config`: `hypr/`, the themed app configs,
|
4. **Config** is copied into `~/.config`: `hypr/`, the themed app configs,
|
||||||
@@ -152,8 +165,11 @@ with `--check`.
|
|||||||
11. **Launch.** `sddm`, `hyprland`, `quickshell` and `uwsm` are checked one last
|
11. **Launch.** `sddm`, `hyprland`, `quickshell` and `uwsm` are checked one last
|
||||||
time and any that are missing are named, because that is the whole difference
|
time and any that are missing are named, because that is the whole difference
|
||||||
between a desktop and a console. Then, when the installer was run from a
|
between a desktop and a console. Then, when the installer was run from a
|
||||||
console and nothing graphical is running, it starts `sddm.service` so the
|
console and nothing graphical is running, it offers a reboot, which brings
|
||||||
desktop appears without a reboot. `--no-launch` prints the command instead.
|
up NetworkManager, the boot splash and any new kernel modules together.
|
||||||
|
Declining starts `sddm.service` so the desktop appears without one.
|
||||||
|
`--no-launch` prints the command instead. Every warning from the run is
|
||||||
|
listed again just before this step.
|
||||||
`--autologin` writes `/etc/sddm.conf.d/zzz-blob-autologin.conf` for the
|
`--autologin` writes `/etc/sddm.conf.d/zzz-blob-autologin.conf` for the
|
||||||
current user.
|
current user.
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -84,10 +84,12 @@ packages pulled in under a different name no longer come back on every run. AUR
|
|||||||
packages are built one at a time, so a build that fails is reported at the end
|
packages are built one at a time, so a build that fails is reported at the end
|
||||||
instead of stopping the install.
|
instead of stopping the install.
|
||||||
|
|
||||||
Repo packages go in one `pacman` call. If that call fails the databases are
|
Repo packages go in one `pacman -Syu --needed` call, so the databases are
|
||||||
refreshed with `pacman -Sy` and it is tried again, because a stale database is
|
fresh and the system is upgraded in the same transaction. Refreshing the
|
||||||
what turns an installed-and-present package into `target not found`. If it still
|
databases without upgrading (`-Sy` then `-S`) is a partial upgrade, which Arch
|
||||||
fails the packages are installed one at a time, so one unresolvable name does not
|
does not support and which breaks libraries on a fresh install whose ISO is a
|
||||||
|
few weeks old. If that call fails the system is upgraded on its own and the
|
||||||
|
packages are installed one at a time, so one unresolvable name does not
|
||||||
block the other hundred - which is how a missing `sddm` used to turn into a
|
block the other hundred - which is how a missing `sddm` used to turn into a
|
||||||
machine with no login screen. `install.sh` ends by naming any of `sddm`,
|
machine with no login screen. `install.sh` ends by naming any of `sddm`,
|
||||||
`hyprland`, `quickshell` and `uwsm` that are still not installed.
|
`hyprland`, `quickshell` and `uwsm` that are still not installed.
|
||||||
|
|||||||
+14
-1
@@ -45,6 +45,7 @@ while (( $# > 0 )); do
|
|||||||
done
|
done
|
||||||
|
|
||||||
source "$repo_dir/install/helpers/lib.sh"
|
source "$repo_dir/install/helpers/lib.sh"
|
||||||
|
source "$repo_dir/install/steps/preflight.sh"
|
||||||
source "$repo_dir/install/steps/directories.sh"
|
source "$repo_dir/install/steps/directories.sh"
|
||||||
source "$repo_dir/install/steps/packages.sh"
|
source "$repo_dir/install/steps/packages.sh"
|
||||||
source "$repo_dir/install/steps/config.sh"
|
source "$repo_dir/install/steps/config.sh"
|
||||||
@@ -60,12 +61,18 @@ say "repo: $repo_dir"
|
|||||||
if [[ $check == true ]]; then
|
if [[ $check == true ]]; then
|
||||||
say "mode: check (nothing will be written)"
|
say "mode: check (nothing will be written)"
|
||||||
fi
|
fi
|
||||||
say ""
|
|
||||||
|
|
||||||
|
section "Preflight"
|
||||||
|
run_preflight
|
||||||
|
|
||||||
|
section "Directories"
|
||||||
create_directories
|
create_directories
|
||||||
link_blob_path
|
link_blob_path
|
||||||
|
|
||||||
|
section "Packages"
|
||||||
install_packages
|
install_packages
|
||||||
|
|
||||||
|
section "Config"
|
||||||
install_shipped_config
|
install_shipped_config
|
||||||
remove_omarchy_font
|
remove_omarchy_font
|
||||||
refresh_font_cache
|
refresh_font_cache
|
||||||
@@ -76,16 +83,19 @@ install_systemd_dropins
|
|||||||
install_zen_config
|
install_zen_config
|
||||||
install_default_apps
|
install_default_apps
|
||||||
|
|
||||||
|
section "Theme"
|
||||||
link_wallpapers
|
link_wallpapers
|
||||||
install_default_theme
|
install_default_theme
|
||||||
install_default_background
|
install_default_background
|
||||||
link_app_themes
|
link_app_themes
|
||||||
|
|
||||||
|
section "Services"
|
||||||
enable_system_services
|
enable_system_services
|
||||||
mask_system_services
|
mask_system_services
|
||||||
install_boot_splash
|
install_boot_splash
|
||||||
enable_user_units
|
enable_user_units
|
||||||
|
|
||||||
|
section "Login screen"
|
||||||
install_login_config
|
install_login_config
|
||||||
install_session_entry
|
install_session_entry
|
||||||
install_autologin
|
install_autologin
|
||||||
@@ -94,10 +104,13 @@ report_greeter_compositor
|
|||||||
report_login_conflicts
|
report_login_conflicts
|
||||||
report_desktop_essentials
|
report_desktop_essentials
|
||||||
|
|
||||||
|
section "Reload"
|
||||||
reload_system_services
|
reload_system_services
|
||||||
reload_user_services
|
reload_user_services
|
||||||
reload_session
|
reload_session
|
||||||
|
|
||||||
|
report_warnings
|
||||||
|
|
||||||
say ""
|
say ""
|
||||||
if [[ $check == true ]]; then
|
if [[ $check == true ]]; then
|
||||||
say "$changes item(s) would change."
|
say "$changes item(s) would change."
|
||||||
|
|||||||
@@ -4,6 +4,28 @@ say() {
|
|||||||
printf '%s\n' "$1"
|
printf '%s\n' "$1"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
warnings=()
|
||||||
|
|
||||||
|
warn() {
|
||||||
|
warnings+=("$1")
|
||||||
|
say "WARN $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
section() {
|
||||||
|
say ""
|
||||||
|
say "==> $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
report_warnings() {
|
||||||
|
(( ${#warnings[@]} == 0 )) && return 0
|
||||||
|
say ""
|
||||||
|
say "${#warnings[@]} warning(s), details above:"
|
||||||
|
local message
|
||||||
|
for message in "${warnings[@]}"; do
|
||||||
|
say " - $message"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
note_change() {
|
note_change() {
|
||||||
changes=$((changes + 1))
|
changes=$((changes + 1))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,6 +32,6 @@ install_boot_splash() {
|
|||||||
if BLOB_PATH="$blob_path" "$repo_dir/bin/blob-boot" "$boot_splash_image"; then
|
if BLOB_PATH="$blob_path" "$repo_dir/bin/blob-boot" "$boot_splash_image"; then
|
||||||
say "set boot splash to branding/blob_boot.png"
|
say "set boot splash to branding/blob_boot.png"
|
||||||
else
|
else
|
||||||
say "WARN could not set the boot splash; run 'blob boot' to retry"
|
warn "could not set the boot splash; run 'blob boot' to retry"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -15,7 +15,7 @@ link_blob_path() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if [[ -e $blob_path && ! -L $blob_path ]]; then
|
if [[ -e $blob_path && ! -L $blob_path ]]; then
|
||||||
say "WARN $blob_path exists and is not a symlink; move it aside first"
|
warn "$blob_path exists and is not a symlink; move it aside first"
|
||||||
note_change
|
note_change
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|||||||
+21
-7
@@ -71,7 +71,7 @@ report_greeter_compositor() {
|
|||||||
[[ -n $binary ]] || return 0
|
[[ -n $binary ]] || return 0
|
||||||
command -v "$binary" &>/dev/null && return 0
|
command -v "$binary" &>/dev/null && return 0
|
||||||
|
|
||||||
say "WARN the greeter's compositor command '$binary' is not installed"
|
warn "the greeter's compositor command '$binary' is not installed"
|
||||||
say " SDDM cannot draw a greeter without it; it is set in $blob_greeter_conf"
|
say " SDDM cannot draw a greeter without it; it is set in $blob_greeter_conf"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ report_login_conflicts() {
|
|||||||
session_entry_exists "$session" && continue
|
session_entry_exists "$session" && continue
|
||||||
|
|
||||||
found=true
|
found=true
|
||||||
say "WARN $file autologs into $session, which is not installed"
|
warn "$file autologs into $session, which is not installed"
|
||||||
done
|
done
|
||||||
|
|
||||||
if [[ $found == true ]]; then
|
if [[ $found == true ]]; then
|
||||||
@@ -107,10 +107,10 @@ report_login_conflicts() {
|
|||||||
enable_display_manager() {
|
enable_display_manager() {
|
||||||
if ! system_unit_exists sddm.service; then
|
if ! system_unit_exists sddm.service; then
|
||||||
if package_installed sddm; then
|
if package_installed sddm; then
|
||||||
say "WARN sddm is installed but sddm.service is not visible to systemd"
|
warn "sddm is installed but sddm.service is not visible to systemd"
|
||||||
say " run 'sudo systemctl daemon-reload', then ./install.sh again"
|
say " run 'sudo systemctl daemon-reload', then ./install.sh again"
|
||||||
else
|
else
|
||||||
say "WARN sddm is not installed; the desktop cannot start at boot"
|
warn "sddm is not installed; the desktop cannot start at boot"
|
||||||
say " install it with 'sudo pacman -S sddm', then ./install.sh again"
|
say " install it with 'sudo pacman -S sddm', then ./install.sh again"
|
||||||
fi
|
fi
|
||||||
return 0
|
return 0
|
||||||
@@ -144,7 +144,7 @@ enable_display_manager() {
|
|||||||
if as_root systemctl enable sddm.service; then
|
if as_root systemctl enable sddm.service; then
|
||||||
say "enable sddm.service"
|
say "enable sddm.service"
|
||||||
else
|
else
|
||||||
say "WARN could not enable sddm.service"
|
warn "could not enable sddm.service"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
@@ -152,7 +152,7 @@ enable_display_manager() {
|
|||||||
if as_root systemctl set-default graphical.target; then
|
if as_root systemctl set-default graphical.target; then
|
||||||
say "set default target to graphical.target"
|
say "set default target to graphical.target"
|
||||||
else
|
else
|
||||||
say "WARN could not set the default target to graphical.target"
|
warn "could not set the default target to graphical.target"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
@@ -184,8 +184,22 @@ launch_desktop() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if reboot_chosen; then
|
||||||
|
say "Rebooting into Blob."
|
||||||
|
as_root systemctl reboot
|
||||||
|
return 0
|
||||||
|
fi
|
||||||
|
|
||||||
say "Starting the login screen. Pick the Blob session to log in."
|
say "Starting the login screen. Pick the Blob session to log in."
|
||||||
as_root systemctl start sddm.service || {
|
as_root systemctl start sddm.service || {
|
||||||
say "WARN sddm.service did not start; see 'systemctl status sddm'"
|
warn "sddm.service did not start; see 'systemctl status sddm'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
reboot_chosen() {
|
||||||
|
[[ -r /dev/tty ]] || return 1
|
||||||
|
local answer
|
||||||
|
say "A reboot brings up the network, boot splash and new kernel modules together."
|
||||||
|
read -rp "Reboot now? [Y/n] " answer </dev/tty
|
||||||
|
[[ -z $answer || $answer == [yY]* ]]
|
||||||
|
}
|
||||||
@@ -54,8 +54,6 @@ install_packages() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
blob_sudo_keepalive
|
|
||||||
|
|
||||||
if (( ${#repo_missing[@]} )); then
|
if (( ${#repo_missing[@]} )); then
|
||||||
say "install ${#repo_missing[@]} repo package(s)"
|
say "install ${#repo_missing[@]} repo package(s)"
|
||||||
install_repo_packages "${repo_missing[@]}"
|
install_repo_packages "${repo_missing[@]}"
|
||||||
@@ -63,7 +61,7 @@ install_packages() {
|
|||||||
|
|
||||||
if (( ${#aur_missing[@]} )); then
|
if (( ${#aur_missing[@]} )); then
|
||||||
ensure_aur_helper || {
|
ensure_aur_helper || {
|
||||||
say "WARN no AUR helper; skipping ${#aur_missing[@]} AUR package(s): ${aur_missing[*]}"
|
warn "no AUR helper; skipping ${#aur_missing[@]} AUR package(s): ${aur_missing[*]}"
|
||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
say "install ${#aur_missing[@]} AUR package(s)"
|
say "install ${#aur_missing[@]} AUR package(s)"
|
||||||
@@ -75,20 +73,17 @@ install_repo_packages() {
|
|||||||
local package
|
local package
|
||||||
local -a failed=()
|
local -a failed=()
|
||||||
|
|
||||||
as_root pacman -S --needed --noconfirm "$@" && return 0
|
as_root pacman -Syu --needed --noconfirm "$@" && return 0
|
||||||
|
|
||||||
say "WARN the batch install failed; refreshing the package databases"
|
say " the batch install failed; upgrading the system, then one package at a time"
|
||||||
as_root pacman -Sy --noconfirm || true
|
as_root pacman -Syu --noconfirm || true
|
||||||
as_root pacman -S --needed --noconfirm "$@" && return 0
|
|
||||||
|
|
||||||
say "WARN still failing; retrying one package at a time"
|
|
||||||
for package in "$@"; do
|
for package in "$@"; do
|
||||||
as_root pacman -S --needed --noconfirm "$package" || failed+=("$package")
|
as_root pacman -S --needed --noconfirm "$package" || failed+=("$package")
|
||||||
done
|
done
|
||||||
|
|
||||||
(( ${#failed[@]} == 0 )) && return 0
|
(( ${#failed[@]} == 0 )) && return 0
|
||||||
|
|
||||||
say "WARN ${#failed[@]} repo package(s) failed to install: ${failed[*]}"
|
warn "${#failed[@]} repo package(s) failed to install: ${failed[*]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
desktop_essentials=(sddm hyprland quickshell uwsm)
|
desktop_essentials=(sddm hyprland quickshell uwsm)
|
||||||
@@ -106,7 +101,7 @@ report_desktop_essentials() {
|
|||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
say "WARN the desktop cannot start without: ${missing[*]}"
|
warn "the desktop cannot start without: ${missing[*]}"
|
||||||
say " install them with 'sudo pacman -S ${missing[*]}', then ./install.sh again"
|
say " install them with 'sudo pacman -S ${missing[*]}', then ./install.sh again"
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -120,8 +115,8 @@ install_aur_packages() {
|
|||||||
|
|
||||||
(( ${#failed[@]} == 0 )) && return 0
|
(( ${#failed[@]} == 0 )) && return 0
|
||||||
|
|
||||||
say "WARN ${#failed[@]} AUR package(s) failed to build: ${failed[*]}"
|
warn "${#failed[@]} AUR package(s) failed to build: ${failed[*]}"
|
||||||
say "WARN the install continued; retry them with 'yay -S <name>'"
|
say " the install continued; retry them with 'yay -S <name>'"
|
||||||
}
|
}
|
||||||
|
|
||||||
# A fresh Arch install has no AUR helper, and yay is not in the official
|
# A fresh Arch install has no AUR helper, and yay is not in the official
|
||||||
@@ -148,7 +143,3 @@ ensure_aur_helper() {
|
|||||||
rm -rf "$build_dir"
|
rm -rf "$build_dir"
|
||||||
command -v yay &>/dev/null
|
command -v yay &>/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
blob_sudo_keepalive() {
|
|
||||||
sudo -v 2>/dev/null || true
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,85 @@
|
|||||||
|
conflicting_network_services=(
|
||||||
|
systemd-networkd.service
|
||||||
|
iwd.service
|
||||||
|
dhcpcd.service
|
||||||
|
netctl.service
|
||||||
|
)
|
||||||
|
|
||||||
|
stop_install() {
|
||||||
|
printf 'ERROR %s\n' "$1" >&2
|
||||||
|
shift
|
||||||
|
local detail
|
||||||
|
for detail in "$@"; do
|
||||||
|
printf ' %s\n' "$detail" >&2
|
||||||
|
done
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
require_regular_user() {
|
||||||
|
(( EUID != 0 )) && return 0
|
||||||
|
stop_install "run install.sh as your own user, not as root" \
|
||||||
|
"it installs into \$HOME and builds AUR packages, which makepkg refuses to do as root" \
|
||||||
|
"it asks for sudo when it needs it"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_arch() {
|
||||||
|
command -v pacman &>/dev/null && return 0
|
||||||
|
stop_install "pacman not found; Blob installs on Arch Linux only"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_sudo() {
|
||||||
|
[[ $check == true ]] && return 0
|
||||||
|
command -v sudo &>/dev/null || stop_install "sudo is not installed" \
|
||||||
|
"as root: pacman -S sudo, then add your user with visudo"
|
||||||
|
sudo -v || stop_install "sudo did not accept this user" \
|
||||||
|
"as root: add your user to the wheel group and allow it in visudo"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_internet() {
|
||||||
|
[[ $check == true || $skip_packages == true ]] && return 0
|
||||||
|
curl -fsS --max-time 15 -o /dev/null https://archlinux.org && return 0
|
||||||
|
stop_install "no internet connection; packages cannot be downloaded" \
|
||||||
|
"connect first (iwctl for Wi-Fi), or rerun with --skip-packages"
|
||||||
|
}
|
||||||
|
|
||||||
|
report_network_conflicts() {
|
||||||
|
local unit
|
||||||
|
local -a enabled=()
|
||||||
|
|
||||||
|
for unit in "${conflicting_network_services[@]}"; do
|
||||||
|
[[ "$(system_unit_state "$unit")" == enabled ]] && enabled+=("$unit")
|
||||||
|
done
|
||||||
|
|
||||||
|
(( ${#enabled[@]} == 0 )) && return 0
|
||||||
|
|
||||||
|
warn "NetworkManager will be enabled, but so is: ${enabled[*]}"
|
||||||
|
say " two network managers fight over the same interfaces after a reboot"
|
||||||
|
say " once NetworkManager works: sudo systemctl disable ${enabled[*]}"
|
||||||
|
}
|
||||||
|
|
||||||
|
sudo_keepalive_pid=""
|
||||||
|
|
||||||
|
start_sudo_keepalive() {
|
||||||
|
[[ $check == true ]] && return 0
|
||||||
|
while true; do
|
||||||
|
sudo -n true 2>/dev/null
|
||||||
|
sleep 60
|
||||||
|
done &
|
||||||
|
sudo_keepalive_pid=$!
|
||||||
|
trap stop_sudo_keepalive EXIT
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_sudo_keepalive() {
|
||||||
|
[[ -n $sudo_keepalive_pid ]] && kill "$sudo_keepalive_pid" 2>/dev/null
|
||||||
|
sudo_keepalive_pid=""
|
||||||
|
}
|
||||||
|
|
||||||
|
run_preflight() {
|
||||||
|
require_regular_user
|
||||||
|
require_arch
|
||||||
|
require_sudo
|
||||||
|
require_internet
|
||||||
|
report_network_conflicts
|
||||||
|
start_sudo_keepalive
|
||||||
|
say "ok preflight"
|
||||||
|
}
|
||||||
@@ -13,14 +13,14 @@ reload_system_services() {
|
|||||||
fi
|
fi
|
||||||
|
|
||||||
if ! as_root systemctl daemon-reload; then
|
if ! as_root systemctl daemon-reload; then
|
||||||
say "WARN could not reload systemd"
|
warn "could not reload systemd"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
local unit
|
local unit
|
||||||
for unit in "${reloaded_system_services[@]}"; do
|
for unit in "${reloaded_system_services[@]}"; do
|
||||||
system_unit_exists "$unit" || continue
|
system_unit_exists "$unit" || continue
|
||||||
as_root systemctl try-restart "$unit" || say "WARN could not restart $unit"
|
as_root systemctl try-restart "$unit" || warn "could not restart $unit"
|
||||||
done
|
done
|
||||||
|
|
||||||
say "ok system services reloaded"
|
say "ok system services reloaded"
|
||||||
@@ -45,7 +45,7 @@ reload_user_services() {
|
|||||||
done
|
done
|
||||||
|
|
||||||
if (( ${#failed[@]} > 0 )); then
|
if (( ${#failed[@]} > 0 )); then
|
||||||
say "WARN could not restart: ${failed[*]}"
|
warn "could not restart: ${failed[*]}"
|
||||||
else
|
else
|
||||||
say "ok user services reloaded"
|
say "ok user services reloaded"
|
||||||
fi
|
fi
|
||||||
@@ -58,7 +58,7 @@ run_session_reload() {
|
|||||||
if BLOB_PATH="$blob_path" PATH="$blob_path/bin:$PATH" "$@" &>/dev/null; then
|
if BLOB_PATH="$blob_path" PATH="$blob_path/bin:$PATH" "$@" &>/dev/null; then
|
||||||
say "ok $label reloaded"
|
say "ok $label reloaded"
|
||||||
else
|
else
|
||||||
say "WARN could not reload $label"
|
warn "could not reload $label"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -135,7 +135,7 @@ enable_user_units() {
|
|||||||
local unit
|
local unit
|
||||||
|
|
||||||
if ! user_manager_available; then
|
if ! user_manager_available; then
|
||||||
say "WARN no user systemd manager; skipping user services"
|
warn "no user systemd manager; skipping user services"
|
||||||
return 0
|
return 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ install_default_theme() {
|
|||||||
blob-theme-set "$default_theme" >/dev/null; then
|
blob-theme-set "$default_theme" >/dev/null; then
|
||||||
say "theme $default_theme"
|
say "theme $default_theme"
|
||||||
else
|
else
|
||||||
say "WARN could not apply the $default_theme theme"
|
warn "could not apply the $default_theme theme"
|
||||||
say " the session will come up without a palette; run 'blob theme set $default_theme'"
|
say " the session will come up without a palette; run 'blob theme set $default_theme'"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user