goubus

package module
v2.0.0-alpha1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 18, 2026 License: MIT Imports: 18 Imported by: 0

README

goubus

OpenWrt ubus Go Client

CI Status Coverage Go Report Card Go Reference

Release Go Version License Contributors

Issues Pull Requests Stars Repo Size

goubus provides an interface to interact with OpenWrt's ubus (micro bus) system, using a Profile system to support hardware-specific differences (like CMCC RAX3000M) while maintaining a consistent base implementation.

中文文档 | Examples | Documentation


Key Features

  • Device Profiles: Native support for hardware-specific dialects (e.g., CMCC RAX3000M, X86 Generic).
  • Selective Imports: Import only what you need, avoiding overhead.
  • Dual Transport: Supports both HTTP JSON-RPC (remote) and Unix Socket (local).
  • Type-Safe API: Fully typed requests and responses.
  • Context Aware: Support for context.Context cancellation and timeouts.

Installation

go get github.com/honeybbq/goubus/v2

Quick Start

1. Initialize Transport

import (
    "context"
    "github.com/honeybbq/goubus/v2"
)

ctx := context.Background()

// Remote via RPC (Requires rpcd and proper ACLs)
caller, _ := goubus.NewRpcClient(ctx, "192.168.1.1", "root", "password")

// Local via Unix Socket (Running on the device)
caller, _ := goubus.NewSocketClient(ctx, "/var/run/ubus/ubus.sock")

2. Use Device Specific Managers

Import the profile matching your hardware:

import (
    "github.com/honeybbq/goubus/v2/profiles/cmcc_rax3000m/system"
    "github.com/honeybbq/goubus/v2/profiles/cmcc_rax3000m/network"
)

// Initialize Managers
sysSvc := system.New(caller)
netSvc := network.New(caller)

// Fetch System Board Info
board, _ := sysSvc.Board(ctx)
fmt.Printf("Model: %s, Kernel: %s\n", board.Model, board.Kernel)

// Dump all network interfaces
ifaces, _ := netSvc.Dump(ctx)

3. Debugging & Logging

goubus natively supports log/slog. You can inject your own logger to see raw ubus interactions (requests and responses):

import "log/slog"

// Create a debug logger
logger := slog.New(slog.NewTextHandler(os.Stderr, &slog.HandlerOptions{Level: slog.LevelDebug}))

// Inject it into the transport
caller.SetLogger(logger)

Implemented Objects

Object Description
System Board, Info, Reboot, Watchdog, Signal, Sysupgrade
Network Interface control, Device status, Routing, Namespaces
Wireless IWInfo (Scan, Assoclist), Wireless radio control
UCI Full CRUD, Commit/Rollback, State tracking
DHCP IPv4/v6 Leases, IPv6 RA, Static Lease management
Service Service lifecycle, Validation, Custom data
Session Login, Access control, Grant/Revoke
Container LxC container management, Console access
Hostapd Low-level AP management (Kick clients, Switch channels)
RPC-SYS Package management, Factory reset, Firmware validation

Project Architecture

goubus is designed with a multi-layer architecture for code reuse:

  • Core Layer (goubus/): Contains the transport implementations (HTTP RPC and Unix Socket), raw ubus message handling (blobmsg), results parsing, and error definitions.
  • Base Layer (goubus/internal/base/): Provides generic, reusable implementations for standard ubus objects (e.g., system, network, uci). This layer encapsulates the common logic that applies to most OpenWrt devices.
  • Profile Layer (goubus/profiles/): The public API entry point. Profiles (e.g., cmcc_rax3000m, generic) use Dialects to handle hardware-specific quirks (like parameter types or special method names) while exposing a consistent, high-level interface.
  • Examples & TestData (examples/, internal/testdata/): Full integration tests using real hardware data and usage examples.

Comparison

Feature HTTP (JSON-RPC) Unix Socket
Use Case Remote management On-device apps
Auth Required Not required
Performance Network overhead Low latency

Contributing & Device Support

This repository includes Profiles for RAX3000M and x86. The x86 Profile is derived from virtual machine data; given the diversity of x86 hardware and drivers, the implementation is undergoing further refinement.

Contributions of Profiles or testdata for other hardware are welcome.

How to help out

  1. Copy: Copy profiles/x86_generic to a new folder.
  2. Test: Run tests using your real hardware data to find parsing errors.
  3. Fix: Use a Dialect to handle the differences.

Guide on how to dump test data: Contributing Test Data Guide.

License

MIT License - See LICENSE file for details.

Acknowledgments

Inspired by Kubernetes client-go and moby/moby.

Documentation

Index

Constants

View Source
const (
	UbusStatusOK               = 0
	UbusStatusInvalidCommand   = 1
	UbusStatusInvalidParameter = 2
	UbusStatusMethodNotFound   = 3
	UbusStatusNotFound         = 4
	UbusStatusNoData           = 5
	UbusStatusPermissionDenied = 6
	UbusStatusTimeout          = 7
	UbusStatusNotSupported     = 8
	UbusStatusUnknown          = 9
	UbusStatusConnectionFailed = 10
)

Ubus error codes.

View Source
const Version = "2.0.0-alpha1"

Version is the current version of the goubus library.

Variables

This section is empty.

Functions

func BoolValue

func BoolValue(b Bool) bool

BoolValue safely dereferences a Bool, returning false when nil.

func Call

func Call[T any](ctx context.Context, t Transport, service, method string, data any) (*T, error)

Call is a generic helper that wraps Transport.Call and unmarshals the response. T represents the expected type of the response data.

func MapUbusCodeToError

func MapUbusCodeToError(code int) error

MapUbusCodeToError maps a ubus integer code to a typed error defined in errdefs. If the code is not recognized, it returns an unknown error wrapping the code.

Types

type Bool

type Bool bool

Bool is a JSON boolean type that gracefully accepts numbers or string representations. It is useful for handling inconsistent boolean representations in ubus responses (e.g., 1/0, "1"/"0", "true"/"false").

func (*Bool) Format

func (b *Bool) Format(state fmt.State, _ rune)

Format enables using Bool with fmt verbs like %t.

func (*Bool) MarshalJSON

func (b *Bool) MarshalJSON() ([]byte, error)

MarshalJSON ensures consistent boolean encoding.

func (*Bool) UnmarshalJSON

func (b *Bool) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler, accepting 0/1, "0"/"1", true/false, "true"/"false", and null.

type Result

type Result interface {
	// Unmarshal decodes the response data into the provided target.
	// The target must be a pointer to a compatible type.
	Unmarshal(target any) error
}

Result is the interface that wraps the basic Unmarshal method. It allows for lazy unmarshaling of ubus call responses into specific Go types.

type RpcClient

type RpcClient struct {
	// contains filtered or unexported fields
}

RpcClient handles communication with the ubus JSON-RPC endpoint. It manages authentication and session state internally.

func NewRpcClient

func NewRpcClient(ctx context.Context, host, username, password string, opts ...RpcOption) (*RpcClient, error)

NewRpcClient creates an authenticated RPC client.

func (*RpcClient) Call

func (rc *RpcClient) Call(ctx context.Context, service, method string, data any) (Result, error)

Call performs a JSON-RPC call with automatic session management.

func (*RpcClient) Close

func (rc *RpcClient) Close() error

func (*RpcClient) SetLogger

func (rc *RpcClient) SetLogger(logger *slog.Logger)

SetLogger sets the logger for the RPC client.

type RpcOption

type RpcOption func(*RpcClient)

RpcOption defines a functional option for an RpcClient.

func WithRpcLogger

func WithRpcLogger(logger *slog.Logger) RpcOption

WithRpcLogger sets the logger for the RPC client.

type SocketClient

type SocketClient struct {
	// contains filtered or unexported fields
}

SocketClient implements direct ubus unix socket transport. It communicates directly with the ubusd daemon on the local system.

func NewSocketClient

func NewSocketClient(ctx context.Context, sockPath string, opts ...SocketOption) (*SocketClient, error)

NewSocketClient creates a new ubus socket client and performs the HELLO handshake. If sockPath is empty, it uses the default path (/tmp/run/ubus/ubus.sock).

func (*SocketClient) Call

func (c *SocketClient) Call(ctx context.Context, service, method string, data any) (Result, error)

Call invokes a ubus method through the socket transport.

func (*SocketClient) Close

func (c *SocketClient) Close() error

func (*SocketClient) DialTimeout

func (c *SocketClient) DialTimeout() time.Duration

func (*SocketClient) PeerID

func (c *SocketClient) PeerID() uint32

func (*SocketClient) ReadTimeout

func (c *SocketClient) ReadTimeout() time.Duration

func (*SocketClient) SetLogger

func (c *SocketClient) SetLogger(logger *slog.Logger)

func (*SocketClient) WriteTimeout

func (c *SocketClient) WriteTimeout() time.Duration

type SocketOption

type SocketOption func(*SocketClient)

SocketOption defines a functional option for a SocketClient.

func WithDialTimeout

func WithDialTimeout(timeout time.Duration) SocketOption

WithDialTimeout sets the timeout for connecting to the socket.

func WithReadTimeout

func WithReadTimeout(timeout time.Duration) SocketOption

WithReadTimeout sets the timeout for reading from the socket.

func WithSocketLogger

func WithSocketLogger(logger *slog.Logger) SocketOption

WithSocketLogger sets the logger for the socket client.

func WithWriteTimeout

func WithWriteTimeout(timeout time.Duration) SocketOption

WithWriteTimeout sets the timeout for writing to the socket.

type Transport

type Transport interface {
	// Call executes a ubus call for the specified service and method.
	// The data parameter is the payload for the call, which will be marshaled to JSON/blobmsg.
	Call(ctx context.Context, service, method string, data any) (Result, error)
	// SetLogger configures the logger used by the transport.
	SetLogger(logger *slog.Logger)
	// Close releases any resources held by the transport (e.g., closing connections).
	Close() error
}

Transport is the interface that wraps the basic ubus call method. Transport provides a unified way to interact with local ubus sockets and remote JSON-RPC endpoints.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL