Skip to content

Commit

Permalink
Add a one-shot mode, move previous default (daemon) mode to a
Browse files Browse the repository at this point in the history
sub command.
  • Loading branch information
joshuar committed Mar 1, 2023
1 parent 975c877 commit be29088
Show file tree
Hide file tree
Showing 8 changed files with 93 additions and 25 deletions.
15 changes: 12 additions & 3 deletions .goreleaser.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,13 +54,22 @@ nfpms:
dst: /etc/cf-ddns/cf-ddns.yml
type: "config|noreplace"

# Simple config file
# Daemon mode systemd service
- src: systemd/cf-ddns.service
dst: /usr/lib/systemd/system/cf-ddns.service
type: config

scripts:
# One-shot mode with systemd timer
- src: systemd/cf-ddns-oneshot.service
dst: /usr/lib/systemd/system/cf-ddns-oneshot.service
type: config

- src: systemd/cf-ddns-oneshot.timer
dst: /usr/lib/systemd/system/cf-ddns-oneshot.timer
type: config

# scripts:
# preinstall: "scripts/preinstall.sh"
postinstall: "scripts/postinstall.sh"
# postinstall: "scripts/postinstall.sh"
# preremove: "scripts/preremove.sh"
# postremove: "scripts/postremove.sh"
2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"spellright.language": [
"en_AU"
"en-GB-10-1."
],
"spellright.documentTypes": [
"markdown",
Expand Down
27 changes: 22 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ file.

- Simple (YAML) configuration. Just specify your account details, domain and a
list of records to update.
- Runs on a defined interval (no need for cron scheduling).
- Runs on a defined interval (no need for cron scheduling) or as a one-shot execution.
- Fail-over external IP service checks.

## Installation
Expand All @@ -44,17 +44,34 @@ Create a configuration file; see the example in this repo. It should contain:
- Interval to run under, specified in a human way (i.e., `1h`, `1d`, `30m`, etc.)
- Interval is optional; the default will be 1 hour.

cf-ddns looks for a configuration file at `~/.cf-ddns.yaml` by default, but you
cf-ddns looks for a configuration file at `/etc/cf-ddns/cf-ddns.yaml` by default, but you
can specify a path with the `--config` command-line option.

Once you've got a configuration file, run the client:
Once you've got a configuration file, you have two options to run:

### Daemon Mode

In daemon mode, cf-ddns will run constantly and check on the interval specific in the configuration
file whether an update is needed:

```bash
cf-ddns daemon # --config /path/to/config.yml (optional)
```

A systemd service file has been provided that will run cf-ddns in daemon mode using a configuration
file at the default location (`/etc/cf-ddns/cf-ddns.yaml`).


### One-shot Mode

In one-shot mode, cf-ddns will run once, will perform updates as needed, then exit:

```bash
cf-ddns # --config /path/to/config.yml (optional)
```

cf-ddns will continue to run on the interval, updating the records
defined if the external IP address changes.
One-shot mode can be run on a systemd timer, see the provided `cf-ddns-oneshot.{service,timer}`
files.

## Contributions

Expand Down
39 changes: 25 additions & 14 deletions cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,27 @@ var (
profileFlag bool
)

var cmdDaemon = &cobra.Command{
Use: "daemon",
Short: "Run as a daemon",
Long: "Run cf-ddns in daemon mode, updating based on timer defined in config.",
Run: func(cmd *cobra.Command, args []string) {
cfDetails := cloudflare.NewCloudflare()

ticker := time.NewTicker(getIntervalFromConfig())
done := make(chan bool)
for {
select {
case <-done:
return
case <-ticker.C:
log.Debug("Checking for external IP update...")
cfDetails.CheckAndUpdate()
}
}
},
}

// rootCmd represents the base command when called without any subcommands
var rootCmd = &cobra.Command{
Use: "cf-ddns",
Expand All @@ -52,18 +73,7 @@ var rootCmd = &cobra.Command{
},
Run: func(cmd *cobra.Command, args []string) {
cfDetails := cloudflare.NewCloudflare()

ticker := time.NewTicker(getIntervalFromConfig())
done := make(chan bool)
for {
select {
case <-done:
return
case <-ticker.C:
log.Debug("Checking for external IP update...")
cfDetails.CheckAndUpdate()
}
}
cfDetails.CheckAndUpdate()
},
}

Expand All @@ -81,8 +91,9 @@ func init() {
// will be global for your application.

rootCmd.PersistentFlags().StringVar(&cfgFile, "config", "/etc/cf-ddns/cf-ddns.yml", "config file (default is /etc/cf-ddns/cf-ddns.yaml)")
rootCmd.Flags().BoolVarP(&debugFlag, "debug", "d", false, "debug output (default is false)")
rootCmd.Flags().BoolVarP(&profileFlag, "profile", "p", false, "enable profiling (default is false)")
rootCmd.PersistentFlags().BoolVarP(&debugFlag, "debug", "d", false, "debug output (default is false)")
rootCmd.PersistentFlags().BoolVarP(&profileFlag, "profile", "p", false, "enable profiling (default is false)")
rootCmd.AddCommand(cmdDaemon)
}

// initConfig reads in config file and ENV variables if set.
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
Expand Down
14 changes: 14 additions & 0 deletions systemd/cf-ddns-oneshot.service
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[Unit]
Description=Run cf-ddns client
Documentation=https://github.com/joshuar/cf-ddns
Wants=network-online.target
After=network-online.target

[Service]
Type=oneshot
ExecStart=/usr/bin/cf-ddns
ProtectSystem=strict
ProtectHome=yes

[Install]
WantedBy=multi-user.target
17 changes: 17 additions & 0 deletions systemd/cf-ddns-oneshot.timer
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
[Unit]
Description=Timer for cf-ddns client
Documentation=https://github.com/joshuar/cf-ddns

[Timer]
Persistent=true

; Run the timer unit every 15 minutes.
OnCalendar=hourly

; Always run the timer on time.
AccuracySec=1us

RandomizedDelaySec=5m

[Install]
WantedBy=timers.target
2 changes: 1 addition & 1 deletion systemd/cf-ddns.service
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ After=network-online.target

[Service]
Type=simple
ExecStart=/usr/bin/cf-ddns
ExecStart=/usr/bin/cf-ddns daemon
ProtectSystem=strict
ProtectHome=yes

Expand Down

0 comments on commit be29088

Please sign in to comment.