Initial phone-setup: Termux zsh bootstrap + dotfiles, Obtainium manifest, provisioning docs

This commit is contained in:
Bill committed 2026-07-08 09:26:03 -04:00
commit 6573969073
7 files changed
+2062

No files matched your search

+2
View File
@@ -0,0 +1,2 @@
*.bak.*
.DS_Store
+41
View File
@@ -0,0 +1,41 @@
# phone-setup
Provisioning artifacts for Bill's GrapheneOS phones (currently the Pixel 6A). Keeps
device setup reproducible: shell dotfiles, an Obtainium app manifest, and provisioning
notes.
## Layout
| Path | Contents |
|------|----------|
| `termux/` | Termux zsh environment — `bootstrap.sh`, `zshrc`, `p10k.zsh` (mirrors soos) |
| `obtainium/` | App manifest — which apps to install and their Obtainium sources |
| `docs/` | GrapheneOS provisioning notes / lessons |
## Quick start (Termux)
This repo is **private** on Gitea, so the phone clones it with a token.
1. In Termux: `pkg install -y git`
2. Create a Gitea token (or app password) at
`https://git.prettyhefty.com/user/settings/applications`.
3. Clone with the token in the URL (one time):
```bash
git clone https://Bill:<TOKEN>@git.prettyhefty.com/Bill/phone-setup.git ~/phone-setup
```
Git stores the credential for subsequent `git pull`s.
4. Run the Termux bootstrap:
```bash
bash ~/phone-setup/termux/bootstrap.sh
```
5. Restart Termux (or `exec zsh`). In Termux **Settings → confirm the MesloLGS NF font**
is applied so Powerlevel10k glyphs render.
## Updating
`termux/zshrc` and `termux/p10k.zsh` are **symlinked** into `$HOME` by the bootstrap, so
`git -C ~/phone-setup pull` updates your live shell config. Re-run `bootstrap.sh` to also
refresh plugins/packages.
The `p10k.zsh` here is a snapshot of soos. To resync after tweaking p10k on soos:
`scp bill@soos:~/.p10k.zsh termux/p10k.zsh` from a workstation, then commit.
+34
View File
@@ -0,0 +1,34 @@
# GrapheneOS Provisioning Notes
Lessons and gotchas from setting up the Pixel 6A. Full migration history lives in the
infrastructure repo (`docs/plans/2026-05-19-phone-migration-pixel9-to-pixel6a.md`).
## Banking / hardened-allocator crashes
Apps that **crash on launch** (Chase, Schwab, Citi Mobile) are dying to GrapheneOS's
hardened memory allocator / memory tagging — **not** Play Integrity. Fix per app:
**Settings → Apps → <app> → Exploit protection compatibility mode → ON**, then relaunch.
Distinguish the two failure modes:
- **Crash on launch** → hardened_malloc → compatibility mode fixes it.
- **Error/attestation screen (no crash)** → real Play Integrity DEVICE wall; compat mode
won't help. Enterprise MDM (Intune / Workspace ONE) is the class that hard-refuses
GrapheneOS regardless.
## Install-source pattern
- Open-source apps → **Obtainium** (tracks GitHub releases). See `../obtainium/apps.md`.
- Closed-source apps → **Aurora Store** (anonymous session, no Google login).
- **Sandboxed Google Play** installed in the Owner profile as the FCM push transport only
(no Google account attached unless a specific app — e.g. WhatsApp Drive restore —
needs one).
## Misc gotchas
- **Tailscale first launch** grabs the VPN slot and captures DNS before auth completes →
breaks resolution. Recover: force-stop Tailscale, confirm DNS, reopen and finish OAuth
(or use a pre-generated auth key).
- **Camera EXIF:** GrapheneOS stock Camera strips EXIF + location by default. Install
GCam (Aurora) for full EXIF/GPS, or accept stripped metadata.
- **Gallery intent:** promote a default gallery app (Aves) so camera "recent photo"
thumbnails and share intents resolve.
+39
View File
@@ -0,0 +1,39 @@
# Obtainium App Manifest
Apps installed via [Obtainium](https://github.com/ImranR98/Obtainium) (open-source, tracks
release APKs). Closed-source apps not on GitHub go through **Aurora Store** (anonymous).
> **Best practice:** Obtainium can export/import all tracked apps as JSON
> (Obtainium → ⋮ → Export). Once the Pixel 6A app set is final, export and commit it here
> as `obtainium-export.json` — that lets a fresh phone re-add every app in one import.
## Confirmed sources
| App | Obtainium source (GitHub) | Notes |
|-----|---------------------------|-------|
| Obtainium (self) | `ImranR98/Obtainium` | bootstrap installer |
| Aurora Store | `whyorean/AuroraStore` | anonymous; for closed-source apps |
| Bitwarden | *(verify)* | password manager + TOTP |
| Nextcloud | `nextcloud/android` | files sync |
| DAVx⁵ | `bitfireAT/davx5-ose` | CardDAV/CalDAV → Nextcloud |
| Immich | `immich-app/immich` | photos |
| Element X | `element-hq/element-x-android` | Matrix |
| Home Assistant | `home-assistant/android` | pick the **`-full-`** APK (FCM push) |
| Jellyfin | `jellyfin/jellyfin-android` | phone client (not androidtv) |
| Organic Maps | `organicmaps/organicmaps` | FOSS offline maps |
| Aves Gallery | `deckerst/aves` | gallery / default image handler |
## Via Aurora Store (closed-source)
| App | Notes |
|-----|-------|
| WhatsApp | restore via Google Drive at first launch (see migration plan) |
| Signal | transfer-code flow from old device |
| Chase / Schwab / Citi | enable **Exploit protection compatibility mode** per app |
| Infinity for Reddit | needs a personal Reddit API key (post-2023 API) |
## Notes
- Photos: install **GCam** (Aurora) before first photo upload — GrapheneOS stock Camera
strips EXIF/GPS by default, so Immich would show no map pins otherwise.
- `-full-` HA flavor uses Firebase/FCM push (works with sandboxed Google Play).
+68
View File
@@ -0,0 +1,68 @@
#!/data/data/com.termux/files/usr/bin/bash
# Termux zsh environment bootstrap — mirrors the soos shell.
# Idempotent: safe to re-run (updates plugins, re-links dotfiles).
#
# Usage (from a Termux shell):
# bash ~/phone-setup/termux/bootstrap.sh
set -euo pipefail
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PLUGIN_DIR="$HOME/.zsh/plugins"
log() { printf '\033[1;32m==>\033[0m %s\n' "$*"; }
# --- Sanity: Termux only ---
if [ -z "${PREFIX:-}" ] || ! command -v pkg >/dev/null 2>&1; then
echo "This script must run inside Termux (no \$PREFIX / pkg found)." >&2
exit 1
fi
# --- 1. Packages ---
log "Installing packages"
pkg update -y && pkg upgrade -y
pkg install -y zsh git eza lazygit openssh curl
# --- 2. Plugins (clone or fast-forward) ---
log "Installing zsh plugins"
mkdir -p "$PLUGIN_DIR"
clone_or_update() {
local url="$1" dest="$2"
if [ -d "$dest/.git" ]; then
git -C "$dest" pull --ff-only || true
else
git clone --depth=1 "$url" "$dest"
fi
}
clone_or_update https://github.com/romkatv/powerlevel10k.git "$PLUGIN_DIR/powerlevel10k"
clone_or_update https://github.com/zsh-users/zsh-autosuggestions "$PLUGIN_DIR/zsh-autosuggestions"
clone_or_update https://github.com/zsh-users/zsh-syntax-highlighting "$PLUGIN_DIR/zsh-syntax-highlighting"
# --- 3. Nerd Font (p10k glyphs; Termux reads a single ~/.termux/font.ttf) ---
log "Installing MesloLGS NF font"
mkdir -p "$HOME/.termux"
if [ ! -f "$HOME/.termux/font.ttf" ]; then
curl -fLo "$HOME/.termux/font.ttf" \
https://github.com/romkatv/powerlevel10k-media/raw/master/MesloLGS%20NF%20Regular.ttf
fi
# --- 4. Link dotfiles (symlink so `git pull` in this repo updates them) ---
log "Linking dotfiles"
link() {
local src="$1" dest="$2"
if [ -e "$dest" ] && [ ! -L "$dest" ]; then
mv "$dest" "$dest.bak.$(date +%s)"
log "backed up existing $dest"
fi
ln -sfn "$src" "$dest"
}
link "$REPO_DIR/zshrc" "$HOME/.zshrc"
link "$REPO_DIR/p10k.zsh" "$HOME/.p10k.zsh"
# --- 5. Default shell ---
log "Setting zsh as login shell"
chsh -s zsh || true
# --- 6. Apply font immediately ---
command -v termux-reload-settings >/dev/null 2>&1 && termux-reload-settings || true
log "Done. Restart Termux (or run 'exec zsh') to enter the new shell."
+1837
View File
File diff suppressed because it is too large. Load diff
+41
View File
@@ -0,0 +1,41 @@
# Managed by Bill/phone-setup (symlinked to ~/.zshrc by termux/bootstrap.sh).
# Mirrors the soos Home-Manager zsh, minus nix-store paths and secrets.
# Powerlevel10k instant prompt
if [[ -r "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh" ]]; then
source "${XDG_CACHE_HOME:-$HOME/.cache}/p10k-instant-prompt-${(%):-%n}.zsh"
fi
autoload -U compinit && compinit
ZPLUG=~/.zsh/plugins
source $ZPLUG/powerlevel10k/powerlevel10k.zsh-theme
source $ZPLUG/zsh-autosuggestions/zsh-autosuggestions.zsh
ZSH_AUTOSUGGEST_STRATEGY=(history)
HISTSIZE=10000
SAVEHIST=10000
HISTFILE=~/.zsh_history
setopt HIST_FCNTL_LOCK HIST_IGNORE_DUPS HIST_IGNORE_SPACE SHARE_HISTORY
[[ -f ~/.p10k.zsh ]] && source ~/.p10k.zsh
alias eza='eza --icons auto --git'
alias ls=eza
alias la='eza -a'
alias ll='eza -l'
alias lla='eza -la'
alias lt='eza --tree'
alias yolo='claude --dangerously-skip-permissions'
lg() {
export LAZYGIT_NEW_DIR_FILE=~/.lazygit/newdir
command lazygit "$@"
if [ -f "$LAZYGIT_NEW_DIR_FILE" ]; then
cd "$(cat "$LAZYGIT_NEW_DIR_FILE")"
rm -f "$LAZYGIT_NEW_DIR_FILE" >/dev/null
fi
}
# Syntax highlighting MUST be sourced last
source $ZPLUG/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh