Utilisation du cron d'une image busybox au lieu de l'intégrer au programme dnsupdater

This commit is contained in:
Laurent Le Houerou 2019-06-12 10:53:29 +04:00
parent 14a45cb1de
commit 5b9ef4233e
6 changed files with 70 additions and 110 deletions

View File

@ -4,8 +4,13 @@ COPY . .
RUN go get . RUN go get .
RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o dnsupdater . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o dnsupdater .
FROM scratch FROM busybox:glibc
COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt COPY --from=builder /etc/ssl/certs/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo COPY --from=builder /usr/share/zoneinfo /usr/share/zoneinfo
COPY --from=builder /tmp/dnsupdater/dnsupdater . COPY --from=builder /tmp/dnsupdater/dnsupdater .
ENTRYPOINT ["/dnsupdater"]
RUN mkdir -p /var/spool/cron/crontabs /var/log
COPY entry.sh /entry.sh
RUN touch /var/log/cron.log
WORKDIR "/"
ENTRYPOINT ["/entry.sh"]

View File

@ -1,4 +1,7 @@
#!/bin/sh #!/bin/sh
docker build --rm -t llehouerou/dnsupdater:latest . docker build --rm -t llehouerou/dnsupdater:latest .
rc=$?
if [[ ${rc} == 0 ]]; then
docker push llehouerou/dnsupdater docker push llehouerou/dnsupdater
fi

21
entry.sh Normal file
View File

@ -0,0 +1,21 @@
#!bin/sh
echo "Starting container ..."
echo "Setup check cron job with cron expression CHECK_CRON: ${CHECK_CRON}"
echo "${CHECK_CRON} flock -n /tmp/check.lockfile /dnsupdater >> /var/log/cron.log 2>&1" > /var/spool/cron/crontabs/root
cat /var/spool/cron/crontabs/root
# Make sure the file exists before we start tail
touch /var/log/cron.log
# start the cron deamon
crond
echo "Container started."
if [[ -n "${CHECKONSTART}" ]]; then
flock -n /tmp/check.lockfile /dnsupdater
fi
tail -fn0 /var/log/cron.log

5
go.mod
View File

@ -3,7 +3,6 @@ module gogs.lehouerou.net/Laurent/dnsupdater
go 1.12 go 1.12
require ( require (
github.com/robfig/cron v1.1.0 // indirect github.com/sirupsen/logrus v1.4.2
github.com/sirupsen/logrus v1.4.2 // indirect github.com/urfave/cli v1.20.0
github.com/urfave/cli v1.20.0 // indirect
) )

13
go.sum
View File

@ -1,13 +1,22 @@
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s=
github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/robfig/cron v1.1.0 h1:jk4/Hud3TTdcrJgUOBgsqrZBarcxl6ADIjSC2iniwLY=
github.com/robfig/cron v1.1.0/go.mod h1:JGuDeoQd7Z6yL4zQhZ3OPEVHB7fL6Ka6skscFHfmt2k=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw= github.com/urfave/cli v1.20.0 h1:fDqGv3UG/4jbVl/QkFwEdddtEDjh/5Ov6X+0B/3bPaw=
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA= github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190609082536-301114b31cce h1:CQakrGkKbydnUmt7cFIlmQ4lNQiqdTPt6xzXij4nYCc=
golang.org/x/sys v0.0.0-20190609082536-301114b31cce/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=

117
main.go
View File

@ -4,18 +4,13 @@ import (
"bytes" "bytes"
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/robfig/cron"
log "github.com/sirupsen/logrus" log "github.com/sirupsen/logrus"
"github.com/urfave/cli" "github.com/urfave/cli"
"io/ioutil" "io/ioutil"
"net/http" "net/http"
"net/smtp" "net/smtp"
"os" "os"
"os/signal"
"path" "path"
"strconv"
"syscall"
"time"
) )
type Configuration struct { type Configuration struct {
@ -34,20 +29,14 @@ type DnsResponse struct {
var ( var (
configPath string configPath string
scheduleSpec string
) )
var version = "master"
var commit = "unknown"
var date = "unknown"
func main() { func main() {
app := cli.NewApp() app := cli.NewApp()
app.Name = "dnsupdater" app.Name = "dnsupdater"
app.Version = version + " - " + commit + " - " + date app.Version = "0.0.1"
app.Usage = "Automatically update dns" app.Usage = "Automatically update dns"
app.Before = before
app.Action = start app.Action = start
app.Flags = []cli.Flag{ app.Flags = []cli.Flag{
@ -57,17 +46,6 @@ func main() {
Value: "/config/conf.json", Value: "/config/conf.json",
EnvVar: "CONFIG_PATH", EnvVar: "CONFIG_PATH",
}, },
cli.IntFlag{
Name: "interval, i",
Usage: "poll interval (in seconds)",
Value: 300,
EnvVar: "DNSUPDATER_POLL_INTERVAL",
},
cli.StringFlag{
Name: "schedule, s",
Usage: "the cron expression which defines when to update",
EnvVar: "DNSUPDATER_SCHEDULE",
},
} }
if err := app.Run(os.Args); err != nil { if err := app.Run(os.Args); err != nil {
@ -75,67 +53,11 @@ func main() {
} }
} }
func before(c *cli.Context) error { func start(c *cli.Context) {
if c.GlobalBool("debug") {
log.SetLevel(log.DebugLevel)
}
pollingSet := c.IsSet("interval")
cronSet := c.IsSet("schedule")
if pollingSet && cronSet {
log.Fatal("Only schedule or interval can be defined, not both.")
} else if cronSet {
scheduleSpec = c.String("schedule")
} else {
scheduleSpec = "@every " + strconv.Itoa(c.Int("interval")) + "s"
}
return nil
}
func start(c *cli.Context) error {
tryLockSem := make(chan bool, 1)
tryLockSem <- true
cr := cron.New()
err := cr.AddFunc(
scheduleSpec,
func() {
select {
case v := <-tryLockSem:
defer func() { tryLockSem <- v }()
if err := update(c); err != nil { if err := update(c); err != nil {
log.Println(err) log.Errorln(err)
SendStatusMail(fmt.Sprintf("Error during update process : %s", err)) SendStatusMail(fmt.Sprintf("Error during update process : %s", err))
} }
default:
log.Debug("Skipped another update already running.")
}
nextRuns := cr.Entries()
if len(nextRuns) > 0 {
log.Debug("Scheduled next run: " + nextRuns[0].Next.String())
}
})
if err != nil {
return err
}
log.Info("First run: " + cr.Entries()[0].Schedule.Next(time.Now()).String())
cr.Start()
// Graceful shut-down on SIGINT/SIGTERM
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
signal.Notify(interrupt, syscall.SIGTERM)
<-interrupt
cr.Stop()
log.Info("Waiting for running update to be finished...")
<-tryLockSem
os.Exit(1)
return nil
} }
func update(c *cli.Context) error { func update(c *cli.Context) error {
@ -151,30 +73,35 @@ func update(c *cli.Context) error {
configuration := Configuration{} configuration := Configuration{}
err := decoder.Decode(&configuration) err := decoder.Decode(&configuration)
currentIp, err := GetCurrentIp(configuration)
if err != nil {
return err
}
newIp, err := GetOutboundIP() newIp, err := GetOutboundIP()
if err != nil { if err != nil {
return err return err
} }
if currentIp == newIp { updatedDomains := ""
return nil for _, domain := range configuration.Domains {
currentIp, err := GetCurrentIp(configuration, domain)
if err != nil {
return err
} }
Info("Ip has changed %s -> %s", currentIp, newIp) if currentIp == newIp {
continue
}
fmt.Printf("%s -> Ip has changed %s -> %s\n", domain, currentIp, newIp)
for _, domain := range configuration.Domains {
err = SetCurrentIp(newIp, domain, configuration) err = SetCurrentIp(newIp, domain, configuration)
if err != nil { if err != nil {
return err return err
} }
updatedDomains += fmt.Sprintf("\t- %s\n", domain)
} }
SendStatusMail(fmt.Sprintf(`Home IP has changed : %s -> %s if updatedDomains != "" {
Dns updated successfully`, currentIp, newIp)) SendStatusMail(fmt.Sprintf(`Home IP has changed : %s
Dns updated successfully for domains\n%s`, newIp, updatedDomains))
}
return nil return nil
} }
@ -210,8 +137,8 @@ Subject: DnsUpdater Status
} }
} }
func GetCurrentIp(configuration Configuration) (string, error) { func GetCurrentIp(configuration Configuration, domain string) (string, error) {
url := "https://dns.api.gandi.net/api/v5/domains/lehouerou.net/records/@/A" url := fmt.Sprintf("https://dns.api.gandi.net/api/v5/domains/%s/records/@/A", domain)
req, err := http.NewRequest("GET", url, nil) req, err := http.NewRequest("GET", url, nil)
if err != nil { if err != nil {
@ -290,7 +217,3 @@ func exists(path string) (bool, error) {
} }
return true, err return true, err
} }
func Info(format string, args ...interface{}) {
fmt.Printf("\x1b[34;1m%s\x1b[0m\n", fmt.Sprintf(format, args...))
}