commit 271f19a446c3c0829612f2808c4b5467c9860017
parent 969e97c171b8d09d307e95071d89988642d53c18
Author: Pablo Murad <pablo@pablomurad.com>
Date: Sat, 21 Mar 2026 16:14:17 -0300
fix
Diffstat:
5 files changed, 35 insertions(+), 26 deletions(-)
diff --git a/patches/yetgg.py b/patches/yetgg.py
@@ -83,7 +83,11 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
)
p.add_argument("--dry-run", action="store_true", help="só simular")
p.add_argument("--verbose", action="store_true", help="log detalhado")
- p.add_argument("--force", action="store_true", help="sobrescrever modelos / symlinks (como setup_alt_protocols)")
+ p.add_argument(
+ "--force",
+ action="store_true",
+ help="sobrescrever gophermap / symlinks (como setup_alt_protocols); index.gmi existente mantém-se",
+ )
p.add_argument(
"--users-json",
type=Path,
diff --git a/scripts/admin/create_runv_user.py b/scripts/admin/create_runv_user.py
@@ -7,9 +7,10 @@ Contrato de provisionamento (ordem garantida após validação):
1. **Criar o usuário** — ``adduser --disabled-password``.
2. **Instalar a chave** — ``~/.ssh/authorized_keys`` com modos ``700`` / ``600``.
3. **Preparar public_html** — diretório ``755``, ``index.html`` estático ``644``.
-4. **Preparar public_gopher / public_gemini** — ``gophermap`` e ``index.gmi`` modelo (não
- sobrescreve sem ``--force-gopher`` / ``--force-gemini``); symlink Gemini em
- ``/var/gemini/users/<user>`` quando o diretório existir.
+4. **Preparar public_gopher / public_gemini** — ``gophermap`` modelo (não sobrescreve sem
+ ``--force-gopher``); ``index.gmi`` só é criado se ainda não existir (nunca substituído);
+ symlink em ``/var/gemini/users/<user>`` quando o diretório existir (``--force-gemini`` só
+ força reparação do symlink / conflitos).
5. **Copiar o skel** — o Debian copia ``/etc/skel`` para a home **durante** o passo 1; depois,
após os diretórios públicos, o script acrescenta ``README.md`` runv (português), sem apagar o que
veio do skel (use ``--force-readme`` para substituir). Prepare ``/etc/skel`` com ``tools.py``
@@ -522,7 +523,6 @@ def prepare_public_gemini(
username: str,
uid: int,
gid: int,
- force_gemini: bool,
log: logging.Logger,
) -> None:
d = home / "public_gemini"
@@ -533,11 +533,9 @@ def prepare_public_gemini(
except PermissionError as e:
raise SystemProvisionError(f"não foi possível ajustar dono de {d}: {e}") from e
idx = d / "index.gmi"
- if idx.exists() and not force_gemini:
- log.info("%s já existe; não sobrescrevendo (use --force-gemini)", idx)
+ if idx.exists():
+ log.info("%s já existe; modelo não aplicado", idx)
return
- if idx.exists() and force_gemini:
- log.warning("sobrescrevendo %s (--force-gemini)", idx)
idx.write_text(default_gemini_index_gmi(username), encoding="utf-8")
os.chmod(idx, 0o644)
try:
@@ -1172,7 +1170,7 @@ def interactive_fill(args: argparse.Namespace) -> None:
default_no=True,
)
args.force_gemini = prompt_yes_no(
- "Se já existir ~/public_gemini/index.gmi, sobrescrever (--force-gemini)?",
+ "Forçar correção do symlink Gemini (/var/gemini/users) se estiver errado ou em conflito (--force-gemini)?",
default_no=True,
)
args.force_readme = prompt_yes_no(
@@ -1270,7 +1268,7 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
p.add_argument(
"--force-gemini",
action="store_true",
- help="sobrescrever ~/public_gemini/index.gmi e corrigir symlink em /var/gemini/users se necessário",
+ help="corrigir symlink em /var/gemini/users (e destinos em conflito); não sobrescreve index.gmi existente",
)
p.add_argument(
"--metadata-file",
@@ -1477,7 +1475,7 @@ def main(argv: list[str] | None = None) -> int:
log.info("=== fase 3b: public_gopher (gophermap) e public_gemini (index.gmi)")
prepare_public_gopher(home, user, uid, gid, args.force_gopher, log)
- prepare_public_gemini(home, user, uid, gid, args.force_gemini, log)
+ prepare_public_gemini(home, user, uid, gid, log)
ensure_gemini_user_symlink(user, home, log, force=args.force_gemini)
log.info("=== fase 4: README.md runv (após skel /etc/skel do adduser; texto em português)")
diff --git a/scripts/admin/setup_alt_protocols.py b/scripts/admin/setup_alt_protocols.py
@@ -494,9 +494,8 @@ def ensure_user_public_dirs(
else:
log.debug("gophermap já existe, mantido: %s", gmap)
- if not xidx.exists() or force:
- if xidx.exists() and force:
- backup_if_exists(xidx, log, dry_run=False)
+ # index.gmi: nunca sobrescrever se já existir (--force não aplica ao modelo Gemini).
+ if not xidx.exists():
xidx.write_text(
DEFAULT_USER_INDEX_GMI.format(username=username),
encoding="utf-8",
@@ -750,7 +749,11 @@ def parse_args(argv: list[str] | None) -> argparse.Namespace:
)
p.add_argument("--dry-run", action="store_true")
p.add_argument("--verbose", action="store_true")
- p.add_argument("--force", action="store_true", help="sobrescreve configs e ficheiros modelo com backup")
+ p.add_argument(
+ "--force",
+ action="store_true",
+ help="sobrescreve configs e ficheiros modelo com backup (index.gmi existente nunca é substituído)",
+ )
p.add_argument("--skip-install", action="store_true")
p.add_argument("--skip-gopher", action="store_true")
p.add_argument("--skip-gemini", action="store_true")
diff --git a/scripts/docs/alt_protocols.md b/scripts/docs/alt_protocols.md
@@ -119,7 +119,7 @@ sudo python3 scripts/admin/setup_alt_protocols.py --verbose
|------|--------|
| `--dry-run` | Simula; não grava (validação de root ignorada em alguns passos só se documentado). |
| `--verbose` | Log detalhado. |
-| `--force` | Sobrescreve configs de sistema (com backup com timestamp) e ficheiros modelo no backfill. Necessário para **regravar** `/etc/molly-brown/runv.club.conf` e remover o drop-in obsoleto **`50-runv-logs.conf`** (v0.05) ao migrar logs para `/var/lib/molly-brown/`. |
+| `--force` | Sobrescreve configs de sistema (com backup com timestamp) e ficheiros modelo no backfill (exceto **`~/public_gemini/index.gmi`** se já existir). Necessário para **regravar** `/etc/molly-brown/runv.club.conf` e remover o drop-in obsoleto **`50-runv-logs.conf`** (v0.05) ao migrar logs para `/var/lib/molly-brown/`. |
| `--skip-install` | Não corre `apt-get`. |
| `--skip-gopher` / `--skip-gemini` | Ignora pacote, config e serviço desse protocolo. |
| `--skip-firewall` | Não altera UFW. |
diff --git a/tools/tools.py b/tools/tools.py
@@ -329,15 +329,19 @@ def install_skel(
log=log,
summary=summary,
)
- copy_one(
- gemini_src,
- gemini_dst,
- 0o644,
- force=force,
- dry_run=dry_run,
- log=log,
- summary=summary,
- )
+ if gemini_dst.is_file():
+ log.info("Destino já existe, mantido (index.gmi em skel): %s", gemini_dst)
+ summary.skipped.append(str(gemini_dst))
+ else:
+ copy_one(
+ gemini_src,
+ gemini_dst,
+ 0o644,
+ force=force,
+ dry_run=dry_run,
+ log=log,
+ summary=summary,
+ )
if not dry_run:
if gopher_dir.is_dir():