-
Notifications
You must be signed in to change notification settings - Fork 2
starting and stopping
Pre-Alpha. This page describes behavior that may change.
Running Ze is the same as running any other Unix daemon with one small twist: SSH credentials must exist before the daemon can expose its CLI. The first time you install Ze, you run ze init once to create the credentials, and after that you treat the process like any other long-running service.
ze initze init is interactive. It prompts for a username, a password, an SSH host, an SSH port, and a name (instance name). Defaults are 127.0.0.1:2222. The database (database.zefs) is created with bcrypt-hashed credentials; the ED25519 host key is auto-generated on first daemon start. You only run it once per install. Running it a second time fails with error: database already exists, which is deliberate.
If you genuinely need to re-initialise (credentials lost, database corrupted, fresh start on the same host), stop the daemon first and then use --force.
ze signal stop
ze init --force--force moves the old database to database.zefs.replaced-<date> as a backup before creating a new one. The data can come from piped stdin; only the confirmation "Type 'yes' to proceed" requires a terminal (either stdin if it is a terminal, or /dev/tty if stdin is a pipe).
ze start # Start from the database
ze start <config-file> # Start with an explicit config file
ze -d start <config-file> # Start with debug logging
ze - # Read the config from stdinA bare ze <config-file> used to work and no longer does. Position 1 of ze accepted a command name or a free-form config path, so a config file named like a command (bgp, signal) was dispatched as that command and never loaded. The path now follows the start keyword. The one free-form value left at position 1 is -, which cannot collide with a command name and reads the config from stdin.
The useful flags are all listed in the command reference. The short version:
| Flag | Purpose |
|---|---|
-d, --debug
|
Shorthand for ze.log=debug and ze.log.relay=debug. |
-f <file> |
Use filesystem storage instead of the blob database. |
--plugin <name> |
Load an extra plugin at start. Repeatable. |
--pprof <addr:port> |
Start the pprof HTTP profiler. |
--chaos-seed <N> |
Deterministic chaos testing. 0 disables with zero overhead. |
--web <port>, --mcp <port>
|
Start the web UI and the MCP server on specific ports. |
ze signal stop # Graceful stop, no GR marker
ze signal restart # Graceful stop WITH GR marker, for restartze signal stop tears down every session with NOTIFICATION Cease (code 6, subcode 2, Administrative Shutdown) and shuts the daemon down cleanly. Peers drop the routes. Use it when you want to stop, not when you want to replace the binary.
ze signal restart is the one you want for binary upgrades. It does the same shutdown but writes the GR marker file on the way out, so when you start the daemon again, peers that negotiated Graceful Restart hold their routes during the handover. The full story is in Upgrade and restart.
Both commands exit non-zero on failure. 1 means the daemon is not running. 2 means no SSH credentials (you forgot ze init). 4 means delivery failed for another reason.
ze signal reload # Re-parse the on-disk config and applyThis is the hot-reload path. It re-parses the config, hands the new tree to the config provider, and every subsystem reconfigures in place. Peers get added, removed, or updated without restarting the daemon. If a change forces a session reset (you changed a capability the peer cannot renegotiate, you moved the local IP, you changed authentication), Ze tells you which sessions will bounce before it bounces them.
The same thing works through Unix signals: SIGHUP reloads, SIGTERM and SIGINT shut down gracefully, SIGUSR1 triggers a status callback logged via the structured logger at Warn level. Use the SSH path from scripts so you get a non-zero exit code on failure. Use the signals when you are already at a shell.
A reload can be carried out two ways: as a set of decomposed operations (add this peer, remove that one), or as a plain apply of each participant's config diff. The operation path is now taken only when it covers every participant that would otherwise be applied, using the same predicate that selects participants for verification, so a participant cannot be verified by one path and skipped by the other.
Before that, one participant yielding operations put the whole transaction on the operation path, and a participant with real diffs but no decomposer was verified and then never applied. Its change was dropped while the reload reported success. A reload that both added a BGP peer and changed a WireGuard interface did exactly this: the interface participant logged nothing at all between received SIGHUP and sighup reload complete.
The trade-off is deliberate. Falling back all-or-nothing costs that transaction's cross-participant operation ordering, which is what reloads had before the operation path existed. Losing ordering is recoverable; losing the change is not.
A plugin whose config root is a nested path (ddos/local, anomaly/detect, traffic/usage) is now driven by reload too. Changed keys were previously grouped under their top-level root only, so a lookup for the plugin's declared nested root found nothing and the plugin was skipped for both verify and apply while the daemon reported the reload complete. Startup was unaffected, because it reads the declared roots directly, which is why only reload was dead. Eight plugins were affected.
[Unit]
Description=Ze BGP Daemon
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
ExecStart=/usr/local/bin/ze start /etc/ze/config.conf
ExecReload=/usr/local/bin/ze signal reload
ExecStop=/usr/local/bin/ze signal stop
Restart=on-failure
RestartSec=5
LimitNOFILE=65535
StandardError=journal
SyslogIdentifier=ze
[Install]
WantedBy=multi-user.targetInitialise credentials before you enable the unit.
sudo ze init
sudo systemctl enable --now zeLimitNOFILE=65535 matters: Ze can hold a lot of file descriptors under load. Letting the systemd default cap you at 1024 is a common reason a large deployment drops sessions.
ze status # Liveness, 0 = running, 1 = notze status dials the SSH port without completing the handshake. It is cheap enough to run from a systemd watchdog or a load-balancer TCP probe. For a deeper check, go through the CLI.
ze cli -c "peer list" # Brief peer list
ze cli -c "bgp summary" # Per-peer state and uptimeIf you want a dedicated service healthcheck that drives route announcement and withdrawal from a shell command, that is a different feature. See healthcheck.
- Upgrade and restart for binary upgrades without dropping sessions.
- Command reference for every flag and every exit code.
- Logging for how to turn the noise up or down.
Adapted from main/docs/guide/operations.md.
Unreviewed draft. This wiki was authored in bulk and has not been reviewed. File corrections on the issue tracker.
- Overview
- YANG Model
- Editor Workflow
- Archive and Rollback
- System
- Interfaces
- VRRP
- BFD
- FIB
- OSPF
- IS-IS
- MPLS / LDP / RSVP-TE
- RSVP-TE
- SRv6
- Static Routes
- Policy Routing
- Firewall
- Traffic Control
- Class of Service
- L2TP/PPP
- PPPoE
- VPP Data Plane
- RPKI
- IPsec VPN
- TACACS+ AAA
- RADIUS AAA
- AS112 DNS
- Authorization
- Fleet
- BGP
- Starting and Stopping
- Show Commands
- Monitoring
- Flow Export
- DDoS Mitigation
- Anomaly Detection
- Health Checks
- Audit Trail
- Production Diagnostics
- Logging
- Operational Reports
- Healthcheck
- Self-Update
- Zero-Touch Provisioning
- MRT Analysis
- Upgrade and Restart
- Storage
- Policy
- Core
- Resilience
- Validation
- Capabilities
- Address Families
- Protocol
- Subsystems
- Infrastructure
- Route Server at an IXP
- Transit Edge with RPKI
- Public Looking Glass
- ExaBGP Migration Walkthrough
- FlowSpec Injection
- Chaos-Tested Peering
- AS Path Topology