Skip to content

clients.zinit_rpc #

Zinit RPC Client

This is a V language client for the Zinit process manager, implementing the JSON-RPC API specification for service management operations.

Overview

Zinit is a process manager that provides service monitoring, dependency management, and system control capabilities. This client provides a comprehensive API to interact with Zinit via its JSON-RPC interface for administrative tasks such as:

  • Service lifecycle management (start, stop, monitor, forget)
  • Service configuration management (create, delete, get)
  • Service status and statistics monitoring
  • System operations (shutdown, reboot, HTTP server control)
  • Log streaming and monitoring

Features

  • ✅ 100% API Coverage: Complete implementation of all 18 methods in the Zinit JSON-RPC specification
  • ✅ Production Tested: All methods tested and working against real Zinit instances
  • ✅ Type-safe API: Proper V struct definitions with comprehensive error handling
  • ✅ Subscription Support: Proper handling of streaming/subscription methods
  • ✅ Unix Socket Transport: Reliable communication via Unix domain sockets
  • ✅ Comprehensive Documentation: Extensive documentation with working examples

Usage

Basic Example

import freeflowuniverse.herolib.clients.zinit_rpc

// Create a new client
mut client := zinit_rpc.new_client(
    name: 'my_client'
    socket_path: '/tmp/zinit.sock'
)!

// List all services
services := client.service_list()!
for service_name, state in services {
    println('Service: ${service_name}, State: ${state}')
}

// Get detailed status of a specific service
status := client.service_status('redis')!
println('Service: ${status.name}')
println('PID: ${status.pid}')
println('State: ${status.state}')
println('Target: ${status.target}')

// Start a service
client.service_start('redis')!

// Stop a service
client.service_stop('redis')!

Service Configuration Management

import freeflowuniverse.herolib.clients.zinit_rpc

mut client := zinit_rpc.new_client()!

// Create a new service configuration
config := zinit_rpc.ServiceConfig{
    exec: '/usr/bin/redis-server'
    oneshot: false
    log: 'stdout'
    env: {
        'REDIS_PORT': '6379'
        'REDIS_HOST': '0.0.0.0'
    }
    shutdown_timeout: 30
}

// Create the service
path := client.service_create('redis', config)!
println('Service created at: ${path}')

// Get service configuration
retrieved_config := client.service_get('redis')!
println('Service exec: ${retrieved_config.exec}')

// Delete service configuration
result := client.service_delete('redis')!
println('Delete result: ${result}')

Service Statistics

import freeflowuniverse.herolib.clients.zinit_rpc

mut client := zinit_rpc.new_client()!

// Get service statistics
stats := client.service_stats('redis')!
println('Service: ${stats.name}')
println('PID: ${stats.pid}')
println('Memory Usage: ${stats.memory_usage} bytes')
println('CPU Usage: ${stats.cpu_usage}%')

// Print child process statistics
for child in stats.children {
    println('Child PID: ${child.pid}, Memory: ${child.memory_usage}, CPU: ${child.cpu_usage}%')
}

Log Streaming

import freeflowuniverse.herolib.clients.zinit_rpc

mut client := zinit_rpc.new_client()!

// Get current logs for all services
logs := client.stream_current_logs(name: '')!
for log in logs {
    println(log)
}

// Get current logs for a specific service
redis_logs := client.stream_current_logs(name: 'redis')!
for log in redis_logs {
    println('Redis: ${log}')
}

// Subscribe to log stream (returns subscription ID)
subscription_id := client.stream_subscribe_logs(name: 'redis')!
println('Subscribed to logs with ID: ${subscription_id}')

API Reference

Service Management Methods

  • service_list() - List all services and their states
  • service_status(name) - Get detailed status of a service
  • service_start(name) - Start a service
  • service_stop(name) - Stop a service
  • service_monitor(name) - Start monitoring a service
  • service_forget(name) - Stop monitoring a service
  • service_kill(name, signal) - Send signal to a service

Service Configuration Methods

  • service_create(name, config) - Create service configuration
  • service_delete(name) - Delete service configuration
  • service_get(name) - Get service configuration

Monitoring Methods

  • service_stats(name) - Get service statistics

System Methods

  • system_shutdown() - Shutdown the system
  • system_reboot() - Reboot the system
  • system_start_http_server(address) - Start HTTP server
  • system_stop_http_server() - Stop HTTP server

Streaming Methods

  • stream_current_logs(args) - Get current logs (returns array of log lines)
  • stream_subscribe_logs(args) - Subscribe to log stream (returns subscription ID)

Discovery Methods

  • rpc_discover() - Get OpenRPC specification

Configuration

Using the Factory Pattern

import freeflowuniverse.herolib.clients.zinit_rpc

// Get client using factory (recommended)
mut client := zinit_rpc.get()!

// Use the client
services := client.service_list()!

Example Heroscript Configuration

!!zinit_rpc.configure
    name: 'production'
    socket_path: '/tmp/zinit.sock'

Error Handling

The client provides comprehensive error handling for all Zinit-specific error codes:

  • -32000: Service not found
  • -32001: Service already monitored
  • -32002: Service is up
  • -32003: Service is down
  • -32004: Invalid signal
  • -32005: Config error
  • -32006: Shutting down
  • -32007: Service already exists
  • -32008: Service file error
import freeflowuniverse.herolib.clients.zinit_rpc

mut client := zinit_rpc.new_client()!

// Handle specific errors
client.service_start('nonexistent') or {
    if err.msg().contains('Service not found') {
        println('Service does not exist')
    } else {
        println('Other error: ${err}')
    }
}

Constants #

const version = '0.0.0'
const default_socket_path = '/tmp/zinit.sock'

Default configuration for Zinit JSON-RPC API

fn delete #

fn delete(args_ ArgsGet) !

fn exists #

fn exists(args_ ArgsGet) !bool

does the config exists?

fn get #

fn get(args_ ArgsGet) !&ZinitRPC

fn heroscript_dumps #

fn heroscript_dumps(obj ZinitRPC) !string

///////////NORMALLY NO NEED TO TOUCH

fn heroscript_loads #

fn heroscript_loads(heroscript string) !ZinitRPC

fn new_client #

fn new_client(args NewClientArgs) !&ZinitRPC

fn play #

fn play(args_ PlayArgs) !

fn set #

fn set(o ZinitRPC) !

register the config for the future

fn switch #

fn switch(name string)

switch instance to be used for zinit_rpc

struct ArgsGet #

@[params]
struct ArgsGet {
pub mut:
	name string
}

///////FACTORY

struct ChildStats #

struct ChildStats {
pub mut:
	pid          u32 @[json: 'pid']          // Process ID of the child process
	memory_usage u64 @[json: 'memory_usage'] // Memory usage in bytes
	cpu_usage    f32 @[json: 'cpu_usage']    // CPU usage as a percentage (0-100)
}

ChildStats represents statistics for a child process

struct DefaultConfigArgs #

@[params]
struct DefaultConfigArgs {
	instance string = 'default'
}

helpers

struct LogParams #

@[params]
struct LogParams {
pub mut:
	name string // Optional service name filter
}

LogParams represents parameters for log streaming methods

struct NewClientArgs #

@[params]
struct NewClientArgs {
pub mut:
	name        string = 'default'
	socket_path string = default_socket_path
}

Factory function to create a new ZinitRPC client instance

struct OpenRPCInfo #

struct OpenRPCInfo {
pub mut:
	version     string         @[json: 'version']     // API version
	title       string         @[json: 'title']       // API title
	description string         @[json: 'description'] // API description
	license     OpenRPCLicense @[json: 'license']     // License information
}

OpenRPCInfo represents API information

struct OpenRPCLicense #

struct OpenRPCLicense {
pub mut:
	name string @[json: 'name'] // License name
}

OpenRPCLicense represents license information

struct OpenRPCMethod #

struct OpenRPCMethod {
pub mut:
	name        string @[json: 'name']        // Method name
	description string @[json: 'description'] // Method description
	// Note: params and result are dynamic and would need more complex handling
}

OpenRPCMethod represents an RPC method

struct OpenRPCServer #

struct OpenRPCServer {
pub mut:
	name string @[json: 'name'] // Server name
	url  string @[json: 'url']  // Server URL
}

OpenRPCServer represents server information

struct OpenRPCSpec #

struct OpenRPCSpec {
pub mut:
	openrpc string          @[json: 'openrpc'] // OpenRPC version
	info    OpenRPCInfo     @[json: 'info']    // API information
	methods []OpenRPCMethod @[json: 'methods'] // Available methods
	servers []OpenRPCServer @[json: 'servers'] // Server information
}

OpenRPCSpec represents the OpenRPC specification structure

struct PlayArgs #

@[params]
struct PlayArgs {
pub mut:
	heroscript string // if filled in then plbook will be made out of it
	plbook     ?playbook.PlayBook
	reset      bool
}

struct ServiceConfig #

struct ServiceConfig {
pub mut:
	exec             string            @[json: 'exec']             // Command to run
	test             string            @[json: 'test']             // Test command (optional)
	oneshot          bool              @[json: 'oneshot']          // Whether the service should be restarted (maps to one_shot in Zinit)
	after            []string          @[json: 'after']            // Services that must be running before this one starts
	log              string            @[json: 'log']              // How to handle service output (null, ring, stdout)
	env              map[string]string @[json: 'env']              // Environment variables for the service
	dir              string            @[json: 'dir']              // Working directory for the service
	shutdown_timeout u64               @[json: 'shutdown_timeout'] // Maximum time to wait for service to stop during shutdown
}

ServiceConfig represents the configuration for a zinit service

struct ServiceCreateParams #

struct ServiceCreateParams {
pub mut:
	name    string        @[json: 'name']    // Name of the service to create
	content ServiceConfig @[json: 'content'] // Configuration for the service
}

ServiceCreateParams represents parameters for service_create method

struct ServiceKillParams #

struct ServiceKillParams {
pub mut:
	name   string @[json: 'name']   // Name of the service to kill
	signal string @[json: 'signal'] // Signal to send (e.g., SIGTERM, SIGKILL)
}

ServiceKillParams represents parameters for service_kill method

struct ServiceStats #

struct ServiceStats {
pub mut:
	name         string       @[json: 'name']         // Service name
	pid          u32          @[json: 'pid']          // Process ID of the service
	memory_usage u64          @[json: 'memory_usage'] // Memory usage in bytes
	cpu_usage    f32          @[json: 'cpu_usage']    // CPU usage as a percentage (0-100)
	children     []ChildStats @[json: 'children']     // Stats for child processes
}

ServiceStats represents memory and CPU usage statistics for a service

struct ServiceStatus #

struct ServiceStatus {
pub mut:
	name   string            @[json: 'name']   // Service name
	pid    u32               @[json: 'pid']    // Process ID of the running service (if running)
	state  string            @[json: 'state']  // Current state of the service (Running, Success, Error, etc.)
	target string            @[json: 'target'] // Target state of the service (Up, Down)
	after  map[string]string @[json: 'after']  // Dependencies of the service and their states
}

ServiceStatus represents detailed status information for a service

struct ZinitRPC #

@[heap]
struct ZinitRPC {
pub mut:
	name        string = 'default'
	socket_path string = default_socket_path // Unix socket path for RPC server
	rpc_client  ?&jsonrpc.Client @[skip]
}

THIS THE THE SOURCE OF THE INFORMATION OF THIS FILE, HERE WE HAVE THE CONFIG OBJECT CONFIGURED AND MODELLED

fn (ZinitRPC) rpc_discover #

fn (mut c ZinitRPC) rpc_discover() !OpenRPCSpec

rpc_discover returns the OpenRPC specification for the API

fn (ZinitRPC) service_create #

fn (mut c ZinitRPC) service_create(name string, config ServiceConfig) !string

service_create creates a new service configuration file

fn (ZinitRPC) service_delete #

fn (mut c ZinitRPC) service_delete(name string) !string

service_delete deletes a service configuration file

fn (ZinitRPC) service_forget #

fn (mut c ZinitRPC) service_forget(name string) !

service_forget stops monitoring a service You can only forget a stopped service

fn (ZinitRPC) service_get #

fn (mut c ZinitRPC) service_get(name string) !ServiceConfig

service_get gets a service configuration file

fn (ZinitRPC) service_kill #

fn (mut c ZinitRPC) service_kill(name string, signal string) !

service_kill sends a signal to a running service

fn (ZinitRPC) service_list #

fn (mut c ZinitRPC) service_list() !map[string]string

service_list lists all services managed by Zinit Returns a map of service names to their current states

fn (ZinitRPC) service_monitor #

fn (mut c ZinitRPC) service_monitor(name string) !

service_monitor starts monitoring a service The service configuration is loaded from the config directory

fn (ZinitRPC) service_start #

fn (mut c ZinitRPC) service_start(name string) !

service_start starts a service

fn (ZinitRPC) service_stats #

fn (mut c ZinitRPC) service_stats(name string) !ServiceStats

service_stats gets memory and CPU usage statistics for a service

fn (ZinitRPC) service_status #

fn (mut c ZinitRPC) service_status(name string) !ServiceStatus

service_status shows detailed status information for a specific service

fn (ZinitRPC) service_stop #

fn (mut c ZinitRPC) service_stop(name string) !

service_stop stops a service

fn (ZinitRPC) stream_current_logs #

fn (mut c ZinitRPC) stream_current_logs(args LogParams) ![]string

stream_current_logs gets current logs from zinit and monitored services

fn (ZinitRPC) stream_subscribe_logs #

fn (mut c ZinitRPC) stream_subscribe_logs(args LogParams) !u64

stream_subscribe_logs subscribes to log messages generated by zinit and monitored services Returns a subscription ID that can be used to manage the subscription

fn (ZinitRPC) system_reboot #

fn (mut c ZinitRPC) system_reboot() !

system_reboot stops all services and reboots the system

fn (ZinitRPC) system_shutdown #

fn (mut c ZinitRPC) system_shutdown() !

system_shutdown stops all services and powers off the system

fn (ZinitRPC) system_start_http_server #

fn (mut c ZinitRPC) system_start_http_server(address string) !string

system_start_http_server starts an HTTP/RPC server at the specified address

fn (ZinitRPC) system_stop_http_server #

fn (mut c ZinitRPC) system_stop_http_server() !

system_stop_http_server stops the HTTP/RPC server if running