830f2d34de
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.
206 lines
7.0 KiB
Bash
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
|