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).
|
//! 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
|
||||||
|
|||||||
@@ -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()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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)"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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");
|
||||||
|
|||||||
@@ -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,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() {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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!(
|
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()
|
||||||
))
|
))
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 +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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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) => {
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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=("$@")
|
||||||
|
|||||||
@@ -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>}"
|
||||||
|
|||||||
@@ -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}"
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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.
|
||||||
|
|||||||
@@ -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}"
|
||||||
|
|||||||
@@ -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 ────────────────────────────────────────────────────────────────────
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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) ---
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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)}"
|
||||||
|
|||||||
@@ -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; }
|
||||||
|
|||||||
@@ -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=""
|
||||||
|
|||||||
@@ -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=""
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
@@ -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}"
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user