mirror of
https://github.com/vmorganp/Lazytainer.git
synced 2025-12-21 13:23:02 +01:00
naming update, more configurable with env vars
This commit is contained in:
13
Dockerfile
13
Dockerfile
@@ -1,14 +1,11 @@
|
||||
from golang:alpine3.14
|
||||
WORKDIR /go/src/app
|
||||
COPY ./sandman.go .
|
||||
RUN go build sandman.go
|
||||
WORKDIR /root/
|
||||
COPY ./lazytainer.go .
|
||||
RUN go build lazytainer.go
|
||||
|
||||
FROM alpine:latest
|
||||
RUN apk --no-cache add docker-cli
|
||||
WORKDIR /root/
|
||||
COPY --from=0 /go/src/app/sandman ./
|
||||
ENV TIMEOUT=30
|
||||
ENV LABEL=sandman
|
||||
COPY --from=0 /root/lazytainer ./
|
||||
|
||||
|
||||
CMD ["./sandman"]
|
||||
CMD ["./lazytainer"]
|
||||
11
README.md
11
README.md
@@ -1,7 +1,7 @@
|
||||
# Sandman
|
||||
# Lazytainer
|
||||
Putting your containers to sleep
|
||||
|
||||
*man me a sand*
|
||||
*I don't really wanna do the work today*
|
||||
|
||||
---
|
||||
|
||||
@@ -13,15 +13,14 @@ if it looks like you're trying to access a stopped container, it starts
|
||||
|
||||
### Want to test it?
|
||||
```
|
||||
$ git clone https://github.com/vmorganp/sandman
|
||||
$ cd sandman
|
||||
$ docker-compose up -d --build
|
||||
$ git clone https://github.com/vmorganp/Lazytainer
|
||||
$ cd Lazytainer
|
||||
$ docker-compose up
|
||||
```
|
||||
|
||||
## TODO
|
||||
- support multiple ports
|
||||
- test on common services
|
||||
- better time adjustment
|
||||
- docker security probably? this really shouldn't be getting exposed except to forward traffic so idk probably firewall all non listed ports?
|
||||
- improve logging
|
||||
- inevitable bugfixes
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
version: "3"
|
||||
services:
|
||||
sandman:
|
||||
container_name: sandman
|
||||
lazytainer:
|
||||
container_name: lazytainer
|
||||
build: .
|
||||
environment:
|
||||
- PORT=81 # TODO make this work with more than one port
|
||||
- LABEL=sandman # sandman checks
|
||||
- LABEL=lazytainer # value of com.lazytainer.marker for other containers that lazytainer checks
|
||||
- TIMEOUT=30 # number of seconds to let container idle
|
||||
ports:
|
||||
- 81:81
|
||||
@@ -16,10 +16,10 @@ services:
|
||||
container_name: whoami2
|
||||
image: containous/whoami
|
||||
command: --port 81
|
||||
network_mode: service:sandman
|
||||
network_mode: service:lazytainer
|
||||
depends_on:
|
||||
- sandman
|
||||
- lazytainer
|
||||
# ports:
|
||||
# - 80:80
|
||||
labels:
|
||||
- "com.sandman.marker=sandman"
|
||||
- "com.lazytainer.marker=lazytainer"
|
||||
@@ -11,12 +11,37 @@ import (
|
||||
|
||||
func main() {
|
||||
inactive_seconds := 0
|
||||
// label := os.Getenv("LABEL")
|
||||
// check if all of the necessary env vars are set, otherwise, use defaults
|
||||
// how long a container is allowed to have no traffic before being stopped
|
||||
inactive_timeout, err := strconv.Atoi(os.Getenv("TIMEOUT"))
|
||||
check(err)
|
||||
// tx
|
||||
// port := os.Getenv("PORT")
|
||||
rx_history := []int{0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
|
||||
if check_env_fetch_recoverable(err) {
|
||||
fmt.Println("using default because env variable TIMEOUT not set ")
|
||||
inactive_timeout = 30
|
||||
}
|
||||
|
||||
// how many polls to keep around
|
||||
rx_history_length, err := strconv.Atoi(os.Getenv("RXHISTLENGTH"))
|
||||
if check_env_fetch_recoverable(err) {
|
||||
fmt.Println("using default because env variable RXHISTLENGTH not set ")
|
||||
rx_history_length = 10
|
||||
}
|
||||
|
||||
// number of packets required between first and last poll to keep container alive
|
||||
min_packet_threshhold, err := strconv.Atoi(os.Getenv("MINPACKETTHRESH"))
|
||||
if check_env_fetch_recoverable(err) {
|
||||
fmt.Println("using default because env variable MINPACKETTHRESH not set ")
|
||||
min_packet_threshhold = 10
|
||||
}
|
||||
|
||||
// how many seconds to wait in between polls
|
||||
poll_rate, err := strconv.Atoi(os.Getenv("POLLRATE"))
|
||||
if check_env_fetch_recoverable(err) {
|
||||
fmt.Println("using default because env variable POLLRATE not set ")
|
||||
poll_rate = 1
|
||||
}
|
||||
|
||||
rx_history := make([]int, rx_history_length)
|
||||
|
||||
for {
|
||||
// check if container is on
|
||||
container_state_on := is_container_on()
|
||||
@@ -27,6 +52,7 @@ func main() {
|
||||
rx_packets, err := strconv.Atoi(strings.TrimSpace(string(rx)))
|
||||
check(err)
|
||||
rx_history = append(rx_history[1:], rx_packets)
|
||||
fmt.Println(rx_packets, "rx packets")
|
||||
|
||||
// if the container is running, see if it needs to be stopped
|
||||
if container_state_on {
|
||||
@@ -37,27 +63,29 @@ func main() {
|
||||
check(err)
|
||||
|
||||
// log out the results
|
||||
println(active_clients, "active clients")
|
||||
println(rx_packets, "rx packets")
|
||||
fmt.Printf("%v rx history\n\n", rx_history)
|
||||
fmt.Println(active_clients, "active clients")
|
||||
// println(rx_packets, "rx packets")
|
||||
// fmt.Printf("%v rx history", rx_history)
|
||||
|
||||
if active_clients == 0 && rx_history[0]+10 > rx_history[9] {
|
||||
if active_clients == 0 && rx_history[0]+min_packet_threshhold > rx_history[len(rx_history)-1] {
|
||||
// count up if we have no active clients
|
||||
// if no clients are active and less than 10 packets recieved in the last 10 seconds
|
||||
inactive_seconds++
|
||||
println(inactive_seconds, "seconds without an active client")
|
||||
fmt.Println(inactive_seconds, "seconds without an active client")
|
||||
if inactive_seconds > inactive_timeout {
|
||||
stop_containers()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// if more than 10 rx in last 10 seconds, start the container
|
||||
if rx_history[0]+10 < rx_history[9] {
|
||||
if rx_history[0]+min_packet_threshhold < rx_history[len(rx_history)-1] {
|
||||
start_containers()
|
||||
}
|
||||
}
|
||||
|
||||
time.Sleep(time.Second)
|
||||
fmt.Println("//////////////////////////////////////////////////////////////////////////////////")
|
||||
for i := 0; i < poll_rate; i++ {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,7 +102,7 @@ func newContainer(id string, state string) *container {
|
||||
|
||||
func get_containers() []container {
|
||||
containers := []container{}
|
||||
out, err := exec.Command("/bin/sh", "-c", "docker ps -a --no-trunc --filter label=\"com.sandman.marker=$LABEL\" --format \"{{.ID}} {{.State}}\"").Output() // todo make this handle multiple ports?
|
||||
out, err := exec.Command("/bin/sh", "-c", "docker ps -a --no-trunc --filter label=\"com.lazytainer.marker=$LABEL\" --format \"{{.ID}} {{.State}}\"").Output() // todo make this handle multiple ports?
|
||||
check(err)
|
||||
fmt.Println(string(out))
|
||||
if strings.TrimSpace(string(out)) == "" {
|
||||
@@ -98,7 +126,7 @@ func is_container_on() bool {
|
||||
}
|
||||
|
||||
func stop_containers() {
|
||||
println("stopping container(s)")
|
||||
fmt.Println("stopping container(s)")
|
||||
containers := get_containers()
|
||||
idString := ""
|
||||
for _, c := range containers {
|
||||
@@ -111,7 +139,7 @@ func stop_containers() {
|
||||
}
|
||||
|
||||
func start_containers() {
|
||||
println("starting container(s)")
|
||||
fmt.Println("starting container(s)")
|
||||
containers := get_containers()
|
||||
idString := ""
|
||||
for _, c := range containers {
|
||||
@@ -125,6 +153,17 @@ func start_containers() {
|
||||
|
||||
func check(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
fmt.Println(err)
|
||||
// panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func check_env_fetch_recoverable(err error) bool {
|
||||
if err != nil {
|
||||
if strings.Contains(err.Error(), "strconv.Atoi: parsing \"\": invalid syntax") {
|
||||
return true
|
||||
}
|
||||
panic(err)
|
||||
}
|
||||
return false
|
||||
}
|
||||
Reference in New Issue
Block a user