Update: systemd-timers notes and examples
This commit is contained in:
parent
669483451b
commit
5aff4e6a06
|
@ -13,6 +13,12 @@ Generally there are 3 pieces to a timer
|
||||||
systemd-analyze calendar *-*-* *:10,20:10
|
systemd-analyze calendar *-*-* *:10,20:10
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Time is in the format:
|
||||||
|
|
||||||
|
```
|
||||||
|
DayOfWeek Year-Month-Day Hour:Minute:Second
|
||||||
|
```
|
||||||
|
|
||||||
To find suitable targets for things like `Wants` and `After`, see
|
To find suitable targets for things like `Wants` and `After`, see
|
||||||
`systemd.special(7)`. If you want to check the current status of your targets,
|
`systemd.special(7)`. If you want to check the current status of your targets,
|
||||||
use:
|
use:
|
||||||
|
@ -28,8 +34,8 @@ Scripts should be put in `/usr/local/bin` if they can be run by anyone or
|
||||||
`/usr/local/sbin` if they should only be run by root
|
`/usr/local/sbin` if they should only be run by root
|
||||||
|
|
||||||
Define a `xxx.service` file in `/etc/systemd/system`. Set the timer as one of
|
Define a `xxx.service` file in `/etc/systemd/system`. Set the timer as one of
|
||||||
its `Wants`. `network.target` may be more appropriate in some cases.
|
its `Wants`. `network.target` may be more appropriate in some cases. Do not add
|
||||||
`multi-user.target` is a good default for `WantedBy`
|
an `[Install]` section, as your timer already handles that
|
||||||
|
|
||||||
```systemd
|
```systemd
|
||||||
[Unit]
|
[Unit]
|
||||||
|
@ -41,9 +47,6 @@ After = network.target
|
||||||
[Service]
|
[Service]
|
||||||
Type = oneshot
|
Type = oneshot
|
||||||
ExecStart = /usr/local/bin/broadcast_ip.sh
|
ExecStart = /usr/local/bin/broadcast_ip.sh
|
||||||
|
|
||||||
[Install]
|
|
||||||
WantedBy = multi-user.target
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Now you'll need a timer file. It's easiest to make it have the same name as the
|
Now you'll need a timer file. It's easiest to make it have the same name as the
|
||||||
|
|
81
systemd/system/timer-scripts/template.set_a_records.sh
Executable file
81
systemd/system/timer-scripts/template.set_a_records.sh
Executable file
|
@ -0,0 +1,81 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
declare wan_ip_record wan_ip cf_records host_record cf_host_ip cf_rec_id
|
||||||
|
|
||||||
|
declare -r HOST=<your-subdomain>
|
||||||
|
declare -r DOMAIN=<your-domain-name>
|
||||||
|
declare -r TOKEN=<your-api-token>
|
||||||
|
declare -r ZONE_ID=<this-zones-id>
|
||||||
|
|
||||||
|
#╔─────────────────────────────────────────────────────────────────────────────╗
|
||||||
|
#│ Gετ WΛN IP |
|
||||||
|
#╚─────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
if ! wan_ip_record="$(host -W2 myip.opendns.com resolver1.opendns.com)"; then
|
||||||
|
echo "Hosts timed out" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
wan_ip="$(echo "$wan_ip_record" | tail -n1 | awk '{ split($0, a, " "); print a[4] }')"
|
||||||
|
|
||||||
|
#╔─────────────────────────────────────────────────────────────────────────────╗
|
||||||
|
#│ Gετ Λ rεcδrd δη Clδμdflαrε |
|
||||||
|
#╚─────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
if ! cf_records="$(curl -s --request GET \
|
||||||
|
--url https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--header "Authorization: Bearer $TOKEN")"
|
||||||
|
then
|
||||||
|
echo "Failed to retrive cloudflare zone records" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
for i in {0..4000}; do # Assuming 4000 is enough
|
||||||
|
record="$(echo "$cf_records" | jq --raw-output ".result[${i}].name")"
|
||||||
|
|
||||||
|
if [[ "$record" == "${HOST}.${DOMAIN}" ]]; then
|
||||||
|
host_record="$(echo "$cf_records" | jq -r ".result[${i}]")"
|
||||||
|
break
|
||||||
|
elif [[ "$record" == null ]]; then
|
||||||
|
echo "No record found for ${HOST}.${DOMAIN}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
#╔─────────────────────────────────────────────────────────────────────────────╗
|
||||||
|
#│ Sετ Λ rεcδrd τδ cμrrεητ WΛN |
|
||||||
|
#╚─────────────────────────────────────────────────────────────────────────────╝
|
||||||
|
cf_host_ip="$(echo "$host_record" | jq -r '.content')"
|
||||||
|
cf_rec_id="$(echo "$host_record" | jq -r '.id')"
|
||||||
|
|
||||||
|
if [[ -z "$cf_host_ip" || "$cf_host_ip" == null ]]; then
|
||||||
|
echo "Failed to find content of A record for ${HOST}.${DOMAIN}" >&2
|
||||||
|
exit 1
|
||||||
|
elif [[ -z "$cf_rec_id" || "$cf_rec_id" == null ]]; then
|
||||||
|
echo "Failed to find A record ID for ${HOST}.${DOMAIN}" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [[ "$cf_host_ip" == "$wan_ip" ]]; then
|
||||||
|
echo "Cloudflare is up to date @ $(date)" >&2
|
||||||
|
else
|
||||||
|
echo "Updating Cloudflare's A record from $cf_host_ip to $wan_ip" >&2
|
||||||
|
|
||||||
|
patch_response="$(curl -s --request PATCH \
|
||||||
|
--url "https://api.cloudflare.com/client/v4/zones/${ZONE_ID}/dns_records/${cf_rec_id}" \
|
||||||
|
--header 'Content-Type: application/json' \
|
||||||
|
--header "Authorization: Bearer $TOKEN" \
|
||||||
|
--data '{
|
||||||
|
"comment": "'"${HOST} @ $(date)"'",
|
||||||
|
"content": "'"$wan_ip"'",
|
||||||
|
"name": "'"${HOST}.${DOMAIN}"'",
|
||||||
|
"proxied": false,
|
||||||
|
"ttl": 1
|
||||||
|
}')"
|
||||||
|
|
||||||
|
if [[ "$(echo "$patch_response" | jq -r '.success')" == true ]]; then
|
||||||
|
echo "Update to $wan_ip succeeded @ $(date)" >&2
|
||||||
|
else
|
||||||
|
echo "Failed to update A record. DUMP:"
|
||||||
|
echo "$patch_response"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
fi
|
12
systemd/system/update_a_record.service
Normal file
12
systemd/system/update_a_record.service
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
[Unit]
|
||||||
|
Description = Sends current ip address to uni servers
|
||||||
|
Wants = update_a_record.timer
|
||||||
|
Wants = network-online.target
|
||||||
|
After = network-online.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type = oneshot
|
||||||
|
ExecStart = /usr/local/bin/set_a_records.sh
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy = multi-user.target
|
11
systemd/system/update_a_record.timer
Normal file
11
systemd/system/update_a_record.timer
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
[Unit]
|
||||||
|
Description=Updates Cloudflare's A record for mirrorside.mami2.moe
|
||||||
|
Requires=update_a_record.service
|
||||||
|
|
||||||
|
[Timer]
|
||||||
|
Unit=update_a_record.service
|
||||||
|
OnCalendar=*-*-* *:00,15,30,45:00
|
||||||
|
RandomizedDelaySec=15min
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=timers.target
|
9
systemd/system/ydotoold.service
Normal file
9
systemd/system/ydotoold.service
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
[Unit]
|
||||||
|
Description=ydotool daemon
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
ExecStart=/usr/bin/ydotoold
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=default.target
|
Loading…
Reference in a new issue