prueba
This commit is contained in:
@@ -423,7 +423,7 @@ impl IntrospectServer {
|
|||||||
"ReloadRules sin path y sin rules_out configurado".into()
|
"ReloadRules sin path y sin rules_out configurado".into()
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
let rules = match crate::kcl_loader::load_rules_file(&path) {
|
let rules = match crate::loader::load_rules_file(&path) {
|
||||||
Ok(r) => r,
|
Ok(r) => r,
|
||||||
Err(e) => return IntrospectResponse::Error(format!("load: {e}")),
|
Err(e) => return IntrospectResponse::Error(format!("load: {e}")),
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,143 +0,0 @@
|
|||||||
//! Loader de reglas desde archivos `.k` vía subprocess al CLI de KCL.
|
|
||||||
//!
|
|
||||||
//! ## ¿Por qué subprocess y no SDK Rust?
|
|
||||||
//!
|
|
||||||
//! El SDK Rust de KusionStack KCL (en el monorepo `kcl-lang/kcl`) no se
|
|
||||||
//! publica como crate independiente en crates.io. Los crates `kcl-*` que
|
|
||||||
//! sí están publicados (kcl-lib, kcl-api, etc.) pertenecen al proyecto
|
|
||||||
//! KittyCAD — un lenguaje CAD distinto pese al nombre. Verificado 2026-05.
|
|
||||||
//!
|
|
||||||
//! Subprocess al CLI `kcl` (instalable vía `go install kcl-lang.io/cli/cmd/kcl@latest`
|
|
||||||
//! o desde el release de GitHub) es funcionalmente equivalente al SDK:
|
|
||||||
//! produce JSON validado contra el schema KCL declarado, sin dependencia
|
|
||||||
//! de Go runtime en el binario final del fractal.
|
|
||||||
//!
|
|
||||||
//! Si `kcl` no está en PATH, el caller decide: cargar JSON crudo (skip KCL),
|
|
||||||
//! o fallar el boot.
|
|
||||||
//!
|
|
||||||
//! ## Formato esperado del .k file
|
|
||||||
//!
|
|
||||||
//! ```kcl
|
|
||||||
//! import .rule # schema/rule.k
|
|
||||||
//!
|
|
||||||
//! rules: [Rule] = [
|
|
||||||
//! Rule { id = "...", priority = 5, when = ..., then = [...] },
|
|
||||||
//! ...
|
|
||||||
//! ]
|
|
||||||
//! ```
|
|
||||||
//!
|
|
||||||
//! Salida tras `kcl run --format json`: `{"rules": [...]}`. El loader busca
|
|
||||||
//! la primera array en el JSON (top-level o anidada un nivel) y la deserializa.
|
|
||||||
|
|
||||||
use crate::rules::Rule;
|
|
||||||
use ente_card::EntityCard;
|
|
||||||
use std::path::Path;
|
|
||||||
use std::process::Command;
|
|
||||||
use tracing::{debug, info};
|
|
||||||
|
|
||||||
/// Detecta si `kcl` está disponible en PATH. Útil para degradar a JSON-only
|
|
||||||
/// en entornos sin la toolchain.
|
|
||||||
pub fn kcl_available() -> bool {
|
|
||||||
Command::new("kcl")
|
|
||||||
.arg("version")
|
|
||||||
.output()
|
|
||||||
.map(|o| o.status.success())
|
|
||||||
.unwrap_or(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ejecuta `kcl run <path> --format=json` y devuelve el JSON crudo.
|
|
||||||
pub fn run_kcl(path: &Path) -> anyhow::Result<String> {
|
|
||||||
let output = Command::new("kcl")
|
|
||||||
.arg("run")
|
|
||||||
.arg(path)
|
|
||||||
.arg("--format=json")
|
|
||||||
.output()
|
|
||||||
.map_err(|e| anyhow::anyhow!("invocando `kcl`: {e}. ¿Instalado en PATH?"))?;
|
|
||||||
if !output.status.success() {
|
|
||||||
anyhow::bail!(
|
|
||||||
"kcl run {} falló: {}",
|
|
||||||
path.display(),
|
|
||||||
String::from_utf8_lossy(&output.stderr)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
debug!(path = %path.display(), out_bytes = output.stdout.len(), "kcl run ok");
|
|
||||||
Ok(String::from_utf8(output.stdout)?)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Carga reglas desde un archivo `.k` o JSON. Discrimina por extensión:
|
|
||||||
/// `.k` → invoca KCL, `.json` → directo.
|
|
||||||
pub fn load_rules_file(path: &Path) -> anyhow::Result<Vec<Rule>> {
|
|
||||||
let raw = match path.extension().and_then(|e| e.to_str()) {
|
|
||||||
Some("k") => {
|
|
||||||
info!(path = %path.display(), "cargando reglas vía kcl");
|
|
||||||
run_kcl(path)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
info!(path = %path.display(), "cargando reglas como JSON crudo");
|
|
||||||
std::fs::read_to_string(path)?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
extract_rules_from_json(&raw)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extrae un `Vec<Rule>` de JSON que puede ser:
|
|
||||||
/// 1. Array directo: `[{...}, {...}]`
|
|
||||||
/// 2. Object con un campo array: `{"rules": [...]}`
|
|
||||||
pub fn extract_rules_from_json(raw: &str) -> anyhow::Result<Vec<Rule>> {
|
|
||||||
let v: serde_json::Value = serde_json::from_str(raw)?;
|
|
||||||
let arr = match v {
|
|
||||||
serde_json::Value::Array(_) => v,
|
|
||||||
serde_json::Value::Object(map) => {
|
|
||||||
map.into_values()
|
|
||||||
.find(|x| x.is_array())
|
|
||||||
.ok_or_else(|| anyhow::anyhow!("JSON no contiene ningún array"))?
|
|
||||||
}
|
|
||||||
_ => anyhow::bail!("JSON debe ser array o object con campo array"),
|
|
||||||
};
|
|
||||||
let rules: Vec<Rule> = serde_json::from_value(arr)?;
|
|
||||||
Ok(rules)
|
|
||||||
}
|
|
||||||
|
|
||||||
// ============================================================================
|
|
||||||
// Carga de Cards desde KCL/JSON. Cierra la "puerta genética": ninguna Card
|
|
||||||
// se acepta sin pasar `validate()` extendido en ente-card.
|
|
||||||
// ============================================================================
|
|
||||||
|
|
||||||
/// Carga una `EntityCard` desde un archivo `.k` (vía kcl run) o `.json`.
|
|
||||||
/// Pasa por `EntityCard::validate()` antes de devolver — falla rápida.
|
|
||||||
pub fn load_card_file(path: &Path) -> anyhow::Result<EntityCard> {
|
|
||||||
let raw = match path.extension().and_then(|e| e.to_str()) {
|
|
||||||
Some("k") => {
|
|
||||||
info!(path = %path.display(), "cargando Card vía kcl");
|
|
||||||
run_kcl(path)?
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
info!(path = %path.display(), "cargando Card como JSON crudo");
|
|
||||||
std::fs::read_to_string(path)?
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let card = extract_card_from_json(&raw)?;
|
|
||||||
card.validate()
|
|
||||||
.map_err(|e| anyhow::anyhow!("Card inválida ({}): {e}", path.display()))?;
|
|
||||||
Ok(card)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extrae una `EntityCard` de JSON. Acepta:
|
|
||||||
/// 1. Object directamente serializable como EntityCard
|
|
||||||
/// 2. Object dict con un único valor que sea EntityCard (KCL output típico)
|
|
||||||
pub fn extract_card_from_json(raw: &str) -> anyhow::Result<EntityCard> {
|
|
||||||
let v: serde_json::Value = serde_json::from_str(raw)?;
|
|
||||||
// Intento 1: deserializar el value directamente.
|
|
||||||
if let Ok(c) = serde_json::from_value::<EntityCard>(v.clone()) {
|
|
||||||
return Ok(c);
|
|
||||||
}
|
|
||||||
// Intento 2: si es dict, buscar el primer value que parsee como Card.
|
|
||||||
if let serde_json::Value::Object(map) = v {
|
|
||||||
for (_, vv) in map {
|
|
||||||
if let Ok(c) = serde_json::from_value::<EntityCard>(vv) {
|
|
||||||
return Ok(c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
anyhow::bail!("JSON no contiene una EntityCard válida")
|
|
||||||
}
|
|
||||||
@@ -22,7 +22,7 @@ pub mod crystallize;
|
|||||||
pub mod dispatch;
|
pub mod dispatch;
|
||||||
pub mod engine;
|
pub mod engine;
|
||||||
pub mod introspect;
|
pub mod introspect;
|
||||||
pub mod kcl_loader;
|
pub mod loader;
|
||||||
pub mod metrics;
|
pub mod metrics;
|
||||||
pub mod observer;
|
pub mod observer;
|
||||||
pub mod rules;
|
pub mod rules;
|
||||||
@@ -32,7 +32,7 @@ pub use crystallize::{detect_crystals, Crystal, CrystallizationParams};
|
|||||||
pub use dispatch::{dispatch_actions, ActionSink, NullSink};
|
pub use dispatch::{dispatch_actions, ActionSink, NullSink};
|
||||||
pub use engine::{EventKindDiscriminant, RuleEngine, SubjectInfo};
|
pub use engine::{EventKindDiscriminant, RuleEngine, SubjectInfo};
|
||||||
pub use introspect::{IntrospectRequest, IntrospectResponse, IntrospectServer, BrainState};
|
pub use introspect::{IntrospectRequest, IntrospectResponse, IntrospectServer, BrainState};
|
||||||
pub use kcl_loader::{kcl_available, load_card_file, load_rules_file};
|
pub use loader::{load_card_file, load_rules_file};
|
||||||
pub use metrics::serve_metrics;
|
pub use metrics::serve_metrics;
|
||||||
pub use observer::{Observer, TimedEvent};
|
pub use observer::{Observer, TimedEvent};
|
||||||
pub use rules::{Action, EventKind, EventPattern, LogLevel, Rule, Scope};
|
pub use rules::{Action, EventKind, EventPattern, LogLevel, Rule, Scope};
|
||||||
|
|||||||
@@ -0,0 +1,68 @@
|
|||||||
|
//! Loader de Cards y Reglas desde archivos JSON.
|
||||||
|
//!
|
||||||
|
//! Sustituye al antiguo `kcl_loader.rs` (eliminado): la rama KCL invocaba
|
||||||
|
//! un subprocess al CLI Go `kcl` que ningún target real tenía instalado y
|
||||||
|
//! cuya validación duplicaba `EntityCard::validate()`. La fuente de verdad
|
||||||
|
//! del shape de la Card es Rust + serde; en disco se guarda JSON crudo.
|
||||||
|
//!
|
||||||
|
//! Ergonomía de autoría futura (RON, Dhall, etc.) se añade como ramas
|
||||||
|
//! adicionales aquí cuando duela escribir JSON a mano. Hoy: una sola rama.
|
||||||
|
|
||||||
|
use crate::rules::Rule;
|
||||||
|
use ente_card::EntityCard;
|
||||||
|
use std::path::Path;
|
||||||
|
use tracing::info;
|
||||||
|
|
||||||
|
/// Carga una `EntityCard` desde un archivo JSON. Pasa por
|
||||||
|
/// `EntityCard::validate()` antes de devolver — falla rápida.
|
||||||
|
pub fn load_card_file(path: &Path) -> anyhow::Result<EntityCard> {
|
||||||
|
info!(path = %path.display(), "cargando Card desde JSON");
|
||||||
|
let raw = std::fs::read_to_string(path)?;
|
||||||
|
let card = extract_card_from_json(&raw)?;
|
||||||
|
card.validate()
|
||||||
|
.map_err(|e| anyhow::anyhow!("Card inválida ({}): {e}", path.display()))?;
|
||||||
|
Ok(card)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extrae una `EntityCard` de JSON. Acepta:
|
||||||
|
/// 1. Object directamente serializable como EntityCard.
|
||||||
|
/// 2. Object dict con un único valor que sea EntityCard (compat con
|
||||||
|
/// salidas de generadores que envuelven en `{"seed": {...}}`).
|
||||||
|
pub fn extract_card_from_json(raw: &str) -> anyhow::Result<EntityCard> {
|
||||||
|
let v: serde_json::Value = serde_json::from_str(raw)?;
|
||||||
|
if let Ok(c) = serde_json::from_value::<EntityCard>(v.clone()) {
|
||||||
|
return Ok(c);
|
||||||
|
}
|
||||||
|
if let serde_json::Value::Object(map) = v {
|
||||||
|
for (_, vv) in map {
|
||||||
|
if let Ok(c) = serde_json::from_value::<EntityCard>(vv) {
|
||||||
|
return Ok(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anyhow::bail!("JSON no contiene una EntityCard válida")
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Carga reglas desde un archivo JSON.
|
||||||
|
pub fn load_rules_file(path: &Path) -> anyhow::Result<Vec<Rule>> {
|
||||||
|
info!(path = %path.display(), "cargando reglas desde JSON");
|
||||||
|
let raw = std::fs::read_to_string(path)?;
|
||||||
|
extract_rules_from_json(&raw)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extrae un `Vec<Rule>` de JSON que puede ser:
|
||||||
|
/// 1. Array directo: `[{...}, {...}]`
|
||||||
|
/// 2. Object con un campo array: `{"rules": [...]}`
|
||||||
|
pub fn extract_rules_from_json(raw: &str) -> anyhow::Result<Vec<Rule>> {
|
||||||
|
let v: serde_json::Value = serde_json::from_str(raw)?;
|
||||||
|
let arr = match v {
|
||||||
|
serde_json::Value::Array(_) => v,
|
||||||
|
serde_json::Value::Object(map) => map
|
||||||
|
.into_values()
|
||||||
|
.find(|x| x.is_array())
|
||||||
|
.ok_or_else(|| anyhow::anyhow!("JSON no contiene ningún array"))?,
|
||||||
|
_ => anyhow::bail!("JSON debe ser array o object con campo array"),
|
||||||
|
};
|
||||||
|
let rules: Vec<Rule> = serde_json::from_value(arr)?;
|
||||||
|
Ok(rules)
|
||||||
|
}
|
||||||
@@ -3,7 +3,7 @@
|
|||||||
//! Tres caminos:
|
//! Tres caminos:
|
||||||
//! 1. `--restore <path>`: leer `FractalSnapshot` y reconstruir Semilla
|
//! 1. `--restore <path>`: leer `FractalSnapshot` y reconstruir Semilla
|
||||||
//! con seed_id preservado + entes anteriores como genesis.
|
//! con seed_id preservado + entes anteriores como genesis.
|
||||||
//! 2. `seed.card` en disco: deserialize directo (prod o dev).
|
//! 2. `seed.card.json` en disco: deserialize directo (prod o dev).
|
||||||
//! 3. Fallback dev: sintetizar Semilla + 6 genesis Entes que ejercitan
|
//! 3. Fallback dev: sintetizar Semilla + 6 genesis Entes que ejercitan
|
||||||
//! todas las capacidades del fractal.
|
//! todas las capacidades del fractal.
|
||||||
|
|
||||||
@@ -63,13 +63,14 @@ fn load_from_snapshot(path: &Path) -> anyhow::Result<EntityCard> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn load_or_synthesize(dev_mode: bool) -> anyhow::Result<EntityCard> {
|
fn load_or_synthesize(dev_mode: bool) -> anyhow::Result<EntityCard> {
|
||||||
// Buscamos primero `.k` (KCL canónico, validado por su schema), luego
|
// Buscamos primero `.json` (canónico), luego sin extensión por
|
||||||
// `.json` para compatibilidad. La puerta genética se cruza vía
|
// compatibilidad con instalaciones que dejan el archivo crudo. La puerta
|
||||||
// `ente_brain::load_card_file` que pasa por `validate()` extendido.
|
// genética se cruza vía `ente_brain::load_card_file` que pasa por
|
||||||
|
// `validate()` extendido.
|
||||||
let candidates: &[&str] = if dev_mode {
|
let candidates: &[&str] = if dev_mode {
|
||||||
&["seed.card.k", SEED_PATH_DEV]
|
&["seed.card.json", SEED_PATH_DEV]
|
||||||
} else {
|
} else {
|
||||||
&["/ente/seed.card.k", SEED_PATH_PROD]
|
&["/ente/seed.card.json", SEED_PATH_PROD]
|
||||||
};
|
};
|
||||||
for cand in candidates {
|
for cand in candidates {
|
||||||
let path = PathBuf::from(cand);
|
let path = PathBuf::from(cand);
|
||||||
@@ -83,7 +84,7 @@ fn load_or_synthesize(dev_mode: bool) -> anyhow::Result<EntityCard> {
|
|||||||
info!("sin seed.card — sintetizando semilla mínima (dev)");
|
info!("sin seed.card — sintetizando semilla mínima (dev)");
|
||||||
return Ok(synthesize_dev_seed());
|
return Ok(synthesize_dev_seed());
|
||||||
}
|
}
|
||||||
anyhow::bail!("seed.card no encontrada en /ente/seed.card[.k]")
|
anyhow::bail!("seed.card no encontrada en /ente/seed.card.json ni /ente/seed.card")
|
||||||
}
|
}
|
||||||
|
|
||||||
fn synthesize_dev_seed() -> EntityCard {
|
fn synthesize_dev_seed() -> EntityCard {
|
||||||
|
|||||||
+9
-41
@@ -35,14 +35,14 @@ escritorio realiza durante la sesión.
|
|||||||
- `ente-echo`, `brainctl`, `busctl`, `ente-journalctl`
|
- `ente-echo`, `brainctl`, `busctl`, `ente-journalctl`
|
||||||
3. Renombra el `/init` original a `/sbin/init.systemd` (backup)
|
3. Renombra el `/init` original a `/sbin/init.systemd` (backup)
|
||||||
4. Symlink `/init` → `/usr/local/bin/ente-zero`
|
4. Symlink `/init` → `/usr/local/bin/ente-zero`
|
||||||
5. Coloca la Card Semilla en `/ente/seed.card.k`
|
5. Coloca la Card Semilla en `/ente/seed.card.json`
|
||||||
6. Desinstala los services systemd que ahora son shims (logind, etc) o
|
6. Desinstala los services systemd que ahora son shims (logind, etc) o
|
||||||
los enmascara con `systemctl mask` (en la imagen base, antes de
|
los enmascara con `systemctl mask` (en la imagen base, antes de
|
||||||
reescribir `/init`)
|
reescribir `/init`)
|
||||||
|
|
||||||
## Card Semilla para el boot test
|
## Card Semilla para el boot test
|
||||||
|
|
||||||
`/ente/seed.card.k` debe declarar como genesis los Entes esenciales:
|
`/ente/seed.card.json` debe declarar como genesis los Entes esenciales:
|
||||||
- D-Bus daemon (`/usr/bin/dbus-daemon --system`)
|
- D-Bus daemon (`/usr/bin/dbus-daemon --system`)
|
||||||
- Los 8 compat-shims
|
- Los 8 compat-shims
|
||||||
- NetworkManager
|
- NetworkManager
|
||||||
@@ -50,45 +50,13 @@ escritorio realiza durante la sesión.
|
|||||||
udev añade reglas de userspace — opcional)
|
udev añade reglas de userspace — opcional)
|
||||||
- gdm o sddm
|
- gdm o sddm
|
||||||
|
|
||||||
Ejemplo mínimo:
|
El shape es la serialización serde de `EntityCard` (ver
|
||||||
|
`crates/ente-card/src/lib.rs`). Para el primer arranque sin GNOME hay un
|
||||||
```kcl
|
ejemplo defensivo en `docs/seed-vps-min.json` (PID 1 + un `sleep infinity`
|
||||||
import .card
|
supervisado). Extiéndelo añadiendo entradas a `genesis[]` con `payload` de
|
||||||
|
forma `{"Native": {"exec": "...", "argv": [...], "envp": []}}` y
|
||||||
seed = EntityCard {
|
`supervision` `{"Restart": {"initial": 100, "max": 30000}}` para los
|
||||||
schema_version = 1
|
daemons que sí queremos restart-supervisados.
|
||||||
id = "01KQ_BOOT_SEED_GNOME_TEST_0"
|
|
||||||
label = "boot-gnome-test"
|
|
||||||
provides = [
|
|
||||||
Capability {kind = "Spawn"}
|
|
||||||
Capability {kind = "Journal"}
|
|
||||||
]
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Virtual"}
|
|
||||||
supervision = Supervision {kind = "OneShot"}
|
|
||||||
genesis = [
|
|
||||||
# dbus-daemon — todo lo demás depende de él.
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQ_BOOT_DBUS_DAEMON__________"
|
|
||||||
label = "dbus-daemon"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {
|
|
||||||
kind = "Native"
|
|
||||||
exec = "/usr/bin/dbus-daemon"
|
|
||||||
argv = ["--system", "--nofork"]
|
|
||||||
}
|
|
||||||
supervision = Supervision {
|
|
||||||
kind = "Restart"
|
|
||||||
initial_ms = 100
|
|
||||||
max_ms = 30000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
# Aquí los 8 compat-shims (mismo patrón) ...
|
|
||||||
# Aquí gdm o sddm ...
|
|
||||||
]
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Boot
|
## Boot
|
||||||
|
|
||||||
|
|||||||
@@ -1,155 +0,0 @@
|
|||||||
# Card Semilla para el boot test de GNOME bajo Ente #0.
|
|
||||||
#
|
|
||||||
# Este archivo se valida con `kcl run` contra el schema en
|
|
||||||
# crates/ente-card/schema/card.k antes de que ente-zero lo cargue.
|
|
||||||
#
|
|
||||||
# Genesis declara la constelación mínima para que GNOME arranque sin
|
|
||||||
# systemd: D-Bus daemon, los 8 compat-shims, NetworkManager, gdm.
|
|
||||||
|
|
||||||
import .ente_card.schema.card
|
|
||||||
|
|
||||||
# Card "supervisor genérico" reutilizable — dispara un binario con Restart.
|
|
||||||
schema NativeRestart(EnteBase):
|
|
||||||
soma = SomaSpec {
|
|
||||||
rlimits = ResourceLimits {nofile = 16384}
|
|
||||||
}
|
|
||||||
supervision = Supervision {
|
|
||||||
kind = "Restart"
|
|
||||||
initial_ms = 100
|
|
||||||
max_ms = 30000
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
# ----- La Semilla -----
|
|
||||||
|
|
||||||
seed = EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTSEEDFRACTAL00"
|
|
||||||
label = "boot-gnome-test"
|
|
||||||
provides = [
|
|
||||||
Capability {kind = "Spawn"}
|
|
||||||
Capability {kind = "Journal"}
|
|
||||||
]
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Virtual"}
|
|
||||||
supervision = Supervision {kind = "OneShot"}
|
|
||||||
|
|
||||||
genesis = [
|
|
||||||
# 1. dbus-daemon — pivote del system bus, todos los demás dependen de él.
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTDBUSDAEMON___"
|
|
||||||
label = "dbus-daemon"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {
|
|
||||||
kind = "Native"
|
|
||||||
exec = "/usr/bin/dbus-daemon"
|
|
||||||
argv = ["--system", "--nofork", "--nopidfile"]
|
|
||||||
}
|
|
||||||
supervision = Supervision {
|
|
||||||
kind = "Restart"
|
|
||||||
initial_ms = 100
|
|
||||||
max_ms = 30000
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 2-9. Los 8 compat-shims D-Bus.
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTLOGIND_______"
|
|
||||||
label = "compat-logind"
|
|
||||||
provides = [Capability {kind = "LegacyLogind"}]
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {
|
|
||||||
kind = "Native"
|
|
||||||
exec = "/usr/local/bin/ente-logind-compat"
|
|
||||||
}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTHOSTNAMED____"
|
|
||||||
label = "compat-hostnamed"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-hostnamed-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTTIMEDATED____"
|
|
||||||
label = "compat-timedated"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-timedated-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTLOCALED______"
|
|
||||||
label = "compat-localed"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-localed-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTJOURNALD_____"
|
|
||||||
label = "compat-journald"
|
|
||||||
provides = [Capability {kind = "Journal"}]
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-journald-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTRESOLVED_____"
|
|
||||||
label = "compat-resolved"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-resolved-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTPOLKIT_______"
|
|
||||||
label = "compat-polkit"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-polkit-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTMACHINED_____"
|
|
||||||
label = "compat-machined"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {kind = "Native", exec = "/usr/local/bin/ente-machined-compat"}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 100, max_ms = 30000}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 10. NetworkManager — la mayoría de distros lo prefieren sobre networkd.
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTNETWORKMGR___"
|
|
||||||
label = "NetworkManager"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {
|
|
||||||
kind = "Native"
|
|
||||||
exec = "/usr/sbin/NetworkManager"
|
|
||||||
argv = ["--no-daemon"]
|
|
||||||
}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 200, max_ms = 30000}
|
|
||||||
}
|
|
||||||
|
|
||||||
# 11. gdm — display manager. GNOME settings panels via gnome-shell.
|
|
||||||
EntityCard {
|
|
||||||
schema_version = 1
|
|
||||||
id = "01KQABOOTTESTGDMDAEMON____"
|
|
||||||
label = "gdm"
|
|
||||||
soma = SomaSpec {}
|
|
||||||
payload = Payload {
|
|
||||||
kind = "Native"
|
|
||||||
exec = "/usr/bin/gdm"
|
|
||||||
argv = ["--no-daemon"]
|
|
||||||
}
|
|
||||||
supervision = Supervision {kind = "Restart", initial_ms = 500, max_ms = 60000}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
# $2 — path opcional a Card Semilla custom (.k o .json)
|
# $2 — path opcional a Card Semilla custom (.k o .json)
|
||||||
#
|
#
|
||||||
# Output: el rootfs queda con /init → ente-zero, binarios en
|
# Output: el rootfs queda con /init → ente-zero, binarios en
|
||||||
# /usr/local/bin, y la Semilla en /ente/seed.card.k.
|
# /usr/local/bin, y la Semilla en /ente/seed.card.json.
|
||||||
|
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
@@ -76,14 +76,14 @@ echo "==> /init → ente-zero"
|
|||||||
ln -sf /usr/local/bin/ente-zero "$ROOTFS/init"
|
ln -sf /usr/local/bin/ente-zero "$ROOTFS/init"
|
||||||
ln -sf /usr/local/bin/ente-zero "$ROOTFS/sbin/init"
|
ln -sf /usr/local/bin/ente-zero "$ROOTFS/sbin/init"
|
||||||
|
|
||||||
# 5. Card Semilla
|
# 5. Card Semilla — JSON crudo, validado en boot por EntityCard::validate().
|
||||||
mkdir -p "$ROOTFS/ente"
|
mkdir -p "$ROOTFS/ente"
|
||||||
if [[ -n "$SEED_CARD" && -f "$SEED_CARD" ]]; then
|
if [[ -n "$SEED_CARD" && -f "$SEED_CARD" ]]; then
|
||||||
cp "$SEED_CARD" "$ROOTFS/ente/seed.card.k"
|
cp "$SEED_CARD" "$ROOTFS/ente/seed.card.json"
|
||||||
echo "==> Semilla custom: $SEED_CARD"
|
echo "==> Semilla custom: $SEED_CARD"
|
||||||
else
|
else
|
||||||
cp "$WORKSPACE/docs/seed-gnome-test.k" "$ROOTFS/ente/seed.card.k" 2>/dev/null \
|
cp "$WORKSPACE/docs/seed-vps-min.json" "$ROOTFS/ente/seed.card.json" 2>/dev/null \
|
||||||
|| echo "WARN: docs/seed-gnome-test.k no existe; ente-zero sintetizará dev seed"
|
|| echo "WARN: docs/seed-vps-min.json no existe; ente-zero sintetizará dev seed"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# 6. Mascara servicios systemd que vamos a sustituir
|
# 6. Mascara servicios systemd que vamos a sustituir
|
||||||
|
|||||||
Reference in New Issue
Block a user