takana: las variables de entorno leen las dos formas, gana la nueva
TAKANA_X con caída a HAMMER_X (ADR 0016). No es un sed: estas variables son
contrato de usuario —knobs del instalador, el entorno del worker, mirror-env.sh—
y viven en perfiles de shell y units FUERA del repo, así que un renombre duro no
falla ruidosamente: la variable no aparece, se toma el default y el build se
comporta distinto sin que nada lo diga.
Rust: takana_core::env::{var,var_os} toma el nombre canónico y deriva el viejo
cambiando el prefijo — se le pasa TAKANA_* para que un grep del nombre nuevo
encuentre todas las lecturas. 5 tests, con DOS controles negativos: sin ninguna
de las dos no hay valor, y un nombre sin prefijo no inventa una caída.
Migrados los 17 sitios directos y los indirectos que el grep no mostraba
(bases_de_mirror, las constantes de kernel_cmd, ROOT_ENV de qorpa, env_path de
recover). takana-recover lleva la caída inline: es un mini-binario que se copia
a /usr/sbin y no vale arrastrarle una dep entera por dos líneas.
Scripts: 30 lecturas pasan a default, manteniendo el
nombre INTERNO de la variable para no tocar sus 190 usos.
Y donde el script EXPORTA en vez de leer, se ponen LAS DOS (mirror-env.sh y el
fragmento in-VM de bootstrap): ahí el lector puede ser un binario viejo —worker
sin recompilar, el /usr/bin/hammer pinado del baseline— que sólo conoce HAMMER_*.
La caída sirve para lectores nuevos; los viejos necesitan que la vieja siga puesta.
Verificado de punta a punta con el binario, no sólo con unit tests: HAMMER_LAB
sigue surtiendo efecto, TAKANA_LAB hace lo mismo, y con las dos gana TAKANA_LAB.
605 tests en verde y el hash de zlib sigue en b3:dc363f26… , intacto.
Cambio de comportamiento que va aparte y hay que decir: el hostname por defecto
de una instalación nueva pasa de 'hammer' a 'takana' (sólo si no se fija ninguna
de las dos variables).
NO se tocan: las rutas /var/lib/hammer de sistemas instalados, el volid
HAMMER_LIVE del ISO, ni el namespace HARKAQ_*, que es de otro subsistema.
This commit is contained in:
@@ -4,7 +4,7 @@
|
||||
//! cliente, completamos el handshake y ejercitamos los caminos no-pesados (`query`, errores).
|
||||
//!
|
||||
//! `compile` real no se ejercita aquí — depende del lab + red, ya cubierto por el e2e de
|
||||
//! grep gated en `HAMMER_NETWORK_TESTS`. Lo que sí verificamos es que un `compile` SIN la
|
||||
//! grep gated en `TAKANA_NETWORK_TESTS`. Lo que sí verificamos es que un `compile` SIN la
|
||||
//! capacidad devuelve `Error{code:"no_cap"}`, lo que prueba el dispatcher + el gate.
|
||||
|
||||
// El binario no expone una API pública; importamos sus módulos privados desde
|
||||
|
||||
@@ -78,8 +78,8 @@ pub struct ClaudeConfig {
|
||||
}
|
||||
|
||||
impl ClaudeConfig {
|
||||
/// Construye desde env vars: `ANTHROPIC_API_KEY` (obligatoria), `HAMMER_LLM_MODEL`,
|
||||
/// `HAMMER_LLM_BASE_URL`, `HAMMER_LLM_EFFORT`.
|
||||
/// Construye desde env vars: `ANTHROPIC_API_KEY` (obligatoria), `TAKANA_LLM_MODEL`,
|
||||
/// `TAKANA_LLM_BASE_URL`, `TAKANA_LLM_EFFORT`.
|
||||
pub fn from_env() -> Result<Self, TranslateError> {
|
||||
let api_key = std::env::var("ANTHROPIC_API_KEY").map_err(|_| {
|
||||
TranslateError::Model(
|
||||
@@ -89,12 +89,12 @@ impl ClaudeConfig {
|
||||
})?;
|
||||
Ok(Self {
|
||||
api_key,
|
||||
model: std::env::var("HAMMER_LLM_MODEL")
|
||||
.unwrap_or_else(|_| "claude-opus-4-8".into()),
|
||||
model: takana_core::env::var("TAKANA_LLM_MODEL")
|
||||
.unwrap_or_else(|| "claude-opus-4-8".into()),
|
||||
max_tokens: 8192,
|
||||
base_url: std::env::var("HAMMER_LLM_BASE_URL")
|
||||
.unwrap_or_else(|_| "https://api.anthropic.com".into()),
|
||||
effort: std::env::var("HAMMER_LLM_EFFORT").unwrap_or_else(|_| "high".into()),
|
||||
base_url: takana_core::env::var("TAKANA_LLM_BASE_URL")
|
||||
.unwrap_or_else(|| "https://api.anthropic.com".into()),
|
||||
effort: takana_core::env::var("TAKANA_LLM_EFFORT").unwrap_or_else(|| "high".into()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1324,7 +1324,13 @@ fi
|
||||
# NOTA: el initramfs debe empaquetarse con `cpio --owner=root:root`. Si los ficheros del toolchain
|
||||
# quedan con el uid del que armó el builder (p. ej. 1000), ese uid no está mapeado en el userns de
|
||||
# bwrap (que mapea sólo 0→0) y el copy-up de overlay falla con EACCES al crear /opt/zig. Ver §8c.
|
||||
export HAMMER_ROOTFS=/toolchain # el sandbox de build: el toolchain (variante a, desde Alpine)
|
||||
# Se exportan LAS DOS formas a propósito (ADR 0016): el binario que corre acá adentro es
|
||||
# `/usr/bin/hammer`, que puede ser el pinado del baseline y sólo conoce los nombres viejos.
|
||||
# Un lector nuevo prefiere TAKANA_*; uno viejo usa HAMMER_*. Las dos se retiran en la etapa 6.
|
||||
export TAKANA_ROOTFS=/toolchain # el sandbox de build: el toolchain (variante a, desde Alpine)
|
||||
export TAKANA_WORK=/work
|
||||
export TAKANA_CACHE=
|
||||
export HAMMER_ROOTFS=/toolchain
|
||||
export HAMMER_WORK=/work
|
||||
export HAMMER_CACHE=
|
||||
echo ">> rebuild stage1 (toolchain in-rootfs, semilla $SEED_HASH)"
|
||||
|
||||
@@ -32,7 +32,7 @@ fn find_lab_upward(start: &Path) -> Option<PathBuf> {
|
||||
/// Resuelve dónde vive el lab SIN atarlo a dónde vive el store.
|
||||
///
|
||||
/// Orden, de más explícito a más adivinado:
|
||||
/// 1. `HAMMER_LAB` — el operador manda.
|
||||
/// 1. `TAKANA_LAB` — el operador manda.
|
||||
/// 2. Hermano del store (`<store>/../.dev-fs`) **si existe**. Preserva exactamente el
|
||||
/// comportamiento histórico en la topología normal (lab y store en la raíz del proyecto).
|
||||
/// 3. Hacia arriba desde el CWD. Ésta es la que desacopla: cubre el caso en que el store fue
|
||||
@@ -40,7 +40,7 @@ fn find_lab_upward(start: &Path) -> Option<PathBuf> {
|
||||
/// 4. `None` ⇒ el llamador cae al default histórico, para que los mensajes de error sigan
|
||||
/// apuntando a un lugar previsible en vez de a la nada.
|
||||
fn resolve_lab_dir(store_root: &Path) -> Option<PathBuf> {
|
||||
if let Some(v) = std::env::var_os("HAMMER_LAB") {
|
||||
if let Some(v) = takana_core::env::var_os("TAKANA_LAB") {
|
||||
return Some(PathBuf::from(v));
|
||||
}
|
||||
if let Some(parent) = store_root.parent() {
|
||||
@@ -92,27 +92,27 @@ impl BuildConfig {
|
||||
}
|
||||
}
|
||||
|
||||
/// Lee overrides desde entorno (`HAMMER_LAB`, `HAMMER_ROOTFS`, `HAMMER_ZIG`, `HAMMER_WORK`,
|
||||
/// `HAMMER_CACHE`). `HAMMER_CACHE=""` (vacío) desactiva la caché.
|
||||
/// Lee overrides desde entorno (`TAKANA_LAB`, `TAKANA_ROOTFS`, `TAKANA_ZIG`, `TAKANA_WORK`,
|
||||
/// `TAKANA_CACHE`). `TAKANA_CACHE=""` (vacío) desactiva la caché.
|
||||
///
|
||||
/// Es el constructor que HUELE EL ENTORNO (env + CWD); `defaults_for_store` se mantiene pura.
|
||||
/// `HAMMER_LAB` mueve el lab entero de una; los `HAMMER_ROOTFS`/`HAMMER_ZIG`/`HAMMER_CACHE`
|
||||
/// `TAKANA_LAB` mueve el lab entero de una; los `TAKANA_ROOTFS`/`TAKANA_ZIG`/`TAKANA_CACHE`
|
||||
/// siguen pisando pieza por pieza y ganan sobre él.
|
||||
pub fn from_env_or_defaults(store_root: &Path) -> Self {
|
||||
let mut cfg = match resolve_lab_dir(store_root) {
|
||||
Some(lab) => Self::defaults_for_store_with_lab(store_root, &lab),
|
||||
None => Self::defaults_for_store(store_root),
|
||||
};
|
||||
if let Ok(v) = std::env::var("HAMMER_ROOTFS") {
|
||||
if let Some(v) = takana_core::env::var("TAKANA_ROOTFS") {
|
||||
cfg.rootfs = PathBuf::from(v);
|
||||
}
|
||||
if let Ok(v) = std::env::var("HAMMER_ZIG") {
|
||||
if let Some(v) = takana_core::env::var("TAKANA_ZIG") {
|
||||
cfg.zig_dir = PathBuf::from(v);
|
||||
}
|
||||
if let Ok(v) = std::env::var("HAMMER_WORK") {
|
||||
if let Some(v) = takana_core::env::var("TAKANA_WORK") {
|
||||
cfg.work_root = PathBuf::from(v);
|
||||
}
|
||||
if let Ok(v) = std::env::var("HAMMER_CACHE") {
|
||||
if let Some(v) = takana_core::env::var("TAKANA_CACHE") {
|
||||
cfg.cache_root = if v.is_empty() { None } else { Some(PathBuf::from(v)) };
|
||||
}
|
||||
cfg
|
||||
|
||||
@@ -387,7 +387,7 @@ fn salida_git(args: &[&str], cwd: &Path) -> takana_core::Result<String> {
|
||||
///
|
||||
/// # Por qué una lista y no una URL (ADR 0014)
|
||||
///
|
||||
/// El ADR 0013 dejó `HAMMER_MIRROR` con un solo valor y con eso el mecanismo que existe para no
|
||||
/// El ADR 0013 dejó `TAKANA_MIRROR` con un solo valor y con eso el mecanismo que existe para no
|
||||
/// depender de 79 servidores ajenos pasaba a depender de **uno nuestro**: el mismo fallo, con
|
||||
/// nuestro nombre encima. La identidad del objeto es su `sha256`/`commit`, así que un origen de más
|
||||
/// no añade confianza que verificar — sólo un sitio más donde mirar. Añadirlos es gratis y no
|
||||
@@ -402,9 +402,9 @@ fn salida_git(args: &[&str], cwd: &Path) -> takana_core::Result<String> {
|
||||
/// se reproduce y se depura — pero objetos distintos se reparten entre todos, así que una tanda del
|
||||
/// corpus **ejercita la lista entera**. Tras el elegido se recorren los demás como respaldo.
|
||||
fn bases_de_mirror(var: &str, clave: &str) -> Vec<String> {
|
||||
match std::env::var(var) {
|
||||
Ok(raw) => rotar_bases(&raw, clave),
|
||||
Err(_) => Vec::new(),
|
||||
match takana_core::env::var(var) {
|
||||
Some(raw) => rotar_bases(&raw, clave),
|
||||
None => Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -466,10 +466,10 @@ fn rotar_bases(raw: &str, clave: &str) -> Vec<String> {
|
||||
/// La verificación sigue siendo criptográfica: git comprueba cada objeto contra su SHA al
|
||||
/// desempaquetar, y el commit de la receta es la identidad. Un bundle alterado no pasa.
|
||||
fn hidratar_desde_bundle(commit: &str, destino: &Path) -> bool {
|
||||
// `HAMMER_MIRROR_GIT` es una LISTA (ADR 0014): se prueban todos los orígenes antes de rendirse
|
||||
// `TAKANA_MIRROR_GIT` es una LISTA (ADR 0014): se prueban todos los orígenes antes de rendirse
|
||||
// y caer a upstream. Un bundle que no está en uno puede estar en otro, y la verificación la
|
||||
// hace git contra el SHA venga de donde venga.
|
||||
bases_de_mirror("HAMMER_MIRROR_GIT", commit)
|
||||
bases_de_mirror("TAKANA_MIRROR_GIT", commit)
|
||||
.iter()
|
||||
.any(|base| hidratar_desde_bundle_en(base, commit, destino))
|
||||
}
|
||||
@@ -623,13 +623,13 @@ fn fetch_tarball(
|
||||
/// Un mirror silencioso **con** vigía separado detecta el bit-rot; uno silencioso **sin** vigía lo
|
||||
/// entierra, que es como el grafo de wlr pasó 17 días anunciando un 121/121 que ya era falso.
|
||||
///
|
||||
/// `HAMMER_MIRROR` es una **lista** de prefijos de URL separada por comas, de cualquier esquema que
|
||||
/// `TAKANA_MIRROR` es una **lista** de prefijos de URL separada por comas, de cualquier esquema que
|
||||
/// curl entienda (`file://`, `https://`, `sftp://`…); el objeto se busca por contenido en
|
||||
/// `{base}/{sha256}.tar` en cada uno, en el orden que dicta [`bases_de_mirror`].
|
||||
/// `HAMMER_MIRROR_KEY`, si está, se pasa como `--key` (Storage Box por sftp). Sin `HAMMER_MIRROR`
|
||||
/// `TAKANA_MIRROR_KEY`, si está, se pasa como `--key` (Storage Box por sftp). Sin `TAKANA_MIRROR`
|
||||
/// el comportamiento es el de siempre: derecho a upstream.
|
||||
fn fetch_con_mirror(url: &str, sha256: &str, dst: &Path) -> takana_core::Result<()> {
|
||||
for base in bases_de_mirror("HAMMER_MIRROR", sha256) {
|
||||
for base in bases_de_mirror("TAKANA_MIRROR", sha256) {
|
||||
let espejo = format!("{base}/{sha256}.tar");
|
||||
// Un fallo acá NO es un error: es el caso normal la primera vez que se ve una fuente, y
|
||||
// también el caso normal cuando un origen de la lista todavía no tiene ese objeto. Se
|
||||
@@ -649,7 +649,7 @@ fn descargar(url: &str, dst: &Path) -> takana_core::Result<()> {
|
||||
let mut cmd = Command::new("curl");
|
||||
cmd.args(["-fL", "--retry", "3", "--connect-timeout", "30"]);
|
||||
// Clave para el mirror por sftp (Storage Box). Inocua para http/file.
|
||||
if let Ok(key) = std::env::var("HAMMER_MIRROR_KEY") {
|
||||
if let Some(key) = takana_core::env::var("TAKANA_MIRROR_KEY") {
|
||||
if !key.is_empty() {
|
||||
cmd.arg("--key").arg(&key);
|
||||
}
|
||||
|
||||
@@ -453,10 +453,10 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Camino feliz real: requiere patchelf + un ELF de verdad. Gated como el resto de tests
|
||||
/// dependientes del host (`HAMMER_HOST_ELF_TESTS=1`).
|
||||
/// dependientes del host (`TAKANA_HOST_ELF_TESTS=1`).
|
||||
#[test]
|
||||
fn hydrate_dynamic_patchea_elf_real() {
|
||||
if std::env::var("HAMMER_HOST_ELF_TESTS").is_err() {
|
||||
if takana_core::env::var("TAKANA_HOST_ELF_TESTS").is_none() {
|
||||
return;
|
||||
}
|
||||
let host_bin = std::path::Path::new("/bin/sh");
|
||||
|
||||
@@ -197,7 +197,7 @@ pub fn build(
|
||||
// `docs/state/lab-toolchain.lock` ni de una ruta derivada del store. Derivarla del padre del
|
||||
// store ya mordió una vez (ver `BuildConfig::defaults_for_store_with_lab`): al anclar el store
|
||||
// de un worker a un volumen, el lab se buscaba donde no estaba. `cfg.rootfs` respeta
|
||||
// `HAMMER_LAB`/`HAMMER_ROOTFS` y es la única fuente que no puede desincronizarse del build.
|
||||
// `TAKANA_LAB`/`TAKANA_ROOTFS` y es la única fuente que no puede desincronizarse del build.
|
||||
let lab = takana_core::lab::LabFingerprint::from_rootfs(&cfg.rootfs)?;
|
||||
let h = artifact_hash(recipe, store, &lab)?;
|
||||
if store.has(&h, &recipe.name) {
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//!
|
||||
//! Doblemente gateado para no penalizar `cargo test` por defecto:
|
||||
//! - Requiere `.dev-fs/` bootstrapeado (rootfs Alpine + zig + cache).
|
||||
//! - Requiere `HAMMER_NETWORK_TESTS=1` (descarga ~3 MB del tarball de GNU).
|
||||
//! - Requiere `TAKANA_NETWORK_TESTS=1` (descarga ~3 MB del tarball de GNU).
|
||||
//!
|
||||
//! Comparte la dev cache (`.dev-fs/cache`) para que la segunda corrida en una máquina dada
|
||||
//! reuse los objetos de musl y termine en segundos.
|
||||
@@ -44,9 +44,9 @@ fn skip_with_reason(reason: &str) -> bool {
|
||||
}
|
||||
|
||||
fn should_skip(cfg: &BuildConfig) -> bool {
|
||||
if std::env::var("HAMMER_NETWORK_TESTS").ok().as_deref() != Some("1") {
|
||||
if takana_core::env::var("TAKANA_NETWORK_TESTS").as_deref() != Some("1") {
|
||||
return skip_with_reason(
|
||||
"HAMMER_NETWORK_TESTS != 1 (este test descarga ~3 MB de ftp.gnu.org y compila ~30s).",
|
||||
"TAKANA_NETWORK_TESTS != 1 (este test descarga ~3 MB de ftp.gnu.org y compila ~30s).",
|
||||
);
|
||||
}
|
||||
if !cfg.rootfs.join("bin/busybox").is_file() {
|
||||
|
||||
@@ -13,11 +13,11 @@ use takana_core::kernel::KernelConfig;
|
||||
use serde::Serialize;
|
||||
|
||||
/// Dónde busca el árbol de Kconfig si no se pasa `--kconfig`.
|
||||
const KCONFIG_ENV: &str = "HAMMER_KCONFIG_ROOT";
|
||||
const KCONFIG_ENV: &str = "TAKANA_KCONFIG_ROOT";
|
||||
/// Ídem para el catálogo de bundles.
|
||||
const CATALOG_ENV: &str = "HAMMER_KERNEL_BUNDLES";
|
||||
const CATALOG_ENV: &str = "TAKANA_KERNEL_BUNDLES";
|
||||
/// Ídem para el contrato de capacidades (SDD 25 §4).
|
||||
const CONTRACT_ENV: &str = "HAMMER_KERNEL_CONTRACT";
|
||||
const CONTRACT_ENV: &str = "TAKANA_KERNEL_CONTRACT";
|
||||
/// Sitios donde buscarlo sin que nadie diga nada: el del repo y el del sistema instalado.
|
||||
const CATALOG_DEFAULTS: &[&str] = &[
|
||||
"docs/state/kernel-bundles.toml",
|
||||
@@ -316,7 +316,7 @@ fn kconfig_root(flag: Option<PathBuf>) -> Result<PathBuf> {
|
||||
if let Some(p) = flag {
|
||||
return Ok(p);
|
||||
}
|
||||
match std::env::var_os(KCONFIG_ENV) {
|
||||
match takana_core::env::var_os(KCONFIG_ENV) {
|
||||
Some(v) => Ok(PathBuf::from(v)),
|
||||
None => anyhow::bail!(
|
||||
"falta el árbol de fuentes del kernel: pasá --kconfig <dir> o exportá {KCONFIG_ENV}"
|
||||
@@ -329,7 +329,7 @@ fn catalog_path(flag: Option<PathBuf>) -> Result<PathBuf> {
|
||||
if let Some(p) = flag {
|
||||
return Ok(p);
|
||||
}
|
||||
if let Some(v) = std::env::var_os(CATALOG_ENV) {
|
||||
if let Some(v) = takana_core::env::var_os(CATALOG_ENV) {
|
||||
return Ok(PathBuf::from(v));
|
||||
}
|
||||
for c in CATALOG_DEFAULTS {
|
||||
@@ -348,7 +348,7 @@ fn contract_path(flag: Option<PathBuf>) -> Result<PathBuf> {
|
||||
if let Some(p) = flag {
|
||||
return Ok(p);
|
||||
}
|
||||
if let Some(v) = std::env::var_os(CONTRACT_ENV) {
|
||||
if let Some(v) = takana_core::env::var_os(CONTRACT_ENV) {
|
||||
return Ok(PathBuf::from(v));
|
||||
}
|
||||
for c in CONTRACT_DEFAULTS {
|
||||
|
||||
@@ -358,7 +358,7 @@ enum Cmd {
|
||||
catalog: Option<PathBuf>,
|
||||
/// Activa el traductor LLM real (Claude API). Requiere `ANTHROPIC_API_KEY` en el env
|
||||
/// y un binario compilado con `--features llm-claude`. Modelo por defecto:
|
||||
/// `claude-opus-4-8` (sobreescribible con `HAMMER_LLM_MODEL`).
|
||||
/// `claude-opus-4-8` (sobreescribible con `TAKANA_LLM_MODEL`).
|
||||
#[arg(long)]
|
||||
llm: bool,
|
||||
/// Re-rootea las mutaciones bajo este prefix en vez de abrir overlay. Útil para
|
||||
|
||||
@@ -25,8 +25,8 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
/// Raíz del espacio de nombres de qorpa. Deliberadamente **fuera** del store.
|
||||
pub const DEFAULT_ROOT: &str = "/var/lib/hammer/qorpa";
|
||||
/// Para correr sin root (tests, laptop). Mismo patrón que `HAMMER_KCONFIG_ROOT`.
|
||||
pub const ROOT_ENV: &str = "HAMMER_QORPA_ROOT";
|
||||
/// Para correr sin root (tests, laptop). Mismo patrón que `TAKANA_KCONFIG_ROOT`.
|
||||
pub const ROOT_ENV: &str = "TAKANA_QORPA_ROOT";
|
||||
/// El manifiesto de la imagen. No confundir con `instancia.toml`, que describe una INSTANCIA.
|
||||
const IMAGE_MANIFEST: &str = "image.toml";
|
||||
/// El árbol desempacado dentro del directorio de la imagen.
|
||||
@@ -56,7 +56,7 @@ pub enum QorpaCmd {
|
||||
/// Dónde está el rootfs DENTRO del archivo, si la detección automática no acierta.
|
||||
#[arg(long)]
|
||||
subdir: Option<String>,
|
||||
/// Raíz de qorpa (default: `$HAMMER_QORPA_ROOT` o `/var/lib/hammer/qorpa`).
|
||||
/// Raíz de qorpa (default: `$TAKANA_QORPA_ROOT` o `/var/lib/hammer/qorpa`).
|
||||
#[arg(long)]
|
||||
root: Option<PathBuf>,
|
||||
},
|
||||
@@ -226,7 +226,7 @@ pub fn run(cmd: QorpaCmd, store: &Path) -> Result<()> {
|
||||
}
|
||||
|
||||
fn resolve_root(flag: Option<PathBuf>) -> PathBuf {
|
||||
flag.or_else(|| std::env::var_os(ROOT_ENV).map(PathBuf::from))
|
||||
flag.or_else(|| takana_core::env::var_os(ROOT_ENV).map(PathBuf::from))
|
||||
.unwrap_or_else(|| PathBuf::from(DEFAULT_ROOT))
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//! coinciden con lo esperado.
|
||||
//!
|
||||
//! NO ejercitamos `source_patch` porque arrastra todo el lab (red + sandbox); para esos
|
||||
//! casos existen los tests gated en `HAMMER_NETWORK_TESTS`. Aquí cubrimos los caminos puros
|
||||
//! casos existen los tests gated en `TAKANA_NETWORK_TESTS`. Aquí cubrimos los caminos puros
|
||||
//! de hammer-core: `verify_schema`, `verify_base`, `apply_config_edit`, `apply_file_drop`.
|
||||
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
//! Lectura de variables de entorno del proyecto durante el renombre `hammer` → `takana`.
|
||||
//!
|
||||
//! # Por qué existe esto en vez de un `sed`
|
||||
//!
|
||||
//! Las variables de entorno del proyecto **no son superficie interna**: son contrato de usuario,
|
||||
//! del mismo tipo que un verbo de CLI. Hay knobs del instalador entre ellas (`HAMMER_TZ`,
|
||||
//! `HAMMER_KEYMAP`, `HAMMER_HOSTNAME`), el entorno del worker las trae puestas desde perfiles de
|
||||
//! shell y units de systemd que **viven fuera del repo**, y `mirror-env.sh` exporta las del espejo.
|
||||
//! Un renombre duro no falla ruidosamente: la variable simplemente no aparece, se toma el valor por
|
||||
//! defecto y el build se comporta distinto sin que nada lo diga.
|
||||
//!
|
||||
//! Por eso valen las dos formas: **`TAKANA_X` gana; si no está, se cae a `HAMMER_X`** (ADR 0016).
|
||||
//! La caída se retira en la etapa 6 del renombre, cuando no queden entornos con la forma vieja.
|
||||
|
||||
/// Lee una variable aceptando el nombre nuevo y, si falta, el viejo.
|
||||
///
|
||||
/// Se le pasa el nombre **canónico** (`TAKANA_…`) para que un `grep` del nombre nuevo encuentre
|
||||
/// todas las lecturas; el nombre viejo se deriva cambiando el prefijo.
|
||||
pub fn var(nombre: &str) -> Option<String> {
|
||||
con_caida(nombre, |n| std::env::var(n).ok())
|
||||
}
|
||||
|
||||
/// Igual que [`var`], para valores que no tienen por qué ser UTF-8 (rutas).
|
||||
pub fn var_os(nombre: &str) -> Option<std::ffi::OsString> {
|
||||
con_caida(nombre, |n: &str| std::env::var_os(n))
|
||||
}
|
||||
|
||||
fn con_caida<T>(nombre: &str, leer: impl Fn(&str) -> Option<T>) -> Option<T> {
|
||||
if let Some(v) = leer(nombre) {
|
||||
return Some(v);
|
||||
}
|
||||
let viejo = format!("HAMMER_{}", nombre.strip_prefix("TAKANA_")?);
|
||||
leer(&viejo)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
// Cada test usa un nombre propio: el entorno del proceso es estado COMPARTIDO entre tests que
|
||||
// corren en hilos, y reusar el mismo nombre los hace pisarse de forma intermitente.
|
||||
#[test]
|
||||
fn prefiere_el_nombre_nuevo_sobre_el_viejo() {
|
||||
std::env::set_var("TAKANA_PRUEBA_A", "nuevo");
|
||||
std::env::set_var("HAMMER_PRUEBA_A", "viejo");
|
||||
assert_eq!(super::var("TAKANA_PRUEBA_A").as_deref(), Some("nuevo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn cae_al_viejo_cuando_el_nuevo_no_esta() {
|
||||
std::env::set_var("HAMMER_PRUEBA_B", "viejo");
|
||||
assert_eq!(super::var("TAKANA_PRUEBA_B").as_deref(), Some("viejo"));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sin_ninguna_de_las_dos_no_hay_valor() {
|
||||
assert_eq!(super::var("TAKANA_PRUEBA_C_QUE_NO_EXISTE"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn un_nombre_sin_prefijo_no_inventa_una_caida() {
|
||||
std::env::set_var("HAMMER_PRUEBA_D", "viejo");
|
||||
assert_eq!(super::var("PRUEBA_D"), None);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn var_os_tambien_cae() {
|
||||
std::env::set_var("HAMMER_PRUEBA_E", "viejo");
|
||||
assert_eq!(
|
||||
super::var_os("TAKANA_PRUEBA_E").as_deref(),
|
||||
Some(std::ffi::OsStr::new("viejo"))
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -118,7 +118,7 @@ impl LabFingerprint {
|
||||
crate::Error::Other(anyhow::anyhow!(
|
||||
"no pude leer el apk db del lab en {}: {e}. \
|
||||
El toolchain entra en el ArtifactHash, así que sin rootfs no se puede calcular \
|
||||
un hash comparable (corré scripts/bootstrap-devfs.sh, o apuntá HAMMER_ROOTFS)",
|
||||
un hash comparable (corré scripts/bootstrap-devfs.sh, o apuntá TAKANA_ROOTFS)",
|
||||
db.display()
|
||||
))
|
||||
})?;
|
||||
|
||||
@@ -8,6 +8,7 @@ pub mod apply;
|
||||
pub mod caps;
|
||||
pub mod compat;
|
||||
pub mod differs;
|
||||
pub mod env;
|
||||
pub mod hash;
|
||||
pub mod installed;
|
||||
pub mod kernel;
|
||||
|
||||
@@ -693,10 +693,10 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Sanity con un binario real del host: `/bin/sh` casi seguro existe y es ELF.
|
||||
/// Gated por `HAMMER_HOST_ELF_TESTS=1` para no acoplar el suite a Linux/Alpine.
|
||||
/// Gated por `TAKANA_HOST_ELF_TESTS=1` para no acoplar el suite a Linux/Alpine.
|
||||
#[test]
|
||||
fn parse_elf_real_host_binary() {
|
||||
if std::env::var("HAMMER_HOST_ELF_TESTS").is_err() {
|
||||
if crate::env::var("TAKANA_HOST_ELF_TESTS").is_none() {
|
||||
return;
|
||||
}
|
||||
let candidates = ["/bin/sh", "/usr/bin/sh", "/bin/ls", "/usr/bin/ls"];
|
||||
@@ -715,10 +715,10 @@ mod tests {
|
||||
}
|
||||
|
||||
/// Exports sobre una librería compartida real del host (una `.so` con `.dynsym`). Gated
|
||||
/// igual que arriba: pide `HAMMER_HOST_ELF_TESTS=1`. Verifica que extraemos ≥1 símbolo.
|
||||
/// igual que arriba: pide `TAKANA_HOST_ELF_TESTS=1`. Verifica que extraemos ≥1 símbolo.
|
||||
#[test]
|
||||
fn parse_exports_real_host_lib() {
|
||||
if std::env::var("HAMMER_HOST_ELF_TESTS").is_err() {
|
||||
if crate::env::var("TAKANA_HOST_ELF_TESTS").is_none() {
|
||||
return;
|
||||
}
|
||||
let candidates = [
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
//! en distros con AppArmor; algunos kernels también requieren la opción `userxattr` en el
|
||||
//! mount). Por eso este test está doblemente gateado:
|
||||
//! - Requiere `bwrap` y overlayfs en el kernel.
|
||||
//! - Requiere `HAMMER_OVERLAY_TESTS=1` — el dev confirma que su entorno admite el
|
||||
//! - Requiere `TAKANA_OVERLAY_TESTS=1` — el dev confirma que su entorno admite el
|
||||
//! mount unprivilegiado, o corre el test bajo `sudo`.
|
||||
//!
|
||||
//! Sin esos requisitos el test salta limpio; los aspectos puros (layout, slug, parsing del
|
||||
@@ -36,13 +36,13 @@ fn overlayfs_supported() -> bool {
|
||||
/// reenviando los args originales. Si ya estamos dentro del sandbox (env marker set),
|
||||
/// no re-anidamos.
|
||||
fn run_inside_userns_or_skip(phase: &str, scratch: &Path) -> bool {
|
||||
if std::env::var("HAMMER_OVERLAY_IN_SANDBOX").is_ok() {
|
||||
if takana_core::env::var("TAKANA_OVERLAY_IN_SANDBOX").is_some() {
|
||||
// Ya estamos dentro — el caller ejecuta la lógica real.
|
||||
return false;
|
||||
}
|
||||
if std::env::var("HAMMER_OVERLAY_TESTS").ok().as_deref() != Some("1") {
|
||||
if takana_core::env::var("TAKANA_OVERLAY_TESTS").as_deref() != Some("1") {
|
||||
eprintln!(
|
||||
"SKIP: HAMMER_OVERLAY_TESTS != 1 (overlayfs en user-ns suele estar denegado por \
|
||||
"SKIP: TAKANA_OVERLAY_TESTS != 1 (overlayfs en user-ns suele estar denegado por \
|
||||
el kernel; setea la var cuando tu host lo permita o corre con sudo)."
|
||||
);
|
||||
return true;
|
||||
@@ -72,7 +72,7 @@ fn run_inside_userns_or_skip(phase: &str, scratch: &Path) -> bool {
|
||||
.arg(scratch)
|
||||
.arg(scratch)
|
||||
.arg("--setenv")
|
||||
.arg("HAMMER_OVERLAY_IN_SANDBOX")
|
||||
.arg("TAKANA_OVERLAY_IN_SANDBOX")
|
||||
.arg("1")
|
||||
.arg("--setenv")
|
||||
.arg("OVERLAY_TEST_SCRATCH")
|
||||
@@ -154,7 +154,7 @@ fn body_try_commit_discard() {
|
||||
|
||||
#[test]
|
||||
fn overlay_try_commit_discard_inside_userns() {
|
||||
if std::env::var("HAMMER_OVERLAY_IN_SANDBOX").is_ok() {
|
||||
if takana_core::env::var("TAKANA_OVERLAY_IN_SANDBOX").is_some() {
|
||||
body_try_commit_discard();
|
||||
return;
|
||||
}
|
||||
@@ -220,7 +220,7 @@ fn body_nested_stack() {
|
||||
|
||||
#[test]
|
||||
fn overlay_nested_stack_inside_userns() {
|
||||
if std::env::var("HAMMER_OVERLAY_IN_SANDBOX").is_ok() {
|
||||
if takana_core::env::var("TAKANA_OVERLAY_IN_SANDBOX").is_some() {
|
||||
body_nested_stack();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
//! generaciones tipo NixOS que seleccionar, sino una reparación determinista del estado a medias.
|
||||
//!
|
||||
//! Paths del producto (overridables por entorno para tests):
|
||||
//! `HAMMER_RECOVER_ROOT=/` `HAMMER_RECOVER_STORE=/store`
|
||||
//! `HAMMER_RECOVER_STATE=/var/lib/hammer/upgrades` `HAMMER_RECOVER_JOURNAL=/var/lib/hammer/journal`
|
||||
//! `TAKANA_RECOVER_ROOT=/` `TAKANA_RECOVER_STORE=/store`
|
||||
//! `TAKANA_RECOVER_STATE=/var/lib/hammer/upgrades` `TAKANA_RECOVER_JOURNAL=/var/lib/hammer/journal`
|
||||
//! Flag: `--rollback` fuerza deshacer en vez de completar.
|
||||
//!
|
||||
//! NUNCA sale con código ≠0 por un fallo de recuperación: es un hook de arranque, no debe abortar el
|
||||
@@ -23,16 +23,26 @@
|
||||
|
||||
use std::path::PathBuf;
|
||||
|
||||
/// Lee la variable aceptando el nombre nuevo y, si falta, el viejo (ADR 0016).
|
||||
///
|
||||
/// La caída va inline y no por `takana_core::env`: este es un mini-binario que se copia a
|
||||
/// `/usr/sbin` de los sistemas instalados, y no vale la pena arrastrarle una dep entera por
|
||||
/// dos líneas. Se retira junto con el resto de las caídas en la etapa 6.
|
||||
fn env_path(key: &str, default: &str) -> PathBuf {
|
||||
std::env::var(key).map(PathBuf::from).unwrap_or_else(|_| PathBuf::from(default))
|
||||
let viejo = key.strip_prefix("TAKANA_").map(|s| format!("HAMMER_{s}"));
|
||||
std::env::var(key)
|
||||
.ok()
|
||||
.or_else(|| viejo.and_then(|v| std::env::var(v).ok()))
|
||||
.map(PathBuf::from)
|
||||
.unwrap_or_else(|| PathBuf::from(default))
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let force_rollback = std::env::args().skip(1).any(|a| a == "--rollback");
|
||||
let root = env_path("HAMMER_RECOVER_ROOT", "/");
|
||||
let store = env_path("HAMMER_RECOVER_STORE", "/store");
|
||||
let state = env_path("HAMMER_RECOVER_STATE", "/var/lib/hammer/upgrades");
|
||||
let journal_dir = env_path("HAMMER_RECOVER_JOURNAL", "/var/lib/hammer/journal");
|
||||
let root = env_path("TAKANA_RECOVER_ROOT", "/");
|
||||
let store = env_path("TAKANA_RECOVER_STORE", "/store");
|
||||
let state = env_path("TAKANA_RECOVER_STATE", "/var/lib/hammer/upgrades");
|
||||
let journal_dir = env_path("TAKANA_RECOVER_JOURNAL", "/var/lib/hammer/journal");
|
||||
|
||||
match takana_upgrade::pending(&state) {
|
||||
Ok(None) => {
|
||||
|
||||
@@ -12,7 +12,7 @@ PKG="${1:?uso: alpine-import.sh <pkg> [main|community]}"
|
||||
REPO="${2:-main}"
|
||||
BRANCH="${ALPINE_BRANCH:-master}"
|
||||
OUTDIR="${OUTDIR:-.}"
|
||||
HAMMER="${HAMMER:-cargo run -q -p takana-cli --}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-cargo run -q -p takana-cli --}}"
|
||||
BASE="https://gitlab.alpinelinux.org/alpine/aports/-/raw/${BRANCH}/${REPO}/${PKG}"
|
||||
|
||||
apk=$(curl -fsSL "${BASE}/APKBUILD") || { echo "no encontré ${REPO}/${PKG} en aports@${BRANCH}" >&2; exit 1; }
|
||||
|
||||
@@ -23,7 +23,7 @@ STORE="${STORE:-./store}"
|
||||
REPO="${REPO:-$ROOT/dist/repo}"
|
||||
KEY="${KEY:-$ROOT/dist/keys/release.ed25519}"
|
||||
DISTRO="${DISTRO:-dev}"
|
||||
HAMMER="${HAMMER:-$ROOT/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
|
||||
PROMOTE="${PROMOTE:-1}"
|
||||
JOBS="${JOBS:-$(( $(nproc) - 2 ))}"; [ "$JOBS" -ge 1 ] || JOBS=1
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
set -uo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
RFS="${RFS:-work/cosmic-rootfs}"; STORE="${STORE:-./store}"; LINK="${LINK:-static}"
|
||||
HAMMER="${HAMMER:-./target/release/takana}"; KEEP="${KEEP:-0}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"; KEEP="${KEEP:-0}"
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
TARGETS=("$@")
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#
|
||||
# Sale con el MISMO código que `hammer build` (transparente para el llamador).
|
||||
set -u
|
||||
HAMMER="${HAMMER:-./target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
|
||||
STORE="${STORE:-./store}"
|
||||
UMBRAL="${UMBRAL_TIEMPO:-3}"
|
||||
f="${1:?uso: build-timed.sh <receta.toml>}"
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
# /opt/hammer/scripts/farm/campana-deuda.sh <recetas…>'
|
||||
# ssh root@<ip> 'journalctl -u campana-deuda -f'
|
||||
set -u
|
||||
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
||||
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
||||
# Ruta absoluta a MÍ MISMO antes del `cd`: acá el `cd` va a HAMMER_DIR, que ni siquiera tiene por
|
||||
# qué contener a este script, así que un `$0` relativo se pierde seguro.
|
||||
YO="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"
|
||||
cd "$HAMMER_DIR"
|
||||
HAMMER="${HAMMER:-$HAMMER_DIR/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$HAMMER_DIR/target/release/takana}}"
|
||||
STORE="${STORE:-$HAMMER_DIR/store}"
|
||||
LOG="${LOG:-/var/log/campana-deuda.log}"
|
||||
|
||||
|
||||
@@ -78,7 +78,7 @@ if [ -s "$FLEET_FIJA" ]; then
|
||||
{ grep -vE '^[[:space:]]*(#|$)' "$FLEET_FIJA" || true; cat "$FLEET" 2>/dev/null || true; } \
|
||||
| awk 'NF && !visto[$1]++' > "$FLEET.seed" && mv "$FLEET.seed" "$FLEET"
|
||||
fi
|
||||
HAMMER="${HAMMER:-$ROOT/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
|
||||
# Workers efímeros reciclan IPs ⇒ no fijar known_hosts (hub-and-spoke, worker sin secretos).
|
||||
SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o BatchMode=yes -o LogLevel=ERROR -o ConnectTimeout=15"
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#
|
||||
# Lo lanza systemd (hammer-farm.service). Manual: JOBS=2 ./scripts/farm/farm-worker-loop.sh
|
||||
set -uo pipefail
|
||||
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
||||
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
||||
cd "$HAMMER_DIR"
|
||||
. "$HOME/.cargo/env" 2>/dev/null || true
|
||||
# JOBS=1 MIENTRAS EL ADR 0012 ESTÉ SIN DECIDIR (2026-07-22). `build-farm.sh` usa `xargs -P$JOBS`, y
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
set -u
|
||||
|
||||
MI_NOMBRE="${1:?uso: harkaq-campana-vol.sh <mi-nombre>}"
|
||||
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
||||
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
||||
cd "$HAMMER_DIR"
|
||||
LISTA="${LISTA:-work/harkaq-cola.txt}"
|
||||
VOL_OUT="/mnt/cosecha"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
# script existe para no tener.
|
||||
set -u
|
||||
|
||||
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
||||
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
||||
cd "$HAMMER_DIR"
|
||||
LISTA="${1:-work/harkaq-cola.txt}"
|
||||
OUT="work/harkaq-campana"
|
||||
|
||||
@@ -29,7 +29,7 @@ STORE="${STORE:-$ROOT/store}"
|
||||
REPO="${REPO:-$ROOT/dist/repo}"
|
||||
KEY="${KEY:-$ROOT/dist/keys/release.ed25519}"
|
||||
DISTRO="${DISTRO:-dev}"
|
||||
HAMMER="${HAMMER:-$ROOT/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
|
||||
SEAL_TIMEOUT="${SEAL_TIMEOUT:-60}"
|
||||
QUEUE="recipes/incoming-go"
|
||||
REVIEW="tandas/needs-review-weekend"
|
||||
|
||||
@@ -13,7 +13,7 @@
|
||||
# Salidas: work/migra-zig/{migrable,matraca}.txt
|
||||
set -u
|
||||
cd "$(dirname "$0")/../.."
|
||||
HAMMER="${HAMMER:-./target/debug/hammer}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/debug/hammer}}"
|
||||
OUT="work/migra-zig"; mkdir -p "$OUT"
|
||||
# ACUMULA entre corridas (no trunca): probar las 47 no cabe en un timeout, así que se corre por
|
||||
# lotes y cada lote SUMA. `reg` evita duplicar una receta ya clasificada en una corrida previa.
|
||||
|
||||
@@ -27,7 +27,7 @@
|
||||
set -u
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
HAMMER="${HAMMER:-$ROOT/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
|
||||
STORE="${STORE:-$ROOT/store}"
|
||||
DRY="${DRY:-0}"
|
||||
# El stack GUI no construye en el laptop (zig-skew rompe cairo). Default: saltarlo salvo que se pida.
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
# /opt/hammer/scripts/farm/tandas.sh "gui:pixman,cairo" …'
|
||||
# ssh root@<ip> 'tail -f /var/log/tandas.log'
|
||||
set -u
|
||||
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
||||
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
||||
cd "$HAMMER_DIR"
|
||||
LOG="${LOG:-/var/log/tandas.log}"
|
||||
ESPERA="${ESPERA:-30}"
|
||||
|
||||
@@ -41,7 +41,7 @@
|
||||
# evita el zig-skew: el worker usa EXACTAMENTE las versiones del hub.
|
||||
set -euo pipefail
|
||||
|
||||
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}"
|
||||
HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
|
||||
cd "$HAMMER_DIR"
|
||||
|
||||
# ── detección de familia ────────────────────────────────────────────────────────────────────
|
||||
|
||||
@@ -20,8 +20,14 @@
|
||||
# La ruta lleva `/~/` a propósito. curl interpreta lo que sigue al host en una URL `sftp://` como
|
||||
# ruta ABSOLUTA del servidor, así que `…:23/hammer/fuentes` busca en la raíz y devuelve
|
||||
# «(78) Could not open remote file for reading» aunque el fichero exista. `/~/` lo ancla al home.
|
||||
export HAMMER_MIRROR="${HAMMER_MIRROR:-sftp://u647150@u647150.your-storagebox.de:23/~/hammer/fuentes}"
|
||||
# ADR 0016: se exportan las DOS formas. Se acepta la vieja como entrada (hay entornos que la
|
||||
# traen puesta desde perfiles y units fuera del repo) y se deja también puesta, porque un
|
||||
# binario viejo —worker sin recompilar, imagen pinada— sólo conoce ésa.
|
||||
export TAKANA_MIRROR="${TAKANA_MIRROR:-${HAMMER_MIRROR:-sftp://u647150@u647150.your-storagebox.de:23/~/hammer/fuentes}}"
|
||||
export HAMMER_MIRROR="$TAKANA_MIRROR"
|
||||
# Fuentes git: bundles shallow por commit. Variable APARTE de HAMMER_MIRROR porque son dos espacios
|
||||
# de nombres distintos —`{sha256}.tar` vs `{commit}.bundle`— y se pueblan y se pierden por separado.
|
||||
export HAMMER_MIRROR_GIT="${HAMMER_MIRROR_GIT:-sftp://u647150@u647150.your-storagebox.de:23/~/hammer/fuentes-git}"
|
||||
export HAMMER_MIRROR_KEY="${HAMMER_MIRROR_KEY:-$HOME/.ssh/github5}"
|
||||
export TAKANA_MIRROR_GIT="${TAKANA_MIRROR_GIT:-${HAMMER_MIRROR_GIT:-sftp://u647150@u647150.your-storagebox.de:23/~/hammer/fuentes-git}}"
|
||||
export HAMMER_MIRROR_GIT="$TAKANA_MIRROR_GIT"
|
||||
export TAKANA_MIRROR_KEY="${TAKANA_MIRROR_KEY:-${HAMMER_MIRROR_KEY:-$HOME/.ssh/github5}}"
|
||||
export HAMMER_MIRROR_KEY="$TAKANA_MIRROR_KEY"
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
set -uo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
RFS="${RFS:-work/gnome-rootfs}"; STORE="${STORE:-./store}"; LINK="${LINK:-static}"
|
||||
HAMMER="${HAMMER:-./target/release/takana}"; KEEP="${KEEP:-0}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"; KEEP="${KEEP:-0}"
|
||||
# Por defecto se hidratan DOS raíces, no una. accountsservice no es dep de build de gnome-shell —no
|
||||
# aparece en su meson.build ni en su cierre— sino dep de RUNTIME: la capa JS del shell hace
|
||||
# `imports.gi.AccountsService` y gjs resuelve el typelib al arrancar. Todo lo que el shell carga por
|
||||
|
||||
@@ -25,7 +25,8 @@
|
||||
# particiona+instala. Es la cara humana del instalador (el /init del ISO installer lo lanza).
|
||||
# DESATENDIDO (con device): hammer-install /dev/vdb [ROOT_MB] [STORE_MB]
|
||||
# Autoinstalador (lo usa iso-install-test.sh con AUTO_INSTALL). La config sale de env:
|
||||
# HAMMER_HOSTNAME / HAMMER_ROOT_PW / HAMMER_ROOT_AUTHKEYS / HAMMER_TZ / HAMMER_KEYMAP.
|
||||
# TAKANA_HOSTNAME / TAKANA_ROOT_PW / TAKANA_ROOT_AUTHKEYS / TAKANA_TZ / TAKANA_KEYMAP.
|
||||
# Los nombres viejos HAMMER_* se siguen aceptando (ADR 0016); gana el nuevo si están los dos.
|
||||
set -eu
|
||||
|
||||
DEV="${1:-}"
|
||||
@@ -132,11 +133,11 @@ apply_post_install_config() {
|
||||
}
|
||||
|
||||
# ---- recolección de config: interactiva (TUI) o desde env (desatendido) ----
|
||||
CFG_HOSTNAME="${HAMMER_HOSTNAME:-hammer}"
|
||||
CFG_ROOT_AUTHKEYS="${HAMMER_ROOT_AUTHKEYS:-}"
|
||||
CFG_ROOT_HASH="${HAMMER_ROOT_HASH:-}"
|
||||
CFG_TZ="${HAMMER_TZ:-}"
|
||||
CFG_KEYMAP="${HAMMER_KEYMAP:-us}"
|
||||
CFG_HOSTNAME="${TAKANA_HOSTNAME:-${HAMMER_HOSTNAME:-takana}}"
|
||||
CFG_ROOT_AUTHKEYS="${TAKANA_ROOT_AUTHKEYS:-${HAMMER_ROOT_AUTHKEYS:-}}"
|
||||
CFG_ROOT_HASH="${TAKANA_ROOT_HASH:-${HAMMER_ROOT_HASH:-}}"
|
||||
CFG_TZ="${TAKANA_TZ:-${HAMMER_TZ:-}}"
|
||||
CFG_KEYMAP="${TAKANA_KEYMAP:-${HAMMER_KEYMAP:-us}}"
|
||||
|
||||
interactive_setup() {
|
||||
echo
|
||||
@@ -250,8 +251,8 @@ fi
|
||||
ROOT_MB="${ROOT_MB:-1500}"
|
||||
STORE_MB="${STORE_MB:-400}"
|
||||
# En modo desatendido con contraseña por env, derivar el hash acá (interactivo ya lo hizo).
|
||||
if [ -z "$CFG_ROOT_HASH" ] && [ -n "${HAMMER_ROOT_PW:-}" ] && have_cryptpw; then
|
||||
CFG_ROOT_HASH=$(printf '%s' "$HAMMER_ROOT_PW" | bb cryptpw -m sha512 2>/dev/null || true)
|
||||
if [ -z "$CFG_ROOT_HASH" ] && [ -n "${TAKANA_ROOT_PW:-${HAMMER_ROOT_PW:-}}" ] && have_cryptpw; then
|
||||
CFG_ROOT_HASH=$(printf '%s' "${TAKANA_ROOT_PW:-$HAMMER_ROOT_PW}" | bb cryptpw -m sha512 2>/dev/null || true)
|
||||
fi
|
||||
|
||||
# --- gancho de prueba: valida TUI + config sin tocar disco (HAMMER_INSTALL_DRYRUN=1) ---
|
||||
|
||||
@@ -23,7 +23,7 @@ set -euo pipefail
|
||||
RECETA="${1:?uso: harkaq-trace-build.sh <receta.toml> [store] [outdir]}"
|
||||
STORE="${2:-./store}"
|
||||
OUT="${3:-/tmp/harkaq-trace-pilot}"
|
||||
HAMMER="${HAMMER:-./target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
|
||||
TRACE="${TRACE:-/tmp/harkaq-trace}"
|
||||
NORM="${NORM:-scripts/harkaq/harkaq-trace-norm.py}"
|
||||
mkdir -p "$OUT"; rm -f "$OUT"/traza-fase-*.txt "$OUT"/canonica.txt "$OUT"/resumen.txt
|
||||
|
||||
@@ -144,7 +144,7 @@ mkdir -p "$ROOT_TREE/store" "$ROOT_TREE/var/lib/hammer"
|
||||
# CLI `hammer` (static musl) para el menú de arranque por grafo (ADR 0010): el hook de init lo invoca
|
||||
# como `hammer boot menu`. El producto trae arje-zero/hammerd pero NO el CLI ⇒ lo inyectamos acá si
|
||||
# está compilado (igual patrón que hammer-recover). Opcional: sin él, el wrapper saltea el menú.
|
||||
HAMMER_MUSL="${HAMMER_MUSL:-$ROOT/target/x86_64-unknown-linux-musl/release/hammer}"
|
||||
HAMMER_MUSL="${TAKANA_MUSL:-${HAMMER_MUSL:-$ROOT/target/x86_64-unknown-linux-musl/release/hammer}}"
|
||||
if [ -x "$HAMMER_MUSL" ]; then
|
||||
cp "$HAMMER_MUSL" "$ROOT_TREE/usr/bin/hammer"; chmod 0755 "$ROOT_TREE/usr/bin/hammer"
|
||||
echo " + CLI hammer (static musl) para el menú de arranque por grafo"
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
set -uo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
STORE="${STORE:-./store}"; RFS="${RFS:-work/kde-store-rootfs}"; LINK="${LINK:-static}"
|
||||
HAMMER="${HAMMER:-./target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
|
||||
CUTOFF="${CUTOFF:-$(date -d 'today 00:00' +%s 2>/dev/null || echo 9999999999)}"
|
||||
# sonames provistos por la base (no soberanos aún / runtime del sistema): no hidratar.
|
||||
BASE_SONAMES="libc.so libc.musl-x86_64.so.1 ld-musl-x86_64.so.1 libc.so.6 ld-linux-x86-64.so.2 libm.so.6 libdl.so.2 libpthread.so.0 librt.so.1 libresolv.so.2"
|
||||
|
||||
@@ -16,7 +16,7 @@ REPO="${REPO:-work/repo-kde}"; TRUST="${TRUST:-dist/keys}"; STORE="${STORE:-./st
|
||||
RFS="${RFS:-work/kde-rootfs}"
|
||||
# TARGETS = uno o varios paquetes tope (unión de cierres). TARGET (singular) sigue soportado.
|
||||
TARGETS="${TARGETS:-${TARGET:-qt6-qtdeclarative}}"
|
||||
HAMMER="${HAMMER:-./target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
|
||||
DB="$RFS/var/lib/hammer/installed.json"
|
||||
|
||||
# cierre transitivo de TODOS los targets, leído del índice (deps + aliases ya resuelven). Excluimos
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
set -uo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
|
||||
REPO="${REPO:-work/repo-kde}"; STORE="${STORE:-./store}"; LINK="${LINK:-static}"
|
||||
RFS="${RFS:-work/kde-store-rootfs}"; HAMMER="${HAMMER:-./target/release/takana}"
|
||||
RFS="${RFS:-work/kde-store-rootfs}"; HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
|
||||
TARGETS="${TARGETS:-${TARGET:-qt6-qtdeclarative}}"
|
||||
# CUTOFF: por defecto medianoche de hoy (excluye rebuilds de la sesión). Pasá 9999999999 para no filtrar.
|
||||
CUTOFF="${CUTOFF:-$(date -d 'today 00:00' +%s 2>/dev/null || echo 9999999999)}"
|
||||
|
||||
@@ -23,7 +23,7 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
||||
STORE="${STORE:-./store}"
|
||||
DEVFS="${DEVFS:-.dev-fs/alpine}"
|
||||
RFS="${RFS:-work/mirada-rootfs}"
|
||||
HAMMER="${HAMMER:-target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-target/release/takana}}"
|
||||
PACKAGE="${PACKAGE:-1}"
|
||||
|
||||
[ -d "$DEVFS" ] || { echo "no existe $DEVFS (corré scripts/bootstrap-devfs.sh)" >&2; exit 1; }
|
||||
|
||||
@@ -9,7 +9,7 @@ set -eu
|
||||
|
||||
ATTR="${1:?uso: nix-import.sh <attr-de-nixpkgs> (ej: hello, jq, ripgrep)}"
|
||||
NIXPKGS="${NIXPKGS:-nixpkgs}"
|
||||
HAMMER="${HAMMER:-cargo run -q -p takana-cli --}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-cargo run -q -p takana-cli --}}"
|
||||
# NIX_STORE: si el /nix/store del sistema no es escribible (install single-user incompleta), apuntá
|
||||
# a un store local, p.ej. NIX_STORE="local?root=$HOME/.nixstore".
|
||||
STORE_OPT=""
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#
|
||||
# Ej: scripts/pin-recipes.sh recipes/*.toml | find recipes -name '*.toml' | xargs scripts/pin-recipes.sh
|
||||
set -eu
|
||||
HAMMER="${HAMMER:-cargo run -q -p takana-cli --}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-cargo run -q -p takana-cli --}}"
|
||||
[ "$#" -gt 0 ] || { echo "uso: pin-recipes.sh <recipe.toml...>" >&2; exit 1; }
|
||||
|
||||
pinned=0; skipped=0; failed=""
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
set -eu
|
||||
|
||||
QORPA_ROOT="${HAMMER_QORPA_ROOT:-/var/lib/hammer/qorpa}"
|
||||
HAMMER="${HAMMER_BIN:-./target/release/takana}"
|
||||
HAMMER="${TAKANA_BIN:-${HAMMER_BIN:-./target/release/takana}}"
|
||||
ID="${1:-arch-probe}"
|
||||
export HAMMER_QORPA_ROOT="$QORPA_ROOT"
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@
|
||||
set -eu
|
||||
|
||||
QORPA_ROOT="${HAMMER_QORPA_ROOT:-/var/lib/hammer/qorpa}"
|
||||
HAMMER="${HAMMER_BIN:-./target/release/takana}"
|
||||
HAMMER="${TAKANA_BIN:-${HAMMER_BIN:-./target/release/takana}}"
|
||||
ID="${1:-sniper-probe}"
|
||||
|
||||
UBUNTU_URL="https://cdimage.ubuntu.com/ubuntu-base/releases/24.04/release/ubuntu-base-24.04.3-base-amd64.tar.gz"
|
||||
|
||||
@@ -31,7 +31,7 @@
|
||||
set -uo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
||||
HAMMER="${HAMMER:-$ROOT/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
|
||||
STORE="${STORE:-./store}"
|
||||
LOCK="$ROOT/work/.farm-build.lock"
|
||||
LOG="${LOG:-$ROOT/work/reconstruccion.log}"
|
||||
|
||||
@@ -241,7 +241,7 @@ fi
|
||||
# kernel): un /init PID1 que copia el rootfs a un tmpfs y hace `switch_root`, dejando `/` como un
|
||||
# mount tmpfs real (pivotable). El kernel debe arrancar con rdinit=/init (ver APPEND abajo). Off por
|
||||
# defecto ⇒ el camino del kernel host queda intacto (rdinit=/sbin/init directo).
|
||||
if [[ "${HAMMER_KERNEL:-0}" == 1 ]]; then
|
||||
if [[ "${TAKANA_KERNEL:-${HAMMER_KERNEL:-0}}" == 1 ]]; then
|
||||
say "HAMMER_KERNEL: inyectar /init wrapper (copy-to-tmpfs + switch_root, escapa del rootfs)"
|
||||
cat > work/builder-rootfs/init <<'INIT'
|
||||
#!/bin/sh
|
||||
|
||||
@@ -37,7 +37,7 @@ set -eu
|
||||
HUB="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$HUB"
|
||||
STORE="${STORE:-$PWD/store}"
|
||||
HAMMER="${HAMMER:-$HUB/target/release/takana}"
|
||||
HAMMER="${TAKANA:-${HAMMER:-$HUB/target/release/takana}}"
|
||||
|
||||
if [ $# -gt 0 ]; then
|
||||
recetas=""
|
||||
|
||||
+1
-1
@@ -38,7 +38,7 @@
|
||||
# Env: STORE (def ./store) HAMMER (def ./target/release/takana) JOBS (def 8)
|
||||
set -uo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
||||
STORE="${STORE:-./store}"; HAMMER="${HAMMER:-./target/release/takana}"; JOBS="${JOBS:-8}"
|
||||
STORE="${STORE:-./store}"; HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"; JOBS="${JOBS:-8}"
|
||||
APLICAR=0; HUERFANOS=0
|
||||
for a in "$@"; do
|
||||
case "$a" in
|
||||
|
||||
@@ -48,7 +48,7 @@
|
||||
# Env: STORE (def ./store) N (def 30, tamaño de la muestra)
|
||||
set -uo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
|
||||
STORE="${STORE:-./store}"; HAMMER="${HAMMER:-./target/release/takana}"; N="${N:-30}"
|
||||
STORE="${STORE:-./store}"; HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"; N="${N:-30}"
|
||||
|
||||
# ── EL LOCK LO TOMA EL SCRIPT, Y ANTES DE TOCAR NADA ───────────────────────────────────────────
|
||||
# Este script llama a `hammer build`, y la regla 1 del repo es que todo build va envuelto en el
|
||||
|
||||
Reference in New Issue
Block a user