Skip to content

Operations

Service control

The RPM ships a systemd template unit named pdns-pf-oxfeed-gitfeed@.service, running as the pdns-oxfeed user. One instance is started per logical feed (typically one per upstream repository).

To add an instance called my-feed:

# 1. Drop a config file for this instance.
cp /etc/pdns-pf/oxfeed-gitfeed/example.yml \
   /etc/pdns-pf/oxfeed-gitfeed/my-feed.yml
$EDITOR /etc/pdns-pf/oxfeed-gitfeed/my-feed.yml

# 2. Enable an instance of the template unit.
ln -s /lib/systemd/system/pdns-pf-oxfeed-gitfeed@.service \
      /etc/systemd/system/pdns-pf-oxfeed-gitfeed@my-feed.service

# 3. Bring it up.
systemctl daemon-reload
systemctl enable --now pdns-pf-oxfeed-gitfeed@my-feed

Everyday commands for an existing instance:

# Status and recent logs
systemctl status pdns-pf-oxfeed-gitfeed@my-feed

# Follow the log stream
journalctl -u pdns-pf-oxfeed-gitfeed@my-feed -f

# Restart after a config change
systemctl restart pdns-pf-oxfeed-gitfeed@my-feed

The service does not watch its config file for changes; restart the instance after editing.

Config location

Each instance reads /etc/pdns-pf/oxfeed-gitfeed/<instance>.yml. The RPM ships a commented template at /etc/pdns-pf/oxfeed-gitfeed/example.yml but does not install a ready-to-use per-instance config. See Configuration for the full reference.

Command-line flags

Flag Default Purpose
-config Path to the YAML config file. The packaged unit passes the per-instance file.
-expand-env false Expand ${VAR} references inside the YAML file.
-strict false Reject unknown YAML fields instead of ignoring them. Recommended.
-r Override git.root.
-f Override git.file_path.
-o Override feed.root with a filesystem path or simpleblob:// URI.
-w false Watch mode (long-lived daemon). Same effect as run_once: false in YAML.
-incremental false Start from the last git_head in feed.json. See Architecture → Incremental startup.
-auth-http-username HTTP Basic username. Overrides config.
-auth-http-password HTTP Basic password. Also accepted via GITFEED_HTTP_PASSWORD.
-auth-ssh-identity SSH identity file (unencrypted; for deployment keys).
-check-interval 0 (use config / 5s) Override git.check_interval.
-fetch-interval 0 (use config / 5m) Override git.fetch_interval.
-http-addr Override http.address.
-http-serve-feed false Override http.serve_feed.
-debug false Shortcut for -log-level=debug.
-log-level (config) Override log.level.
-log-format (config) Override log.format.
-log-timestamp (config) Override log.timestamp.
-version Print version and exit.

Running with only a -config argument is the standard production mode. The packaged unit invokes /usr/bin/pdns-pf-oxfeed-gitfeed --config /etc/pdns-pf/oxfeed-gitfeed/<instance>.yml which defaults run_once to false.

Running without -config (CLI-only) is a one-shot mode useful for ad-hoc conversions:

pdns-pf-oxfeed-gitfeed \
    -r /path/to/local/repo \
    -f feed.csv \
    -o /tmp/feed-out

In this mode the service exits after writing the feed once.

Environment variables

Variable Purpose
GITFEED_HTTP_PASSWORD HTTP Basic password for git. Read at startup; overridden by -auth-http-password if both are set.

When -expand-env is passed, every ${NAME} in the YAML file is substituted from the process environment as well — use this to keep secrets out of the YAML file.

HTTP endpoints

The HTTP server bound to http.address exposes:

  • Status page (/). HTML summary of the running converter: memory use, uptime, current git HEAD and ref, total feed size, and per-snapshot and per-delta tables with version, entry count, commit hash, and the first line of each commit message.
  • Metrics (/metrics). Prometheus endpoint. See Metrics.
  • Healthz (/healthz). JSON response from the embedded go-healthz library. Gitfeed does not register custom checks, so this reports liveness only.
  • pprof (/debug/pprof/...). Go net/http/pprof handlers for CPU, heap, goroutine, and block profiles.
  • Feed tree (/feed/). Only when http.serve_feed is set. Development and testing only — front the feed tree with a static HTTP server in production.

Watch mode vs. one-shot

  • Watch mode (run_once: false, the default when -config is given, or -w on the command line). The service runs the initial full conversion, then waits for HEAD changes. Local roots are polled every git.check_interval; remote roots additionally fetch every git.fetch_interval. Command-source overlays run on git.command_source.interval.
  • One-shot (run_once: true, the default without -config). Writes the feed once and exits.

feed-codes.json is regenerated from git.codes_csv_file_path or git.codes_json_file_path on every write, in both modes — there is no separate codes refresh cadence to tune.

Memory model for remote repos

Remote repos are cloned into an in-memory go-billy filesystem. That means:

  • The clone is rebuilt from scratch on every process start; restart is cheap but adds startup time roughly proportional to repo size.
  • Repo size grows the process RSS. Multi-gigabyte repositories are not appropriate for this service; use a local clone maintained by a sidecar puller in that case.
  • incremental: true does not skip the clone — it only skips the linear log walk after the clone is up.

Troubleshooting

Empty repo / cannot resolve HEAD

The service logs Repo has no HEAD reference (empty) and writes nothing. This is intentional during initial setup. Push a first commit to the repo and the next tick will pick it up.

History rewrite

After a force-push or rebase, expect a single spike on oxfeed_gitfeed_reset_total and a matching jump on oxfeed_gitfeed_version_remove_total. The feed is rebuilt from sequential number 1 and downstream clients re-snap from the new history.

Fetch failures

Transient errors (DNS, TLS handshake, auth refresh) increment oxfeed_gitfeed_fetch_error_total but do not fatal the process. Persistent failure shows as the success gap between the gauge and the current time growing without bound. Investigate by tailing the journal: the underlying go-git error is logged with level=error.

Command source not producing updates

When the command-source overlay is configured but no new commits appear:

  1. Check that oxfeed_source_command_exec_total is increasing — the command is being scheduled.
  2. Check oxfeed_source_command_exec_exitcode_total. Exit code 11 ("not modified") is the expected steady state when the source data is quiet; non-zero codes other than 11 indicate a broken command.
  3. Check oxfeed_source_command_feed_change_total. If exec rate is high but change rate is zero, the command keeps producing the same output — verify the source data actually changed.