diff --git a/CLAUDE.md b/CLAUDE.md index d267340..518ba60 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -43,6 +43,8 @@ Current modules in execution order: - `easyEffects` — restores EasyEffects config and presets from `secrets/easyEffectsConfig.zip` - `wireplumber` — restores WirePlumber state (default audio device, Bluetooth profiles) from `secrets/wireplumberState.zip` - `cups` — restores CUPS printer definitions and PPD drivers from `secrets/cupsConfig.zip` +- `firefox` — installs Firefox (snap) and restores the profile from `secrets/firefoxProfile.zip` +- `vscodium` — installs VSCodium natively (official apt repo), restores config (settings, snippets, profiles, workspace state), and reinstalls extensions from `secrets/vscodiumConfig.zip` **`modules/registry.sh`** — the main workhorse. Reads all entries from `config/registry.yaml` and dispatches each one to a handler based on its `type`. Supported types: `ppa`, `apt`, `snap`, `flatpak`, `dotfile`, `service`, `pipewire`, `video`, `docker`. @@ -65,6 +67,8 @@ Current modules in execution order: - `easyEffectsConfig.zip` — EasyEffects settings and output presets - `wireplumberState.zip` — WirePlumber state (default audio sink, Bluetooth device profiles, per-app volumes) - `cupsConfig.zip` — CUPS `printers.conf` and PPD driver files for all configured printers +- `firefoxProfile.zip` — Firefox Snap profile (bookmarks, history, passwords, extensions, cookies, containers, prefs; excludes caches and site storage) +- `vscodiumConfig.zip` — VSCodium native config (settings, snippets, profiles, workspace state, extension list) **`scripts/`** — capture scripts to run on the current machine before pushing: - `encryptSsh.sh` — encrypts `~/.ssh` into `secrets/sshKeys.tar.gz.age` @@ -72,9 +76,12 @@ Current modules in execution order: - `easyEffects/capture.sh` — captures EasyEffects Flatpak config into `secrets/easyEffectsConfig.zip` - `wireplumber/capture.sh` — captures WirePlumber state into `secrets/wireplumberState.zip` - `cups/capture.sh` — captures CUPS printer config into `secrets/cupsConfig.zip` (requires sudo) +- `firefox/capture.sh` — captures the Firefox Snap profile into `secrets/firefoxProfile.zip` (excludes caches, site storage, telemetry) +- `vscodium/capture.sh` — captures VSCodium native config into `secrets/vscodiumConfig.zip` (settings, profiles, workspace state, extension list) **`config/keys/`** — GPG public keys for third-party apt repositories: - `claude-code.asc` — Anthropic signing key for the Claude Code apt repository +- `vscodium.asc` — Pavlo Rudyi (paulcarroty) signing key for the VSCodium apt repository **`.claude/`** — Claude Code project configuration: - `settings.json` — allowed bash commands for this project @@ -93,7 +100,6 @@ Current modules in execution order: | buildEssential | apt | build-essential | | virtualbox | apt | virtualbox | | dbeaverCe | snap | dbeaver-ce | -| vscodium | flatpak | com.vscodium.codium | | filezilla | flatpak | org.filezillaproject.Filezilla | | angryIpScanner | flatpak | org.angryip.ipscan | | anydesk | flatpak | com.anydesk.Anydesk | @@ -122,6 +128,8 @@ Current modules in execution order: | `easyEffects` | `secrets/easyEffectsConfig.zip` | Settings DB and output presets (HB-Flat, HB-Lite, HB-Mid, Heavy Bass) | | `wireplumber` | `secrets/wireplumberState.zip` | Default audio sink (Bluetooth headphones), A2DP profile, per-app volumes | | `cups` | `secrets/cupsConfig.zip` | 5 printers: Epson L8050 WiFi, Canon MP230, Samsung M2020, POS80, Cups PDF | +| `firefox` | `secrets/firefoxProfile.zip` | Firefox profiles: bookmarks, passwords, extensions, cookies, containers, prefs | +| `vscodium` | `secrets/vscodiumConfig.zip` | Native apt install (official VSCodium repo) + settings, snippets, profiles, workspace state, reinstalled extensions | ## Adding a new package @@ -150,6 +158,8 @@ bash scripts/thunderbird/capture.sh && git add secrets/thunderbirdProfile.zip bash scripts/easyEffects/capture.sh && git add secrets/easyEffectsConfig.zip bash scripts/wireplumber/capture.sh && git add secrets/wireplumberState.zip bash scripts/cups/capture.sh && git add secrets/cupsConfig.zip +bash scripts/firefox/capture.sh && git add secrets/firefoxProfile.zip +bash scripts/vscodium/capture.sh && git add secrets/vscodiumConfig.zip bash scripts/encryptSsh.sh && git add secrets/sshKeys.tar.gz.age ``` diff --git a/config/keys/vscodium.asc b/config/keys/vscodium.asc new file mode 100644 index 0000000..d4fb5f7 --- /dev/null +++ b/config/keys/vscodium.asc @@ -0,0 +1,52 @@ +-----BEGIN PGP PUBLIC KEY BLOCK----- + +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 +=LCWI +-----END PGP PUBLIC KEY BLOCK----- + diff --git a/config/modules b/config/modules index 5ea1585..4b427a4 100644 --- a/config/modules +++ b/config/modules @@ -11,3 +11,5 @@ claudeCode easyEffects wireplumber cups +firefox +vscodium diff --git a/config/registry.yaml b/config/registry.yaml index 2969ec5..4984bf8 100644 --- a/config/registry.yaml +++ b/config/registry.yaml @@ -58,11 +58,10 @@ registry: type: snap package: dbeaver-ce - # Flatpaks - - id: vscodium - type: flatpak - appId: com.vscodium.codium + # VSCodium se instala de forma nativa (repo apt oficial) desde modules/vscodium.sh, + # que además restaura la configuración. No usar la variante flatpak. + # Flatpaks - id: filezilla type: flatpak appId: org.filezillaproject.Filezilla diff --git a/modules/firefox.sh b/modules/firefox.sh new file mode 100755 index 0000000..8d11154 --- /dev/null +++ b/modules/firefox.sh @@ -0,0 +1,46 @@ +#!/usr/bin/env bash +set -euo pipefail +source "$stpRoot/lib/log.sh" +source "$stpRoot/lib/utils.sh" + +readonly firefoxCommonDirectory="$HOME/snap/firefox/common" +readonly firefoxProfilesDirectory="$firefoxCommonDirectory/.mozilla/firefox" +readonly firefoxArchive="$stpRoot/secrets/firefoxProfile.zip" + +firefoxIsInstalled() { + util::isSnapInstalled "firefox" +} + +firefoxProfileExists() { + [[ -f "$firefoxProfilesDirectory/profiles.ini" ]] +} + +installFirefox() { + sudo snap install firefox + log::ok "Firefox instalado" +} + +restoreProfile() { + log::info "Restaurando perfil desde secrets/firefoxProfile.zip..." + mkdir -p "$firefoxCommonDirectory" + unzip -qo "$firefoxArchive" -d "$firefoxCommonDirectory" + log::ok "Perfil restaurado en: $firefoxProfilesDirectory" +} + +if firefoxIsInstalled; then + log::info "Firefox ya instalado" +else + installFirefox +fi + +if [[ ! -f "$firefoxArchive" ]]; then + log::info "Sin respaldo de perfil (secrets/firefoxProfile.zip), salteando restauración" + exit 0 +fi + +if firefoxProfileExists; then + log::info "Perfil de Firefox ya existe, salteando restauración" + exit 0 +fi + +restoreProfile diff --git a/modules/vscodium.sh b/modules/vscodium.sh new file mode 100755 index 0000000..8df2ac1 --- /dev/null +++ b/modules/vscodium.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +set -euo pipefail +source "$stpRoot/lib/log.sh" +source "$stpRoot/lib/utils.sh" + +readonly vscodiumKeyring="/etc/apt/keyrings/vscodium.asc" +readonly vscodiumSources="/etc/apt/sources.list.d/vscodium.list" +readonly vscodiumSourcesEntry="deb [signed-by=${vscodiumKeyring}] https://download.vscodium.com/debs vscodium main" + +readonly vscodiumConfigDirectory="$HOME/.config/VSCodium" +readonly vscodiumUserDirectory="$vscodiumConfigDirectory/User" +readonly vscodiumArchive="$stpRoot/secrets/vscodiumConfig.zip" + +vscodiumIsInstalled() { + util::cmdExists codium +} + +repoIsConfigured() { + [[ -f "$vscodiumSources" ]] +} + +addSigningKey() { + sudo install -m 0755 -d /etc/apt/keyrings + sudo install -m 644 "$stpRoot/config/keys/vscodium.asc" "$vscodiumKeyring" + log::ok "Clave GPG instalada: $vscodiumKeyring" +} + +addRepository() { + echo "$vscodiumSourcesEntry" | sudo tee "$vscodiumSources" > /dev/null + sudo apt-get update -qq + log::ok "Repositorio configurado: $vscodiumSources" +} + +vscodiumConfigExists() { + [[ -f "$vscodiumUserDirectory/settings.json" ]] +} + +restoreUserConfig() { + local extractedDirectory="$1" + mkdir -p "$vscodiumConfigDirectory" + cp -r "$extractedDirectory/User" "$vscodiumConfigDirectory/" + log::ok "Configuración restaurada en: $vscodiumUserDirectory" +} + +installExtensions() { + local extensionsFile="$1" + if [[ ! -f "$extensionsFile" ]]; then + log::info "Sin lista de extensiones en el respaldo, salteando" + return 0 + fi + + local extensionId installedCount=0 + while IFS= read -r extensionId; do + [[ -n "$extensionId" ]] || continue + if codium --install-extension "$extensionId" &>/dev/null; then + log::ok "Extensión instalada: $extensionId" + ((++installedCount)) + else + log::warn "No se pudo instalar: $extensionId" + fi + done < "$extensionsFile" + + log::ok "$installedCount extensión(es) instaladas" +} + +if vscodiumIsInstalled; then + log::info "VSCodium ya instalado: $(codium --version | head -1)" +else + log::info "Instalando VSCodium (nativo)..." + util::requireSudo + if ! repoIsConfigured; then + addSigningKey + addRepository + fi + sudo apt-get install -y codium + log::ok "Instalado: codium" +fi + +if [[ ! -f "$vscodiumArchive" ]]; then + log::info "Sin respaldo de configuración (secrets/vscodiumConfig.zip), salteando restauración" + exit 0 +fi + +if vscodiumConfigExists; then + log::info "Configuración de VSCodium ya existe, salteando restauración" + exit 0 +fi + +log::step "Restaurando configuración de VSCodium" +extractedDirectory="$(mktemp -d)" +trap 'rm -rf "$extractedDirectory"' EXIT + +unzip -qo "$vscodiumArchive" -d "$extractedDirectory" +restoreUserConfig "$extractedDirectory" +installExtensions "$extractedDirectory/extensions.txt" diff --git a/scripts/firefox/capture.sh b/scripts/firefox/capture.sh new file mode 100755 index 0000000..a002ad5 --- /dev/null +++ b/scripts/firefox/capture.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Captura el perfil de Firefox (Snap): marcadores, historial, contraseñas, +# extensiones, cookies, contenedores y preferencias de todos los perfiles. +# Excluye cachés, almacenamiento de sitios, crash reports y telemetría. +set -euo pipefail +stpRoot="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +source "$stpRoot/lib/log.sh" + +readonly firefoxCommonDirectory="$HOME/snap/firefox/common" +readonly firefoxProfilesDirectory="$firefoxCommonDirectory/.mozilla/firefox" +readonly outputFile="$stpRoot/secrets/firefoxProfile.zip" + +firefoxDataExists() { + [[ -f "$firefoxProfilesDirectory/profiles.ini" ]] +} + +if ! firefoxDataExists; then + log::warn "Datos de Firefox Snap no encontrados en: $firefoxProfilesDirectory" + log::info "Asegurate de haber abierto Firefox al menos una vez antes de capturar" + exit 0 +fi + +log::step "Capturando perfil de Firefox" +log::info "Cerrá Firefox antes de capturar para evitar bases de datos a medio escribir" +mkdir -p "$stpRoot/secrets" +rm -f "$outputFile" + +( + cd "$firefoxCommonDirectory" + find ".mozilla/firefox" \ + | grep -Ev "/(cache2|startupCache|OfflineCache|thumbnails|shader-cache|jumpListCache|storage|minidumps|crashes|datareporting|saved-telemetry-pings|security_state|gmp-widevinecdm|gmp-gmpopenh264)(/|$)" \ + | grep -Ev "/(Crash Reports|Pending Pings)(/|$)" \ + | grep -Ev "\.(sqlite-wal|sqlite-shm)$" \ + | grep -Ev "/(lock|\.parentlock)$" \ + | zip -q "$outputFile" -@ +) + +log::ok "Guardado: secrets/firefoxProfile.zip ($(du -sh "$outputFile" | cut -f1))" +log::info "Commiteá secrets/firefoxProfile.zip antes de hacer push" diff --git a/scripts/vscodium/capture.sh b/scripts/vscodium/capture.sh new file mode 100755 index 0000000..e3acd8f --- /dev/null +++ b/scripts/vscodium/capture.sh @@ -0,0 +1,64 @@ +#!/usr/bin/env bash +# Captura la configuración de VSCodium (instalación nativa, ~/.config/VSCodium): +# settings, keybindings, snippets, perfiles, la lista de extensiones y el +# estado de los workspaces (mapeo carpeta↔workspace + estado de UI). +# Excluye la caché regenerable de las extensiones (p. ej. redhat.java/jdt_ws). +set -euo pipefail +stpRoot="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)" +source "$stpRoot/lib/log.sh" +source "$stpRoot/lib/utils.sh" + +readonly vscodiumConfigDirectory="$HOME/.config/VSCodium" +readonly vscodiumUserDirectory="$vscodiumConfigDirectory/User" +readonly outputFile="$stpRoot/secrets/vscodiumConfig.zip" + +vscodiumDataExists() { + [[ -d "$vscodiumUserDirectory" ]] +} + +listConfigFiles() { + local configFile + for configFile in settings.json keybindings.json tasks.json argv.json; do + [[ -f "User/$configFile" ]] && echo "User/$configFile" + done + + find "User/snippets" "User/profiles" -type f 2>/dev/null + + # De cada workspace solo interesa el mapeo a la carpeta y el estado de UI; + # el resto son cachés de extensiones que se regeneran solas. + find "User/workspaceStorage" -type f \ + \( -name workspace.json -o -name 'state.vscdb' -o -name 'state.vscdb.backup' \) 2>/dev/null + + # Estado global: lista de workspaces recientes y asociaciones de perfil. + find "User/globalStorage" -maxdepth 1 -type f \ + \( -name 'state.vscdb' -o -name 'storage.json' \) 2>/dev/null +} + +if ! vscodiumDataExists; then + log::warn "Datos de VSCodium no encontrados en: $vscodiumUserDirectory" + log::info "Asegurate de haber abierto VSCodium al menos una vez antes de capturar" + exit 0 +fi + +log::step "Capturando configuración de VSCodium" +mkdir -p "$stpRoot/secrets" +rm -f "$outputFile" + +( + cd "$vscodiumConfigDirectory" + listConfigFiles | zip -q "$outputFile" -@ +) + +if util::cmdExists codium; then + workingDirectory="$(mktemp -d)" + trap 'rm -rf "$workingDirectory"' EXIT + codium --list-extensions > "$workingDirectory/extensions.txt" + # -j descarta la ruta: el archivo queda como extensions.txt en la raíz del zip. + zip -qj "$outputFile" "$workingDirectory/extensions.txt" + log::ok "Lista de extensiones incluida en el respaldo ($(wc -l < "$workingDirectory/extensions.txt") extensiones)" +else + log::warn "Comando 'codium' no disponible: no se guardó la lista de extensiones" +fi + +log::ok "Guardado: secrets/vscodiumConfig.zip ($(du -sh "$outputFile" | cut -f1))" +log::info "Commiteá secrets/vscodiumConfig.zip antes de hacer push" diff --git a/secrets/firefoxProfile.zip b/secrets/firefoxProfile.zip new file mode 100644 index 0000000..53e3b2b Binary files /dev/null and b/secrets/firefoxProfile.zip differ diff --git a/secrets/vscodiumConfig.zip b/secrets/vscodiumConfig.zip new file mode 100644 index 0000000..be93f62 Binary files /dev/null and b/secrets/vscodiumConfig.zip differ