diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..c8e2d80 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,89 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## What this is + +A Fedora automated mass-installation and post-setup scripting collection. It uses an **OEMDRV** partition (BTRFS, mounted at `/opt/sys_config`) that Anaconda/Kickstart picks up automatically during Fedora installation. The system requires: +- A FreeIPA server (domain controller, KRA vault for encryption keys) +- A Nextcloud instance (config and software sync, WebDAV token auth) +- Client PCs with an OEMDRV partition prepared beforehand + +## Configuration + +Before any script runs, copy the dist file and fill in your environment: +```sh +cp /opt/sys_config/config/setup_system.conf.dist /opt/sys_config/config/setup_system.conf +# Edit setup_system.conf with your domain, server FQDNs, paths, etc. +``` + +Local per-machine overrides go in `config.d/*.conf` (gitignored). These are sourced after `setup_system.conf` and can override any exported variable (e.g. `config.d/system_defines.conf` overrides `UPGRADEBRANCH`). + +`config/skel.tar.zst` (gitignored) holds the `/etc/skel` archive deployed to new installs. The `.dist` version is the default. To modify skel: extract, edit, then repack: +```sh +cd /opt/sys_config/config +tar -I 'zstd -9' -cf skel.tar.zst skel/ # or use pack_skel.sh +``` + +## Installation lifecycle + +1. **Kickstart pre** — `ks_base_profiles/basic_pre_script.inc` runs inside Anaconda's `%pre` section. It locates the OEMDRV partition, identifies the target drive, and **deletes all other partitions on that drive** (non-interactive, no prompt). + +2. **Kickstart post** — After Fedora installs, `setup_system_full.sh install` runs (as root, non-interactive). It adjusts umask, adds the OEMDRV fstab entry, deploys `/etc/skel` via `setup_skel.sh`, and installs the `setup-system.service` systemd unit. + +3. **First boot** (`firstrun_run` mode) — The `setup-system.service` unit runs `setup_system_full.sh firstrun_run` on `/dev/tty2`. It calls `ipa_register_host` which prompts for domain credentials and joins the PC to FreeIPA via `ipa-client-install`. The service then disables itself. + +4. **User logon** — `logon_script.sh` is triggered by KDE autostart. It: + - Mounts the gocryptfs-encrypted home directory (`mount_ecrypt_home.sh`) using a key stored in the FreeIPA KRA vault (`IPAVAULTNAME`) + - Obtains a Nextcloud WebDAV app token (`get_nc_token` in `setup_system.inc.sh`) + - Checks for a matching IPA sudo rule, then calls `sync_client_software.sh install` as root (preserving env) to sync configs and run software installs + - Calls `client_software/user_run.sh` (as the logged-in user) + - Syncs Firefox and Thunderbird profiles via Nextcloud (`mozilla_starter.sh`) + +## Script roles + +| Script | Who runs it | How called | +|---|---|---| +| `system_setup/setup_system.inc.sh` | sourced, never executed directly | `source`d by all other scripts | +| `system_setup/setup_system_full.sh` | root | kickstart post, firstrun service, or manual | +| `system_setup/logon_script.sh` | domain user | KDE autostart (via `.desktop` in autostart) | +| `system_setup/sync_client_software.sh` | root (sudo, preserve-env) | called by logon_script.sh | +| `system_setup/mount_ecrypt_home.sh` | user | called by logon_script.sh | +| `system_setup/mozilla_starter.sh` | user | called by logon_script.sh; args: `firefox\|thunderbird run\|sync [profile]` | +| `system_setup/setup_skel.sh` | root | called by setup_system_full.sh or manually | +| `config/pack_skel.sh` | root | manually, to repack skel archive after editing | +| `system_setup/create_nc_package_from_sys_config.sh` | user | manually, creates `~/temp/sys_config.tar.zst` | + +## client_software layout + +`client_software/` is synced from Nextcloud (`CLIENT_SOFTWARE_SRC` → `CLIENT_SOFTWARE_DST`). Each numbered subdirectory may contain: +- `install.sh` — run as root by `client_software/install.sh` (iterates sorted dirs) +- `user_run.sh` — run as the logged-in user by `client_software/user_run.sh` + +Naming convention: directories `< 0100` are base installs, `>= 0100` are additional apps. Pass a filter string to run only matching directories: +```sh +# Run only the kwallet install: +${CLIENT_SOFTWARE_DST}/install.sh 0010_kwallet +``` + +## Kickstart files + +- `ks.cfg` — the primary kickstart used for production installs (Fedora 43, KDE, x86_64, German locale/keyboard) +- `ks_base_profiles/kde_fullsetup.cfg` — an alternate/reference profile generated by Anaconda +- `ks_base_profiles/minimal_setup.cfg`, `part_sda.cfg` — additional profile fragments +- `ks_pc_prof/` — per-machine kickstart overrides, named by system UUID suffix (e.g. `pc-9cdb93ef7c20.cfg`) + +## Sudo rule required for logon_script + +The logon script requires a FreeIPA sudo rule allowing the domain user group to run `sync_client_software.sh` as root without a password, with environment preservation. The rule must include `!authenticate` and `setenv` options. The expected command pattern: +``` +^/opt/sys_config/system_setup/sync_client_software\.sh.*$ +``` + +## gitignore notes + +The following are intentionally excluded from git and must be set up locally: +- `config/setup_system.conf` — site-specific config (copy from `.dist`) +- `config/skel.tar.zst` — skel archive (copy from `.dist` or rebuild) +- `config.d/*.conf` — local overrides +- `client_software/.sync_*.db` — Nextcloud sync DB files