feat(gateway): hivectl gateway user management + fix htpasswdFile assertion
Add `hivectl gateway {create-user,delete-user,list-users}` subcommands for
managing htpasswd files used by gateway Basic auth. Pure Rust bcrypt
(cost 12, $2y$ prefix nginx accepts). No external htpasswd binary required.
Also fix the NixOS module assertion: `cfg.auth ? htpasswdFile` is always
true in the module system (declared options always exist as keys); switch
to `nullOr path; default = null` + `!= null` check so the assertion
actually fires with a useful error when enable=true but no file is set.
Guard bind-mount and nginx config against null to prevent eval errors.
Update docs/gateway.md to show hivectl commands instead of raw htpasswd.
This commit is contained in:
parent
25d2951d1e
commit
4bff450343
61 changed files with 1084 additions and 547 deletions
|
|
@ -23,7 +23,7 @@ use std::time::{Duration, SystemTime, UNIX_EPOCH};
|
|||
|
||||
use crate::coordinator::Coordinator;
|
||||
|
||||
const VACUUM_INTERVAL: Duration = Duration::from_hours(1);
|
||||
const VACUUM_INTERVAL: Duration = Duration::from_secs(3600);
|
||||
/// Keep completed task files for 48 hours before sweeping them.
|
||||
const KEEP_SECS: i64 = 48 * 3600;
|
||||
|
||||
|
|
@ -65,7 +65,9 @@ fn sweep_once() {
|
|||
/// files removed (each represents one task; `.out`/`.err` deletions
|
||||
/// are not counted separately).
|
||||
fn vacuum_dir(dir: &Path, cutoff: i64) -> u64 {
|
||||
let Ok(rd) = std::fs::read_dir(dir) else { return 0 };
|
||||
let Ok(rd) = std::fs::read_dir(dir) else {
|
||||
return 0;
|
||||
};
|
||||
let mut removed: u64 = 0;
|
||||
for entry in rd.flatten() {
|
||||
let path = entry.path();
|
||||
|
|
@ -97,7 +99,10 @@ fn should_delete(json_path: &Path, cutoff: i64) -> bool {
|
|||
if !TERMINAL_STATUSES.contains(&status) {
|
||||
return false;
|
||||
}
|
||||
let completed_at = v.get("completed_at").and_then(serde_json::Value::as_i64).unwrap_or(i64::MAX);
|
||||
let completed_at = v
|
||||
.get("completed_at")
|
||||
.and_then(|t| t.as_i64())
|
||||
.unwrap_or(i64::MAX);
|
||||
completed_at < cutoff
|
||||
}
|
||||
|
||||
|
|
@ -106,10 +111,10 @@ fn should_delete(json_path: &Path, cutoff: i64) -> bool {
|
|||
fn delete_trio(dir: &Path, stem: &str) {
|
||||
for ext in ["json", "out", "err"] {
|
||||
let path = dir.join(format!("{stem}.{ext}"));
|
||||
if path.exists()
|
||||
&& let Err(e) = std::fs::remove_file(&path)
|
||||
{
|
||||
tracing::warn!(path = %path.display(), error = ?e, "bash-tasks vacuum: remove failed");
|
||||
if path.exists() {
|
||||
if let Err(e) = std::fs::remove_file(&path) {
|
||||
tracing::warn!(path = %path.display(), error = ?e, "bash-tasks vacuum: remove failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue