feat(browser): auto-commit con 3 cambios
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,81 @@
|
||||
---
|
||||
name: install_chromium_proxy_extension
|
||||
kind: function
|
||||
lang: bash
|
||||
domain: browser
|
||||
version: 1.0.0
|
||||
purity: impure
|
||||
signature: install_chromium_proxy_extension --ext-dir DIR [--name NAME] [--stable-dir DIR] [--uninstall]
|
||||
description: "Instala una extension desempaquetada de Chromium en todos los perfiles del usuario de forma persistente, escribiendo un fragmento en /etc/chromium.d/ que el wrapper de Chromium carga en cada arranque. Pensado para distribuir la extension de toggle de proxy de web_proxy sin Web Store, pero sirve para cualquier extension desempaquetada."
|
||||
tags: [web-proxy, chromium, extension, browser, proxy, install]
|
||||
uses_functions: []
|
||||
uses_types: []
|
||||
returns: []
|
||||
returns_optional: false
|
||||
error_type: "error_go_core"
|
||||
params:
|
||||
- name: --ext-dir
|
||||
desc: "Directorio de la extension desempaquetada de origen (debe contener manifest.json). Obligatorio salvo en --uninstall."
|
||||
- name: --name
|
||||
desc: "Nombre del fragmento en /etc/chromium.d/ (default web_proxy_ext). Identifica esta instalacion para poder desinstalarla."
|
||||
- name: --stable-dir
|
||||
desc: "Ruta estable donde se copia la extension, independiente del repo (default ~/.web_proxy/extension). --load-extension apunta aqui."
|
||||
- name: --uninstall
|
||||
desc: "Elimina el fragmento de /etc/chromium.d/ y la copia estable. No requiere --ext-dir."
|
||||
output: "JSON en stdout: {installed|uninstalled, name, stable_dir, chromiumd, ext_id}. Requiere sudo para escribir en /etc/chromium.d/."
|
||||
file_path: bash/functions/browser/install_chromium_proxy_extension.sh
|
||||
---
|
||||
|
||||
# install_chromium_proxy_extension
|
||||
|
||||
Instala una extension desempaquetada de Chromium en **todos los perfiles** del
|
||||
usuario, de forma persistente, sin pasar por la Chrome Web Store.
|
||||
|
||||
## Ejemplo
|
||||
|
||||
```bash
|
||||
# Instalar la extension de toggle de proxy de web_proxy en todos los perfiles
|
||||
install_chromium_proxy_extension --ext-dir /home/enmanuel/fn_registry/apps/web_proxy/extension
|
||||
|
||||
# Desinstalarla
|
||||
install_chromium_proxy_extension --uninstall
|
||||
|
||||
# Otra extension, con nombre y ruta estable propios
|
||||
install_chromium_proxy_extension --ext-dir ~/mis-extensiones/foo --name foo_ext --stable-dir ~/.local/share/foo_ext
|
||||
```
|
||||
|
||||
Tras instalar, cierra y vuelve a abrir Chromium: la extension aparece en todos
|
||||
los perfiles, incluidos los que se creen despues.
|
||||
|
||||
## Cuando usarla
|
||||
|
||||
Cuando necesitas que una extension desempaquetada este presente en todos los
|
||||
perfiles de Chromium de una maquina (por ejemplo, un toggle de proxy de captura
|
||||
preconfigurado) y no quieres publicarla en la Web Store ni cargarla a mano en
|
||||
cada perfil. Es la pieza que hace que `web_proxy` quede "a un clic" en cualquier
|
||||
ventana de Chromium.
|
||||
|
||||
## Gotchas
|
||||
|
||||
- **Requiere sudo** para escribir en `/etc/chromium.d/`. Ten las credenciales
|
||||
cacheadas (`sudo -v`) antes de invocarla de forma no interactiva.
|
||||
- **Solo para el wrapper de Chromium de Debian/Ubuntu** (paquete `chromium`,
|
||||
no snap ni Google Chrome). El wrapper hace `source /etc/chromium.d/*` en cada
|
||||
arranque. Comprueba con `head -1 $(command -v chromium)` que es un script.
|
||||
- **`--enable-remote-extensions` es imprescindible** en estos builds: sin el,
|
||||
el wrapper anade `--disable-extensions-except` y `--disable-background-networking`,
|
||||
que deshabilitan toda extension que no venga por `--load-extension`. El
|
||||
fragmento generado lo incluye; por eso las demas extensiones del usuario
|
||||
siguen funcionando.
|
||||
- La extension se carga **desempaquetada** (`--load-extension`), no como `.crx`
|
||||
firmado. Chromium puede mostrar un aviso de "extensiones en modo desarrollador".
|
||||
El force-install via managed policy con `.crx` local + `update_url file://`
|
||||
no funciona con este wrapper (lo bloquea `--disable-extensions-except`).
|
||||
- El ID de la extension depende de `--stable-dir` (se deriva del path). Si
|
||||
cambias la ruta estable, el ID cambia.
|
||||
- No reinicia Chromium: los cambios aplican en el siguiente arranque del
|
||||
navegador.
|
||||
|
||||
## Capability growth log
|
||||
|
||||
- v1.0.0 (2026-06-02) — version inicial. Instala/desinstala extension global via /etc/chromium.d con --enable-remote-extensions + --load-extension.
|
||||
@@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env bash
|
||||
# install_chromium_proxy_extension — instala una extension desempaquetada de
|
||||
# Chromium en TODOS los perfiles del usuario, de forma persistente, escribiendo
|
||||
# un fragmento en /etc/chromium.d/ que el wrapper de Chromium carga en cada
|
||||
# arranque.
|
||||
#
|
||||
# Por que /etc/chromium.d en vez de managed policy con .crx force_installed:
|
||||
# el wrapper de Chromium de Debian/Ubuntu (xtradeb y derivados), cuando NO se
|
||||
# pasa --enable-remote-extensions, anade --disable-extensions-except=<solo las
|
||||
# de --load-extension> y --disable-background-networking. Eso deshabilita
|
||||
# cualquier extension force_installed por policy y bloquea su update check. La
|
||||
# via fiable es habilitar --enable-remote-extensions y cargar la extension
|
||||
# desempaquetada con --load-extension, ambos inyectados de forma global desde
|
||||
# /etc/chromium.d/, que el wrapper hace `source` en cada lanzamiento.
|
||||
|
||||
install_chromium_proxy_extension() {
|
||||
local ext_dir=""
|
||||
local name="web_proxy_ext"
|
||||
local stable_dir="$HOME/.web_proxy/extension"
|
||||
local chromiumd="/etc/chromium.d"
|
||||
local uninstall="no"
|
||||
|
||||
# Permite sudo no interactivo via SUDO_ASKPASS (sudo -A) cuando se ejecuta
|
||||
# sin terminal (agentes, CI). Con terminal interactivo usa sudo normal.
|
||||
local SUDO="sudo"
|
||||
[[ -n "${SUDO_ASKPASS:-}" ]] && SUDO="sudo -A"
|
||||
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--ext-dir) ext_dir="$2"; shift 2 ;;
|
||||
--name) name="$2"; shift 2 ;;
|
||||
--stable-dir) stable_dir="$2"; shift 2 ;;
|
||||
--uninstall) uninstall="yes"; shift ;;
|
||||
*) echo "ERROR: argumento desconocido: $1" >&2; return 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ! -d "$chromiumd" ]]; then
|
||||
echo "ERROR: $chromiumd no existe. Este Chromium no usa el wrapper con /etc/chromium.d." >&2
|
||||
echo " Comprueba 'head -1 \$(command -v chromium)'; si no es un wrapper shell, usa otra via." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Desinstalacion: quitar el fragmento global y la copia estable.
|
||||
if [[ "$uninstall" == "yes" ]]; then
|
||||
$SUDO rm -f "${chromiumd}/${name}" || {
|
||||
echo "ERROR: no se pudo eliminar ${chromiumd}/${name} (requiere sudo)." >&2
|
||||
return 1
|
||||
}
|
||||
rm -rf "$stable_dir"
|
||||
printf '{"uninstalled": true, "name": "%s"}\n' "$name"
|
||||
return 0
|
||||
fi
|
||||
|
||||
# Instalacion: validar la extension de origen.
|
||||
if [[ -z "$ext_dir" || ! -f "${ext_dir}/manifest.json" ]]; then
|
||||
echo "ERROR: --ext-dir debe apuntar a un directorio con manifest.json." >&2
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Copiar la extension a una ubicacion estable, independiente del repo, para
|
||||
# que --load-extension no se rompa si el repo se mueve o se limpia.
|
||||
mkdir -p "$stable_dir" || {
|
||||
echo "ERROR: no se pudo crear $stable_dir." >&2
|
||||
return 1
|
||||
}
|
||||
# Vaciar destino y copiar el contenido del origen.
|
||||
rm -rf "${stable_dir:?}/"* 2>/dev/null
|
||||
cp -r "${ext_dir}/." "$stable_dir/" || {
|
||||
echo "ERROR: no se pudo copiar la extension a $stable_dir." >&2
|
||||
return 1
|
||||
}
|
||||
|
||||
# Escribir el fragmento que el wrapper carga en cada arranque. Se hace via
|
||||
# archivo temporal + sudo cp para no exponer el contenido por una tuberia.
|
||||
local tmp
|
||||
tmp="$(mktemp)"
|
||||
printf 'export CHROMIUM_FLAGS="$CHROMIUM_FLAGS --enable-remote-extensions --load-extension=%s"\n' "$stable_dir" > "$tmp"
|
||||
if ! $SUDO cp "$tmp" "${chromiumd}/${name}"; then
|
||||
rm -f "$tmp"
|
||||
echo "ERROR: no se pudo escribir ${chromiumd}/${name} (requiere sudo)." >&2
|
||||
return 1
|
||||
fi
|
||||
$SUDO chmod 0644 "${chromiumd}/${name}" 2>/dev/null
|
||||
rm -f "$tmp"
|
||||
|
||||
# ID de extension desempaquetada (deterministico: sha256 del path estable).
|
||||
local ext_id
|
||||
ext_id="$(python3 - "$stable_dir" <<'PY' 2>/dev/null
|
||||
import hashlib, sys
|
||||
h = hashlib.sha256(sys.argv[1].encode()).hexdigest()[:32]
|
||||
print(''.join(chr(ord('a') + int(c, 16)) for c in h))
|
||||
PY
|
||||
)"
|
||||
|
||||
printf '{"installed": true, "name": "%s", "stable_dir": "%s", "chromiumd": "%s/%s", "ext_id": "%s"}\n' \
|
||||
"$name" "$stable_dir" "$chromiumd" "$name" "$ext_id"
|
||||
}
|
||||
|
||||
# Ejecutar si se llama directamente (fn run / bash <file>)
|
||||
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
||||
install_chromium_proxy_extension "$@"
|
||||
fi
|
||||
@@ -7,6 +7,7 @@ launch_chromium_proxy() {
|
||||
local start_url=""
|
||||
local ca_cert=""
|
||||
local extra_args=""
|
||||
local ext_dir=""
|
||||
|
||||
# Parsear argumentos
|
||||
while [[ $# -gt 0 ]]; do
|
||||
@@ -19,6 +20,8 @@ launch_chromium_proxy() {
|
||||
start_url="$2"; shift 2 ;;
|
||||
--ca-cert)
|
||||
ca_cert="$2"; shift 2 ;;
|
||||
--ext)
|
||||
ext_dir="$2"; shift 2 ;;
|
||||
--extra)
|
||||
extra_args="$2"; shift 2 ;;
|
||||
*)
|
||||
@@ -52,13 +55,24 @@ launch_chromium_proxy() {
|
||||
|
||||
# Construir argumentos del navegador
|
||||
local args=(
|
||||
"--proxy-server=${proxy_url}"
|
||||
"--user-data-dir=${profile_dir}"
|
||||
"--proxy-bypass-list=<-loopback>"
|
||||
"--no-first-run"
|
||||
"--no-default-browser-check"
|
||||
)
|
||||
|
||||
# Proxy fijo opcional. Con "--proxy none" (o vacio) no se fija proxy en el
|
||||
# cmdline: util cuando una extension de proxy gestiona la conexion (toggle).
|
||||
if [[ -n "$proxy_url" && "$proxy_url" != "none" ]]; then
|
||||
args+=("--proxy-server=${proxy_url}" "--proxy-bypass-list=<-loopback>")
|
||||
fi
|
||||
|
||||
# Cargar una extension desempaquetada (--load-extension). Funciona en
|
||||
# Chromium (no en Chrome stable 138+). Para persistencia en todos los
|
||||
# perfiles se usa managed policy en su lugar.
|
||||
if [[ -n "$ext_dir" ]]; then
|
||||
args+=("--load-extension=${ext_dir}")
|
||||
fi
|
||||
|
||||
# Manejo de certificados TLS
|
||||
if [[ -n "$ca_cert" ]]; then
|
||||
# El usuario instalo el CA en el perfil; no ignorar errores de certificado.
|
||||
|
||||
Reference in New Issue
Block a user