Files
fn_registry/bash/functions/browser/apply_chromium_cdp_flag.sh
T
Egutierrez 830f2d34de feat(browser): funciones idempotentes para config de sistema de chromium
Cierra el gap de reproducibilidad entre PCs del proyecto web_scraping:
la organizacion de extensiones y el CDP global dejaban de ser pasos
manuales con sudo documentados en prosa.

- apply_chromium_extension_policy: escribe ExtensionInstallForcelist
  (whitelist via --keep) en /etc/chromium/policies/managed/extensions.json
  de forma idempotente, con backup automatico y validacion JSON. --dry-run
  previsualiza sin tocar el sistema.
- apply_chromium_cdp_flag: gestiona /etc/chromium.d/cdp (CDP global).
  Loopback por defecto, --network para bind 0.0.0.0 (con aviso), --remove
  para desactivar, --dry-run para previsualizar. Idempotente con backup.

Ambas: dominio browser, grupo navegator, impuras (escriben en /etc via
sudo), guard de auto-ejecucion (ejecutables con fn run y sourceables).

Docs del proyecto (CONVENTIONS.md reglas 8/9, CHROMIUM_SYSTEM.md
inventario + tabla accionable) ahora apuntan a 'fn run apply_chromium_*'
como metodo canonico en vez de editar los archivos de /etc a mano.
2026-06-05 16:33:35 +02:00

206 lines
7.0 KiB
Bash

#!/usr/bin/env bash
# apply_chromium_cdp_flag — gestiona el fragmento /etc/chromium.d/cdp que activa CDP global.
#
# Uso:
# apply_chromium_cdp_flag [--port N] [--network] [--fragment-path <path>] [--remove] [--dry-run]
apply_chromium_cdp_flag() {
local port=9222
local network=0
local fragment_path="/etc/chromium.d/cdp"
local remove=0
local dry_run=0
# Parseo de argumentos
while [[ $# -gt 0 ]]; do
case "$1" in
--port)
port="$2"
shift 2
;;
--network)
network=1
shift
;;
--fragment-path)
fragment_path="$2"
shift 2
;;
--remove)
remove=1
shift
;;
--dry-run)
dry_run=1
shift
;;
*)
echo "apply_chromium_cdp_flag: argumento desconocido: $1" >&2
return 1
;;
esac
done
# Validación del puerto
if ! [[ "$port" =~ ^[0-9]+$ ]] || (( port < 1 || port > 65535 )); then
echo "apply_chromium_cdp_flag: puerto inválido: $port (debe ser 1-65535)" >&2
return 1
fi
# Construcción del contenido del fragmento
local flags_line
if (( network )); then
echo "ADVERTENCIA DE SEGURIDAD: --network activa --remote-debugging-address=0.0.0.0." >&2
echo "El navegador quedará expuesto a toda la red local. Cualquier host en la red" >&2
echo "podrá controlar Chromium remotamente y leer todas las sesiones abiertas." >&2
flags_line='export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --remote-debugging-port='"${port}"' --remote-allow-origins=* --remote-debugging-address=0.0.0.0"'
else
flags_line='export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --remote-debugging-port='"${port}"' --remote-allow-origins=*"'
fi
local mode_label
if (( network )); then
mode_label="network (0.0.0.0)"
else
mode_label="loopback (127.0.0.1)"
fi
local fragment_content
fragment_content="# CDP global para automatizacion del navegador del usuario (proyecto web_scraping, regla 8).
# Bind ${mode_label} por defecto: el puerto solo
# es accesible desde 127.0.0.1, no desde la red.
${flags_line}"
# Modo --dry-run: solo mostrar y salir
if (( dry_run )); then
echo "--- dry-run: fragmento que se escribiría en ${fragment_path} ---"
echo "${fragment_content}"
echo "--- fin dry-run ---"
return 0
fi
# Modo --remove
if (( remove )); then
if [[ ! -e "$fragment_path" ]]; then
echo "apply_chromium_cdp_flag: ${fragment_path} no existe, nada que borrar."
return 0
fi
local backup_path="${fragment_path}.bak.$(date +%Y%m%d)"
if [[ ! -e "$backup_path" ]]; then
if [[ $EUID -eq 0 ]]; then
cp "$fragment_path" "$backup_path"
else
sudo cp "$fragment_path" "$backup_path" || {
echo "apply_chromium_cdp_flag: no se pudo crear backup en ${backup_path}" >&2
return 1
}
fi
fi
if [[ $EUID -eq 0 ]]; then
rm "$fragment_path"
else
sudo rm "$fragment_path" || {
echo "apply_chromium_cdp_flag: no se pudo borrar ${fragment_path}" >&2
return 1
}
fi
echo "apply_chromium_cdp_flag: fragmento eliminado (backup: ${backup_path})"
echo "Nota: el chromium ya abierto antes de este cambio no lo hereda hasta reiniciarlo."
return 0
fi
# Idempotencia: comparar con contenido actual
if [[ -f "$fragment_path" ]]; then
local current_content
current_content=$(cat "$fragment_path" 2>/dev/null)
if [[ "$current_content" == "$fragment_content" ]]; then
echo "apply_chromium_cdp_flag: ya aplicado, sin cambios (${fragment_path})."
return 0
fi
fi
# Crear directorio si falta
local fragment_dir
fragment_dir=$(dirname "$fragment_path")
if [[ ! -d "$fragment_dir" ]]; then
if [[ $EUID -eq 0 ]]; then
mkdir -p "$fragment_dir"
else
sudo mkdir -p "$fragment_dir" || {
echo "apply_chromium_cdp_flag: no se pudo crear ${fragment_dir}" >&2
return 1
}
fi
fi
# Backup si ya existe y difiere
if [[ -e "$fragment_path" ]]; then
local backup_path="${fragment_path}.bak.$(date +%Y%m%d)"
if [[ ! -e "$backup_path" ]]; then
if [[ $EUID -eq 0 ]]; then
cp "$fragment_path" "$backup_path"
else
sudo cp "$fragment_path" "$backup_path" || {
echo "apply_chromium_cdp_flag: no se pudo crear backup en ${backup_path}" >&2
return 1
}
fi
echo "apply_chromium_cdp_flag: backup creado en ${backup_path}"
fi
fi
# Escribir fragmento
local tmpfile
tmpfile=$(mktemp)
printf '%s\n' "$fragment_content" > "$tmpfile"
if [[ $EUID -eq 0 ]]; then
cp "$tmpfile" "$fragment_path"
chmod 644 "$fragment_path"
else
sudo cp "$tmpfile" "$fragment_path" || {
rm -f "$tmpfile"
echo "apply_chromium_cdp_flag: no se pudo escribir ${fragment_path}" >&2
return 1
}
sudo chmod 644 "$fragment_path" 2>/dev/null || true
fi
rm -f "$tmpfile"
# Validación post-escritura
local expected_line="--remote-debugging-port=${port}"
if ! grep -qF "$expected_line" "$fragment_path" 2>/dev/null; then
echo "apply_chromium_cdp_flag: validación fallida — la línea export no apareció en ${fragment_path}." >&2
# Restaurar backup si existe
local backup_path="${fragment_path}.bak.$(date +%Y%m%d)"
if [[ -f "$backup_path" ]]; then
if [[ $EUID -eq 0 ]]; then
cp "$backup_path" "$fragment_path"
else
sudo cp "$backup_path" "$fragment_path" 2>/dev/null || true
fi
echo "apply_chromium_cdp_flag: backup restaurado desde ${backup_path}" >&2
fi
return 1
fi
# Resumen final
echo "apply_chromium_cdp_flag: CDP global activado correctamente."
echo " Fragmento : ${fragment_path}"
echo " Puerto : ${port}"
echo " Modo : ${mode_label}"
echo ""
echo "Nota: el chromium ya abierto antes de este cambio no hereda el flag hasta reiniciarlo."
echo "Nota: dos procesos chromium no pueden compartir el mismo puerto; usa --port <otro> para"
echo " automatización dedicada que corra en paralelo al navegador del usuario."
}
# Auto-ejecución al correr el archivo directo (bash file.sh / fn run). Si se hace `source`,
# solo se define la función y no se ejecuta nada.
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
apply_chromium_cdp_flag "$@"
fi