Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 12 additions & 9 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,31 @@ module github.com/codeshelldev/wol-dockerized

go 1.25.5

require github.com/codeshelldev/gotl v0.0.4
require (
github.com/codeshelldev/gotl v0.0.5
github.com/moby/moby/api v1.52.0
)

require (
github.com/Microsoft/go-winio v0.6.2 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/containerd/errdefs v1.0.0 // indirect
github.com/containerd/errdefs/pkg v0.3.0 // indirect
github.com/distribution/reference v0.6.0 // indirect
github.com/docker/go-connections v0.6.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/logr v1.4.3 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/moby/docker-image-spec v1.3.1 // indirect
github.com/moby/moby/api v1.52.0 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.1.1 // indirect
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 // indirect
go.opentelemetry.io/otel v1.35.0 // indirect
go.opentelemetry.io/otel/metric v1.35.0 // indirect
go.opentelemetry.io/otel/trace v1.35.0 // indirect
golang.org/x/sys v0.38.0 // indirect
go.opentelemetry.io/auto/sdk v1.2.1 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 // indirect
go.opentelemetry.io/otel v1.39.0 // indirect
go.opentelemetry.io/otel/metric v1.39.0 // indirect
go.opentelemetry.io/otel/trace v1.39.0 // indirect
golang.org/x/sys v0.39.0 // indirect
)

require (
Expand Down
40 changes: 40 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs=
github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/codeshelldev/gotl v0.0.4 h1:W2cup8Pw9LzFLxmS5QUzY+NSE3ZgiRSUM7FiGd6qJrI=
github.com/codeshelldev/gotl v0.0.4/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg=
github.com/codeshelldev/gotl v0.0.5 h1:Qs6Pb9iOuXqyRPHmf6yOn6mVD3tl1dr/qMul6gYS1Mg=
github.com/codeshelldev/gotl v0.0.5/go.mod h1:Mfb+Lb+DV3DUXdA1sixJb2pLawaJGGFFeC29gUZQLcg=
github.com/containerd/errdefs v1.0.0 h1:tg5yIfIlQIrxYtu9ajqY42W3lpS19XqdxRQeEwYG8PI=
github.com/containerd/errdefs v1.0.0/go.mod h1:+YBYIdtsnF4Iw6nWZhJcqGSg/dwvV7tyJ/kCkyJ2k+M=
github.com/containerd/errdefs/pkg v0.3.0 h1:9IKJ06FvyNlexW690DXuQNx2KA2cUJXx151Xdx3ZPPE=
github.com/containerd/errdefs/pkg v0.3.0/go.mod h1:NJw6s9HwNuRhnjJhM7pylWwMyAkmCQvQ4GpJHEqRLVk=
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/distribution/reference v0.6.0 h1:0IXCQ5g4/QMHHkarYzh5l+u8T3t73zM5QvfrDyIgxBk=
github.com/distribution/reference v0.6.0/go.mod h1:BbU0aIcezP1/5jX/8MP0YiH4SdvB5Y4f/wlDRiLyi3E=
github.com/docker/go-connections v0.6.0 h1:LlMG9azAe1TqfR7sO+NJttz1gy6KO7VJBh+pMmjSD94=
Expand All @@ -17,8 +23,12 @@ github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSw
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg=
Expand All @@ -33,19 +43,49 @@ 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.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
github.com/opencontainers/image-spec v1.1.1/go.mod h1:qpqAh3Dmcf36wStyyWU+kCeDgrGnAve2nCC8+7h8Q0M=
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/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA=
github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA=
go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A=
go.opentelemetry.io/auto/sdk v1.2.1 h1:jXsnJ4Lmnqd11kwkBV2LgLoFMZKizbCi5fNZ/ipaZ64=
go.opentelemetry.io/auto/sdk v1.2.1/go.mod h1:KRTj+aOaElaLi+wW1kO/DZRXwkF4C5xPbEe3ZiIhN7Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0 h1:sbiXRNDSWJOTobXh5HyQKjq6wUC5tNybqjIqDpAY4CU=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.60.0/go.mod h1:69uWxva0WgAA/4bu2Yy70SLDBwZXuQ6PbBpbsa5iZrQ=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0 h1:ssfIgGNANqpVFCndZvcuyKbl0g+UAVcbBcqGkG28H0Y=
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.64.0/go.mod h1:GQ/474YrbE4Jx8gZ4q5I4hrhUzM6UPzyrqJYV2AqPoQ=
go.opentelemetry.io/otel v1.35.0 h1:xKWKPxrxB6OtMCbmMY021CqC45J+3Onta9MqjhnusiQ=
go.opentelemetry.io/otel v1.35.0/go.mod h1:UEqy8Zp11hpkUrL73gSlELM0DupHoiq72dR+Zqel/+Y=
go.opentelemetry.io/otel v1.39.0 h1:8yPrr/S0ND9QEfTfdP9V+SiwT4E0G7Y5MO7p85nis48=
go.opentelemetry.io/otel v1.39.0/go.mod h1:kLlFTywNWrFyEdH0oj2xK0bFYZtHRYUdv1NklR/tgc8=
go.opentelemetry.io/otel/metric v1.35.0 h1:0znxYu2SNyuMSQT4Y9WDWej0VpcsxkuklLa4/siN90M=
go.opentelemetry.io/otel/metric v1.35.0/go.mod h1:nKVFgxBZ2fReX6IlyW28MgZojkoAkJGaE8CpgeAU3oE=
go.opentelemetry.io/otel/metric v1.39.0 h1:d1UzonvEZriVfpNKEVmHXbdf909uGTOQjA0HF0Ls5Q0=
go.opentelemetry.io/otel/metric v1.39.0/go.mod h1:jrZSWL33sD7bBxg1xjrqyDjnuzTUB0x1nBERXd7Ftcs=
go.opentelemetry.io/otel/sdk v1.35.0 h1:iPctf8iprVySXSKJffSS79eOjl9pvxV9ZqOWT0QejKY=
go.opentelemetry.io/otel/sdk v1.35.0/go.mod h1:+ga1bZliga3DxJ3CQGg3updiaAJoNECOgJREo9KHGQg=
go.opentelemetry.io/otel/sdk v1.39.0 h1:nMLYcjVsvdui1B/4FRkwjzoRVsMK8uL/cj0OyhKzt18=
go.opentelemetry.io/otel/sdk/metric v1.35.0 h1:1RriWBmCKgkeHEhM7a2uMjMUfP7MsOF5JpUCaEqEI9o=
go.opentelemetry.io/otel/sdk/metric v1.35.0/go.mod h1:is6XYCUMpcKi+ZsOvfluY5YstFnhW0BidkR+gL+qN+w=
go.opentelemetry.io/otel/sdk/metric v1.39.0 h1:cXMVVFVgsIf2YL6QkRF4Urbr/aMInf+2WKg+sEJTtB8=
go.opentelemetry.io/otel/trace v1.35.0 h1:dPpEfJu1sDIqruz7BHFG3c7528f6ddfSWfFDVt/xgMs=
go.opentelemetry.io/otel/trace v1.35.0/go.mod h1:WUk7DtFp1Aw2MkvqGdwiXYDZZNvA/1J8o6xRXLrIkyc=
go.opentelemetry.io/otel/trace v1.39.0 h1:2d2vfpEDmCJ5zVYz7ijaJdOF59xLomrvj7bjt6/qCJI=
go.opentelemetry.io/otel/trace v1.39.0/go.mod h1:88w4/PnZSazkGzz/w84VHpQafiU4EtqqlVdxWy+rNOA=
go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.27.1 h1:08RqriUEv8+ArZRYSTXy1LeBScaMpVSTBhCeaZYfMYc=
go.uber.org/zap v1.27.1/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/sys v0.38.0 h1:3yZWxaJjBmCWXqhN1qh02AkOnCQ1poK6oF+a7xWL6Gc=
golang.org/x/sys v0.38.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/sys v0.39.0 h1:CvCKL8MeisomCi6qNZ+wbb0DN9E5AATixKsvNtMoMFk=
golang.org/x/sys v0.39.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.5.2 h1:7koQfIKdy+I8UTetycgUqXWSDwpgv193Ka+qRsmBY8Q=
gotest.tools/v3 v3.5.2/go.mod h1:LtdLGcnqToBH83WByAAi/wiwSFCArdFIUV/xxN4pcjA=
pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=
pgregory.net/rapid v1.2.0/go.mod h1:PY5XlDGj0+V1FCq0o192FdRhpKHGTRIWBgqjDBTrq04=
36 changes: 20 additions & 16 deletions internals/server/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ import (
"net/http"
"net/url"
"strconv"
"text/template"
"strings"
"time"

"github.com/codeshelldev/gotl/pkg/logger"
"github.com/codeshelldev/gotl/pkg/templating"
"github.com/codeshelldev/wol-dockerized/internals/config"
"github.com/codeshelldev/wol-dockerized/internals/wol"
)
Expand Down Expand Up @@ -68,10 +67,12 @@ func wakeHandler(w http.ResponseWriter, req *http.Request) {
err = wol.WakeContainers(body.Query)

if err != nil {
logger.Error("Could not start container with ", body.Query, ": ", err.Error())

sendToClient(client, map[string]any{
"success": false,
"error": true,
"message": "Could not start containers",
"message": err.Error(),
})

closeClient(client)
Expand All @@ -80,8 +81,8 @@ func wakeHandler(w http.ResponseWriter, req *http.Request) {

sendToClient(client, map[string]any{
"success": true,
"error": true,
"message": "Started containers",
"error": false,
"message": "Started containers.",
})

closeClient(client)
Expand All @@ -101,25 +102,28 @@ func activityHandler(w http.ResponseWriter, req *http.Request) {
return
}

variables := map[string]any{
logger.Debug("Activity on ", urlStr, "detected")

variables := map[string]string{
"HOSTNAME": URL.Hostname(),
"HOST": URL.Host,
"PORT": URL.Port,
"PORT": URL.Port(),
"PROTOCOL": URL.Scheme,
"PATH": URL.Path,
}

templt := templating.CreateTemplateWithFunc("query", template.FuncMap{})
templt.Delims("{", "}")

query, err := templating.ParseTemplate(templt, config.ENV.QUERY_PATTERN, variables)

if err != nil {
logger.Error("Error building query: ", err.Error())
http.Error(w, "Internal Server Error", http.StatusInternalServerError)
}
query := buildQuery(config.ENV.QUERY_PATTERN, variables)

wol.OnActivity(query)

w.WriteHeader(http.StatusOK)
}

func buildQuery(pattern string, context map[string]string) string {
result := pattern
for k, v := range context {
placeholder := "{" + k + "}"
result = strings.ReplaceAll(result, placeholder, v)
}
return result
}
4 changes: 2 additions & 2 deletions internals/server/websocket.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ var upgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool { return true },
}

var waiters = make(map[string]chan *websocket.Conn)
var waiters = map[string]chan *websocket.Conn{}
var waitersMutex = &sync.Mutex{}

var clients = make(map[string]*websocket.Conn)
var clients = map[string]*websocket.Conn{}
var clientsMutex = &sync.Mutex{}

func websocketHandler(w http.ResponseWriter, req *http.Request) {
Expand Down
36 changes: 30 additions & 6 deletions internals/wol/wol.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ func OnActivity(query string) {
}

func Monitor(threshold int) {
logger.Dev("Performing activity check")
logger.Debug("Performing activity check")
if updateContainers() {
doActivityCheck(threshold)
}
Expand All @@ -48,19 +48,27 @@ func doActivityCheck(threshold int) {
containerQueryMutex.RUnlock()

for query, lastTime := range lastActivities {
if currentTime - lastTime > threshold64 {
logger.Info("Containers with ", query, " have been flagged for Inactivity")
logger.Debug("Stopping Containers with ", query)
timePassed := currentTime - lastTime

logger.Dev("Last activity for ", query, " ", timePassed, "s ago")

if timePassed > threshold64 {
logger.Info("Containers with ", query, " have been flagged for inactivity")

ids := containerIDs[query]
resetLastActivity(query)
removeLastActivity(query)

if len(ids) <= 0 {
continue
}

logger.Debug("Stopping containers with ", query)

for _, id := range ids {
if getLabel(id, WOL_AUTOSTOP) == "true" {
autostop := getLabel(id, WOL_AUTOSTOP)

if strings.ToLower(autostop) != "false" {
logger.Dev("Stopping container ", id)
_, err := docker.StopContainer(id, client.ContainerStopOptions{})

if err != nil {
Expand All @@ -75,7 +83,10 @@ func doActivityCheck(threshold int) {
func WakeContainers(query string) error {
query = strings.TrimSpace(query)

logger.Dev("Waking container with ", query)

containerQueryMutex.RLock()
logger.Dev("Queries: ", containerQueries)
containers, exists := containerQueries[query]
containerQueryMutex.RUnlock()

Expand All @@ -86,6 +97,12 @@ func WakeContainers(query string) error {
logger.Debug("Found ", len(containers), " with query ", query)

for _, containerID := range containers {
if logger.IsDebug() {
logger.Debug("Starting container ", containerID, " with ", query)
} else {
logger.Info("Starting container with ", query)
}

_, err := docker.StartContainer(containerID, client.ContainerStartOptions{})

if err != nil {
Expand Down Expand Up @@ -180,6 +197,12 @@ func resetLastActivity(query string) {
queryLastActivityMutex.Unlock()
}

func removeLastActivity(query string) {
queryLastActivityMutex.Lock()
delete(queryLastActivity, query)
queryLastActivityMutex.Unlock()
}

func getLabel(id, label string) string {
container, err := docker.GetContainer(id, client.ContainerInspectOptions{})

Expand All @@ -195,6 +218,7 @@ func getEnabledContainers() ([]container.Summary, error) {
filters.Add("label", "wol.enable=true")

return docker.GetContainers(client.ContainerListOptions{
All: true,
Filters: filters,
})
}
7 changes: 5 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/codeshelldev/wol-dockerized/internals/wol"
)

//s
func main() {
config.Load()

Expand All @@ -35,11 +36,13 @@ func main() {
}

go func() {
ticker := time.NewTicker(time.Duration(config.ENV.MONITOR_INTERVAL) * time.Second)
wol.Monitor(config.ENV.INACTIVITY_THRESHOLD)

ticker := time.NewTicker(time.Duration(config.ENV.INACTIVITY_THRESHOLD) * time.Second)
defer ticker.Stop()

for range ticker.C {
wol.Monitor(config.ENV.MONITOR_INTERVAL)
wol.Monitor(config.ENV.INACTIVITY_THRESHOLD)
}
}()

Expand Down