mirror of
https://github.com/SeriousBug/gandi-live-dns-rust
synced 2024-12-28 08:10:14 -06:00
Use async sleep & document the repeat option (#70)
* Use async sleep when long running Using an async sleep just seems more appropriate as we are in an async context, although the results are identical since gandi-live-dns only uses a single thread. * Document repeat option * Fix lints
This commit is contained in:
parent
041c1109e0
commit
220e368bf3
32
Readme.md
32
Readme.md
|
@ -10,8 +10,8 @@ this creates a dynamic DNS system.
|
||||||
If you want to host web services but you don't have a static IP address, this
|
If you want to host web services but you don't have a static IP address, this
|
||||||
tool will allow you to keep your domains pointed at the right IP address. This
|
tool will allow you to keep your domains pointed at the right IP address. This
|
||||||
program can update both IPv4 and IPv6 addresses for one or more domains and
|
program can update both IPv4 and IPv6 addresses for one or more domains and
|
||||||
subdomains. It's a one-shot tool that's meant to be managed with a systemd timer
|
subdomains. It can be used as a one-shot tool managed with a systemd timer
|
||||||
or cron.
|
or cron, or a long-running process that reschedules itself.
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|
||||||
|
@ -67,6 +67,34 @@ build it from source and you have a working rust install, you can use `cargo ins
|
||||||
|
|
||||||
## Automation
|
## Automation
|
||||||
|
|
||||||
|
### By running as a background process
|
||||||
|
|
||||||
|
`gandi-live-dns` can run as a daemon, a background process, periodically perform
|
||||||
|
the IP address updates. To do so, add the `--repeat=<delay-in-seconds>` command
|
||||||
|
line option. When given, this tool will not quit after updating your IP address
|
||||||
|
and instead will continue to perform periodic updates.
|
||||||
|
|
||||||
|
If you are using Docker, you can add this option when starting it:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# This will update your IP now, then repeat every 24 hours
|
||||||
|
docker run --rm -it -v $(pwd)/gandi.toml:/gandi.toml:ro seriousbug/gandi-live-dns-rust:latest --repeat=86400
|
||||||
|
```
|
||||||
|
|
||||||
|
Or with a `docker-compose.yml` file, add it in the arguments:
|
||||||
|
|
||||||
|
```yml
|
||||||
|
gandi-live-dns:
|
||||||
|
image: seriousbug/gandi-live-dns-rust:latest
|
||||||
|
restart: always
|
||||||
|
volumes:
|
||||||
|
- ./gandi.toml:/gandi.toml:ro
|
||||||
|
# Repeat the update every day
|
||||||
|
command: --repeat=86400
|
||||||
|
```
|
||||||
|
|
||||||
|
### With a Systemd timer
|
||||||
|
|
||||||
The `Packaging` folder contains a Systemd service and timer, which you can use
|
The `Packaging` folder contains a Systemd service and timer, which you can use
|
||||||
to automatically run this tool. By default it will update the IP addresses after
|
to automatically run this tool. By default it will update the IP addresses after
|
||||||
every boot up, and at least once a day. You can adjust the timer to speed this
|
every boot up, and at least once a day. You can adjust the timer to speed this
|
||||||
|
|
11
src/main.rs
11
src/main.rs
|
@ -6,9 +6,8 @@ use config::IPSourceName;
|
||||||
use ip_source::icanhazip::IPSourceIcanhazip;
|
use ip_source::icanhazip::IPSourceIcanhazip;
|
||||||
use reqwest::{header, Client, ClientBuilder, StatusCode};
|
use reqwest::{header, Client, ClientBuilder, StatusCode};
|
||||||
use serde::Serialize;
|
use serde::Serialize;
|
||||||
use std::thread;
|
|
||||||
use std::{num::NonZeroU32, sync::Arc, time::Duration};
|
use std::{num::NonZeroU32, sync::Arc, time::Duration};
|
||||||
use tokio::{self, task::JoinHandle};
|
use tokio::{self, task::JoinHandle, time::sleep};
|
||||||
mod config;
|
mod config;
|
||||||
mod gandi;
|
mod gandi;
|
||||||
mod ip_source;
|
mod ip_source;
|
||||||
|
@ -41,7 +40,7 @@ pub struct APIPayload {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn run<IP: IPSource>(base_url: &str, conf: &Config) -> anyhow::Result<()> {
|
async fn run<IP: IPSource>(base_url: &str, conf: &Config) -> anyhow::Result<()> {
|
||||||
config::validate_config(&conf).die_with(|error| format!("Invalid config: {}", error));
|
config::validate_config(conf).die_with(|error| format!("Invalid config: {}", error));
|
||||||
println!("Finding out the IP address...");
|
println!("Finding out the IP address...");
|
||||||
let ipv4_result = IP::get_ipv4().await;
|
let ipv4_result = IP::get_ipv4().await;
|
||||||
let ipv6_result = IP::get_ipv6().await;
|
let ipv6_result = IP::get_ipv6().await;
|
||||||
|
@ -69,7 +68,7 @@ async fn run<IP: IPSource>(base_url: &str, conf: &Config) -> anyhow::Result<()>
|
||||||
|
|
||||||
for entry in &conf.entry {
|
for entry in &conf.entry {
|
||||||
for entry_type in Config::types(entry) {
|
for entry_type in Config::types(entry) {
|
||||||
let fqdn = Config::fqdn(entry, &conf).to_string();
|
let fqdn = Config::fqdn(entry, conf).to_string();
|
||||||
let url = GandiAPI {
|
let url = GandiAPI {
|
||||||
fqdn: &fqdn,
|
fqdn: &fqdn,
|
||||||
rrset_name: &entry.name,
|
rrset_name: &entry.name,
|
||||||
|
@ -84,7 +83,7 @@ async fn run<IP: IPSource>(base_url: &str, conf: &Config) -> anyhow::Result<()>
|
||||||
};
|
};
|
||||||
let payload = APIPayload {
|
let payload = APIPayload {
|
||||||
rrset_values: vec![ip.to_string()],
|
rrset_values: vec![ip.to_string()],
|
||||||
rrset_ttl: Config::ttl(entry, &conf),
|
rrset_ttl: Config::ttl(entry, conf),
|
||||||
};
|
};
|
||||||
let req = client.put(url).json(&payload);
|
let req = client.put(url).json(&payload);
|
||||||
let task_governor = governor.clone();
|
let task_governor = governor.clone();
|
||||||
|
@ -126,7 +125,7 @@ async fn main() -> anyhow::Result<()> {
|
||||||
if let Some(delay) = opts.repeat {
|
if let Some(delay) = opts.repeat {
|
||||||
loop {
|
loop {
|
||||||
run_dispatch(&conf).await.ok();
|
run_dispatch(&conf).await.ok();
|
||||||
thread::sleep(Duration::from_secs(delay))
|
sleep(Duration::from_secs(delay)).await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// otherwise run just once
|
// otherwise run just once
|
||||||
|
|
|
@ -17,9 +17,14 @@ pub struct Opts {
|
||||||
/// If enabled, any IPv6 (AAAA) records in the configuration file are ignored.
|
/// If enabled, any IPv6 (AAAA) records in the configuration file are ignored.
|
||||||
#[clap(action, long)]
|
#[clap(action, long)]
|
||||||
pub skip_ipv6: bool,
|
pub skip_ipv6: bool,
|
||||||
/// Repeat after specified delay
|
/// Repeat after specified delay, in seconds.
|
||||||
///
|
///
|
||||||
/// If enabled waits for the given delay between updating DNS records
|
/// If enabled, this will continue to run and perform the updates
|
||||||
|
/// periodically. The first update will happen immediately, and later
|
||||||
|
/// updates will be delayed by this many seconds.
|
||||||
|
///
|
||||||
|
/// This process will not fork, so you may need to use something like
|
||||||
|
/// `nohup` to keep it running in the background.
|
||||||
#[clap(long)]
|
#[clap(long)]
|
||||||
pub repeat: Option<u64>,
|
pub repeat: Option<u64>,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue