Fixed odd issue with the cli not finding the socket properly
Release / release (push) Successful in 3m21s
Container image / image (push) Successful in 5m57s

This commit is contained in:
2026-05-15 08:05:55 +00:00
parent f60b0a0609
commit a1d74cf36d
2 changed files with 39 additions and 14 deletions
+14 -2
View File
@@ -4,7 +4,7 @@ All notable changes to this project are documented here. The format
follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [Unreleased]
## [v0.1.1] — 2026-05-15
### Changed
@@ -19,6 +19,17 @@ this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
that left files owned by root). Unknown files in the dir are left
alone.
### Fixed
- **CLI socket lookup as the daemon user.** `sudo -u quptime qu …`
no longer fails with `dial daemon socket /tmp/quptime-quptime/…:
no such file or directory` while the system daemon is running.
`config.SocketPath()` now probes the canonical systemd location
(`/run/quptime/quptime.sock`, then `/var/run/quptime/quptime.sock`)
regardless of euid before falling back to per-user paths, so the
CLI reaches the daemon's socket even when `sudo` has stripped
`RUNTIME_DIRECTORY` and `XDG_RUNTIME_DIR` from the environment.
## [v0.1.0] — 2026-05-15
### Changed
@@ -127,4 +138,5 @@ Initial public release.
Planned for a future release.
[v0.0.1]: https://git.cer.sh/axodouble/quptime/releases/tag/v0.0.1
[v0.1.0]: https://git.cer.sh/axodouble/quptime/releases/tag/v0.1.0
[v0.1.0]: https://git.cer.sh/axodouble/quptime/releases/tag/v0.1.0
[v0.1.1]: https://git.cer.sh/axodouble/quptime/releases/tag/v0.1.1
+25 -12
View File
@@ -58,19 +58,20 @@ func DataDir() string {
// SocketPath returns the unix socket used for local CLI ↔ daemon control.
//
// Resolution order:
// 1. $QUPTIME_SOCKET — explicit operator override
// 1. $QUPTIME_SOCKET — explicit operator override.
// 2. $RUNTIME_DIRECTORY — set by systemd when the unit declares
// RuntimeDirectory=quptime. This is the path that matters in
// practice: with User=quptime + PrivateTmp=true, the daemon's
// /tmp is namespaced and invisible to the root CLI shell, so a
// /tmp fallback yields "no such file" even though the daemon is
// happily listening. Anchoring on $RUNTIME_DIRECTORY puts the
// socket at /run/quptime/quptime.sock, which is the same inode
// the root-CLI default (/var/run/quptime/…) reaches via the
// /var/run → /run symlink.
// 3. /var/run/quptime/… when euid is 0 (CLI side, packaged installs)
// 4. $XDG_RUNTIME_DIR/quptime/… for user-mode installs
// 5. /tmp/quptime-<user>/… as a last resort
// RuntimeDirectory=quptime. This is the path the daemon uses
// when run under the packaged unit: /run/quptime/quptime.sock.
// 3. The canonical system socket path — /run/quptime/quptime.sock —
// if it exists. This catches the CLI side regardless of who is
// invoking it: `sudo -u quptime qu status` strips RUNTIME_DIRECTORY
// and XDG_RUNTIME_DIR, so without this probe the CLI falls all
// the way through to /tmp/quptime-<user>/… and reports "no such
// file" even while the daemon is happily listening.
// 4. /var/run/quptime/… when euid is 0 (CLI side, packaged installs
// on systems where /var/run isn't a symlink to /run).
// 5. $XDG_RUNTIME_DIR/quptime/… for user-mode installs.
// 6. /tmp/quptime-<user>/… as a last resort.
func SocketPath() string {
if v := os.Getenv("QUPTIME_SOCKET"); v != "" {
return v
@@ -84,6 +85,18 @@ func SocketPath() string {
}
return filepath.Join(v, SocketName)
}
// If a system-managed daemon is already listening, route there
// regardless of euid. Without this, `sudo -u quptime qu …` can't
// find the socket the daemon (also running as quptime) created
// via RuntimeDirectory=.
for _, p := range []string{
"/run/quptime/" + SocketName,
"/var/run/quptime/" + SocketName,
} {
if _, err := os.Stat(p); err == nil {
return p
}
}
if os.Geteuid() == 0 {
return "/var/run/quptime/" + SocketName
}