Sigue estos tres pasos para escribir cualquier imagen ISO en un dispositivo USB de forma manual y segura.
Paso 1: Identificar el dispositivo USB
Conecta tu memoria USB y localiza el nombre que el sistema le ha asignado (generalmente da0, da1, etc.).
Bash
camcontrol devlist
Busca la línea que corresponde a tu marca de USB y anota el identificador al final (ejemplo: da0).
Paso 2: Escribir la imagen ISO
Utiliza el comando dd para transferir los datos bit a bit. Reemplaza archivo.iso por tu ruta y daX por tu identificador del Paso 1.
Bash
dd if=archivo.iso of=/dev/daX bs=1M status=progress
Este proceso borrará todos los datos previos en el USB. Espera a que el contador llegue al 100%.
Paso 3: Sincronizar y Extraer
Asegura que todos los datos en caché se hayan escrito físicamente en el USB antes de desconectarlo.
Bash
sync
Una vez que el comando termine y la terminal quede libre, puedes retirar el USB con total seguridad.
Arquitectura: Asegúrate de que la ISO descargada sea la versión amd64.
Permisos: Estos comandos deben ejecutarse con privilegios de superusuario (root).
Eficiencia: El parámetro bs=1M garantiza el equilibrio óptimo entre velocidad de escritura y estabilidad del sistema.
Esta estructura está lista para ser copiada y pegada en tu documentación técnica o en el portal de soporte de tus aplicaciones.
gcloud compute instances create lideros-lab \
--zone=us-central1-a \
--machine-type=e2-micro \
--create-disk=image=projects/freebsd-org-cloud-dev/global/images/freebsd-14-4-release-amd64-zfs,size=30,type=pd-standard,mode=rw,boot=yes,auto-delete=yes \
--network-interface=network-tier=PREMIUM,subnet=default \
--maintenance-policy=MIGRATE \
--provisioning-model=STANDARD \
--tags=lideros-lab
Para que tu FreeBSD sea "amigable" desde el minuto uno, este es el orden de batalla:
Sincronizar Repositorios: pkg update
Instalar Bash (Shell de Compatibilidad): pkg install bash
Establecer Bash por Defecto: chsh -s /usr/local/bin/bash
Instalar Doas (Privilegios de Cirujano): pkg install doas
Configurar Doas (Persistencia de Entorno): echo "permit keepenv :wheel" > /usr/local/etc/doas.conf
Crear Enlace de Compatibilidad Sudo: ln -s /usr/local/bin/doas /usr/local/bin/sudo
Instalar Runtimes de Sistema (Python 3.11): pkg install python311
Instalar Node.js 20 y npm: pkg install node20
Instalar Git y Nano (Editores y Control): pkg install git nano
Instalar Rust (El Corazón de LiderOS): pkg install rust
Instalar Go (Backend de Alto Rendimiento): pkg install go
Instalar TypeScript y Angular CLI: doas npm install -g typescript @angular/cli
Instalar Firebase Tools: doas npm install -g firebase-tools
pkg install autossh
Descargar SDK de Google Cloud: fetch https://dl.google.com/dl/cloudsdk/channels/rapid/downloads/google-cloud-cli-freebsd-x86_64.tar.gz
Descomprimir e Instalar GCloud: tar -xvf google-cloud-cli-freebsd-x86_64.tar.gz && ./google-cloud-sdk/install.sh
Configurar Variables Globales: echo "alias sudo='doas'" >> ~/.bashrc && echo 'export GOPATH=$HOME/go' >> ~/.bashrc && echo 'export PATH=$PATH:$GOPATH/bin' >> ~/.bashrc
Recargar y Validar: source ~/.bashrc && rustc --version && go version && ng version && gcloud --version
Para que no te falte nada en el momento de la verdad, así quedan los pasos de gráficos:
Servidor Gráfico Mínimo (Xorg): doas pkg install xorg-minimal
Instalar soporte de Kernel: doas pkg install drm-kmod
Instalar Librerías 3D: doas pkg install mesa-libs libxkbcommon wayland vulkan-loader
Instalar Motor Web: doas pkg install webkit2-gtk3
Configurar Arranque: doas sysrc kld_list+=i915kms
Para que el sistema reconozca la pantalla y los gráficos de Intel al encenderse, debes ejecutar estos comandos como administrador:
Activar Driver Intel en el Kernel: doas sysrc kld_list+="/boot/modules/i915kms.ko"
Asegurar Permisos de Video para tu usuario: doas pw groupmod video -m edgar (reemplaza 'edgar' por tu usuario).
Para que el portátil Intel de LiderOS pase del encendido directamente a tu aplicación de Angular (saltándose la petición de usuario y contraseña de FreeBSD), debemos configurar el sistema en dos puntos clave.
Siguiendo la metodología LiderModel30, esto automatiza el hardware para que el software (tu servicio de Firebase Auth) tome el control total.
FreeBSD usa un servicio llamado getty para pedir el login. Vamos a crear una regla que "presione Enter" por ti con tu usuario.
Abre el archivo de configuración de terminales: doas nano /etc/gettytab
Al final del archivo, añade esta configuración personalizada (sustituye edgar por tu nombre de usuario de FreeBSD):
Plaintext
# Configuración LiderOS para Autologin
lideros.autologin:\
:al=edgar:tc=default:
Ahora, dile al sistema que use esa regla en la terminal principal. Abre el archivo de terminales:
doas nano /etc/ttys
Busca la línea que empieza por ttyv0 (es la primera consola) y cámbiala para que se vea así:
Plaintext
# Antes: ttyv0 "/usr/libexec/getty pc" xterm on secure
# Después (LiderOS):
ttyv0 "/usr/libexec/getty lideros.autologin" xterm on secure
Ya logramos que el sistema entre a tu usuario solo. Ahora necesitamos que, apenas entre, lance el entorno gráfico y tu binario de Rust.
Crea o edita el archivo de perfil de tu usuario: nano ~/.bash_profile
Añade este código al final. Esto detecta si estás en la terminal principal (ttyv0) e inicia el entorno gráfico automáticamente:
Bash
# Si estamos en la consola 1, iniciar el escritorio LiderOS
if [ -z "$DISPLAY" ] && [ "$(tty)" = "/dev/ttyv0" ]; then
startx
fi
Finalmente, necesitamos que startx sepa qué abrir. Queremos que abra tu binario de Rust a pantalla completa.
Crea el archivo de inicio gráfico: nano ~/.xinitrc
Añade estas líneas para optimizar la pantalla del portátil:
Bash
# Desactivar protector de pantalla de FreeBSD
xset s off
xset -dpms
xset s noblank
# Ejecutar el corazón de LiderOS (Tu binario de Rust)
# --fullscreen es un flag común en motores como Wry/Tauri
exec /home/edgar/lideros/target/release/lider_shell --fullscreen
BIOS -> Kernel: Carga drivers Intel (i915kms).
ttyv0: Lee lideros.autologin y entra a tu sesión automáticamente.
Bash: Lee .bash_profile y ejecuta startx.
Xorg: Lee .xinitrc y lanza tu app de Angular (vía Rust).
Tu App: Tu servicio de Firebase detecta si ya estás logueado con edgar@lidertech.work.
¡Listo! El PC ahora es un dispositivo dedicado. Si necesitas salir de este modo para mantenimiento, simplemente conectas un teclado y presionas Ctrl + Alt + F2 para entrar a una terminal secundaria manual.
// entorno.service.ts
import { Injectable, signal } from '@angular/core';
@Injectable({ providedIn: 'root' })
export class EntornoService {
// Verificamos si existe la marca de LiderOS en el navegador
readonly esModoKiosko = signal<boolean>(
window.navigator.userAgent.includes('LiderOS-Kiosk') || (window as any).isLiderOS === true
);
}
<nav class="box-responsive">
<button mat-button routerLink="/vacantes">Vacantes</button>
<button mat-button routerLink="/perfil">Mi Cuenta</button>
@if (entorno.esModoKiosko()) {
<span class="espaciador"></span>
<button mat-icon-button color="warn" (click)="confirmarApagado()" title="Apagar Sistema">
<mat-icon>power_settings_new</mat-icon>
</button>
<button mat-icon-button (click)="abrirConfiguracionWifi()">
<mat-icon>wifi</mat-icon>
</button>
}
</nav>
Para que tu Angular tenga control total del PC, estos serían los 5 métodos que yo programaría en Rust:
ejecutar_comando(comando: String): El más importante. Permite que Angular mande cualquier instrucción al Shell de FreeBSD (instalar paquetes, apagar el PC, mover archivos).
leer_archivo(ruta: String): Para que Angular pueda mostrar logs, leer la temperatura del procesador Intel o ver configuraciones.
gestionar_tunel(accion: bool, puerto: i32, llave: String): El método que abre o cierra el SSH para tu soporte técnico.
obtener_info_hardware(): Para que Angular sepa el ID único, la MAC y el estado de la batería/disco.
escribir_archivo(ruta: String, contenido: String): Para guardar configuraciones locales o notas del técnico.
// ==========================================================
// LIDEROS - NÚCLEO SOBERANO (CONVENCIÓN LIDERMODEL30)
// ==========================================================
use warp::Filter;
use std::process::Command;
use std::fs;
use serde::Deserialize;
// Estructuras para recibir datos desde Angular (JSON)
#[derive(Deserialize)]
struct ParamsFile { ruta: String, contenido: Option<String> }
#[derive(Deserialize)]
struct ParamsSoporte { activar: bool, puerto: i32, llave: String }
#[tokio::main]
async fn main() {
let cors = warp::cors()
.allow_any_origin()
.allow_methods(vec!["GET", "POST", "OPTIONS"]);
// --- LOS 5 MÉTODOS MAESTROS DEFINITIVOS ---
// 1. EJECUTAR (sh -c)
let ruta_ejecutar = warp::path("ejecutar")
.and(warp::query::<std::collections::HashMap<String, String>>())
.map(|p| {
let cmd = p.get("cmd").cloned().unwrap_or_default();
ejecutar_comando(cmd)
});
// 2. LEER
let ruta_leer = warp::path("leer")
.and(warp::query::<ParamsFile>())
.map(|p: ParamsFile| {
leer_archivo(p.ruta)
});
// 3. ESCRIBIR
let ruta_escribir = warp::path("escribir")
.and(warp::body::json())
.map(|p: ParamsFile| {
escribir_archivo(p.ruta, p.contenido.unwrap_or_default()).to_string()
});
// 4. IDENTIFICAR
let ruta_id = warp::path("id").map(|| {
obtener_id_hardware()
});
// 5. SOPORTE
let ruta_soporte = warp::path("soporte")
.and(warp::body::json())
.map(|p: ParamsSoporte| {
gestionar_soporte(p.activar, p.puerto, p.llave).to_string()
});
let rutas = ruta_ejecutar.or(ruta_leer).or(ruta_escribir).or(ruta_id).or(ruta_soporte).with(cors);
println!("========================================");
println!(" lideros v1.0.0 - NÚCLEO ACTIVO ");
println!(" SDL Investment S.A.S. - 2026 ");
println!("========================================");
warp::serve(rutas).run(([127, 0, 0, 1], 8888)).await;
}
// --- IMPLEMENTACIÓN DE TUS MÉTODOS MAESTROS ---
pub fn ejecutar_comando(comando: String) -> String {
let salida = Command::new("sh").arg("-c").arg(&comando).output();
match salida {
Ok(s) => String::from_utf8_lossy(&s.stdout).to_string(),
Err(e) => format!("Error L10: {}", e),
}
}
pub fn leer_archivo(ruta: String) -> String {
fs::read_to_string(ruta).unwrap_or_else(|_| "ERROR_LECTURA".into())
}
pub fn escribir_archivo(ruta: String, contenido: String) -> bool {
fs::write(ruta, contenido).is_ok()
}
pub fn obtener_id_hardware() -> String {
Command::new("kenv").arg("smbios.system.uuid").output()
.map(|o| String::from_utf8_lossy(&o.stdout).trim().to_string())
.unwrap_or_else(|_| "ID_DESCONOCIDO".into())
}
pub fn gestionar_soporte(activar: bool, puerto: i32, llave: String) -> bool {
if activar {
fs::write("/tmp/lider_key", llave).ok();
Command::new("chmod").args(["600", "/tmp/lider_key"]).status().ok();
Command::new("ssh").args([
"-i", "/tmp/lider_key", "-N", "-R",
&format!("{}:localhost:22", puerto),
"lider@tu-servidor.com", "-o", "StrictHostKeyChecking=no"
]).spawn().is_ok()
} else {
Command::new("pkill").arg("-f").arg("ssh -N -R").status().is_ok()
}
}
# Asegúrate de estar en la raíz de tu proyecto
cargo new lideros
Configuracion .toml
[package]
name = "lideros"
version = "1.0.0"
edition = "2021"
authors = ["Edgar Alexander Sandoval Cabrera"]
[dependencies]
# Tokio es el motor asíncrono para que el sistema sea rápido
tokio = { version = "1", features = ["full"] }
# Warp es el framework de red más ligero para los 5 métodos
warp = "0.3"
# Serde sirve para que Rust y Angular hablen el mismo idioma (JSON)
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
Aquí construyes el sistema, no es para usuarios finales.
Google Cloud VM (FreeBSD)
└── Instalas todo
└── Configuras kiosko
└── Pruebas que funciona
└── Exportas como ISO
Un archivo .iso que cualquiera graba en USB y instala en cualquier PC.
ISO
└── FreeBSD base
└── WebKit2 + Xorg
└── autossh
└── binario lideros
└── autologin configurado
└── kiosko arranca solo
└── abre https://tu-app.web.app
Solo graba USB, instala, enciende. No toca nada más.
PC usuario
└── Instala ISO
└── Enciende
└── Ve tu app Angular directamente