Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
a4ba815
Refresh the status of the instance owning a changed ip addr
cvaroqui Jul 1, 2026
84dcc1c
Add a mntmon daemon manager
cvaroqui Jul 1, 2026
6d0c8c3
Queue a instance status refresh if one of its mounts changed
cvaroqui Jul 1, 2026
ccd99d2
Update the README
cvaroqui Jul 2, 2026
d2c7229
Use the relaxed expand from the daemon api GetObjectPaths()
cvaroqui Jul 2, 2026
357c53a
Add object labels to instance.Config
cvaroqui Jul 2, 2026
2eb9452
Return a [400] Bad Request if evaluating a non-existent kw
cvaroqui Jul 2, 2026
aa42957
Honor --ignore-not-found in "o[mx] <sel> config get|eval"
cvaroqui Jul 2, 2026
e863474
Add the "make test-cover" target and "make help"
cvaroqui Jul 3, 2026
d96378a
Sanitize command aliases in o[mx]
cvaroqui Jul 3, 2026
559380e
Add the ReplacedBy field to the "ips_per_node" net kw
cvaroqui Jul 3, 2026
8497a62
Fix the routedbridge network split checker and allocator
cvaroqui Jul 3, 2026
300e188
Switch to local-by-default "om <actor> resource ls"
cvaroqui Jul 6, 2026
5a76a52
Avoid queueing a status refresh on ip/fs evt if a action is in progress
cvaroqui Jul 6, 2026
4d35a28
Move the "instance resource info list|push" commands
cvaroqui Jul 6, 2026
183f916
Support the "om svc1 container enter zzz" command
cvaroqui Jul 6, 2026
2029679
Support the "om svc1 container logs zzz" command
cvaroqui Jul 6, 2026
f89ab5d
Add the "om <svc> container ls" command
cvaroqui Jul 6, 2026
47a1440
Add the "om svc task ls" command
cvaroqui Jul 6, 2026
9d1c1f0
Add the "om svc task run <id>" command
cvaroqui Jul 6, 2026
39c7752
Add the "om svc sync ls" command
cvaroqui Jul 6, 2026
63d72be
Support the resource id as a positional parm in "sync" commands
cvaroqui Jul 6, 2026
6fe96ee
Mark the core keywords as applicable in the DEFAULT section only
cvaroqui Jul 7, 2026
3ea21af
Add more per driver-group commandsets
cvaroqui Jul 7, 2026
b091153
Group resource group commands in the help
cvaroqui Jul 7, 2026
29165c1
Add the missing res-group list commands
cvaroqui Jul 7, 2026
2a0dc1d
Fix the svcconf compobj
cvaroqui Jul 8, 2026
017481c
Add goodies to the stressful CHANGELOG
cvaroqui Jul 8, 2026
ab916cd
Add the "om svc|vol resource <action> <rid sel>" commands
cvaroqui Jul 8, 2026
d396c67
Factorize more core/o[mx] code into commoncmd
cvaroqui Jul 8, 2026
d67f74c
Factorize more core/o[mx] code into commoncmd - add nscfg
cvaroqui Jul 8, 2026
4a87690
Factorize more core/o[mx] code into commoncmd
cvaroqui Jul 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,56 @@
max_delay = 10m # interpreted as 10m in om2 and om3 => Good
```

## What's New in v3

OpenSVC v3 is a major evolution, rebuilt in Go for performance, reliability, and maintainability. Beyond the migration considerations, v3 introduces exciting new capabilities:

### Architecture & Performance

* **Complete Go rewrite**: The agent is now written in Go, delivering a compiled, statically-linked binary with improved performance, memory safety, and lower resource footprint compared to the Python v2 agent.

* **Simplified deployment**: Single binary distribution with minimal dependencies.

* **OpenAPI 3 based API**: Modern RESTful API with OpenAPI 3 specification, served over both Unix socket and inet, with bearer token authentication, replacing the custom raw JSON-RPC protocol.

### User Experience

* **New `ox` terminal UI**: A dedicated terminal interface for real-time cluster monitoring and management, complementing the `om` CLI. Open an `ox` session to watch services move around the cluster interactively.

* **Enhanced logging with journald**: All agent logs now integrate with systemd-journald, enabling fast filtering with `journalctl _COMM=om` and adding indexed attributes like `OBJ_PATH` for precise log queries.

### Orchestration & Management

* **Live migration for KVM**: Full support for live migration of KVM instances with data on `disk.disk` and `disk.drbd` resources using `om <svc> switch --live` and `om <svc> takeover --live` commands.

* **New placement policy**: `last start` policy uses the mtime of `<objvar>/last_start` as the candidate sort key, with more recent starts having higher priority.

* **Improved object labels**: Enhanced support for labeling objects, enabling better organization and selection. Labels help third-party solutions like backup tools, ingress gateways, and monitoring systems identify and handle objects appropriately.

* **Better container management**: New commands for container operations including `om <svc> container ls`, `om <svc> container enter <id>`, and `om <svc> container logs <id>`.

* **Task management**: New commands for task operations including `om <svc> task ls` and `om <svc> task run <id>`.

* **Resource group commands**: New per-driver-group command sets for more targeted resource management.

### Configuration & Operations

* **Unified configuration update**: The new `update` command with `--set`, `--unset`, and `--delete` flags allows atomic commits for different types of configuration changes.

* **Quiet mode**: New `--quiet` flag for instance actions disables both progress rendering and console logging, useful for scripts and automation.

* **Enhanced secret management**: New commands like `om <kvstore> key rename` for better key management in secret stores.

### Network & Storage

* **Modern firewall management**: Configuration now uses nftables exclusively, with better support for large subnets including IPv6 via the new `mask_per_node` keyword.

* **Improved mount monitoring**: New daemon manager (`mntmon`) for monitoring mount events and refreshing instance status when mounts change.

* **Network event handling**: New daemon network monitor (`netmon`) relays netlink events to pubsub, enabling faster response to network changes.

* **New install keyword**: For fs and volume resources, the new `install` keyword enables deployment of complex file trees on start, with support for sec keys, cfg keys, local files or remote URIs, file/directory nesting, and user/group/permission setup.

## Breaking Changes

### Cluster and Node Configuration
Expand Down
29 changes: 29 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,10 @@ restart:
test:
$(GOTEST) -p 1 -timeout 60s ./...

test-cover:
$(GOTEST) -p 1 -timeout 60s -race -coverprofile=coverage.out ./...
$(GOCMD) tool cover -html=coverage.out -o coverage.html

testinfo:
TEST_LOG_LEVEL=info $(GOTEST) -p 1 -timeout 60s ./...

Expand All @@ -124,3 +128,28 @@ vet:
$(GOVET) ./...


help:
@echo "Available targets:"
@echo " api - Generate the api code from api.yaml"
@echo " build - Build om and ox"
@echo " compobj - Build the compliance modules pack"
@echo " dist - Build, strip binaries and make a tarball"
@echo " om - Build om"
@echo " ox - Build ox"
@echo " install - Install o[mx] to /usr/bin"
@echo " restart - Restart the daemon"
@echo " deploy - Install and restart on all nodes"
@echo " clean - Clean build artifacts"
@echo " deps - Update dependencies"
@echo " test - Run tests"
@echo " test-cover - Run tests with coverage"
@echo " vet - Run go static analyzer"
@echo " version - Update the version string from git status"
@echo
@echo "Available -race targets:"
@echo " build-race - Build om and ox if race-free"
@echo " compobj-race - Build the compliance modules pack if race-free"
@echo " om-race - Build om if race-free"
@echo " ox-race - Build ox if race-free"
@echo " test-race - Run tests with race detection"

47 changes: 26 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,31 +1,36 @@
# README.md
# om3

[![Go](https://github.com/opensvc/om3/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/opensvc/om3/actions/workflows/go.yml)

**_NOTE:_** This project is the golang port and next release of https://github.com/opensvc/opensvc.
*The Go port and continuation of [opensvc/opensvc](https://github.com/opensvc/opensvc).*

> **_NOTE:_** General Availability is expected Q1 2025
om3 is a cluster orchestrator for small-to-mid clusters — a coherent alternative to
stitching together systemd, container runtimes, and ad-hoc scripts, with symmetric
orchestration on every node.

A cluster orchestrator with a distinctive feature set
=====================================================
## Features

* Simple and powerful
* Targeted at 1-32 nodes clusters
* Human readable services configurations and status
* Coherent alternative to a wide range of integration methods: from systemd to kubernetes
* Highly redundant cluster communications (ucast, mcast, disk, 3rd site relay)
* All nodes symmetric orchestration policies
* Orchestrate application stacks based on containers, and much more
* Provision stacks from template configurations, including disk, vg, fs, ip
* Optional CNI cluster networks, cluster DNS, ingress gateways
* DevOps, or pipelined delivery
* Targeted at 1-32 node clusters, human-readable service configurations and status
* Highly redundant cluster communications (unicast, multicast, disk, third-site relay)
* Deploy application stacks on containers, persistent or volatile volumes, or
low-level resources — disks, volume groups, filesystems, IP addresses, app launchers
* Native, zeroconf, encrypted datastores, with keys exposed as files for your deployments
* Manage everything through the API, the `om` command line, or the `ox` terminal UI

Dig Agent Features
==================
## Install

https://book.opensvc.com
See the [installation guide](https://book.opensvc.com/agent/install.html) — the
complete documentation lives there too.

Agent Installation
==================
## Play

https://book.opensvc.com/agent/install.html
Deploy a simple service:
```
om test/svc/simple deploy --kw fs#1.type=flag --kw nodes='*' --kw orchestrate=ha
```
Then open an `ox` session and watch it move around the cluster.

## Examples

Browse [ready-to-use templates](https://github.com/opensvc/opensvc_templates) — VIPs,
cluster DNS, ingress gateways, ACME, HA NFS, meshed VPN backend networks, and more.
221 changes: 221 additions & 0 deletions core/commoncmd/factory_kind.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
package commoncmd

import (
"github.com/spf13/cobra"
)

// NewCmdAll creates the "all" command
func NewCmdAll() *cobra.Command {
return &cobra.Command{
Use: "all",
Short: "manage a mix of objects, tentatively exposing all commands",
}
}

// NewCmdCcfg creates the "ccfg" command
func NewCmdCcfg() *cobra.Command {
return &cobra.Command{
Use: "ccfg",
Short: "manage the cluster shared configuration",
Long: `The cluster nodes merge their private configuration
over the cluster shared configuration.

The shared configuration is hosted in a ccfg-kind object, and is
replicated using the same rules as other kinds of object (last write is
eventually replicated).`,
}
}

// NewCmdCfg creates the "cfg" command
func NewCmdCfg() *cobra.Command {
return &cobra.Command{
Use: "cfg",
Short: "manage configmaps",
Long: `A configmap is an unencrypted key-value store.

Values can be binary or text.

A key can be installed as a file in a Vol, then exposed to apps
and containers.

A key can be exposed as a environment variable for apps and
containers.

A signal can be sent to consumer processes upon exposed key value
changes.

The key names can include the '/' character, interpreted as a path separator
when installing the key in a volume.`,
}
}

// NewCmdSec creates the "sec" command
func NewCmdSec() *cobra.Command {
return &cobra.Command{
Use: "sec",
Short: "manage secrets",
Long: `A secret is an encrypted key-value store.

Values can be binary or text.

A key can be installed as a file in a Vol, then exposed to apps
and containers.

A key can be exposed as a environment variable for apps and
containers.

A signal can be sent to consumer processes upon exposed key value
changes.

The key names can include the '/' character, interpreted as a path separator
when installing the key in a volume.`,
}
}

// NewCmdSVC creates the "svc" command
func NewCmdSVC() *cobra.Command {
return &cobra.Command{
Use: "svc",
Short: "manage services",
Long: `Service objects subsystem.

A service is typically made of ip, app, container and task resources.

They can use support objects like volumes, secrets and configmaps to
isolate lifecycles or to abstract cluster-specific knowledge.`,
}
}

// NewCmdUsr creates the "usr" command
func NewCmdUsr() *cobra.Command {
return &cobra.Command{
Use: "usr",
Short: "manage users",
Long: `A user stores the grants and credentials of user of the agent API.

User objects are not necessary with OpenID authentication, as the
grants are embedded in the trusted bearer tokens.`,
}
}

// NewCmdVol creates the "vol" command
func NewCmdVol() *cobra.Command {
return &cobra.Command{
Use: "vol",
Short: "manage volumes",
Long: `A volume is a persistent data provider.

A volume is made of disk, fs and sync resources. It is created by a pool,
to satisfy a demand from a volume resource in a service.

Volumes and their subdirectories can be mounted inside containers.`,
}
}

// NewCmdNscfg creates the "nscfg" command
func NewCmdNscfg() *cobra.Command {
return &cobra.Command{
Use: "nscfg",
Short: "manage namespace configurations",
}
}

// NewCmdNetwork creates the "network" command
func NewCmdNetwork() *cobra.Command {
return &cobra.Command{
Use: "network",
Short: "manage backend networks",
Aliases: []string{"net"},
Long: "A backend network provides ip addresses to svc objects via ip.cni resources. These addresses are automatically allocated, accessible from all cluster nodes, and resolved by the cluster dns.",
}
}

// NewCmdNetworkIP creates the "ip" subcommand for network
func NewCmdNetworkIP() *cobra.Command {
return &cobra.Command{
Use: "ip",
Short: "manage ip on backend networks",
}
}

// NewCmdPool creates the "pool" command
func NewCmdPool() *cobra.Command {
return &cobra.Command{
Use: "pool",
Short: "manage storage pools",
Long: " A pool is a vol provider. Pools abstract the hardware and software specificities of the cluster infrastructure.",
}
}

// NewCmdPoolVolume creates the "volume" subcommand for pool
func NewCmdPoolVolume() *cobra.Command {
return &cobra.Command{
Use: "volume",
Short: "manage storage pool volumes",
Aliases: []string{"vol"},
}
}

// NewCmdNodeCapabilities creates the "capabilities" subcommand for node
func NewCmdNodeCapabilities() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "capabilities",
Short: "scan and list what the node is capable of",
Aliases: []string{"capa", "caps", "cap"},
}
}

// NewCmdNodeCollector creates the "collector" subcommand for node
func NewCmdNodeCollector() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "collector",
Short: "node collector data management commands",
}
}

// NewCmdNodeCollectorTag creates the "tag" subcommand for node collector
func NewCmdNodeCollectorTag() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "tag",
Short: "collector tags management commands",
}
}

// NewCmdNodeCompliance creates the "compliance" subcommand for node
func NewCmdNodeCompliance() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "compliance",
Short: "node configuration manager commands",
}
}

// NewCmdNodeSCSI creates the "scsi" subcommand for node
func NewCmdNodeSCSI() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "scsi",
Short: "scsi commands",
}
}

// NewCmdNodeRelay creates the "relay" subcommand for node
func NewCmdNodeRelay() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "relay",
Short: "relay commands",
}
}

// NewCmdNodeSSH creates the "ssh" subcommand for node
func NewCmdNodeSSH() *cobra.Command {
return &cobra.Command{
GroupID: GroupIDSubsystems,
Use: "ssh",
Short: "ssh commands",
}
}
Loading
Loading