Visión general

El systemcontroller es el servicio central del backend de Town OS. Está construido sobre Echo v5 y en producción escucha en el puerto 5309 (TCP) o en un socket de dominio Unix. Todos los cuerpos de petición y respuesta usan JSON. Los errores siguen el RFC 9457 (application/problem+json).

CORS está habilitado para desarrollo. En producción, la API se sirve desde el mismo origen que la interfaz.

Autenticación

Autentícate llamando a POST /account/authenticate con un usuario y una contraseña. La respuesta trae un token Bearer. Inclúyelo en las peticiones siguientes:

Authorization: Bearer <token>

Las sesiones caducan a los 7 días de inactividad. Hay cinco niveles de autorización:

NivelDescripción
PúblicoNo requiere token.
AutenticadoCualquier token de sesión válido.
AdministradorToken de sesión de una cuenta de administrador.
ConcesiónUna concesión concreta en la cuenta deja pasar a quien no es administrador. Los extremos de almacenamiento de objetos toman la concesión de almacenamiento de objetos; el enrolamiento de pares toma la de wireguard, y el ámbito por red y la pertenencia de cada par los aplica el propio manejador.
LocalhostLas peticiones desde loopback pasan sin autenticarse — poder llegar a loopback ya significa estar en el ordenador — y cualquier otro origen necesita el nivel que aparece junto a la insignia. Lo usan los extremos de unidades y de registros de systemd, que lee el propio instrumental del controlador.

Crear una partición de almacenamiento de objetos queda reservado a los administradores aunque los extremos de dentro de una partición no lo estén: una partición es la raíz de un árbol de permisos y reserva un subvolumen btrfs con cuota, así que la concesión te admite a los usuarios que hay dentro de una partición, no a la decisión de que deba existir.

Paginación

Todos los endpoints de listado aceptan estos parámetros de consulta y devuelven una envoltura común:

ParámetroTipoDescripción
sort_bystringNombre del campo por el que ordenar.
sort_orderstringasc o desc.
limitintTamaño de página (20 por omisión).
offsetintDesplazamiento de paginación.
searchstringCoincidencia de subcadena, sin distinguir mayúsculas, sobre todos los campos de texto.

Envoltura de la respuesta

{
  "entries":     [...],
  "has_more":    true,
  "total_pages": 5,
  "total_count": 97
}

Estado

GET /status/ping Público

Comprobación de salud y visión general del sistema. Quien llame sin autenticarse recibe una respuesta mínima con status y needs_setup. Quien llame autenticado recibe los datos completos del panel, incluyendo el número de sistemas de ficheros, los recuentos de paquetes, el resumen del estado de las unidades, el uso de disco, la IP externa e interna y si hay actualizaciones disponibles.

Cuentas

POST /account/authenticate Público

Autentica con usuario y contraseña. Devuelve un token de sesión y el objeto de la cuenta.

CampoTipoDescripción
usernamestringObligatorio. Usuario de la cuenta.
passwordstringObligatorio. Contraseña de la cuenta.
POST /account/create Público / Administrador

Crea una cuenta nueva. En modo de arranque inicial (cuando no existe ninguna cuenta de administrador habilitada), este endpoint es público. Si no, requiere autenticación de administrador. La primera cuenta creada se convierte en la administradora. La contraseña debe tener al menos 8 caracteres. El correo, el teléfono y el nombre real son obligatorios.

CampoTipoDescripción
usernamestringObligatorio.
passwordstringObligatorio. Mínimo 8 caracteres.
emailstringObligatorio.
phonestringObligatorio.
real_namestringObligatorio.
adminbooleanSi la cuenta tiene privilegios de administrador.
POST /account Autenticado

Obtiene una sola cuenta por su usuario. Cuerpo de la petición: {"username": "alice"}.

GET /account Autenticado

Lista todas las cuentas. Admite parámetros de paginación.

POST /account/update Autenticado

Actualiza campos de una cuenta. Envía username para identificarla y un objeto fields con cualquier combinación de password, email, phone, real_name y admin. Solo se cambian los campos que envíes.

GET /account/me Autenticado

Devuelve el usuario asociado al token de la cabecera Authorization.

GET /account/sessions Autenticado

Lista todas las sesiones activas del usuario autenticado. Cada sesión incluye su ID, el usuario, la hora de creación y la del último uso.

POST /account/session/revoke Autenticado

Revoca una sesión por su ID. Cuerpo de la petición: {"session_id": "..."}.

POST /account/disable Administrador

Deshabilita una cuenta. Cuerpo de la petición: {"username": "bob"}.

POST /account/enable Administrador

Vuelve a habilitar una cuenta deshabilitada. Cuerpo de la petición: {"username": "bob"}.

Almacenamiento

POST /storage Autenticado

Lista los sistemas de ficheros. Además de los parámetros de paginación, acepta en el cuerpo un name opcional (filtro por prefijo) y un state (user, installed o uninstalled).

POST /storage/create Autenticado

Crea un subvolumen btrfs nuevo. Envía name y, si quieres, quota (en bytes). Si la cuota es 0 o se omite, se usa el valor predeterminado del sistema (50 GB). Los nombres reservados (installed, uninstalled, archives) se rechazan.

POST /storage/modify Autenticado

Modifica un sistema de ficheros existente. Envía name para identificarlo y un objeto filesystem con el name y/o la quota actualizados.

POST /storage/remove Autenticado

Elimina un sistema de ficheros. Cuerpo de la petición: {"name": "mydata"}.

POST /storage/upload-archive Administrador

Sube y descomprime un fichero dentro de un subvolumen de destino. Acepta multipart/form-data con un campo subvolume y un fichero archive. Admite .tar.gz, .tgz, .tar.bz2, .tbz2, .tar.xz, .txz, .tar, .zip y .7z.

CampoTipoDescripción
subvolumestringObligatorio. Ruta del subvolumen de destino.
archivefileObligatorio. Fichero comprimido que se va a subir.
subpathstringOpcional. Ruta relativa dentro del volumen donde descomprimir; se crea si hace falta.
stop_servicestringOpcional. Nombre de la unidad de systemd que se detiene antes de descomprimir y se reinicia al terminar.
AjustePor omisiónDescripción
max_archive_size1 GBTamaño máximo de subida.
archive_unpack_timeout600 segundosTiempo máximo para descomprimir.
POST /storage/download-archive Administrador

Descarga un fichero comprimido con el contenido de un subvolumen. Devuelve un fichero transmitido en el formato solicitado.

CampoTipoDescripción
subvolumestringObligatorio. Ruta del subvolumen de origen.
pathsstring[]Opcional. Array de rutas concretas dentro del subvolumen que se van a incluir.
stop_servicestringOpcional. Nombre de la unidad de systemd que se detiene mientras se comprime y se reinicia después.
formatstringOpcional. Formato de compresión: tar.gz (por omisión), tar.bz2 o tar.xz.
filenamestringOpcional. Nombre base personalizado para el fichero descargado. El servidor le añade la extensión que corresponda. Por omisión, download.
POST /storage/package-volumes Autenticado

Lista los volúmenes de los paquetes agrupados por paquete, con la opción de incluir los volúmenes desinstalados.

POST /storage/remove-package-volume Administrador

Borra un volumen concreto de un paquete usando su nombre interno.

POST /storage/remove-package-volume-group Administrador

Borra en una sola llamada todos los volúmenes que pertenecen a un paquete, en lugar de quitarlos uno a uno por nombre interno.

Repositorios

GET /repository Autenticado

Lista todos los repositorios de paquetes configurados, con su nombre, su URL y cualquier estado de error. Admite parámetros de paginación.

POST /repository/add Autenticado

Añade un repositorio de paquetes nuevo. Dispara una actualización inmediata.

CampoTipoDescripción
namestringObligatorio. Nombre visible del repositorio.
urlstringObligatorio. URL de git del repositorio.
usernamestringOpcional. Usuario de autenticación para repositorios privados.
passwordstringOpcional. Contraseña de autenticación para repositorios privados.
POST /repository/remove Autenticado

Elimina un repositorio por su nombre. Dispara una actualización inmediata. Cuerpo de la petición: {"name": "my-repo"}.

POST /repository/move Administrador

Reordena un repositorio a una posición nueva (empezando en cero). Los repositorios posteriores prevalecen sobre los anteriores cuando los nombres de paquete chocan. Cuerpo de la petición: {"name": "my-repo", "position": 0}.

POST /repository/refresh Autenticado

Fuerza una actualización inmediata de los metadatos de todos los repositorios. Devuelve un cuerpo vacío si sale bien, o un objeto JSON que asocia nombres de repositorio a cadenas de error si alguno falla.

Paquetes

GET /packages Autenticado

Lista todos los paquetes disponibles en todos los repositorios. Cada entrada incluye el repositorio, el nombre, la versión, la descripción, las etiquetas supplies, el estado de instalación y si hay una actualización disponible. Admite parámetros de paginación.

GET /packages/by-repo Autenticado

Lista los paquetes agrupados por repositorio. Acepta un parámetro de consulta search opcional. Devuelve un array de grupos {"repo": "...", "packages": [...]}.

GET /packages/installed Autenticado

Lista los identificadores de los paquetes instalados. Admite parámetros de paginación.

POST /packages/installed/info Autenticado

Obtiene información detallada de un paquete instalado. Envía repo, name y version. Devuelve las preguntas, las respuestas del usuario, las notas y los tipos de nota.

POST /packages/responses Autenticado

Obtiene las respuestas guardadas de un paquete instalado. Envía repo, name y version. Devuelve un mapa de clave y valor.

POST /packages/versions Autenticado

Lista las versiones disponibles de un paquete. Cuerpo de la petición: {"name": "nginx"}. Devuelve un array de cadenas con los identificadores de versión.

POST /packages/children Autenticado

Lista los paquetes hijos. Envía repo y name. Devuelve un array de cadenas.

POST /packages/questions Administrador

Obtiene las preguntas de instalación de un paquete. Cuerpo de la petición: {"name": "nginx"}. Devuelve un mapa de clave de pregunta a {"query": "...", "type": "..."}.

POST /packages/questions/identity Administrador

Obtiene las preguntas de una versión concreta de un paquete. Envía repo, name y version.

POST /packages/oauth/start Administrador

Inicia el flujo de dispositivo OAuth de una pregunta oauth. Envía repo, name, version y question. El controlador del sistema ejecuta el paso inicial del flujo contra el proveedor y devuelve flow_id, approve_url (ábrela en el navegador del usuario), un user_code opcional y interval_ms — cada cuánto sondear.

Las URL del proveedor vienen del paquete, no de Town OS, así que se comprueban antes de llamarlas: solo https, y nunca una dirección de la propia red del anfitrión.

POST /packages/oauth/poll Administrador

Sondea un flujo iniciado arriba. Envía flow_id. Devuelve status: pending mientras el usuario no haya aprobado, approved junto con el token, o expired una vez que el flujo ha caducado o su token ya se ha recogido — cada flujo es de un solo uso. El token después se envía como respuesta de esa pregunta a /packages/install, igual que una respuesta escrita a mano.

POST /packages/install-preview Administrador

Muestra qué hará una instalación antes de comprometerse. Envía repo, name y version. Devuelve los detalles de los volúmenes, las asignaciones de puertos, el uso de disco, la información de cuotas, la versión de origen de la actualización y un resumen legible.

POST /packages/install Administrador

Instala un paquete.

CampoTipoDescripción
repostringObligatorio. Nombre del repositorio.
namestringObligatorio. Nombre del paquete.
versionstringObligatorio. Versión que se va a instalar.
responsesobjectObligatorio. Respuestas de clave y valor a las preguntas de instalación.
reuse_volumesbooleanReutilizar los volúmenes de datos de una instalación anterior.
import_from_versionstringVersión desde la que importar los volúmenes al actualizar.
POST /packages/uninstall Administrador

Desinstala un paquete. Envía repo, name, version y, si quieres borrar los datos asociados, purge_volumes (booleano).

POST /packages/disable Administrador

Deshabilita un paquete instalado (detiene su servicio). Envía repo y name.

POST /packages/enable Administrador

Vuelve a habilitar un paquete deshabilitado (arranca su servicio). Envía repo y name.

POST /packages/purge-volumes Administrador

Borra todos los volúmenes de datos de un paquete instalado. Envía repo y name.

POST /packages/uninstalled-volumes Administrador

Comprueba si un paquete tiene volúmenes sobrantes de una instalación anterior. Envía repo y name. Devuelve has_uninstalled_volumes, uninstalled_versions e installed_versions.

POST /packages/purge-uninstalled-volumes Administrador

Borra los volúmenes que quedaron de versiones desinstaladas anteriormente. Envía repo y name.

GET /packages/upgrades Autenticado

Lista las actualizaciones disponibles de los paquetes instalados. Cada entrada incluye installed_version, latest_version y si la definición del paquete ha changed.

POST /packages/upgrades/dismiss Administrador

Descarta las notificaciones de actualización actuales. Envía un objeto JSON vacío.

POST /packages/manifest Autenticado

Devuelve la definición YAML en bruto del paquete. Envía repo, name y version. Devuelve el contenido del fichero con Content-Type: text/x-yaml. Devuelve 404 si el fichero del paquete no existe.

GET /packages/featured Autenticado

Lista los paquetes destacados de todos los repositorios.

POST /packages/last-responses Autenticado

Recupera las últimas respuestas en caché de un paquete. Envía repo y name. Devuelve las respuestas guardadas de una desinstalación previa, para reutilizarlas al reinstalar.

POST /packages/clear-last-responses Administrador

Borra el fichero de últimas respuestas en caché de un paquete. Envía repo y name.

POST /packages/rebuild-git Administrador

Trae los últimos cambios de los volúmenes inicializados por git de un paquete instalado y reinicia el servicio que depende de ellos. Envía repo, name y version. Las variables de plantilla se vuelven a evaluar con las respuestas guardadas antes de recompilar.

Systemd

GET /systemd/units Autenticado / Localhost

Lista las unidades de systemd que gestiona Town OS. Cada entrada incluye el nombre de la unidad, la descripción, los estados load/active/sub, el identificador y la descripción del paquete asociado, y un indicador de fallo. Admite parámetros de paginación.

GET /systemd/units-tree Autenticado / Localhost

Las mismas unidades que el listado plano, pero agrupadas en un árbol de dependencias: los paquetes raíz arriba y las dependencias anidadas bajo su padre, hasta abajo — la misma forma que usa /storage/package-volumes. Las filas llevan los mismos datos de estado que devuelve el extremo plano, así que un cliente no necesita una segunda petición para enriquecerlas.

POST /systemd/status Administrador

Controla una unidad de systemd. Envía name (el nombre de la unidad) y action (start, stop, restart, enable o disable).

POST /systemd/status/tree Administrador

Aplica una acción a un paquete y a todo su árbol de dependencias en una sola llamada, en orden de dependencia. Aquí se rechazan enable y disable por la misma razón que en /systemd/status: encadenar un enable habilitaría dos veces las dependencias que ya están enlazadas a través de su padre.

GET /systemd/logs Administrador / Localhost

Transmite las entradas del journal de una unidad en tiempo real mediante Server-Sent Events. Pasa el parámetro de consulta unit; si va vacío o vale __system__, devuelve los registros de todo el sistema. Cada evento SSE contiene una entrada del journal codificada en JSON, con campos como Message, Priority, RealtimeTimestamp y SystemdUnit.

GET /systemd/logs/tail Administrador / Localhost

Trae una página de entradas del journal, con paginación basada en cursores y filtrado.

ParámetroTipoDescripción
unitstringNombre de la unidad de systemd. Vacío o __system__ para los registros de todo el sistema.
linesintCantidad de entradas que devolver (100 por omisión).
beforestringCursor — devuelve las entradas anteriores a esa posición.
afterstringCursor — devuelve las entradas posteriores a esa posición.
grepstringFiltro de subcadena sobre el texto del mensaje, sin distinguir mayúsculas.
sinceintMarca de tiempo Unix — devuelve las entradas desde ese momento en adelante.
untilintMarca de tiempo Unix — deja de recolectar en ese momento.
priorityintFiltro por severidad de syslog (0 = sin filtro).

Devuelve entries, cursor (la primera entrada) y end_cursor (la última) para seguir paginando.

GET /systemd/logs/tree Administrador / Localhost

El equivalente en árbol de /systemd/logs: un solo flujo de Server-Sent Events con el registro de un paquete y de todas las unidades por debajo de él, entremezclados en orden cronológico. Una raíz desconocida sin registro de instalación recibe igualmente un flujo abierto y sin entradas en lugar de un 404, así que el visor de registros funciona igual para una unidad suelta y para todo un árbol.

GET /systemd/logs/tree/tail Administrador / Localhost

La forma paginada del registro entremezclado del árbol, que toma los mismos parámetros de cursor, filtro y rango de tiempo que /systemd/logs/tail.

Ajustes

GET /settings Administrador

Obtiene todos los ajustes como un objeto de clave y valor.

POST /settings/get Administrador

Obtiene un solo ajuste. Cuerpo de la petición: {"key": "default_quota"}. Devuelve key y value.

POST /settings/set Administrador

Establece el valor de un ajuste. Cuerpo de la petición: {"key": "default_quota", "value": "107374182400"}.

Ajustes predeterminados

ClavePor omisiónDescripción
default_quota53687091200 (50 GB)Cuota predeterminada de los sistemas de ficheros nuevos.
max_archive_size1073741824 (1 GB)Tamaño máximo de fichero comprimido que se puede subir.
archive_unpack_timeout600 (segundos)Tiempo máximo para descomprimir un fichero.
localeen-USIdioma de todo el sistema para la internacionalización.
proton_imagequay.io/town/proton:latestImagen de contenedor del ejecutor de Proton/Wine.
dns_tldhomeDominio de nivel superior para la resolución DNS local.

Registro de auditoría

POST /audit/log Administrador

Lista las entradas del registro de auditoría. Todos los campos del cuerpo son opcionales.

CampoTipoDescripción
before_idintPaginación por conjunto de claves — devuelve las entradas con ID menor a este.
accountstringFiltrar por el usuario de la cuenta.
sort_bystringCampo por el que ordenar.
sort_orderstringasc o desc.
limitintTamaño de página.
offsetintDesplazamiento de paginación.
searchstringFiltro de búsqueda.

Cada entrada de auditoría contiene id, account, action, path, detail, success, error y created_at. Entre las acciones auditadas están: autenticarse, crear/actualizar/deshabilitar una cuenta, revocar una sesión, instalar/desinstalar/deshabilitar/habilitar un paquete, crear/modificar/eliminar un sistema de ficheros, añadir/eliminar/mover/actualizar un repositorio, subir/descargar un fichero comprimido, actualizar un ajuste, descartar actualizaciones y purgar volúmenes.

Páginas

Alojamiento de sitios estáticos con tres tipos de origen de contenido: subir un fichero comprimido, imágenes de contenedor y repositorios git. Los usuarios asignan un dominio y el sistema sirve el contenido desde un contenedor de Caddy. Todos los endpoints que modifican algo requieren autenticación de administrador; el de listado requiere autenticación normal.

GET /pages Autenticado

Lista todas las páginas, con ordenación, búsqueda y paginación. Se puede ordenar por nombre, URL del repositorio, rama, dominio, tipo de origen, estado y marcas de tiempo.

POST /pages/create Administrador

Crea una página nueva. Acepta el nombre, el tipo de origen (archive, container_image o git), la URL del repositorio, la rama, el dominio, la imagen de contenedor y el directorio dentro de la imagen. El tipo de origen es archive por omisión. Las páginas de git y de imagen de contenedor se aprovisionan de forma asíncrona.

POST /pages/upload Administrador

Sube un fichero tar con el contenido de una página de tipo fichero. Acepta un formulario multiparte con name y el fichero archive. Solo es válido para páginas con tipo de origen archive; para otros tipos devuelve 400.

POST /pages/update Administrador

Actualización parcial de la URL del repositorio, la rama, el dominio, el tipo de origen, la imagen de contenedor o el directorio de la imagen de una página. Solo se cambian los campos que envíes.

POST /pages/remove Administrador

Borra una página de la base de datos, quita el enlace simbólico del webroot y elimina el subvolumen btrfs.

POST /pages/rebuild Administrador

Recompila el contenido de una página desde su origen. Las páginas de git traen los últimos cambios; las de imagen de contenedor vuelven a extraer desde la imagen. Las páginas de fichero devuelven 400 (vuelve a subirlo con /pages/upload).

Redes

Una red es una superposición WireGuard con nombre, emparejada con un TLD de DNS. Los paquetes se instalan en una red, los pares se unen a ella y el TLD es lo que divide quién puede resolver qué. Los nombres de red son seguros como etiqueta DNS y están limitados a 32 caracteres, porque se reutilizan como sufijos de interfaz WireGuard y como nombres de unidad de systemd.

La red home siempre existe — se siembra junto con la propia base de datos, no se crea al arrancar — y es especial de tres maneras: no se puede eliminar ni crear una segunda vez, es solo de DNS (sin interfaz WireGuard, sin subred, sin pares), y el enrolamiento de pares en ella se rechaza con un 400. Toda cuenta pertenece a la red home, así que aceptar el enrolamiento ahí haría que la mera pertenencia fuera una forma de entrar en un túnel — y el par guardado describiría un túnel que no existe.

Deshabilitar una red tira abajo únicamente el transporte: la interfaz WireGuard no se levanta, lo que corta el acceso remoto, mientras la resolución DNS local y los contenedores siguen ejecutándose.

GET /networks Autenticado

Lista las redes. Cada entrada lleva el nombre, el TLD, la subred, la dirección del propio ordenador en la superposición, la clave pública, el puerto de escucha y el indicador de habilitación. La clave privada nunca se serializa.

POST /networks/create Administrador

Crea una red. La subred se deriva de forma determinista de una semilla de identidad del ordenador y del nombre de la red, tomada de 10.64.0.0/10 para no chocar con los rangos que reparten los routers domésticos. Derivarla de la identidad del ordenador hace que dos ordenadores Town OS que sirvan pares elijan subredes distintas, así que un dispositivo que se une a los dos nunca ve una colisión. Crear home devuelve 409 por la comprobación de colisión de TLD.

POST /networks/remove Administrador

Elimina una red. Rechaza la red home.

POST /networks/enable Administrador

Levanta el transporte WireGuard de la red.

POST /networks/disable Administrador

Tira abajo el transporte dejando el DNS y los contenedores en marcha.

Pares

GET /networks/peers Autenticado

Lista los pares enrolados en una red.

GET /networks/peers/connected Administrador

Lista los pares conectados en este momento, a diferencia de los que solo están enrolados.

POST /networks/peers/add Concesión

Enrola un par. La concesión de wireguard es lo que deja pasar a quien no es administrador; el ámbito por red y la pertenencia de cada par los aplica el manejador. Devuelve 400 para la red home, que es solo de DNS.

POST /networks/peers/refresh Concesión

Renueva el enrolamiento de un par antes de que caduque su TTL. Los enrolamientos tienen vigencia y un recolector retira los que vencen.

POST /networks/peers/remove Administrador

Retira un par de una red.

La autoridad certificadora local

GET /tls/ca.crt Público

Descarga en formato PEM la autoridad certificadora local del ordenador. Town OS emite sus propios certificados para los nombres de los paquetes, así que confiar en este certificado es lo que hace que esos nombres funcionen en un navegador sin advertencias. Es público a propósito: un certificado de CA es justo la parte que se reparte, y un cliente lo necesita antes de tener cualquier credencial con la que autenticarse.

Almacenamiento de objetos

Town OS incorpora almacenamiento de objetos mediante gfeh. Una partición es un subvolumen btrfs, un proceso gfehd, un socket de administración y su propio conjunto de usuarios. Hay exactamente una partición por red de Town OS, así que el espacio de nombres del almacenamiento de objetos se divide por la misma frontera que divide el DNS y WireGuard: un principal, una concesión o una exposición en la partición office no significan nada en home.

Cada partición sirve cuatro vistas HTTP en puertos de contenedor fijos — S3 en el 9000, HTTP en el 9001, unidad en el 9002 e IPFS en el 9003 — y no publica ningún puerto del anfitrión. Eso es justo lo que vuelve seguros los puertos fijos: cada partición tiene su propio espacio de nombres de red y el ingress llega a ella por el nombre del contenedor, igual que llega a un paquete, así que dos particiones sirviendo S3 en el 9000 no pueden colisionar.

Particiones

Estas cuatro rutas existen aparte de /storage/* porque /storage/create reescribe todo nombre que se le envía a user/<nombre> sin excepción, y por eso no puede producir un volumen bajo el prefijo gfeh/. Sus formas en el cable son un contrato publicado que el cliente de gfeh interpreta, no un detalle interno.

Hay dos detalles que sostienen peso. El prefijo es asimétrico: las peticiones llevan el nombre escueto y las respuestas llevan gfeh/<nombre>, porque el prefijo es un artefacto del espacio de nombres de Town OS y no parte de la identidad de la partición. Y el listado devuelve un array JSON escueto, no un sobre paginado, a diferencia de todos los demás extremos de listado de esta API: el cliente de gfeh deserializa una lista simple directamente y una envoltura de paginación no se puede decodificar.

RutaAutorizaciónPeticiónRespuesta
POST /gfeh/partitions/createAdministradorname (sin prefijo), quotaFilesystem, nombre gfeh/<n>
POST /gfeh/partitions/modifyAdministradorname, quotaFilesystem
POST /gfeh/partitions/removeAdministradorname200, vacío
POST /gfeh/partitionsAutenticadosin cuerpoarray simple de Filesystem

Códigos de estado sobre los que un cliente debe ramificar: 409 ya existe (el aprovisionamiento de gfeh es un crear-o-redimensionar y distingue ambos casos por este estado), 404 no existe, 400 nombre inválido, 403 no es administrador. Un nombre que lleva un separador de rutas se rechaza aquí porque gfehd lo rechaza en su propia frontera — no ponerse de acuerdo sobre qué es un nombre de partición legal dejaría que un nombre como ../user/algo apuntara a un volumen fuera de la raíz del almacenamiento de objetos.

Crear una partición es solo de administrador y no se alcanza con una concesión: es la raíz de un árbol de permisos y reserva un subvolumen btrfs con cuota, así que a una cuenta con concesión se le niega antes de que se ejecute ningún manejador.

Exploración

GET /gfeh Autenticado

El panorama del almacenamiento de objetos: qué particiones existen y en qué estado están.

Principales

Los usuarios de una partición. Crear uno toma un nombre, un padre y un techo — y ninguna contraseña, que es la razón por la que la interfaz nunca la pide. El techo sigue la regla de proyección de gfeh: all para un administrador de Town OS, lectura/escritura en los demás casos.

GET /gfeh/principals Autenticado

Lista los principales de una partición.

POST /gfeh/principals/add Concesión

Crea un principal bajo un padre, con un techo.

POST /gfeh/principals/remove Concesión

Elimina un principal.

Concesiones

Las listas de control de acceso. gfehd recorta la concesión al techo del principal, así que un cliente debe mostrar los permisos que han vuelto y no los que envió: un administrador tiene que poder ver que una concesión se ha estrechado.

GET /gfeh/grants Autenticado

Lista las concesiones, opcionalmente las de un solo principal.

POST /gfeh/grants/add Concesión

Da acceso a un principal. La respuesta lleva los permisos tal como han quedado guardados.

POST /gfeh/grants/revoke Concesión

Revoca una concesión por id.

Exposiciones

Un enlace de fichero publicado, servido en /f/<token>.

GET /gfeh/exposures Autenticado

Lista los enlaces publicados de una partición.

POST /gfeh/exposures/withdraw Concesión

Retira un enlace publicado por su token, para que la URL deje de resolver.

DNS

Resolutor DNS local integrado, impulsado por un contenedor rolodex-dns. Gestiona los ficheros de zona y los registros de los paquetes instalados, y ofrece resolución de nombres local a través de una interfaz gRPC sobre socket Unix.

GET /dns/status Autenticado

Devuelve el estado del DNS, incluyendo si está habilitado, si está en marcha, el TLD y el número de registros.

GET /dns/records Autenticado

Lista todos los registros DNS.

POST /dns/records/add Administrador

Añade un registro DNS. Acepta el nombre, el tipo de registro, el valor y el TTL.

POST /dns/records/remove Administrador

Elimina un registro DNS por nombre y tipo.

GET /dns/tld Autenticado

Obtiene el ajuste actual del dominio de nivel superior.

POST /dns/tld Administrador

Establece el TLD. Cambia el TLD existente y vuelve a registrar todos los paquetes instalados.

POST /dns/setup Administrador

Inicializa o reinicia el servidor DNS y registra todos los paquetes instalados.

Listas de bloqueo

Son dos listas independientes. La DNSBL se basa en suscripciones — listas de bloqueo externas que rolodex descarga y aplica — con una lista de permitidos que exime a los nombres que quieres que se resuelvan sin importar lo que diga una lista externa. La lista de bloqueo local (RBL) es la lista propia del ordenador, que se edita entrada por entrada.

GET /dns/dnsbl Autenticado

Obtiene la configuración de DNSBL: a qué listas de bloqueo externas se está suscrito y cómo se aplican.

POST /dns/dnsbl Administrador

Sustituye la configuración de DNSBL.

GET /dns/dnsbl/allowlist Autenticado

Lista los nombres eximidos de las listas de bloqueo suscritas.

POST /dns/dnsbl/allowlist/add Administrador

Exime un nombre de las listas de bloqueo suscritas.

POST /dns/dnsbl/allowlist/remove Administrador

Quita una entrada de la lista de permitidos, dejando que las listas suscritas vuelvan a aplicarse a ese nombre.

GET /dns/rbl/local Autenticado

Lista las entradas de la lista de bloqueo propia del ordenador.

POST /dns/rbl/local/add Administrador

Añade un nombre a la lista de bloqueo local.

POST /dns/rbl/local/remove Administrador

Quita un nombre de la lista de bloqueo local.

Publicación de servicios en DNS

GET /dns/services Autenticado

Lista los servicios instalados junto con si cada uno publica o no un nombre en DNS.

POST /dns/services/set Administrador

Activa o desactiva la publicación en DNS de un servicio, para que un paquete pueda ejecutarse sin reclamar un nombre en la red.

Monitorización

Conjunto integrado de Prometheus, Node Exporter y Grafana para la monitorización del sistema. Todo se ejecuta como contenedores de podman supervisados por systemd con Restart=always.

GET /monitoring/status Autenticado

Devuelve el estado del contenedor (nombre, imagen, si está en marcha, puerto) de cada servicio de monitorización. Devuelve {"status": "disabled"} cuando la monitorización no está configurada.

Cómo se llega a los datos del panel

No hay ningún proxy inverso a través del controlador del sistema. Los datos de monitorización se sirven en su propio puerto dedicado, el 5308, y el navegador habla directamente con ese puerto; el puerto del controlador (5309) solo lleva /monitoring/status. Lo que escucha en el 5308 depende del backend configurado:

  • Modo uPlot (el predeterminado) — un reenviador socat expone la API HTTP de Prometheus en el 5308, y la interfaz consulta /api/v1/query_range directamente y dibuja las gráficas ella misma.
  • Modo Grafana — Grafana escucha directamente en el 5308 mediante una asignación de puertos de podman, y la interfaz lo incrusta en un iframe.

TOWN_OS_MONITORING_PORT reubica el puerto del panel; TOWN_OS_PROMETHEUS_PORT y TOWN_OS_NODE_EXPORTER_PORT hacen lo mismo con los dos puertos de loopback.

Servicios del sistema

Los servicios del sistema son contenedores de infraestructura gestionados por systemd (distintos de los servicios de los paquetes que instala el usuario). Usan el prefijo de nombre de unidad town-os-system--.

GET /system-services Público / Autenticado

Lista los servicios del sistema con el estado de sus unidades en vivo. Accesible desde el propio equipo sin autenticación. Cada entrada incluye la clave, el nombre visible, la imagen, el puerto y los campos de estado de la unidad de systemd.

POST /system-services/status Administrador

Controla un servicio del sistema. Acepta key y action (start, stop o restart).

POST /system-services/refresh Administrador

Actualiza los ficheros de unidad y el estado de los servicios del sistema.

Idiomas

Información de idiomas del sistema para la internacionalización.

GET /locales Autenticado

Devuelve el idioma actual, la lista de idiomas ya poblados, los idiomas comunes (con sus nombres en su propia escritura) y los idiomas extendidos. Usa códigos de idioma BCP 47.

Imágenes de máquina virtual

Gestión de las imágenes de disco en caché que usan los paquetes de máquina virtual. Las imágenes remotas se descargan y se convierten a formato raw con qemu-img convert; la imagen convertida queda en caché en el subvolumen vm-images.

GET /vm-images Autenticado

Lista las imágenes de disco de máquina virtual en caché. Devuelve el nombre y el tamaño de fichero de cada una.

POST /vm-images/upload Administrador

Descarga una imagen de máquina virtual desde una URL y la convierte a formato raw. Acepta una URL y un nombre opcional. Por omisión, el nombre es el del fichero de la URL con extensión .raw. Las descargas tienen un límite de 30 minutos.

POST /vm-images/delete Administrador

Elimina por nombre una imagen de máquina virtual en caché.

API de administración del almacenamiento de objetos (gfeh)

Todo lo anterior es la API de Town OS, que es la que normalmente debe usar una aplicación. Por debajo de ella, cada partición de gfehd tiene su propia superficie administrativa: JSON sobre HTTP en únicamente su socket Unix, nunca en un puerto.

En esta superficie no hay token ni autenticación. Los permisos del sistema de ficheros sobre el socket son el control de acceso, así que poder llegar a él ya significa ser root en el ordenador. El socket vive en el volumen btrfs porque es el único sistema de ficheros que ven a la vez el contenedor de gfehd y el del controlador del sistema.

LlamadaMétodo y rutaPara qué sirve
HealthGET /v1/healthSeñal de vida, y también la sonda de disponibilidad.
NamesGET /v1/namesLos nombres que esta partición quiere publicar.
ListPrincipalsGET /v1/principalsEl bosque de usuarios de la partición.
CreatePrincipalPOST /v1/principalsToma name, parent, ceiling — y ninguna contraseña.
DeletePrincipalDELETE /v1/principals/<name>Retira un principal.
ListGrantsGET /v1/grants?principal=Las ACL, opcionalmente de un principal.
CreateGrantPOST /v1/grantsDa acceso; se recorta al techo del principal.
RevokeGrantDELETE /v1/grants/<id>Revoca una concesión.
ListExposuresGET /v1/exposuresEnlaces publicados en /f/<token>.
WithdrawExposureDELETE /v1/exposures/<token>Deja de servir un enlace publicado.

gfehd asigna sus errores internos a códigos de estado HTTP — 404, 409, 400 — y el cliente de Go los asigna de vuelta a errores centinela, así que errors.Is funciona al otro lado del socket.

Dónde viven los ficheros de una partición, para una red llamada <network>:

CosaUbicación
Datos de la partición<btrfsBase>/gfeh/<network>, montado en /data/<network>
Configuración<btrfsBase>/gfeh-control/<network>/gfehd.yaml
Socket de administración<btrfsBase>/gfeh-control/<network>/run/admin.sock
Unidadtown-os-system--gfeh-<network>.service

API gRPC de DNS (rolodex)

Los extremos /dns/* anteriores son la vista de DNS que da Town OS. Rolodex en sí se gestiona por gRPC, expuesto en un socket Unix (/var/run/rolodex-dns.sock por omisión) y opcionalmente en TCP. De serie el socket es la única vía de gestión: grpc.tcp_bind viene vacío.

Hay un solo servicio, rolodex_dns.RolodexDnsService, con 74 métodos. Toda ruta es /rolodex_dns.RolodexDnsService/<Método>. Las definiciones completas de los mensajes están en proto/rolodex_dns.proto del repositorio rolodex-dns; las agrupaciones de abajo son lo que esos métodos cubren.

Registros y resolución

MétodoPara qué sirve
AddRecordAñade un registro DNS a la base local.
RemoveRecordRetira registros de la base local.
ListRecordsConsulta la base local con filtros opcionales.
SetForwardersConfigura los reenviadores externos.
SetResolutionMode / GetResolutionModeCambia y lee el modo de resolución en caliente.
GetSearchDomainsLos dominios de búsqueda de una IP cliente.
FlushCacheLimpia las cachés de DNS y de listas de bloqueo.

Zonas autoritativas

MétodoPara qué sirve
AddAuthoritativeZoneDeclara una zona como autoritativa.
RemoveAuthoritativeZoneSaca una zona de la lista de autoritativas.
ListAuthoritativeZonesLista las zonas autoritativas.

Ámbitos de red

Los ámbitos son la forma en que rolodex divide quién resuelve qué, y son a lo que se asignan las redes de Town OS. La asociación de una IP con un ámbito lleva un TTL y hay que refrescarla.

MétodoPara qué sirve
CreateNetworkScope / DeleteNetworkScope / ListNetworkScopesGestiona ámbitos. Borrar uno se lleva sus registros y asociaciones.
JoinNetwork / LeaveNetworkAsocia una IP cliente con un ámbito, o retira la asociación.
GetNetworkAssociationsLee las asociaciones de IP con ámbito.
AddScopedRecord / RemoveScopedRecord / ListScopedRecordsRegistros que solo existen dentro de un ámbito.

TLD de ámbito

Zonas propias de cada red, repartidas entre redes.

MétodoPara qué sirve
AddScopeTld / RemoveScopeTld / ListScopeTldsRegistra un TLD globalmente único como propiedad de un ámbito.
SetScopeTldForwarders / ListScopeTldForwardersLos reenviadores pares del TLD de un ámbito.
ListScopeTldListenersLas escuchas DNS del ingress ligadas a los TLD de un ámbito.

Listas de bloqueo

MétodoPara qué sirve
SetDnsblConfig / GetDnsblConfigLa configuración de la lista de bloqueo por suscripción.
AddDnsblAllowlistEntryExime un nombre y sus subdominios de la comprobación por nombre.
RemoveDnsblAllowlistEntry / ListDnsblAllowlistEntriesGestiona la lista de permitidos.
AddLocalBlocklistEntry / RemoveLocalBlocklistEntry / ListLocalBlocklistEntriesLa lista de bloqueo propia del ordenador.

Transportes cifrados

Cada transporte tiene su par de métodos para fijar y leer. DoH sirve HTTP/2 y, cuando enable_h3 está activado, HTTP/3 en la misma dirección, puerto y certificado.

MétodoPara qué sirve
SetDotConfig / GetDotConfigDNS sobre TLS.
SetDohConfig / GetDohConfigDNS sobre HTTPS, incluido HTTP/3.
SetDoqConfig / GetDoqConfigDNS sobre QUIC.
SetProxyConfig / GetProxyConfigLa configuración del proxy HTTP.

DNSSEC, DANE y ACME

MétodoPara qué sirve
GenerateDnssecKey / ListDnssecKeys / DeleteDnssecKeyMaterial de claves DNSSEC por zona.
GetDsRecordsLos registros DS de una zona.
SignZoneFirma una zona con sus claves DNSSEC.
GenerateTlsaRecord / ListTlsaRecordsRegistros TLSA, generados a partir de un certificado.
GenerateDaneRootCaGenera un certificado de CA raíz para DANE.
EnsureZoneCaAsegura que una zona tenga una CA.
RequestAcmeCert / GetAcmeStatusPide un certificado por ACME DNS-01 y consulta su estado.
CreateEabCredential / RemoveEabCredentialAcuña un External Account Binding (kid más HMAC) acotado a una zona, para el newAccount de un cliente ACME.
ListAcmeAccounts / ListAcmeCertificatesCuentas ACME registradas y certificados emitidos.

DHCP

MétodoPara qué sirve
AddDhcpPool / RemoveDhcpPool / ListDhcpPoolsRangos de direcciones para asignar dentro de un ámbito.
ListDhcpLeases / DeleteDhcpLeaseConcesiones de dirección, borradas por dirección MAC.
SetDhcpCertOption / RemoveDhcpCertOption / ListDhcpCertOptionsUn certificado entregado a los clientes por DHCP para un ámbito.

Diagnóstico y ajuste

MétodoPara qué sirve
GetCacheStats / FlushDnsCacheEstadísticas de caché, y limpieza de la caché de respuestas.
GetQueryLatencyStatsLatencia de las consultas externas.
SetTtlDriftConfig / GetTtlDriftConfigConfiguración de deriva de TTL.
SetTrackedTlds / ListTrackedTldsLa lista de TLD vigilados detrás de las métricas por TLD, guardada y efectiva.
SetDns64Config / GetDns64ConfigConfiguración de DNS64.

Bibliotecas cliente

Town OS trae bibliotecas cliente de Go y de JavaScript que cubren la API completa. Ambos clientes lanzan errores con tipo ante respuestas distintas de 200, usando el detalle de problema del RFC 9457.

Cliente de Go

El cliente de Go vive en src/svc/systemcontroller/client.go e implementa la interfaz Client. Admite tanto conexiones por socket Unix como por HTTP.

// Conectar por socket de dominio Unix (producción)
client := systemcontroller.InitClient("/run/town-os/systemcontroller.sock")

// Conectar por HTTP (desarrollo / pruebas)
client := systemcontroller.FromClient(http.DefaultClient, "http://localhost:5309")

Establece client.Token después de autenticarte. Todos los métodos reciben un context.Context como primer parámetro.

Almacenamiento

MétodoDescripción
CreateFilesystem(ctx, fs)Crea un subvolumen btrfs nuevo.
ModifyFilesystem(ctx, name, fs)Renombra o redimensiona un sistema de ficheros.
RemoveFilesystem(ctx, name)Borra un sistema de ficheros por su nombre.
ListFilesystems(ctx, prefix, state, params)Listado paginado filtrado por prefijo de nombre y por estado ("user", "installed", "uninstalled").

Repositorios

MétodoDescripción
AddRepository(ctx, name, rawURL, username, password)Registra un repositorio de paquetes, con credenciales opcionales.
RemoveRepository(ctx, name)Elimina un repositorio por su nombre.
MoveRepository(ctx, name, position)Cambia la prioridad (0 = la más alta).
RefreshRepositories(ctx)Actualiza todos los metadatos. Devuelve un mapa de errores.
ListRepositories(ctx, params)Listado paginado de repositorios.

Paquetes

MétodoDescripción
ListPackages(ctx, params)Listado paginado de los paquetes disponibles.
ListPackagesByRepo(ctx, params)Paquetes agrupados por repositorio.
ListPackageVersions(ctx, name)Versiones disponibles de un paquete.
GetPackageQuestions(ctx, name)Preguntas de configuración por nombre.
GetPackageQuestionsByIdentity(ctx, repo, name, version)Preguntas de una versión concreta.
ListChildren(ctx, repo, name)Nombres de los paquetes hijos.
InstallPreview(ctx, repo, name, version)Vista previa de volúmenes y puertos sin instalar.
InstallPackage(ctx, name, version, responses, reuseVolumes, importFromVersion, skipResponseReuse)Instala un paquete. El nombre usa el formato "repo/paquete".
UninstallPackage(ctx, repo, name, version, purgeVolumes)Elimina un paquete instalado.
DisablePackage(ctx, repo, name)Detiene los servicios sin desinstalar.
EnablePackage(ctx, repo, name)Vuelve a habilitar un paquete deshabilitado.
PurgeVolumes(ctx, repo, name)Borra todos los volúmenes de datos de un paquete.
ListUninstalledVolumes(ctx, repo, name)Comprueba si hay volúmenes sobrantes.
PurgeUninstalledVolumes(ctx, repo, name)Borra los volúmenes sobrantes.
ListInstalled(ctx, params)Paquetes instalados como "repo/nombre@versión".
GetResponses(ctx, repo, name, version)Respuestas de configuración guardadas.
GetInstalledInfo(ctx, repo, name, version)Información detallada, con preguntas, respuestas y notas.

Systemd

MétodoDescripción
ListUnits(ctx, params)Listado paginado de unidades de systemd.
SetUnitStatus(ctx, name, action)Aplica "start", "stop" o "restart".
LogReplay(ctx, name)Transmite entradas del journal por SSE. Devuelve un canal.
LogTail(ctx, params)Página de entradas del journal con paginación por cursor, grep, rango de tiempo y filtro de prioridad.

Cuentas

MétodoDescripción
Authenticate(ctx, username, password)Devuelve el token de sesión y la cuenta.
CreateAccount(ctx, username, password, email, phone, realName, admin)Crea un usuario. Contraseña de mínimo 8 caracteres.
GetAccount(ctx, username)Obtiene una cuenta por su usuario.
UpdateAccount(ctx, username, fields)Modifica campos de la cuenta (password, email, phone, real_name, admin).
ListAccounts(ctx, params)Listado paginado de cuentas.
DisableAccount(ctx, username)Impide la autenticación.
EnableAccount(ctx, username)Vuelve a habilitar una cuenta deshabilitada.
ListSessions(ctx, token)Sesiones activas del usuario dueño del token.
SessionUsername(ctx, token)Usuario asociado a un token de sesión.
RevokeSession(ctx, sessionID)Invalida una sesión.

Auditoría, ajustes y actualizaciones

MétodoDescripción
ListAuditLog(ctx, opts, token)Registro de auditoría paginado con filtros.
GetSettings(ctx)Todos los ajustes como mapa de clave y valor.
GetSetting(ctx, key)Un solo ajuste por su clave.
SetSetting(ctx, key, value)Actualiza un ajuste.
ListUpgrades(ctx)Paquetes con versiones más nuevas disponibles.
DismissUpgrades(ctx)Marca como descartadas las actualizaciones pendientes.

Ficheros comprimidos

MétodoDescripción
UploadArchive(ctx, subvolume, archiveReader, filename, subpath, stopService)Sube y extrae un fichero comprimido dentro de un subvolumen. Formatos: tar.gz, tar.bz2, tar.xz.
DownloadArchive(ctx, subvolume, paths, stopService, format)Crea un fichero comprimido con el contenido de un subvolumen. Devuelve un io.ReadCloser.

Salud

MétodoDescripción
Ping(ctx)Salud del servicio y recuentos de resumen.

Cliente de JavaScript

El cliente de JavaScript vive en ui/src/api/ y lo usa el panel de Town OS. Está construido como un conjunto modular de mixins sobre la clase SystemControllerClient. Las respuestas distintas de 200 lanzan ApiError con el detalle de problema RFC 9457 ya interpretado.

import SystemControllerClient from './api/client.js';

const client = new SystemControllerClient('http://localhost:5309');

// Después de autenticarse
const result = await client.authenticate('admin', 'password');
client.setToken(result.token);

Almacenamiento

MétodoDescripción
createFilesystem(fs)Crea un subvolumen btrfs nuevo.
modifyFilesystem(name, fs)Renombra o redimensiona un sistema de ficheros.
removeFilesystem(name)Borra un sistema de ficheros por su nombre.
listFilesystems(prefix, sortBy, sortOrder, state, limit, offset, search)Listado paginado con filtros.

Repositorios

MétodoDescripción
addRepository(name, url, username?, password?)Registra un repositorio, con credenciales opcionales.
removeRepository(name)Elimina un repositorio por su nombre.
moveRepository(name, position)Cambia la prioridad (0 = la más alta).
refreshRepositories()Actualiza todos los metadatos. Devuelve un mapa de errores o null.
listRepositories(sortBy, sortOrder, limit, offset, search)Listado paginado.

Paquetes

MétodoDescripción
listPackages(sortBy, sortOrder, limit, offset, search)Listado paginado de los paquetes disponibles.
listPackagesByRepo(search)Paquetes agrupados por repositorio.
listPackageVersions(name)Versiones disponibles de un paquete.
getPackageQuestions(name)Preguntas de configuración por nombre.
getPackageQuestionsByIdentity(repo, name, version)Preguntas de una versión concreta.
installPreview(repo, name, version)Vista previa de volúmenes y puertos sin instalar.
installPackage(repo, name, version, responses, reuseVolumes?, importFromVersion?)Instala un paquete con las respuestas de configuración.
uninstallPackage(repo, name, version, purgeVolumes?)Elimina un paquete instalado.
disablePackage(repo, name)Detiene los servicios sin desinstalar.
enablePackage(repo, name)Vuelve a habilitar un paquete deshabilitado.
purgeVolumes(repo, name)Borra todos los volúmenes de datos de un paquete.
listUninstalledVolumes(repo, name)Comprueba si hay volúmenes sobrantes.
purgeUninstalledVolumes(repo, name)Borra los volúmenes sobrantes.
listInstalled(sortBy, sortOrder, limit, offset, search)Paquetes instalados como "repo/nombre@versión".
getResponses(repo, name, version)Respuestas de configuración guardadas.
getInstalledInfo(repo, name, version)Información detallada, con preguntas, respuestas y notas.

Systemd

MétodoDescripción
listUnits(sortBy, sortOrder, limit, offset, search)Listado paginado de unidades de systemd.
setUnitStatus(name, action)Aplica "start", "stop" o "restart".
logReplay(unit)Transmite entradas del journal por SSE. Devuelve un AsyncGenerator.
logTail(unit, lines?, before?, after?, grep?, since?, until?, priority?)Página de entradas del journal con paginación por cursor, grep, rango de tiempo y filtro de prioridad.

Cuentas

MétodoDescripción
authenticate(username, password)Devuelve el token de sesión y la cuenta.
createAccount(username, password, email, phone, realName, admin)Crea un usuario. Contraseña de mínimo 8 caracteres.
getAccount(username)Obtiene una cuenta por su usuario.
updateAccount(username, fields)Modifica campos de la cuenta.
listAccounts(sortBy, sortOrder, limit, offset, search)Listado paginado de cuentas.
disableAccount(username)Impide la autenticación.
enableAccount(username)Vuelve a habilitar una cuenta deshabilitada.
listSessions(token)Sesiones activas del usuario dueño del token.
sessionUsername(token)Usuario asociado a un token de sesión.
revokeSession(sessionID)Invalida una sesión.

Auditoría, ajustes y actualizaciones

MétodoDescripción
listAuditLog(opts)Registro de auditoría paginado con filtros.
getSettings()Todos los ajustes como objeto de clave y valor.
getSetting(key)Un solo ajuste por su clave.
setSetting(key, value)Actualiza un ajuste.
listUpgrades()Paquetes con versiones más nuevas disponibles.
dismissUpgrades()Marca como descartadas las actualizaciones pendientes.

Ficheros comprimidos

MétodoDescripción
uploadArchive(subvolume, file, subpath?, stopService?)Sube y extrae un fichero comprimido con FormData. Devuelve {needs_restart, message}.
downloadArchive(subvolume, paths?, stopService?, format?)Descarga un fichero comprimido del subvolumen. Devuelve la Response en bruto para transmitirla.

Salud

MétodoDescripción
ping()Salud del servicio y recuentos de resumen.

Referencia de desarrollo

El backend de Town OS se ejecuta en el puerto 5309, con un servidor de desarrollo de Vite en el 5173. Usa make dev para levantar todo el entorno de desarrollo.

Objetivos principales

ObjetivoDescripción
make devLevanta todo el entorno de desarrollo (backend + servidor de Vite).
make dev-stopDetiene y elimina el contenedor del backend de desarrollo.
make dev-logsSigue journalctl dentro del contenedor de desarrollo en marcha.
make dev-cleanDetiene el contenedor y desmonta el volumen btrfs de desarrollo.

Objetivos de pruebas

ObjetivoDescripción
make testLanza el análisis estático y las pruebas unitarias de Go y de JS.
make test-integrationLanza las pruebas de integración de Go en un contenedor de Podman con privilegios.
make test-ui-integrationLanza las pruebas de integración de la interfaz con Bun contra un contenedor del backend.
make test-fullLanza todas las baterías de pruebas en orden.
make auto-testVigila los cambios de ficheros y vuelve a lanzar las pruebas solo.

Objetivos de compilación

ObjetivoDescripción
make production-imageCompila la imagen de contenedor de producción.
make test-imageCompila la imagen de contenedor de pruebas.
make pull-imagesDescarga las imágenes base de contenedor desde Docker Hub.

Requisitos previos

  • Go 1.25+
  • Bun — entorno de ejecución de JavaScript
  • Podman — en modo rootful, con sudo
  • btrfs-progsmkfs.btrfs
  • golangci-lint

Crea un fichero .env con las credenciales del repositorio:

TOWN_OS_REPO_USERNAME=<usuario>
TOWN_OS_REPO_PASSWORD=<contraseña>

Después de instalar los requisitos previos, ejecuta make pull-images antes que cualquier otro objetivo.