diff --git a/Dockerfile b/Dockerfile index 703262a..d078403 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,11 @@ FROM icinga/icinga2-deps -COPY --chown=icinga:icinga icinga2-bin/ / +COPY icinga2-bin/ / + +RUN ["install", "-o", "icinga", "-g", "icinga", "-d", "/data"] +VOLUME ["/data"] + +RUN ["bash", "-exo", "pipefail", "-c", "for d in /etc/icinga2 /var/*/icinga2; do mkdir -p $(dirname /data-init$d); mv $d /data-init$d; ln -vs /data$d $d; done"] USER icinga CMD ["icinga2", "daemon"] diff --git a/deps.Dockerfile b/deps.Dockerfile index 58d8c4d..1d78371 100644 --- a/deps.Dockerfile +++ b/deps.Dockerfile @@ -1,3 +1,11 @@ +FROM golang:buster as entrypoint + +COPY entrypoint /entrypoint + +WORKDIR /entrypoint +RUN ["go", "build", "."] + + FROM buildpack-deps:scm as clone SHELL ["/bin/bash", "-exo", "pipefail", "-c"] @@ -51,9 +59,13 @@ FROM debian:buster-slim RUN ["/bin/bash", "-exo", "pipefail", "-c", "export DEBIAN_FRONTEND=noninteractive; apt-get update; apt-get install --no-install-{recommends,suggests} -y libboost-{context,coroutine,date-time,filesystem,program-options,regex,system,thread}1.67 libedit2 libmariadb3 libmoosex-role-timer-perl libpq5 libssl1.1 mailutils monitoring-plugins openssl postfix; apt-get clean; rm -vrf /var/lib/apt/lists/*"] +COPY --from=entrypoint /entrypoint/entrypoint /entrypoint + RUN ["adduser", "--system", "--group", "--home", "/var/lib/icinga2", "--disabled-login", "--force-badname", "--no-create-home", "icinga"] COPY --from=build /check_mssql_health/bin/ / COPY --from=build /check_nwc_health/bin/ / COPY --from=build /check_postgres/bin/ / COPY --from=clone /check_ssl_cert/check_ssl_cert /usr/lib/nagios/plugins/check_ssl_cert + +ENTRYPOINT ["/entrypoint"] diff --git a/entrypoint/go.mod b/entrypoint/go.mod new file mode 100644 index 0000000..5b5f2f4 --- /dev/null +++ b/entrypoint/go.mod @@ -0,0 +1,8 @@ +module entrypoint + +go 1.14 + +require ( + github.com/otiai10/copy v1.2.0 + golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 +) diff --git a/entrypoint/go.sum b/entrypoint/go.sum new file mode 100644 index 0000000..44550cd --- /dev/null +++ b/entrypoint/go.sum @@ -0,0 +1,16 @@ +github.com/otiai10/copy v1.2.0 h1:HvG945u96iNadPoG2/Ja2+AUJeW5YuFQMixq9yirC+k= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0 h1:TJIWdbX0B+kpNagQrjgq8bCMrbhiuX73M2XwgtDMoOI= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1 h1:BCmzIS3n71sGfHB5NMNDB3lHYPz8fWSkCAErHed//qc= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9 h1:vEg9joUBmeBcK9iSJftGNf3coIG4HqZElCPehJsfAYM= +golang.org/x/crypto v0.0.0-20200604202706-70a84ac30bf9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d h1:+R4KGOnez64A81RvjARKc4UT5/tI9ujCIVX+P5KiHuI= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/entrypoint/main.go b/entrypoint/main.go new file mode 100644 index 0000000..180db9d --- /dev/null +++ b/entrypoint/main.go @@ -0,0 +1,109 @@ +package main + +import ( + "bufio" + "fmt" + "github.com/otiai10/copy" + "golang.org/x/crypto/ssh/terminal" + "os" + "os/exec" + "path" + "path/filepath" + "syscall" + "time" +) + +func main() { + if err := entrypoint(); err != nil { + logf(critical, "%s", err.Error()) + os.Exit(1) + } +} + +func entrypoint() error { + if len(os.Args) < 2 { + logf(warning, "Nothing to do.") + return nil + } + + if os.Getpid() == 1 { + logf(info, "Initializing /data as we're the init process (PID 1)") + + for _, dir := range []string{"etc", "var/cache", "var/lib", "var/log", "var/run", "var/spool"} { + dest := path.Join("/data", dir, "icinga2") + logf(info, "Checking %#v", dest) + + if _, errSt := os.Stat(dest); errSt != nil { + if os.IsNotExist(errSt) { + src := path.Join("/data-init", dir, "icinga2") + logf(info, "Copying %#v to %#v", src, dest) + + if errMA := os.MkdirAll(path.Dir(dest), 0755); errMA != nil { + return errMA + } + + if errCp := copy.Copy(src, dest); errCp != nil { + return errCp + } + } else { + return errSt + } + } + } + } + + path := os.Args[1] + if filepath.Base(path) == path { + logf(info, "Looking up %#v in $PATH", path) + + abs, errLP := exec.LookPath(path) + if errLP != nil { + return errLP + } + + path = abs + } + + logf(info, "Running %#v", path) + return syscall.Exec(path, os.Args[1:], os.Environ()) +} + +type logSeverity uint8 + +const ( + info logSeverity = iota + warning + critical +) + +var out = bufio.NewWriter(os.Stderr) +var isTerminal = terminal.IsTerminal(int(os.Stderr.Fd())) + +func logf(severity logSeverity, format string, a ...interface{}) { + var color, colorOff, seeverity string + + switch severity { + case info: + color = "\x1b[32m" + seeverity = "information" + case warning: + color = "\x1b[33m\x1b[1m" + seeverity = "warning" + case critical: + color = "\x1b[31m\x1b[1m" + seeverity = "critical" + } + + if isTerminal { + colorOff = "\x1b[0m" + } else { + color = "" + } + + _, _ = fmt.Fprintf(out, "[%s] ", time.Now().Format("2006-01-02 15:04:05 -0700")) + _, _ = fmt.Fprintf(out, "%s%s%s/DockerEntrypoint: ", color, seeverity, colorOff) + _, _ = fmt.Fprintf(out, format, a...) + + _, _ = fmt.Fprintln(out) + _ = out.Flush() +}