Skip to content

Commit

Permalink
feat: 🎸 add Dockerfile, rework flags to support ENV variables
Browse files Browse the repository at this point in the history
  • Loading branch information
RobinHeidenis committed Nov 28, 2023
1 parent 8c9c066 commit c11c70d
Show file tree
Hide file tree
Showing 9 changed files with 71 additions and 46 deletions.
5 changes: 5 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.dockerignore
.gitignore
Dockerfile
README.md
heimdall
4 changes: 3 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,6 @@
# Go workspace file
go.work

.idea
.idea

heimdall
30 changes: 30 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
FROM golang:latest as BUILD
LABEL authors="Robin Heidenis"

WORKDIR /app

# Download dependencies
COPY go.mod go.sum ./
RUN go mod download

# Copy source code
COPY . .

# Build the application
RUN CGO_ENABLED=0 GOOS=linux go build -o /heimdall ./cmd/heimdall

FROM alpine:latest

WORKDIR /

COPY --from=BUILD /heimdall /heimdall

# Expose port 8080 for healthchecks
EXPOSE 8080

HEALTHCHECK --interval=5s --timeout=5s --retries=3 CMD wget localhost:8080/health -q -O - > /dev/null 2>&1

VOLUME /var/run/docker.sock

# Run the application
CMD ["/heimdall"]
File renamed without changes.
7 changes: 3 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -5,26 +5,25 @@ go 1.21
require (
github.com/davidbanham/human_duration v1.4.0
github.com/docker/docker v24.0.7+incompatible
github.com/gtuk/discordwebhook v1.2.0
github.com/jedib0t/go-pretty/v6 v6.4.9
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4
)

require (
github.com/Microsoft/go-winio v0.6.1 // indirect
github.com/distribution/reference v0.5.0 // indirect
github.com/docker/distribution v2.8.3+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/gtuk/discordwebhook v1.2.0 // indirect
github.com/jedib0t/go-pretty/v6 v6.4.9 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.6.0 // indirect
Expand Down
12 changes: 6 additions & 6 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,6 @@ github.com/docker/docker v24.0.7+incompatible h1:Wo6l37AuwP3JaMnZa226lzVXGA3F9Ig
github.com/docker/docker v24.0.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c h1:+pKlWGMw7gf6bQ+oDZB4KHQFypsfjYlq/C4rfL7D3g8=
github.com/docker/go-events v0.0.0-20190806004212-e31b211e4f1c/go.mod h1:Uw6UezgYA44ePAFQYUehOuCzmy5zmg/+nl2ZfMWGkpA=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
Expand All @@ -39,18 +37,19 @@ github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
github.com/opencontainers/image-spec v1.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/pelletier/go-toml/v2 v2.0.9 h1:uH2qQXheeefCCkuBBSLi7jCiSmj3VRh2+Goq2N7Xxu0=
github.com/pelletier/go-toml/v2 v2.0.9/go.mod h1:tJU2Z3ZkXwnxa4DPO899bsyIoywizdUvyaeZurnPPDc=
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4 h1:aiqS8aBlF9PsAKeMddMSfbwp3smONCn3UO8QfUg0Z7Y=
github.com/peterbourgon/ff/v4 v4.0.0-alpha.4/go.mod h1:H/13DK46DKXy7EaIxPhk2Y0EC8aubKm35nBjBe8AAGc=
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pkg/profile v1.6.0/go.mod h1:qBsxPvzyUincmltOk6iyRVxHYg4adc0OFOv72ZdLa18=
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/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.4/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
Expand Down Expand Up @@ -78,7 +77,6 @@ golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.5.0 h1:MUK/U/4lj1t1oPg0HfuXDN/Z1wv31ZJ/YcPiGccS4DU=
golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
Expand All @@ -97,6 +95,8 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
Expand Down
Binary file modified heimdall
Binary file not shown.
35 changes: 22 additions & 13 deletions pkg/heimdall/heimdall.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,39 +3,48 @@ package heimdall
import (
"context"
"encoding/json"
"flag"
"fmt"
"github.com/docker/docker/client"
"github.com/peterbourgon/ff/v4"
"github.com/peterbourgon/ff/v4/ffhelp"
"io"
"os"
"strconv"
"time"
)

var DebugMode bool
var Timeout int
var PeriodicNotifications bool
var PeriodicNotificationInterval int
var AllContainers bool
var Retry int
var Provider IProvider

var IsHealthy = false

func init() {
flag.BoolVar(&DebugMode, "debug", false, "Enable debug mode")
fs := ff.NewFlagSet("heimdall")

flag.BoolVar(&PeriodicNotifications, "periodic-notification", false, "Enable periodic notifications about the state of containers")
flag.IntVar(&PeriodicNotificationInterval, "notification-interval", 60, "Interval in minutes between periodic notifications")
flag.BoolVar(&AllContainers, "all-containers", false, "Enable periodic notifications for all containers, including stopped ones")
fs.BoolVar(&DebugMode, 'd', "debug", "Enable debug mode")
fs.BoolVar(&PeriodicNotifications, 'n', "periodic-notification", "Enable periodic notifications about the state of containers")
fs.IntVar(&PeriodicNotificationInterval, 'i', "notification-interval", 60, "Interval in minutes between periodic notifications")
fs.BoolVar(&AllContainers, 'a', "all-containers", "Enable periodic notifications for all containers, including stopped ones")
fs.IntVar(&Retry, 'r', "retry", 10, "Retry in seconds when the docker event stream ends")
var provider = fs.StringEnum('p', "provider", "Provider to use for notifications", "discord")
var webhookUrl = fs.String('w', "webhook-url", "", "Webhook URL to use for notifications")

flag.IntVar(&Timeout, "retry", 10, "Retry in seconds when the docker event stream ends")
err := ff.Parse(fs, os.Args[1:], ff.WithEnvVarPrefix("HEIMDALL"))

provider := flag.String("provider", "discord", "Provider to use for notifications")
webhookUrl := flag.String("webhook-url", "", "Webhook URL to use for notifications")

flag.Parse()
if err != nil {
fmt.Printf("%s\n", ffhelp.Flags(fs))
Fatal("Something went wrong while parsing flags: " + err.Error())
}

if PeriodicNotifications {
Info(fmt.Sprintf("Periodic notifications enabled. Interval: %d minutes\n", PeriodicNotificationInterval))
if AllContainers {
Info("All containers option specified, sending notifications about all containers, including stopped ones")
}
} else {
if PeriodicNotificationInterval != 60 {
Warn("Periodic notifications disabled. Ignoring notification interval.")
Expand Down Expand Up @@ -96,8 +105,8 @@ func Start() {
case err := <-errorChannel:
if err == io.EOF {
IsHealthy = false
Warn(fmt.Sprintf("No containers running. Sleeping for %s seconds and trying again.\n", strconv.Itoa(Timeout)))
time.Sleep(time.Duration(Timeout * int(time.Second)))
Warn(fmt.Sprintf("No containers running. Sleeping for %s seconds and trying again.\n", strconv.Itoa(Retry)))
time.Sleep(time.Duration(Retry * int(time.Second)))
IsHealthy = true
go EventRoutine(cli, ctx, eventChannel, logChannel, errorChannel)
} else {
Expand Down
24 changes: 2 additions & 22 deletions pkg/heimdall/periodCheckRoutine.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package heimdall

import (
"context"
"github.com/davidbanham/human_duration"
"github.com/docker/docker/api/types"
"github.com/docker/docker/client"
"github.com/jedib0t/go-pretty/v6/table"
Expand Down Expand Up @@ -41,30 +40,11 @@ func PeriodicCheckRoutine(ticker time.Ticker, cli *client.Client, ctx context.Co

var health = inspectedContainer.State.Status

if inspectedContainer.State.Health != nil {
if inspectedContainer.State.Health != nil && health != "exited" {
health = inspectedContainer.State.Health.Status
}

startTimeStr := inspectedContainer.State.StartedAt

// Parse the start time string into a time.Time object
startTime, err := time.Parse(time.RFC3339, startTimeStr)
if err != nil {
Fatal(err.Error())
}

// Calculate the uptime
uptime := time.Since(startTime)

c := Container{
ID: listContainer.ID,
Name: strings.Split(inspectedContainer.Name, "/")[1],
Image: listContainer.Image,
Uptime: human_duration.String(uptime, human_duration.Second),
Health: HealthStatus(health),
}

t.AppendRow(table.Row{i, c.Name, c.Health})
t.AppendRow(table.Row{i, strings.Split(inspectedContainer.Name, "/")[1], HealthStatus(health)})
t.AppendSeparator()
}

Expand Down

0 comments on commit c11c70d

Please sign in to comment.