No description
  • Rust 88%
  • Shell 10%
  • Makefile 1.9%
  • Dockerfile 0.1%
Find a file
despiegk a2f0762a7d
Some checks failed
Build and Test / build (push) Failing after 8s
Tests / test (push) Failing after 10s
Merge branch 'development' of https://forge.ourworld.tf/geomind_code/my_init into development
2026-06-06 08:05:31 +02:00
.claude cargo fmt, nothing else 2026-04-20 08:25:48 +02:00
.forgejo/workflows chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
crates chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
docker chore: remove all remaining zinit references from codebase 2026-03-23 14:24:49 +01:00
docs chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
etc/my_init chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
examples chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
scripts chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
tests chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
.gitignore cargo fmt, nothing else 2026-04-20 08:25:48 +02:00
ARCHITECTURE.md chore: remove Cargo.lock and update gitignore 2026-06-06 08:05:28 +02:00
buildenv.sh chore: remove all remaining zinit references from codebase 2026-03-23 14:24:49 +01:00
Cargo.toml Merge branch 'development' of https://forge.ourworld.tf/geomind_code/my_init into development 2026-06-06 08:05:31 +02:00
LICENSE chore: canonicalize LICENSE 2026-05-27 19:58:47 +02:00
Makefile feat: rename project to my_init 2026-03-19 17:13:33 +02:00
README.md Merge branch 'development' of https://forge.ourworld.tf/geomind_code/my_init into development 2026-06-06 08:05:31 +02:00

my_init

What this is

A lightweight process supervisor with dependency management, similar to systemd but simpler. It manages services through an explicit state machine, handles process groups correctly, supports health checks (TCP, HTTP, and exec-based), ordered shutdown, and runs in multiple deployment modes (container, VM/bare-metal, standalone). It includes a fully embedded web admin dashboard with real-time service management, charts, logs, events, and bulk operations.

What this repository contains

  • my_init_sdk — Library: shared types, protocol, and client implementations
  • my_init_server — Binary: process supervisor daemon (IPC + OpenRPC)
  • my_init — Binary: CLI client and TUI
  • my_init_ui — Binary: web admin dashboard
  • my_init_pid1 — Binary: PID 1 init shim (Linux only)
  • docs/ — User guides, CLI reference, configuration reference, and architecture docs

Role in the stack

my_init serves as the process supervision and service management layer. It can run as PID 1 in containers or VMs, or as a standalone supervisor. It provides a web admin dashboard, CLI/TUI, and OpenRPC API for managing service lifecycles, making it suitable for both development and production deployments in the Hero stack.

Relation to ThreeFold

This technology is used within the ThreeFold ecosystem and was first deployed on the ThreeFold Grid. The component itself is designed as reusable infrastructure technology and should be understood by its technical function first, independent of any specific deployment.

Ownership

This repository is owned and maintained by TF-Tech NV, a Belgian company responsible for the development and maintenance of this technology.

License

This project is licensed under the Apache License 2.0 — see the LICENSE file for details.


Quick Install

Get started in one command:

curl -fsSL https://forge.ourworld.tf/geomind_code/my_init/raw/branch/main/scripts/install.sh | bash

Or download and run the installer script directly:

cd /tmp && curl -O https://forge.ourworld.tf/geomind_code/my_init/raw/branch/main/scripts/install.sh
chmod +x install.sh
./install.sh

This will:

  • Detect your OS and architecture
  • Download pre-built binaries (Linux amd64, macOS arm64)
  • Install to $HOME/hero/bin
  • Configure your shell PATH automatically
  • Start my_init_server in background (macOS/Windows only)

Features

  • Dependency Graph: Services declare dependencies (requires, after, wants, conflicts)
  • State Machine: 8 explicit states (Inactive, Blocked, Starting, Running, Stopping, Success, Exited, Failed)
  • Process Groups: Signals sent to process groups, handling sh -c child processes correctly
  • Health Checks: TCP, HTTP, and exec-based health checks with retries
  • Ordered Shutdown: Dependents stop before their dependencies
  • Production Hardening: OOM protection (-1000 for PID 1), supervisor watchdog, and environment sanitization
  • User/Group Support: Run services as specific users/groups for least-privilege security
  • Hot Reload: Reload configuration without full restart
  • Multi-Environment: Works in containers, VMs, and bare-metal
  • Web Admin Dashboard: Real-time service management UI with charts, logs, events, and bulk operations
  • Fully Embedded UI: All assets (Bootstrap, Chart.js, icons) compiled into the binary — no CDN or network required

Deployment Modes

my_init adapts its behavior based on deployment environment:

Container Mode

Use my_init_pid1 as your container entrypoint:

ENTRYPOINT ["/usr/bin/my_init_pid1", "--container"]

Or set the environment variable:

MY_INIT_CONTAINER=1 my_init_pid1

Behavior:

  • Loads services from /etc/my_init/services/
  • Clean exit on shutdown (no reboot syscall)
  • No system services directory

VM / Bare-Metal Mode

Use my_init_pid1 as your init system (PID 1):

# In /sbin/init or kernel cmdline: init=/usr/bin/my_init_pid1

Behavior:

  • Loads system services from /etc/my_init/system/ first (auto-assigned class=system)
  • Loads user services from /etc/my_init/services/ second
  • Handles reboot/poweroff via syscalls (SIGINT=reboot, SIGTERM=poweroff)
  • Never exits (kernel panic prevention)

Standalone Mode

Run my_init_server directly (not as PID 1):

my_init_server --config-dir /etc/my_init/services

Optionally enable system services directory:

my_init_server --config-dir /etc/my_init/services --pid1-mode

Quick Start

Download and install pre-built binaries:

./scripts/install.sh

This script:

  • Detects your OS and architecture
  • Downloads binaries from Forgejo registry
  • Installs to $HOME/hero/bin
  • Configures your PATH automatically
  • On macOS/Windows, automatically starts the server in the background

Building from Source

# Full build with Makefile
make build

# Or manual build
cargo build --release --workspace

# Run the server + admin UI
make run

# Use the CLI
my_init list
my_init status my-service
my_init start my-service
my_init stop my-service

See scripts/README.md for detailed information about installation scripts and the Makefile for build targets.

Architecture

my_init_pid1 (PID 1 shim)
 | spawns/monitors
 v
my_init_server (daemon)
 | unix socket (IPC + OpenRPC)
 v
my_init (CLI/TUI) my_init_ui (web admin dashboard)

Crate Structure

crates/
 my_init_sdk/ # Library: shared types, protocol, client implementations
 my_init_server/ # Binary: process supervisor daemon (IPC + OpenRPC)
 my_init/ # Binary: CLI client and TUI
 my_init_ui/ # Binary: web admin dashboard
 my_init_pid1/ # Binary: PID 1 init shim (Linux only)

Dependency Graph

my_init_sdk (no internal deps)
 ^ ^ ^ ^
 | | | |
 server CLI UI pid1

All crates depend only on my_init_sdk. No cross-dependencies between server, CLI, UI, or pid1.

Ports and Sockets

Component Binding Default
my_init_server Unix socket (IPC) ~/hero/var/sockets/my_init_server.sock
my_init_server TCP (API, optional, disable with --web-port 0) 3875
my_init_ui TCP (HTTP dashboard) 9880
my_init_ui Unix socket (local tool access) ~/hero/var/sockets/my_init_admin.sock

Configuration

Service configs are TOML files in the config directory (default: /etc/my_init/services/).

[service]
name = "my-app"
exec = "/usr/bin/my-app --daemon"
dir = "/var/lib/my-app" # optional working directory
oneshot = false # exit after success (default: false)
status = "start" # start | stop | ignore (default: start)
class = "user" # user | system (default: user)

[dependencies]
requires = ["database"] # must be running
after = ["logger"] # start order only
wants = ["metrics"] # soft dependency
conflicts = ["legacy-app"] # mutual exclusion

[lifecycle]
restart = "on-failure" # always | on-failure | never
stop_signal = "SIGTERM"
start_timeout_ms = 30000
stop_timeout_ms = 10000
restart_delay_ms = 1000
restart_delay_max_ms = 60000
max_restarts = 0 # 0 = unlimited

[health]
type = "http"
endpoint = "http://localhost:8080/health"
interval_ms = 10000
retries = 3

[logging]
buffer_lines = 1000

Targets

Virtual services for grouping:

[target]
name = "multi-user"

[dependencies]
requires = ["network", "logger", "database"]

Service Status

The status field controls supervisor behavior:

  • start (default): Automatically start and keep running
  • stop: Keep stopped (won't auto-start)
  • ignore: Supervisor ignores this service

Service Class

The class field protects critical services from bulk operations:

  • user (default): Normal service, affected by *_all commands
  • system: Protected service, skipped by bulk operations

System-class services are immune to start_all, stop_all, and delete_all commands.

CLI Commands

my_init list # List all services
my_init status <name> # Show service status
my_init start <name> # Start a service
my_init stop <name> # Stop (cascades to dependents)
my_init restart <name> # Restart a service
my_init kill <name> [signal] # Send signal to service
my_init logs <name> [-n N] # View service logs
my_init why <name> # Show why service is blocked
my_init tree # Show dependency tree
my_init reload # Reload configuration
my_init add-service <toml> # Add service at runtime
my_init remove-service <name> # Remove a service
my_init start-all # Start all user-class services
my_init stop-all # Stop all user-class services
my_init delete-all # Delete all user-class services
my_init shutdown # Stop all services, exit daemon
my_init poweroff # Power off system (signals init)
my_init reboot # Reboot system (signals init)

# Debug commands
my_init debug-state # Full graph state dump
my_init debug-procs <name> # Process tree for a service

Web Admin Dashboard

The my_init_ui crate provides a real-time web admin dashboard at http://localhost:9880:

  • Services tab: Live service list with state badges, PID, memory usage, restart counts
  • Tasks tab: Oneshot service results with exit codes
  • Add Service: Full form for creating/editing services with all config options
  • Logs: Per-service log viewer with ANSI color support, stream filtering, auto-refresh
  • Events: Real-time event stream with filtering
  • Reset All: Bulk stop and delete all services with confirmation
  • API Docs: Interactive OpenRPC documentation
  • MCP: Model Context Protocol connection details for AI tool integration
  • Charts: Memory usage history graph, service state distribution

All UI assets (Bootstrap 5.3.3, Bootstrap Icons, Chart.js) are embedded in the binary via rust-embed — no internet connection needed.

The UI connects to my_init_server via the SDK (AsyncMyInitClient) over Unix socket.

# Start server + UI
make run

# Or start separately
my_init_server --config-dir ~/hero/cfg/my_init &
my_init_ui --port 9880

Path Configuration

my_init uses platform-specific default paths. For details, see the Path Configuration guide.

Environment Variables

Variable Default Description
MY_INIT_LOG_LEVEL info Log level: trace, debug, info, warn, error
MY_INIT_CONFIG_DIR Platform-specific (see above) Service config directory
MY_INIT_SOCKET Platform-specific (see above) Unix socket path
MY_INIT_CONTAINER unset If set, my_init_pid1 runs in container mode

Example: Custom Paths

# Use custom config and socket directories
export MY_INIT_CONFIG_DIR=/opt/my-services
export MY_INIT_SOCKET=/tmp/my-my_init.sock

# Start server
my_init_server

# Connect with CLI
my_init list

Library Usage

Use my_init_sdk as a library dependency:

use my_init_sdk::{MyInitClient, ServiceConfig};

// Blocking client
let socket = my_init_sdk::socket::default_path();
let mut client = MyInitClient::connect_unix(&socket)?;
let services = client.list()?;

// Async client
use my_init_sdk::AsyncMyInitClient;
let mut client = AsyncMyInitClient::connect_unix(&socket).await?;
let status = client.status("my-service").await?;

Docker Usage

# Build test image
docker build -t my_init-test -f docker/Dockerfile .

# Run (uses container mode automatically)
docker run -it --rm my_init-test

# With debug logging
docker run -it --rm -e MY_INIT_LOG_LEVEL=debug my_init-test

# Explicit container mode
docker run -it --rm -e MY_INIT_CONTAINER=1 my_init-test

Shutdown Ordering

Services are stopped in reverse dependency order:

Example: database <- app <- worker

Startup order: database -> app -> worker
Shutdown order: worker -> app -> database

When stopping a single service, dependents are stopped first:

  • my_init stop database stops worker, then app, then database
  • Dependencies are NOT auto-stopped (other services may need them)

Development

make check # Verify workspace builds
make test # Run unit tests
make build # Build all release binaries
make lint # Run clippy linter
make test-all # Run all tests (unit + bash)

# Run specific integration tests
make test-bash # Legacy bash-based tests

# Playground
make play-tui # Launch TUI with sample services for manual testing
make play-web # Launch web UI with sample services

Documentation