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:
Sergio
2026-09-09 19:14:49 +00:00
parent 8c2cb10414
commit 1c3e185167
50 changed files with 203 additions and 107 deletions
+1 -1
View File
@@ -4,7 +4,7 @@
//! cliente, completamos el handshake y ejercitamos los caminos no-pesados (`query`, errores). //! 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 //! `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. //! 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 // El binario no expone una API pública; importamos sus módulos privados desde
+7 -7
View File
@@ -78,8 +78,8 @@ pub struct ClaudeConfig {
} }
impl ClaudeConfig { impl ClaudeConfig {
/// Construye desde env vars: `ANTHROPIC_API_KEY` (obligatoria), `HAMMER_LLM_MODEL`, /// Construye desde env vars: `ANTHROPIC_API_KEY` (obligatoria), `TAKANA_LLM_MODEL`,
/// `HAMMER_LLM_BASE_URL`, `HAMMER_LLM_EFFORT`. /// `TAKANA_LLM_BASE_URL`, `TAKANA_LLM_EFFORT`.
pub fn from_env() -> Result<Self, TranslateError> { pub fn from_env() -> Result<Self, TranslateError> {
let api_key = std::env::var("ANTHROPIC_API_KEY").map_err(|_| { let api_key = std::env::var("ANTHROPIC_API_KEY").map_err(|_| {
TranslateError::Model( TranslateError::Model(
@@ -89,12 +89,12 @@ impl ClaudeConfig {
})?; })?;
Ok(Self { Ok(Self {
api_key, api_key,
model: std::env::var("HAMMER_LLM_MODEL") model: takana_core::env::var("TAKANA_LLM_MODEL")
.unwrap_or_else(|_| "claude-opus-4-8".into()), .unwrap_or_else(|| "claude-opus-4-8".into()),
max_tokens: 8192, max_tokens: 8192,
base_url: std::env::var("HAMMER_LLM_BASE_URL") base_url: takana_core::env::var("TAKANA_LLM_BASE_URL")
.unwrap_or_else(|_| "https://api.anthropic.com".into()), .unwrap_or_else(|| "https://api.anthropic.com".into()),
effort: std::env::var("HAMMER_LLM_EFFORT").unwrap_or_else(|_| "high".into()), effort: takana_core::env::var("TAKANA_LLM_EFFORT").unwrap_or_else(|| "high".into()),
}) })
} }
} }
+7 -1
View File
@@ -1324,7 +1324,13 @@ fi
# NOTA: el initramfs debe empaquetarse con `cpio --owner=root:root`. Si los ficheros del toolchain # 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 # 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. # 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_WORK=/work
export HAMMER_CACHE= export HAMMER_CACHE=
echo ">> rebuild stage1 (toolchain in-rootfs, semilla $SEED_HASH)" echo ">> rebuild stage1 (toolchain in-rootfs, semilla $SEED_HASH)"
+9 -9
View File
@@ -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. /// Resuelve dónde vive el lab SIN atarlo a dónde vive el store.
/// ///
/// Orden, de más explícito a más adivinado: /// 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 /// 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). /// 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 /// 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 /// 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. /// apuntando a un lugar previsible en vez de a la nada.
fn resolve_lab_dir(store_root: &Path) -> Option<PathBuf> { 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)); return Some(PathBuf::from(v));
} }
if let Some(parent) = store_root.parent() { 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`, /// Lee overrides desde entorno (`TAKANA_LAB`, `TAKANA_ROOTFS`, `TAKANA_ZIG`, `TAKANA_WORK`,
/// `HAMMER_CACHE`). `HAMMER_CACHE=""` (vacío) desactiva la caché. /// `TAKANA_CACHE`). `TAKANA_CACHE=""` (vacío) desactiva la caché.
/// ///
/// Es el constructor que HUELE EL ENTORNO (env + CWD); `defaults_for_store` se mantiene pura. /// 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. /// siguen pisando pieza por pieza y ganan sobre él.
pub fn from_env_or_defaults(store_root: &Path) -> Self { pub fn from_env_or_defaults(store_root: &Path) -> Self {
let mut cfg = match resolve_lab_dir(store_root) { let mut cfg = match resolve_lab_dir(store_root) {
Some(lab) => Self::defaults_for_store_with_lab(store_root, &lab), Some(lab) => Self::defaults_for_store_with_lab(store_root, &lab),
None => Self::defaults_for_store(store_root), 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); 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); 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); 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.cache_root = if v.is_empty() { None } else { Some(PathBuf::from(v)) };
} }
cfg cfg
+10 -10
View File
@@ -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) /// # 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 /// 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 /// 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 /// 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 /// 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. /// 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> { fn bases_de_mirror(var: &str, clave: &str) -> Vec<String> {
match std::env::var(var) { match takana_core::env::var(var) {
Ok(raw) => rotar_bases(&raw, clave), Some(raw) => rotar_bases(&raw, clave),
Err(_) => Vec::new(), 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 /// 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. /// desempaquetar, y el commit de la receta es la identidad. Un bundle alterado no pasa.
fn hidratar_desde_bundle(commit: &str, destino: &Path) -> bool { 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 // 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. // hace git contra el SHA venga de donde venga.
bases_de_mirror("HAMMER_MIRROR_GIT", commit) bases_de_mirror("TAKANA_MIRROR_GIT", commit)
.iter() .iter()
.any(|base| hidratar_desde_bundle_en(base, commit, destino)) .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 /// 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. /// 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 /// 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`]. /// `{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. /// el comportamiento es el de siempre: derecho a upstream.
fn fetch_con_mirror(url: &str, sha256: &str, dst: &Path) -> takana_core::Result<()> { 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"); 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 // 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 // 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"); let mut cmd = Command::new("curl");
cmd.args(["-fL", "--retry", "3", "--connect-timeout", "30"]); cmd.args(["-fL", "--retry", "3", "--connect-timeout", "30"]);
// Clave para el mirror por sftp (Storage Box). Inocua para http/file. // 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() { if !key.is_empty() {
cmd.arg("--key").arg(&key); cmd.arg("--key").arg(&key);
} }
+2 -2
View File
@@ -453,10 +453,10 @@ mod tests {
} }
/// Camino feliz real: requiere patchelf + un ELF de verdad. Gated como el resto de 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] #[test]
fn hydrate_dynamic_patchea_elf_real() { 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; return;
} }
let host_bin = std::path::Path::new("/bin/sh"); let host_bin = std::path::Path::new("/bin/sh");
+1 -1
View File
@@ -197,7 +197,7 @@ pub fn build(
// `docs/state/lab-toolchain.lock` ni de una ruta derivada del store. Derivarla del padre del // `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 // 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 // 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 lab = takana_core::lab::LabFingerprint::from_rootfs(&cfg.rootfs)?;
let h = artifact_hash(recipe, store, &lab)?; let h = artifact_hash(recipe, store, &lab)?;
if store.has(&h, &recipe.name) { if store.has(&h, &recipe.name) {
+3 -3
View File
@@ -3,7 +3,7 @@
//! //!
//! Doblemente gateado para no penalizar `cargo test` por defecto: //! Doblemente gateado para no penalizar `cargo test` por defecto:
//! - Requiere `.dev-fs/` bootstrapeado (rootfs Alpine + zig + cache). //! - 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 //! 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. //! 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 { 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( 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() { if !cfg.rootfs.join("bin/busybox").is_file() {
+6 -6
View File
@@ -13,11 +13,11 @@ use takana_core::kernel::KernelConfig;
use serde::Serialize; use serde::Serialize;
/// Dónde busca el árbol de Kconfig si no se pasa `--kconfig`. /// 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. /// Í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). /// Í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. /// Sitios donde buscarlo sin que nadie diga nada: el del repo y el del sistema instalado.
const CATALOG_DEFAULTS: &[&str] = &[ const CATALOG_DEFAULTS: &[&str] = &[
"docs/state/kernel-bundles.toml", "docs/state/kernel-bundles.toml",
@@ -316,7 +316,7 @@ fn kconfig_root(flag: Option<PathBuf>) -> Result<PathBuf> {
if let Some(p) = flag { if let Some(p) = flag {
return Ok(p); return Ok(p);
} }
match std::env::var_os(KCONFIG_ENV) { match takana_core::env::var_os(KCONFIG_ENV) {
Some(v) => Ok(PathBuf::from(v)), Some(v) => Ok(PathBuf::from(v)),
None => anyhow::bail!( None => anyhow::bail!(
"falta el árbol de fuentes del kernel: pasá --kconfig <dir> o exportá {KCONFIG_ENV}" "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 { if let Some(p) = flag {
return Ok(p); 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)); return Ok(PathBuf::from(v));
} }
for c in CATALOG_DEFAULTS { for c in CATALOG_DEFAULTS {
@@ -348,7 +348,7 @@ fn contract_path(flag: Option<PathBuf>) -> Result<PathBuf> {
if let Some(p) = flag { if let Some(p) = flag {
return Ok(p); 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)); return Ok(PathBuf::from(v));
} }
for c in CONTRACT_DEFAULTS { for c in CONTRACT_DEFAULTS {
+1 -1
View File
@@ -358,7 +358,7 @@ enum Cmd {
catalog: Option<PathBuf>, catalog: Option<PathBuf>,
/// Activa el traductor LLM real (Claude API). Requiere `ANTHROPIC_API_KEY` en el env /// 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: /// 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)] #[arg(long)]
llm: bool, llm: bool,
/// Re-rootea las mutaciones bajo este prefix en vez de abrir overlay. Útil para /// Re-rootea las mutaciones bajo este prefix en vez de abrir overlay. Útil para
+4 -4
View File
@@ -25,8 +25,8 @@ use serde::{Deserialize, Serialize};
/// Raíz del espacio de nombres de qorpa. Deliberadamente **fuera** del store. /// Raíz del espacio de nombres de qorpa. Deliberadamente **fuera** del store.
pub const DEFAULT_ROOT: &str = "/var/lib/hammer/qorpa"; pub const DEFAULT_ROOT: &str = "/var/lib/hammer/qorpa";
/// Para correr sin root (tests, laptop). Mismo patrón que `HAMMER_KCONFIG_ROOT`. /// Para correr sin root (tests, laptop). Mismo patrón que `TAKANA_KCONFIG_ROOT`.
pub const ROOT_ENV: &str = "HAMMER_QORPA_ROOT"; pub const ROOT_ENV: &str = "TAKANA_QORPA_ROOT";
/// El manifiesto de la imagen. No confundir con `instancia.toml`, que describe una INSTANCIA. /// El manifiesto de la imagen. No confundir con `instancia.toml`, que describe una INSTANCIA.
const IMAGE_MANIFEST: &str = "image.toml"; const IMAGE_MANIFEST: &str = "image.toml";
/// El árbol desempacado dentro del directorio de la imagen. /// 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. /// Dónde está el rootfs DENTRO del archivo, si la detección automática no acierta.
#[arg(long)] #[arg(long)]
subdir: Option<String>, 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)] #[arg(long)]
root: Option<PathBuf>, root: Option<PathBuf>,
}, },
@@ -226,7 +226,7 @@ pub fn run(cmd: QorpaCmd, store: &Path) -> Result<()> {
} }
fn resolve_root(flag: Option<PathBuf>) -> PathBuf { 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)) .unwrap_or_else(|| PathBuf::from(DEFAULT_ROOT))
} }
+1 -1
View File
@@ -3,7 +3,7 @@
//! coinciden con lo esperado. //! coinciden con lo esperado.
//! //!
//! NO ejercitamos `source_patch` porque arrastra todo el lab (red + sandbox); para esos //! 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`. //! de hammer-core: `verify_schema`, `verify_base`, `apply_config_edit`, `apply_file_drop`.
use std::collections::BTreeMap; use std::collections::BTreeMap;
+72
View File
@@ -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"))
);
}
}
+1 -1
View File
@@ -118,7 +118,7 @@ impl LabFingerprint {
crate::Error::Other(anyhow::anyhow!( crate::Error::Other(anyhow::anyhow!(
"no pude leer el apk db del lab en {}: {e}. \ "no pude leer el apk db del lab en {}: {e}. \
El toolchain entra en el ArtifactHash, así que sin rootfs no se puede calcular \ 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() db.display()
)) ))
})?; })?;
+1
View File
@@ -8,6 +8,7 @@ pub mod apply;
pub mod caps; pub mod caps;
pub mod compat; pub mod compat;
pub mod differs; pub mod differs;
pub mod env;
pub mod hash; pub mod hash;
pub mod installed; pub mod installed;
pub mod kernel; pub mod kernel;
+4 -4
View File
@@ -693,10 +693,10 @@ mod tests {
} }
/// Sanity con un binario real del host: `/bin/sh` casi seguro existe y es ELF. /// 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] #[test]
fn parse_elf_real_host_binary() { 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; return;
} }
let candidates = ["/bin/sh", "/usr/bin/sh", "/bin/ls", "/usr/bin/ls"]; 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 /// 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] #[test]
fn parse_exports_real_host_lib() { 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; return;
} }
let candidates = [ let candidates = [
+7 -7
View File
@@ -7,7 +7,7 @@
//! en distros con AppArmor; algunos kernels también requieren la opción `userxattr` en el //! en distros con AppArmor; algunos kernels también requieren la opción `userxattr` en el
//! mount). Por eso este test está doblemente gateado: //! mount). Por eso este test está doblemente gateado:
//! - Requiere `bwrap` y overlayfs en el kernel. //! - 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`. //! mount unprivilegiado, o corre el test bajo `sudo`.
//! //!
//! Sin esos requisitos el test salta limpio; los aspectos puros (layout, slug, parsing del //! 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), /// reenviando los args originales. Si ya estamos dentro del sandbox (env marker set),
/// no re-anidamos. /// no re-anidamos.
fn run_inside_userns_or_skip(phase: &str, scratch: &Path) -> bool { 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. // Ya estamos dentro — el caller ejecuta la lógica real.
return false; 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!( 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)." el kernel; setea la var cuando tu host lo permita o corre con sudo)."
); );
return true; return true;
@@ -72,7 +72,7 @@ fn run_inside_userns_or_skip(phase: &str, scratch: &Path) -> bool {
.arg(scratch) .arg(scratch)
.arg(scratch) .arg(scratch)
.arg("--setenv") .arg("--setenv")
.arg("HAMMER_OVERLAY_IN_SANDBOX") .arg("TAKANA_OVERLAY_IN_SANDBOX")
.arg("1") .arg("1")
.arg("--setenv") .arg("--setenv")
.arg("OVERLAY_TEST_SCRATCH") .arg("OVERLAY_TEST_SCRATCH")
@@ -154,7 +154,7 @@ fn body_try_commit_discard() {
#[test] #[test]
fn overlay_try_commit_discard_inside_userns() { 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(); body_try_commit_discard();
return; return;
} }
@@ -220,7 +220,7 @@ fn body_nested_stack() {
#[test] #[test]
fn overlay_nested_stack_inside_userns() { 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(); body_nested_stack();
return; return;
} }
+17 -7
View File
@@ -14,8 +14,8 @@
//! generaciones tipo NixOS que seleccionar, sino una reparación determinista del estado a medias. //! generaciones tipo NixOS que seleccionar, sino una reparación determinista del estado a medias.
//! //!
//! Paths del producto (overridables por entorno para tests): //! Paths del producto (overridables por entorno para tests):
//! `HAMMER_RECOVER_ROOT=/` `HAMMER_RECOVER_STORE=/store` //! `TAKANA_RECOVER_ROOT=/` `TAKANA_RECOVER_STORE=/store`
//! `HAMMER_RECOVER_STATE=/var/lib/hammer/upgrades` `HAMMER_RECOVER_JOURNAL=/var/lib/hammer/journal` //! `TAKANA_RECOVER_STATE=/var/lib/hammer/upgrades` `TAKANA_RECOVER_JOURNAL=/var/lib/hammer/journal`
//! Flag: `--rollback` fuerza deshacer en vez de completar. //! 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 //! 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; 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 { 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() { fn main() {
let force_rollback = std::env::args().skip(1).any(|a| a == "--rollback"); let force_rollback = std::env::args().skip(1).any(|a| a == "--rollback");
let root = env_path("HAMMER_RECOVER_ROOT", "/"); let root = env_path("TAKANA_RECOVER_ROOT", "/");
let store = env_path("HAMMER_RECOVER_STORE", "/store"); let store = env_path("TAKANA_RECOVER_STORE", "/store");
let state = env_path("HAMMER_RECOVER_STATE", "/var/lib/hammer/upgrades"); let state = env_path("TAKANA_RECOVER_STATE", "/var/lib/hammer/upgrades");
let journal_dir = env_path("HAMMER_RECOVER_JOURNAL", "/var/lib/hammer/journal"); let journal_dir = env_path("TAKANA_RECOVER_JOURNAL", "/var/lib/hammer/journal");
match takana_upgrade::pending(&state) { match takana_upgrade::pending(&state) {
Ok(None) => { Ok(None) => {
+1 -1
View File
@@ -12,7 +12,7 @@ PKG="${1:?uso: alpine-import.sh <pkg> [main|community]}"
REPO="${2:-main}" REPO="${2:-main}"
BRANCH="${ALPINE_BRANCH:-master}" BRANCH="${ALPINE_BRANCH:-master}"
OUTDIR="${OUTDIR:-.}" 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}" 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; } apk=$(curl -fsSL "${BASE}/APKBUILD") || { echo "no encontré ${REPO}/${PKG} en aports@${BRANCH}" >&2; exit 1; }
+1 -1
View File
@@ -23,7 +23,7 @@ STORE="${STORE:-./store}"
REPO="${REPO:-$ROOT/dist/repo}" REPO="${REPO:-$ROOT/dist/repo}"
KEY="${KEY:-$ROOT/dist/keys/release.ed25519}" KEY="${KEY:-$ROOT/dist/keys/release.ed25519}"
DISTRO="${DISTRO:-dev}" DISTRO="${DISTRO:-dev}"
HAMMER="${HAMMER:-$ROOT/target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
PROMOTE="${PROMOTE:-1}" PROMOTE="${PROMOTE:-1}"
JOBS="${JOBS:-$(( $(nproc) - 2 ))}"; [ "$JOBS" -ge 1 ] || JOBS=1 JOBS="${JOBS:-$(( $(nproc) - 2 ))}"; [ "$JOBS" -ge 1 ] || JOBS=1
+1 -1
View File
@@ -21,7 +21,7 @@
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
RFS="${RFS:-work/cosmic-rootfs}"; STORE="${STORE:-./store}"; LINK="${LINK:-static}" 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 if [ $# -gt 0 ]; then
TARGETS=("$@") TARGETS=("$@")
+1 -1
View File
@@ -19,7 +19,7 @@
# #
# Sale con el MISMO código que `hammer build` (transparente para el llamador). # Sale con el MISMO código que `hammer build` (transparente para el llamador).
set -u set -u
HAMMER="${HAMMER:-./target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
STORE="${STORE:-./store}" STORE="${STORE:-./store}"
UMBRAL="${UMBRAL_TIEMPO:-3}" UMBRAL="${UMBRAL_TIEMPO:-3}"
f="${1:?uso: build-timed.sh <receta.toml>}" f="${1:?uso: build-timed.sh <receta.toml>}"
+2 -2
View File
@@ -25,12 +25,12 @@
# /opt/hammer/scripts/farm/campana-deuda.sh <recetas…>' # /opt/hammer/scripts/farm/campana-deuda.sh <recetas…>'
# ssh root@<ip> 'journalctl -u campana-deuda -f' # ssh root@<ip> 'journalctl -u campana-deuda -f'
set -u 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 # 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. # qué contener a este script, así que un `$0` relativo se pierde seguro.
YO="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")" YO="$(cd "$(dirname "$0")" && pwd)/$(basename "$0")"
cd "$HAMMER_DIR" cd "$HAMMER_DIR"
HAMMER="${HAMMER:-$HAMMER_DIR/target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-$HAMMER_DIR/target/release/takana}}"
STORE="${STORE:-$HAMMER_DIR/store}" STORE="${STORE:-$HAMMER_DIR/store}"
LOG="${LOG:-/var/log/campana-deuda.log}" LOG="${LOG:-/var/log/campana-deuda.log}"
+1 -1
View File
@@ -78,7 +78,7 @@ if [ -s "$FLEET_FIJA" ]; then
{ grep -vE '^[[:space:]]*(#|$)' "$FLEET_FIJA" || true; cat "$FLEET" 2>/dev/null || true; } \ { grep -vE '^[[:space:]]*(#|$)' "$FLEET_FIJA" || true; cat "$FLEET" 2>/dev/null || true; } \
| awk 'NF && !visto[$1]++' > "$FLEET.seed" && mv "$FLEET.seed" "$FLEET" | awk 'NF && !visto[$1]++' > "$FLEET.seed" && mv "$FLEET.seed" "$FLEET"
fi 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). # 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" SSH="ssh -i $SSH_KEY -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o BatchMode=yes -o LogLevel=ERROR -o ConnectTimeout=15"
+1 -1
View File
@@ -9,7 +9,7 @@
# #
# Lo lanza systemd (hammer-farm.service). Manual: JOBS=2 ./scripts/farm/farm-worker-loop.sh # Lo lanza systemd (hammer-farm.service). Manual: JOBS=2 ./scripts/farm/farm-worker-loop.sh
set -uo pipefail set -uo pipefail
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}" HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
cd "$HAMMER_DIR" cd "$HAMMER_DIR"
. "$HOME/.cargo/env" 2>/dev/null || true . "$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 # JOBS=1 MIENTRAS EL ADR 0012 ESTÉ SIN DECIDIR (2026-07-22). `build-farm.sh` usa `xargs -P$JOBS`, y
+1 -1
View File
@@ -10,7 +10,7 @@
set -u set -u
MI_NOMBRE="${1:?uso: harkaq-campana-vol.sh <mi-nombre>}" 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" cd "$HAMMER_DIR"
LISTA="${LISTA:-work/harkaq-cola.txt}" LISTA="${LISTA:-work/harkaq-cola.txt}"
VOL_OUT="/mnt/cosecha" VOL_OUT="/mnt/cosecha"
+1 -1
View File
@@ -18,7 +18,7 @@
# script existe para no tener. # script existe para no tener.
set -u set -u
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}" HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
cd "$HAMMER_DIR" cd "$HAMMER_DIR"
LISTA="${1:-work/harkaq-cola.txt}" LISTA="${1:-work/harkaq-cola.txt}"
OUT="work/harkaq-campana" OUT="work/harkaq-campana"
+1 -1
View File
@@ -29,7 +29,7 @@ STORE="${STORE:-$ROOT/store}"
REPO="${REPO:-$ROOT/dist/repo}" REPO="${REPO:-$ROOT/dist/repo}"
KEY="${KEY:-$ROOT/dist/keys/release.ed25519}" KEY="${KEY:-$ROOT/dist/keys/release.ed25519}"
DISTRO="${DISTRO:-dev}" DISTRO="${DISTRO:-dev}"
HAMMER="${HAMMER:-$ROOT/target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
SEAL_TIMEOUT="${SEAL_TIMEOUT:-60}" SEAL_TIMEOUT="${SEAL_TIMEOUT:-60}"
QUEUE="recipes/incoming-go" QUEUE="recipes/incoming-go"
REVIEW="tandas/needs-review-weekend" REVIEW="tandas/needs-review-weekend"
+1 -1
View File
@@ -13,7 +13,7 @@
# Salidas: work/migra-zig/{migrable,matraca}.txt # Salidas: work/migra-zig/{migrable,matraca}.txt
set -u set -u
cd "$(dirname "$0")/../.." cd "$(dirname "$0")/../.."
HAMMER="${HAMMER:-./target/debug/hammer}" HAMMER="${TAKANA:-${HAMMER:-./target/debug/hammer}}"
OUT="work/migra-zig"; mkdir -p "$OUT" 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 # 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. # lotes y cada lote SUMA. `reg` evita duplicar una receta ya clasificada en una corrida previa.
+1 -1
View File
@@ -27,7 +27,7 @@
set -u set -u
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
HAMMER="${HAMMER:-$ROOT/target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
STORE="${STORE:-$ROOT/store}" STORE="${STORE:-$ROOT/store}"
DRY="${DRY:-0}" DRY="${DRY:-0}"
# El stack GUI no construye en el laptop (zig-skew rompe cairo). Default: saltarlo salvo que se pida. # El stack GUI no construye en el laptop (zig-skew rompe cairo). Default: saltarlo salvo que se pida.
+1 -1
View File
@@ -21,7 +21,7 @@
# /opt/hammer/scripts/farm/tandas.sh "gui:pixman,cairo" …' # /opt/hammer/scripts/farm/tandas.sh "gui:pixman,cairo" …'
# ssh root@<ip> 'tail -f /var/log/tandas.log' # ssh root@<ip> 'tail -f /var/log/tandas.log'
set -u set -u
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}" HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
cd "$HAMMER_DIR" cd "$HAMMER_DIR"
LOG="${LOG:-/var/log/tandas.log}" LOG="${LOG:-/var/log/tandas.log}"
ESPERA="${ESPERA:-30}" ESPERA="${ESPERA:-30}"
+1 -1
View File
@@ -41,7 +41,7 @@
# evita el zig-skew: el worker usa EXACTAMENTE las versiones del hub. # evita el zig-skew: el worker usa EXACTAMENTE las versiones del hub.
set -euo pipefail set -euo pipefail
HAMMER_DIR="${HAMMER_DIR:-/opt/hammer}" HAMMER_DIR="${TAKANA_DIR:-${HAMMER_DIR:-/opt/hammer}}"
cd "$HAMMER_DIR" cd "$HAMMER_DIR"
# ── detección de familia ──────────────────────────────────────────────────────────────────── # ── detección de familia ────────────────────────────────────────────────────────────────────
+9 -3
View File
@@ -20,8 +20,14 @@
# La ruta lleva `/~/` a propósito. curl interpreta lo que sigue al host en una URL `sftp://` como # 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 # 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. # «(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 # 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. # 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 TAKANA_MIRROR_GIT="${TAKANA_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 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"
+1 -1
View File
@@ -18,7 +18,7 @@
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
RFS="${RFS:-work/gnome-rootfs}"; STORE="${STORE:-./store}"; LINK="${LINK:-static}" 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 # 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 # 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 # `imports.gi.AccountsService` y gjs resuelve el typelib al arrancar. Todo lo que el shell carga por
+9 -8
View File
@@ -25,7 +25,8 @@
# particiona+instala. Es la cara humana del instalador (el /init del ISO installer lo lanza). # 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] # 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: # 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 set -eu
DEV="${1:-}" DEV="${1:-}"
@@ -132,11 +133,11 @@ apply_post_install_config() {
} }
# ---- recolección de config: interactiva (TUI) o desde env (desatendido) ---- # ---- recolección de config: interactiva (TUI) o desde env (desatendido) ----
CFG_HOSTNAME="${HAMMER_HOSTNAME:-hammer}" CFG_HOSTNAME="${TAKANA_HOSTNAME:-${HAMMER_HOSTNAME:-takana}}"
CFG_ROOT_AUTHKEYS="${HAMMER_ROOT_AUTHKEYS:-}" CFG_ROOT_AUTHKEYS="${TAKANA_ROOT_AUTHKEYS:-${HAMMER_ROOT_AUTHKEYS:-}}"
CFG_ROOT_HASH="${HAMMER_ROOT_HASH:-}" CFG_ROOT_HASH="${TAKANA_ROOT_HASH:-${HAMMER_ROOT_HASH:-}}"
CFG_TZ="${HAMMER_TZ:-}" CFG_TZ="${TAKANA_TZ:-${HAMMER_TZ:-}}"
CFG_KEYMAP="${HAMMER_KEYMAP:-us}" CFG_KEYMAP="${TAKANA_KEYMAP:-${HAMMER_KEYMAP:-us}}"
interactive_setup() { interactive_setup() {
echo echo
@@ -250,8 +251,8 @@ fi
ROOT_MB="${ROOT_MB:-1500}" ROOT_MB="${ROOT_MB:-1500}"
STORE_MB="${STORE_MB:-400}" STORE_MB="${STORE_MB:-400}"
# En modo desatendido con contraseña por env, derivar el hash acá (interactivo ya lo hizo). # 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 if [ -z "$CFG_ROOT_HASH" ] && [ -n "${TAKANA_ROOT_PW:-${HAMMER_ROOT_PW:-}}" ] && have_cryptpw; then
CFG_ROOT_HASH=$(printf '%s' "$HAMMER_ROOT_PW" | bb cryptpw -m sha512 2>/dev/null || true) CFG_ROOT_HASH=$(printf '%s' "${TAKANA_ROOT_PW:-$HAMMER_ROOT_PW}" | bb cryptpw -m sha512 2>/dev/null || true)
fi fi
# --- gancho de prueba: valida TUI + config sin tocar disco (HAMMER_INSTALL_DRYRUN=1) --- # --- gancho de prueba: valida TUI + config sin tocar disco (HAMMER_INSTALL_DRYRUN=1) ---
+1 -1
View File
@@ -23,7 +23,7 @@ set -euo pipefail
RECETA="${1:?uso: harkaq-trace-build.sh <receta.toml> [store] [outdir]}" RECETA="${1:?uso: harkaq-trace-build.sh <receta.toml> [store] [outdir]}"
STORE="${2:-./store}" STORE="${2:-./store}"
OUT="${3:-/tmp/harkaq-trace-pilot}" OUT="${3:-/tmp/harkaq-trace-pilot}"
HAMMER="${HAMMER:-./target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
TRACE="${TRACE:-/tmp/harkaq-trace}" TRACE="${TRACE:-/tmp/harkaq-trace}"
NORM="${NORM:-scripts/harkaq/harkaq-trace-norm.py}" NORM="${NORM:-scripts/harkaq/harkaq-trace-norm.py}"
mkdir -p "$OUT"; rm -f "$OUT"/traza-fase-*.txt "$OUT"/canonica.txt "$OUT"/resumen.txt mkdir -p "$OUT"; rm -f "$OUT"/traza-fase-*.txt "$OUT"/canonica.txt "$OUT"/resumen.txt
+1 -1
View File
@@ -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 # 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 # 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ú. # 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 if [ -x "$HAMMER_MUSL" ]; then
cp "$HAMMER_MUSL" "$ROOT_TREE/usr/bin/hammer"; chmod 0755 "$ROOT_TREE/usr/bin/hammer" 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" echo " + CLI hammer (static musl) para el menú de arranque por grafo"
+1 -1
View File
@@ -9,7 +9,7 @@
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
STORE="${STORE:-./store}"; RFS="${RFS:-work/kde-store-rootfs}"; LINK="${LINK:-static}" 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)}" 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. # 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" 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"
+1 -1
View File
@@ -16,7 +16,7 @@ REPO="${REPO:-work/repo-kde}"; TRUST="${TRUST:-dist/keys}"; STORE="${STORE:-./st
RFS="${RFS:-work/kde-rootfs}" RFS="${RFS:-work/kde-rootfs}"
# TARGETS = uno o varios paquetes tope (unión de cierres). TARGET (singular) sigue soportado. # TARGETS = uno o varios paquetes tope (unión de cierres). TARGET (singular) sigue soportado.
TARGETS="${TARGETS:-${TARGET:-qt6-qtdeclarative}}" TARGETS="${TARGETS:-${TARGET:-qt6-qtdeclarative}}"
HAMMER="${HAMMER:-./target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-./target/release/takana}}"
DB="$RFS/var/lib/hammer/installed.json" DB="$RFS/var/lib/hammer/installed.json"
# cierre transitivo de TODOS los targets, leído del índice (deps + aliases ya resuelven). Excluimos # cierre transitivo de TODOS los targets, leído del índice (deps + aliases ya resuelven). Excluimos
+1 -1
View File
@@ -15,7 +15,7 @@
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT" ROOT="$(cd "$(dirname "$0")/../.." && pwd)"; cd "$ROOT"
REPO="${REPO:-work/repo-kde}"; STORE="${STORE:-./store}"; LINK="${LINK:-static}" 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}}" TARGETS="${TARGETS:-${TARGET:-qt6-qtdeclarative}}"
# CUTOFF: por defecto medianoche de hoy (excluye rebuilds de la sesión). Pasá 9999999999 para no filtrar. # 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)}" CUTOFF="${CUTOFF:-$(date -d 'today 00:00' +%s 2>/dev/null || echo 9999999999)}"
+1 -1
View File
@@ -23,7 +23,7 @@ ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
STORE="${STORE:-./store}" STORE="${STORE:-./store}"
DEVFS="${DEVFS:-.dev-fs/alpine}" DEVFS="${DEVFS:-.dev-fs/alpine}"
RFS="${RFS:-work/mirada-rootfs}" RFS="${RFS:-work/mirada-rootfs}"
HAMMER="${HAMMER:-target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-target/release/takana}}"
PACKAGE="${PACKAGE:-1}" PACKAGE="${PACKAGE:-1}"
[ -d "$DEVFS" ] || { echo "no existe $DEVFS (corré scripts/bootstrap-devfs.sh)" >&2; exit 1; } [ -d "$DEVFS" ] || { echo "no existe $DEVFS (corré scripts/bootstrap-devfs.sh)" >&2; exit 1; }
+1 -1
View File
@@ -9,7 +9,7 @@ set -eu
ATTR="${1:?uso: nix-import.sh <attr-de-nixpkgs> (ej: hello, jq, ripgrep)}" ATTR="${1:?uso: nix-import.sh <attr-de-nixpkgs> (ej: hello, jq, ripgrep)}"
NIXPKGS="${NIXPKGS:-nixpkgs}" 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á # 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". # a un store local, p.ej. NIX_STORE="local?root=$HOME/.nixstore".
STORE_OPT="" STORE_OPT=""
+1 -1
View File
@@ -6,7 +6,7 @@
# #
# Ej: scripts/pin-recipes.sh recipes/*.toml | find recipes -name '*.toml' | xargs scripts/pin-recipes.sh # Ej: scripts/pin-recipes.sh recipes/*.toml | find recipes -name '*.toml' | xargs scripts/pin-recipes.sh
set -eu 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; } [ "$#" -gt 0 ] || { echo "uso: pin-recipes.sh <recipe.toml...>" >&2; exit 1; }
pinned=0; skipped=0; failed="" pinned=0; skipped=0; failed=""
+1 -1
View File
@@ -18,7 +18,7 @@
set -eu set -eu
QORPA_ROOT="${HAMMER_QORPA_ROOT:-/var/lib/hammer/qorpa}" 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}" ID="${1:-arch-probe}"
export HAMMER_QORPA_ROOT="$QORPA_ROOT" export HAMMER_QORPA_ROOT="$QORPA_ROOT"
+1 -1
View File
@@ -21,7 +21,7 @@
set -eu set -eu
QORPA_ROOT="${HAMMER_QORPA_ROOT:-/var/lib/hammer/qorpa}" 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}" 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" UBUNTU_URL="https://cdimage.ubuntu.com/ubuntu-base/releases/24.04/release/ubuntu-base-24.04.3-base-amd64.tar.gz"
+1 -1
View File
@@ -31,7 +31,7 @@
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT" ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT"
HAMMER="${HAMMER:-$ROOT/target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-$ROOT/target/release/takana}}"
STORE="${STORE:-./store}" STORE="${STORE:-./store}"
LOCK="$ROOT/work/.farm-build.lock" LOCK="$ROOT/work/.farm-build.lock"
LOG="${LOG:-$ROOT/work/reconstruccion.log}" LOG="${LOG:-$ROOT/work/reconstruccion.log}"
+1 -1
View File
@@ -241,7 +241,7 @@ fi
# kernel): un /init PID1 que copia el rootfs a un tmpfs y hace `switch_root`, dejando `/` como un # 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 # 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). # 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)" say "HAMMER_KERNEL: inyectar /init wrapper (copy-to-tmpfs + switch_root, escapa del rootfs)"
cat > work/builder-rootfs/init <<'INIT' cat > work/builder-rootfs/init <<'INIT'
#!/bin/sh #!/bin/sh
+1 -1
View File
@@ -37,7 +37,7 @@ set -eu
HUB="$(cd "$(dirname "$0")/.." && pwd)" HUB="$(cd "$(dirname "$0")/.." && pwd)"
cd "$HUB" cd "$HUB"
STORE="${STORE:-$PWD/store}" STORE="${STORE:-$PWD/store}"
HAMMER="${HAMMER:-$HUB/target/release/takana}" HAMMER="${TAKANA:-${HAMMER:-$HUB/target/release/takana}}"
if [ $# -gt 0 ]; then if [ $# -gt 0 ]; then
recetas="" recetas=""
+1 -1
View File
@@ -38,7 +38,7 @@
# Env: STORE (def ./store) HAMMER (def ./target/release/takana) JOBS (def 8) # Env: STORE (def ./store) HAMMER (def ./target/release/takana) JOBS (def 8)
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT" 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 APLICAR=0; HUERFANOS=0
for a in "$@"; do for a in "$@"; do
case "$a" in case "$a" in
+1 -1
View File
@@ -48,7 +48,7 @@
# Env: STORE (def ./store) N (def 30, tamaño de la muestra) # Env: STORE (def ./store) N (def 30, tamaño de la muestra)
set -uo pipefail set -uo pipefail
ROOT="$(cd "$(dirname "$0")/.." && pwd)"; cd "$ROOT" 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 ─────────────────────────────────────────── # ── 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 # Este script llama a `hammer build`, y la regla 1 del repo es que todo build va envuelto en el