feat(browser): CRUD de perfiles Chromium + pipeline reset_chrome_profiles

Cinco funciones nuevas (dominio browser, grupo navegator) que cierran los gaps
de gestión de perfiles, más un pipeline que las orquesta:

- backup_chrome_bookmarks / restore_chrome_bookmarks: backup y restore de los
  archivos Bookmarks (copia byte a byte verbatim para preservar el checksum
  interno; en Chromium 148 los bookmarks no están bajo el super_mac de Secure
  Preferences). Guard por user-data-dir (no global).
- delete_chrome_profile: borra la carpeta del perfil + limpia su entrada en
  Local State (info_cache, profiles_order, last_active_profiles, last_used).
- create_chrome_profile: lanza chromium headless (vía systemd-run) para que la
  managed policy instale la whitelist de extensiones, y asigna el nombre legible
  en Local State. Mata todo el árbol de chromium del udd antes de editar Local
  State (los hijos zygote/gpu no repiten --user-data-dir pero referencian la ruta).
- list_chrome_profile_extensions (Go): lista extensiones de un perfil con
  ID/name/version/location/enabled/fromPolicy. 7 unit tests.
- reset_chrome_profiles (pipeline): backup -> cerrar chromium -> delete -> create
  -> restore -> verify. Destructivo (--yes), --dry-run seguro.

Validado: unit tests Go verdes, backup/restore byte-idéntico, delete limpia Local
State, create instala la forcelist global (uBlock + web_proxy) en perfiles nuevos.
This commit is contained in:
Egutierrez
2026-06-06 01:24:21 +02:00
parent 736e019e19
commit ae841ceedb
13 changed files with 1984 additions and 0 deletions
@@ -0,0 +1,93 @@
---
name: restore_chrome_bookmarks
kind: function
lang: bash
domain: browser
version: "1.0.0"
purity: impure
signature: "restore_chrome_bookmarks --backup-dir <ts-dir> [--user-data-dir <dir>] [--profile <name>]... [--dry-run]"
description: "Restaura archivos Bookmarks de Chrome/Chromium desde un directorio de backup generado por backup_chrome_bookmarks hacia los perfiles destino en user-data-dir. Copia byte a byte con cp -p para preservar el checksum MD5 interno del archivo. Nunca parsea ni reserializa el JSON. Requiere que Chromium esté cerrado antes de ejecutar."
tags: [navegator, chromium, bookmarks, restore, browser, scraping, profile]
uses_functions: []
uses_types: []
returns: []
returns_optional: false
error_type: "error_go_core"
imports: []
tested: false
tests: []
test_file_path: ""
file_path: "bash/functions/browser/restore_chrome_bookmarks.sh"
params:
- name: --backup-dir
desc: "Directorio de backup con timestamp generado por backup_chrome_bookmarks. Debe contener subdirectorios <profile>/Bookmarks. OBLIGATORIO."
- name: --user-data-dir
desc: "Ruta raíz del user-data-dir de Chrome/Chromium destino. Default: ~/.config/chromium"
- name: --profile
desc: "Nombre del perfil a restaurar (repetible, ej. Default, Profile 1). Si no se pasa ninguno se restauran TODOS los perfiles presentes en el backup-dir."
- name: --dry-run
desc: "Muestra qué archivos se copiarían y cuáles Bookmarks.bak se borrarían, sin tocar nada en disco."
output: "JSON en stdout: {\"restored\": [{\"profile\": \"Default\", \"dst\": \"<path>\", \"bytes\": N}, ...]}. Exit 0 en éxito o dry-run. Errores a stderr con exit != 0."
---
## Ejemplo
```bash
# PASO 1 — cerrar Chromium (OBLIGATORIO en modo real)
pkill -TERM chromium
# PASO 2 — restaurar todos los perfiles desde el backup más reciente
source $HOME/fn_registry/bash/functions/browser/restore_chrome_bookmarks.sh
restore_chrome_bookmarks \
--user-data-dir "$HOME/.config/chromium" \
--backup-dir "$HOME/backups/chromium_bookmarks/2026-06-04T15:30:00"
# Restaurar solo un perfil concreto
restore_chrome_bookmarks \
--backup-dir "$HOME/backups/chromium_bookmarks/2026-06-04T15:30:00" \
--profile Default
# Restaurar dos perfiles específicos
restore_chrome_bookmarks \
--backup-dir "$HOME/backups/chromium_bookmarks/2026-06-04T15:30:00" \
--profile Default \
--profile "Profile 1"
# Previsualizar sin tocar nada (no necesita Chromium cerrado)
restore_chrome_bookmarks \
--backup-dir "$HOME/backups/chromium_bookmarks/2026-06-04T15:30:00" \
--dry-run
# Salida esperada:
# {"restored":[{"profile":"Default","dst":"/home/enmanuel/.config/chromium/Default/Bookmarks","bytes":12453}]}
```
También ejecutable directamente con `fn run`:
```bash
cd $HOME/fn_registry
./fn run restore_chrome_bookmarks_bash_browser -- \
--backup-dir "$HOME/backups/chromium_bookmarks/2026-06-04T15:30:00" \
--dry-run
```
## Cuando usarla
Úsala después de una sesión de scraping o automatización que haya alterado los bookmarks, o para recuperar bookmarks tras formatear/recrear un perfil de Chromium. Combínala con `backup_chrome_bookmarks` (que genera el `--backup-dir` con la estructura esperada) para tener un ciclo completo de backup/restore. También útil para propagar bookmarks de un perfil o PC a otro.
## Gotchas
- **Chromium DEBE estar cerrado** antes de ejecutar en modo real. Chromium mantiene los bookmarks en memoria y los reescribe al archivo `Bookmarks` al cerrar; si restauras con Chromium abierto, el proceso sobreescribirá tu restauración al cerrarse. La función lo comprueba con `pgrep -x chromium` y aborta con exit 2 si hay procesos vivos. En `--dry-run` este check se omite.
- **Copia verbatim — nunca reserializar el JSON**. El archivo `Bookmarks` contiene un campo `checksum` con el MD5 del propio contenido JSON (calculado por Chromium internamente). Si se parsea y reserializa el JSON (aunque sea equivalente), el checksum queda inválido y Chromium descarta silenciosamente el archivo y regenera uno vacío. Esta función usa `cp -p` para garantizar que los bytes son idénticos al original.
- **En Chromium 148 los bookmarks NO están bajo `super_mac` de Secure Preferences**. No es necesario tocar `Preferences` ni `Secure Preferences` al restaurar bookmarks (a diferencia de extensiones). La función solo opera sobre el archivo `Bookmarks`.
- **`Bookmarks.bak` residual se borra**. Chromium crea `Bookmarks.bak` como copia de seguridad interna. Si existe antes de la restauración, esta función lo borra para que Chromium no lo use como fallback en lugar del archivo recién restaurado.
- **El directorio destino del perfil se crea si no existe**. Si el perfil aún no tiene directorio en `user-data-dir`, se crea con `mkdir -p`. Chromium lo inicializará correctamente la primera vez que arranque con ese perfil.
- **Opera por perfil**. Si no pasas `--profile`, restaura todos los perfiles presentes en el backup. Pasa `--profile` explícito para restaurar selectivamente y evitar sobreescribir perfiles sin querer.
## Exit codes
| Código | Significado |
|--------|------------|
| 0 | Éxito o dry-run completado |
| 1 | Argumento inválido, backup-dir/user-data-dir no encontrado, o perfil no presente en backup |
| 2 | Chromium está corriendo (solo en modo real) |