rebuilderd_common/
config.rs

1use crate::auth::AuthConfig;
2use crate::errors::*;
3use serde::Deserialize;
4use std::collections::HashMap;
5use std::fs;
6use std::path::{Path, PathBuf};
7
8pub const IDLE_DELAY: u64 = 180;
9pub const PING_DEADLINE: i64 = PING_INTERVAL as i64 * 9;
10pub const PING_INTERVAL: u64 = 60;
11pub const WORKER_DELAY: u64 = 3;
12pub const API_ERROR_DELAY: u64 = 30;
13
14pub const DEFAULT_RETRY_DELAY_BASE: i64 = 24;
15
16pub fn load<P: AsRef<Path>>(path: Option<P>) -> Result<ConfigFile> {
17    let mut config = ConfigFile::default();
18
19    if let Some(c) = load_from("/etc/rebuilderd.conf")? {
20        config.update(c);
21    }
22
23    if let Ok(path) = config_path() {
24        if let Some(c) = load_from(path)? {
25            config.update(c);
26        }
27    }
28
29    if let Some(path) = path {
30        let c = load_from(path)?.ok_or_else(|| format_err!("Failed to read config file"))?;
31        config.update(c);
32    }
33
34    Ok(config)
35}
36
37fn config_path() -> Result<PathBuf> {
38    let config_dir =
39        dirs_next::config_dir().ok_or_else(|| format_err!("Failed to find config dir"))?;
40    Ok(config_dir.join("rebuilderd.conf"))
41}
42
43fn load_from<P: AsRef<Path>>(path: P) -> Result<Option<ConfigFile>> {
44    if let Ok(buf) = fs::read_to_string(path.as_ref()) {
45        debug!("loading config file {:?}", path.as_ref());
46        let config = toml::from_str(&buf).context("Failed to load config")?;
47        Ok(Some(config))
48    } else {
49        Ok(None)
50    }
51}
52
53#[derive(Debug, Default, Clone, Deserialize)]
54pub struct ConfigFile {
55    #[serde(default)]
56    pub http: HttpConfig,
57    #[serde(default)]
58    pub auth: AuthConfig,
59    #[serde(default)]
60    pub endpoints: HashMap<String, EndpointConfig>,
61    #[serde(default)]
62    pub worker: WorkerConfig,
63    #[serde(default)]
64    pub schedule: ScheduleConfig,
65}
66
67impl ConfigFile {
68    pub fn update(&mut self, c: ConfigFile) {
69        self.http.update(c.http);
70        self.auth.update(c.auth);
71        for (k, v) in c.endpoints {
72            if let Some(o) = self.endpoints.get_mut(&k) {
73                o.update(v);
74            } else {
75                self.endpoints.insert(k, v);
76            }
77        }
78        self.worker.update(c.worker);
79        self.schedule.update(c.schedule);
80    }
81}
82
83#[derive(Debug, Default, Clone, Deserialize)]
84pub struct HttpConfig {
85    pub bind_addr: Option<String>,
86    pub real_ip_header: Option<String>,
87    pub post_body_size_limit: Option<usize>,
88    pub transparently_sign_attestations: Option<bool>,
89    pub endpoint: Option<String>,
90}
91
92impl HttpConfig {
93    pub fn update(&mut self, c: HttpConfig) {
94        if c.bind_addr.is_some() {
95            self.bind_addr = c.bind_addr;
96        }
97        if c.real_ip_header.is_some() {
98            self.real_ip_header = c.real_ip_header;
99        }
100        if c.endpoint.is_some() {
101            self.endpoint = c.endpoint;
102        }
103    }
104}
105
106#[derive(Debug, Default, Clone, Deserialize)]
107pub struct EndpointConfig {
108    pub cookie: String,
109}
110
111impl EndpointConfig {
112    pub fn update(&mut self, c: EndpointConfig) {
113        self.cookie = c.cookie;
114    }
115}
116
117#[derive(Debug, Default, Clone, Deserialize)]
118pub struct WorkerConfig {
119    #[serde(default)]
120    pub authorized_workers: Vec<String>,
121    pub signup_secret: Option<String>,
122}
123
124impl WorkerConfig {
125    pub fn update(&mut self, c: WorkerConfig) {
126        if !c.authorized_workers.is_empty() {
127            self.authorized_workers = c.authorized_workers;
128        }
129        if c.signup_secret.is_some() {
130            self.signup_secret = c.signup_secret;
131        }
132    }
133}
134
135#[derive(Debug, Default, Clone, Deserialize)]
136pub struct ScheduleConfig {
137    retry_delay_base: Option<i64>,
138}
139
140impl ScheduleConfig {
141    pub fn update(&mut self, c: ScheduleConfig) {
142        if c.retry_delay_base.is_some() {
143            self.retry_delay_base = c.retry_delay_base;
144        }
145    }
146
147    pub fn retry_delay_base(&self) -> i64 {
148        self.retry_delay_base.unwrap_or(DEFAULT_RETRY_DELAY_BASE)
149    }
150}