I give up for now.
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
This commit is contained in:
parent
49b60cd698
commit
9428343a52
77
build.sh
77
build.sh
|
|
@ -1,70 +1,43 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Default architecture
|
ARCHITECTURES=("linux/amd64" "linux/arm64" "darwin/amd64" "windows/amd64")
|
||||||
DEFAULT_ARCH="linux/amd64"
|
PROJECT_NAME=$(basename "$PWD")
|
||||||
|
|
||||||
# Supported architectures (adjust as needed)
|
|
||||||
ARCHITECTURES=("linux/amd64" "linux/arm64" "linux/arm/v7" "darwin/amd64" "darwin/arm64")
|
|
||||||
|
|
||||||
# Ensure all necessary directories exist and go modules are ready
|
|
||||||
prepare_build() {
|
prepare_build() {
|
||||||
# Create necessary directories if they don't exist
|
mkdir -p dist build_logs
|
||||||
mkdir -p dist
|
|
||||||
mkdir -p build_logs
|
|
||||||
|
|
||||||
# Initialize go modules if go.mod does not exist
|
|
||||||
if [ ! -f go.mod ]; then
|
if [ ! -f go.mod ]; then
|
||||||
echo "Initializing Go modules"
|
go mod init "$PROJECT_NAME"
|
||||||
go mod init yourmodule # Replace 'yourmodule' with your actual module name or path
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Fetch and ensure all dependencies are up to date
|
|
||||||
echo "Checking dependencies..."
|
|
||||||
go mod tidy
|
go mod tidy
|
||||||
}
|
}
|
||||||
|
|
||||||
# Build function
|
|
||||||
build_binary() {
|
build_binary() {
|
||||||
os=$1
|
local os=$1
|
||||||
arch=$2
|
local arch=$2
|
||||||
output_name="oculus"
|
local output="dist/${PROJECT_NAME}_${os}_${arch}"
|
||||||
|
env GOOS=$os GOARCH=$arch go build -o $output . &> build_logs/${os}_${arch}.log
|
||||||
if [[ "$os/$arch" != "$DEFAULT_ARCH" ]]; then
|
if [ $? -ne 0 ]; then
|
||||||
output_name="${output_name}_${os}_${arch}"
|
echo "Build failed for $os/$arch" >> build_logs/error.log
|
||||||
fi
|
|
||||||
|
|
||||||
output_name="dist/${output_name}"
|
|
||||||
|
|
||||||
# Dynamic Linking
|
|
||||||
echo "Building dynamically linked for ${os}/${arch} -> ${output_name}"
|
|
||||||
GOOS=${os} GOARCH=${arch} go build -o ${output_name} main.go 2>build_logs/${os}_${arch}_build.log
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "Successfully built ${output_name}"
|
|
||||||
else
|
else
|
||||||
echo "Failed to build ${output_name}. Check build_logs/${os}_${arch}_build.log for errors."
|
echo "Build succeeded for $os/$arch"
|
||||||
fi
|
fi
|
||||||
|
if [ "$os" == "linux" ]; then
|
||||||
# Static Linking
|
env GOOS=$os GOARCH=$arch CGO_ENABLED=0 go build -a -ldflags '-extldflags "-static"' -o ${output}_static . &> build_logs/${os}_${arch}_static.log
|
||||||
if [[ "$os" == "linux" ]]; then # Typically, static linking is most relevant for Linux environments
|
if [ $? -ne 0 ]; then
|
||||||
static_output_name="${output_name}_static"
|
echo "Static build failed for $os/$arch" >> build_logs/error.log
|
||||||
echo "Building statically linked for ${os}/${arch} -> ${static_output_name}"
|
|
||||||
CGO_ENABLED=0 GOOS=${os} GOARCH=${arch} go build -a -ldflags '-extldflags "-static"' -o ${static_output_name} main.go 2>build_logs/${os}_${arch}_static_build.log
|
|
||||||
if [ $? -eq 0 ]; then
|
|
||||||
echo "Successfully built ${static_output_name}"
|
|
||||||
else
|
else
|
||||||
echo "Failed to build ${static_output_name}. Check build_logs/${os}_${arch}_static_build.log for errors."
|
echo "Static build succeeded for $os/$arch"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Main Build Process
|
main() {
|
||||||
prepare_build
|
prepare_build
|
||||||
for arch in "${ARCHITECTURES[@]}"; do
|
for arch in "${ARCHITECTURES[@]}"; do
|
||||||
IFS='/' read -r -a parts <<< "$arch" # Split architecture string
|
IFS="/" read -r os arch <<< "$arch"
|
||||||
os=${parts[0]}
|
build_binary $os $arch
|
||||||
arch=${parts[1]}
|
done
|
||||||
build_binary $os $arch
|
echo "Build process completed."
|
||||||
done
|
}
|
||||||
|
|
||||||
echo "Build process completed."
|
|
||||||
|
|
||||||
|
main
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# oculus
|
||||||
|
./main.go:38:67: undefined: types.ContainerListOptions
|
||||||
|
./main.go:119:4: savedDiffs declared and not used
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
Build failed for linux/amd64
|
||||||
|
Static build failed for linux/amd64
|
||||||
|
Build failed for linux/arm64
|
||||||
|
Static build failed for linux/arm64
|
||||||
|
Build failed for darwin/amd64
|
||||||
|
Build failed for windows/amd64
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# oculus
|
||||||
|
./main.go:38:67: undefined: types.ContainerListOptions
|
||||||
|
./main.go:119:4: savedDiffs declared and not used
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# oculus
|
||||||
|
./main.go:38:67: undefined: types.ContainerListOptions
|
||||||
|
./main.go:119:4: savedDiffs declared and not used
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# oculus
|
||||||
|
./main.go:38:67: undefined: types.ContainerListOptions
|
||||||
|
./main.go:119:4: savedDiffs declared and not used
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# oculus
|
||||||
|
./main.go:38:67: undefined: types.ContainerListOptions
|
||||||
|
./main.go:119:4: savedDiffs declared and not used
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
# command-line-arguments
|
|
||||||
./main.go:34:67: undefined: types.ContainerListOptions
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
# oculus
|
||||||
|
./main.go:38:67: undefined: types.ContainerListOptions
|
||||||
|
./main.go:119:4: savedDiffs declared and not used
|
||||||
17
install.sh
17
install.sh
|
|
@ -4,12 +4,8 @@ INSTALL_DIR="/usr/local/bin"
|
||||||
BINARY_NAME="oculus"
|
BINARY_NAME="oculus"
|
||||||
BASE_URL="https://git.nixc.us/colin/Oculus/raw/branch/main/dist"
|
BASE_URL="https://git.nixc.us/colin/Oculus/raw/branch/main/dist"
|
||||||
|
|
||||||
declare -A binaries
|
# Supported architectures
|
||||||
binaries["linux/amd64"]="oculus_linux_amd64"
|
ARCHITECTURES=("linux/amd64" "linux/arm64" "linux/arm/v7" "darwin/amd64" "darwin/arm64")
|
||||||
binaries["linux/arm64"]="oculus_linux_arm64"
|
|
||||||
binaries["linux/arm/v7"]="oculus_linux_arm"
|
|
||||||
binaries["darwin/amd64"]="oculus_darwin_amd64"
|
|
||||||
binaries["darwin/arm64"]="oculus_darwin_arm64"
|
|
||||||
|
|
||||||
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
OS="$(uname -s | tr '[:upper:]' '[:lower:]')"
|
||||||
ARCH="$(uname -m)"
|
ARCH="$(uname -m)"
|
||||||
|
|
@ -21,14 +17,7 @@ case $ARCH in
|
||||||
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
*) echo "Unsupported architecture: $ARCH"; exit 1 ;;
|
||||||
esac
|
esac
|
||||||
|
|
||||||
KEY="${OS}/${ARCH}"
|
BINARY_URL="${BASE_URL}/oculus_${OS}_${ARCH}"
|
||||||
|
|
||||||
if [[ -z "${binaries[$KEY]}" ]]; then
|
|
||||||
echo "No pre-built binary for your system architecture ($KEY)."
|
|
||||||
exit 1
|
|
||||||
fi
|
|
||||||
|
|
||||||
BINARY_URL="${BASE_URL}/${binaries[$KEY]}"
|
|
||||||
|
|
||||||
echo "Downloading and installing $BINARY_NAME from $BINARY_URL..."
|
echo "Downloading and installing $BINARY_NAME from $BINARY_URL..."
|
||||||
|
|
||||||
|
|
|
||||||
143
main.go
143
main.go
|
|
@ -4,12 +4,13 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
|
"os/signal"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/docker/docker/api/types"
|
"github.com/docker/docker/api/types"
|
||||||
|
|
@ -22,14 +23,17 @@ const (
|
||||||
logDir = "/log"
|
logDir = "/log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ContainerDiff represents the state of a container
|
|
||||||
type ContainerDiff struct {
|
type ContainerDiff struct {
|
||||||
ID string
|
ID string
|
||||||
Image string
|
Image string
|
||||||
Labels map[string]string
|
Labels map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
// getRunningContainers fetches the list of running containers with relevant labels
|
type FileChange struct {
|
||||||
|
Path string
|
||||||
|
Kind string
|
||||||
|
}
|
||||||
|
|
||||||
func getRunningContainers(cli *client.Client) ([]ContainerDiff, error) {
|
func getRunningContainers(cli *client.Client) ([]ContainerDiff, error) {
|
||||||
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
|
containers, err := cli.ContainerList(context.Background(), types.ContainerListOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -38,7 +42,7 @@ func getRunningContainers(cli *client.Client) ([]ContainerDiff, error) {
|
||||||
|
|
||||||
var diffs []ContainerDiff
|
var diffs []ContainerDiff
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
if _, ok := container.Labels["oculus.containerid"]; ok {
|
if _, ok := container.Labels["oculus.cname"]; ok {
|
||||||
diffs = append(diffs, ContainerDiff{
|
diffs = append(diffs, ContainerDiff{
|
||||||
ID: container.ID,
|
ID: container.ID,
|
||||||
Image: container.Image,
|
Image: container.Image,
|
||||||
|
|
@ -50,29 +54,26 @@ func getRunningContainers(cli *client.Client) ([]ContainerDiff, error) {
|
||||||
return diffs, nil
|
return diffs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// saveDiffs writes the container diffs to a file
|
func saveDiffs(diffs []FileChange, filePath string) error {
|
||||||
func saveDiffs(diffs []ContainerDiff, filePath string) error {
|
|
||||||
data, err := json.Marshal(diffs)
|
data, err := json.Marshal(diffs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return ioutil.WriteFile(filePath, data, 0644)
|
return os.WriteFile(filePath, data, 0644)
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadDiffs reads the container diffs from a file
|
func loadDiffs(filePath string) ([]FileChange, error) {
|
||||||
func loadDiffs(filePath string) ([]ContainerDiff, error) {
|
data, err := os.ReadFile(filePath)
|
||||||
data, err := ioutil.ReadFile(filePath)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
var diffs []ContainerDiff
|
var diffs []FileChange
|
||||||
err = json.Unmarshal(data, &diffs)
|
err = json.Unmarshal(data, &diffs)
|
||||||
return diffs, err
|
return diffs, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// shouldIgnore checks if the change should be ignored based on the ignore list
|
|
||||||
func shouldIgnore(change string, ignoreList []string) bool {
|
func shouldIgnore(change string, ignoreList []string) bool {
|
||||||
for _, ignore := range ignoreList {
|
for _, ignore := range ignoreList {
|
||||||
if strings.Contains(change, ignore) {
|
if strings.Contains(change, ignore) {
|
||||||
|
|
@ -82,7 +83,6 @@ func shouldIgnore(change string, ignoreList []string) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// logDetection logs detection events to a file and sends to Go Glitch
|
|
||||||
func logDetection(containerID, message string) {
|
func logDetection(containerID, message string) {
|
||||||
logFilePath := filepath.Join(logDir, fmt.Sprintf("%s.log", containerID))
|
logFilePath := filepath.Join(logDir, fmt.Sprintf("%s.log", containerID))
|
||||||
f, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
f, err := os.OpenFile(logFilePath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
|
||||||
|
|
@ -97,7 +97,6 @@ func logDetection(containerID, message string) {
|
||||||
sendToGlitchtip(logFilePath)
|
sendToGlitchtip(logFilePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendToGlitchtip sends the log file content to Go Glitch
|
|
||||||
func sendToGlitchtip(logFilePath string) {
|
func sendToGlitchtip(logFilePath string) {
|
||||||
if dsn := os.Getenv("GLITCHTIP_DSN"); dsn != "" {
|
if dsn := os.Getenv("GLITCHTIP_DSN"); dsn != "" {
|
||||||
cmd := exec.Command("go-glitch", logFilePath)
|
cmd := exec.Command("go-glitch", logFilePath)
|
||||||
|
|
@ -108,70 +107,66 @@ func sendToGlitchtip(logFilePath string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// profileContainers logs the current state of containers to a file
|
func compareContainers(cli *client.Client, mode string) {
|
||||||
func profileContainers(cli *client.Client) {
|
|
||||||
diffs, err := getRunningContainers(cli)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error profiling containers: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, diff := range diffs {
|
|
||||||
if diff.Labels["oculus.mode"] == "profile" {
|
|
||||||
filePath := fmt.Sprintf("%s.json", diff.Labels["oculus.containerid"])
|
|
||||||
err := saveDiffs([]ContainerDiff{diff}, filePath)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatalf("Error saving diffs: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("Profiled current containers and saved to file")
|
|
||||||
}
|
|
||||||
|
|
||||||
// compareContainers compares the current state of containers with the saved state
|
|
||||||
func compareContainers(cli *client.Client) {
|
|
||||||
currentDiffs, err := getRunningContainers(cli)
|
currentDiffs, err := getRunningContainers(cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Error getting current containers: %v", err)
|
log.Fatalf("Error getting current containers: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, current := range currentDiffs {
|
for _, current := range currentDiffs {
|
||||||
if current.Labels["oculus.mode"] == "monitor" {
|
if current.Labels["oculus.mode"] == mode {
|
||||||
filePath := fmt.Sprintf("%s.json", current.Labels["oculus.containerid"])
|
filePath := filepath.Join(logDir, fmt.Sprintf("%s.json", current.Labels["oculus.cname"]))
|
||||||
savedDiffs, err := loadDiffs(filePath)
|
savedDiffs, err := loadDiffs(filePath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error loading saved diffs for %s: %v", current.ID, err)
|
log.Printf("Error loading saved diffs for %s: %v", current.ID, err)
|
||||||
continue
|
savedDiffs = []FileChange{} // Initialize to an empty slice
|
||||||
}
|
}
|
||||||
|
|
||||||
ignoreList := strings.Split(current.Labels["oculus.ignorelist"], ",")
|
ignoreList := strings.Split(current.Labels["oculus.ignorelist"], ",")
|
||||||
|
|
||||||
if len(savedDiffs) > 0 {
|
currentChanges, err := cli.ContainerDiff(context.Background(), current.ID)
|
||||||
saved := savedDiffs[0]
|
if err != nil {
|
||||||
if current.Image != saved.Image && !shouldIgnore(current.Image, ignoreList) {
|
log.Printf("Error getting container diff for %s: %v", current.ID, err)
|
||||||
message := fmt.Sprintf("Container %s changed: Image %s -> %s", current.ID, saved.Image, current.Image)
|
continue
|
||||||
logDetection(current.Labels["oculus.containerid"], message)
|
}
|
||||||
runNotifyScript(filepath.Join(logDir, fmt.Sprintf("%s.log", current.Labels["oculus.containerid"])))
|
|
||||||
|
var changes []FileChange
|
||||||
|
for _, change := range currentChanges {
|
||||||
|
path := change.Path
|
||||||
|
kind := ""
|
||||||
|
switch change.Kind {
|
||||||
|
case 0:
|
||||||
|
kind = "Modified"
|
||||||
|
case 1:
|
||||||
|
kind = "Added"
|
||||||
|
case 2:
|
||||||
|
kind = "Deleted"
|
||||||
}
|
}
|
||||||
if current.Labels["oculus.ignorelist"] != saved.Labels["oculus.ignorelist"] {
|
|
||||||
message := fmt.Sprintf("Container %s ignore list changed: %s -> %s", current.ID, saved.Labels["oculus.ignorelist"], current.Labels["oculus.ignorelist"])
|
if !shouldIgnore(path, ignoreList) {
|
||||||
if !shouldIgnore(message, ignoreList) {
|
changes = append(changes, FileChange{
|
||||||
logDetection(current.Labels["oculus.containerid"], message)
|
Path: path,
|
||||||
runNotifyScript(filepath.Join(logDir, fmt.Sprintf("%s.log", current.Labels["oculus.containerid"])))
|
Kind: kind,
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
message := fmt.Sprintf("New container detected: ID %s, Image %s", current.ID, current.Image)
|
|
||||||
if !shouldIgnore(current.Image, ignoreList) {
|
if mode == "monitor" {
|
||||||
logDetection(current.Labels["oculus.containerid"], message)
|
err = saveDiffs(changes, filePath)
|
||||||
runNotifyScript(filepath.Join(logDir, fmt.Sprintf("%s.log", current.Labels["oculus.containerid"])))
|
if err != nil {
|
||||||
|
log.Fatalf("Error saving diffs: %v", err)
|
||||||
|
}
|
||||||
|
} else if mode == "report" {
|
||||||
|
for _, change := range changes {
|
||||||
|
message := fmt.Sprintf("Container %s changed: %s %s", current.ID, change.Kind, change.Path)
|
||||||
|
logDetection(current.Labels["oculus.cname"], message)
|
||||||
|
runNotifyScript(filepath.Join(logDir, fmt.Sprintf("%s.log", current.Labels["oculus.cname"])))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// runNotifyScript executes the notification script with the container details
|
|
||||||
func runNotifyScript(logFilePath string) {
|
func runNotifyScript(logFilePath string) {
|
||||||
cmd := exec.Command(notifyScript, logFilePath)
|
cmd := exec.Command(notifyScript, logFilePath)
|
||||||
err := cmd.Run()
|
err := cmd.Run()
|
||||||
|
|
@ -180,7 +175,6 @@ func runNotifyScript(logFilePath string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// watchDockerEvents listens for Docker events and triggers comparisons
|
|
||||||
func watchDockerEvents(cli *client.Client) {
|
func watchDockerEvents(cli *client.Client) {
|
||||||
eventFilter := filters.NewArgs()
|
eventFilter := filters.NewArgs()
|
||||||
eventFilter.Add("type", "container")
|
eventFilter.Add("type", "container")
|
||||||
|
|
@ -196,7 +190,7 @@ func watchDockerEvents(cli *client.Client) {
|
||||||
select {
|
select {
|
||||||
case event := <-messages:
|
case event := <-messages:
|
||||||
log.Printf("Docker event received: %s for container %s", event.Action, event.ID)
|
log.Printf("Docker event received: %s for container %s", event.Action, event.ID)
|
||||||
compareContainers(cli)
|
compareContainers(cli, "monitor")
|
||||||
case err := <-errs:
|
case err := <-errs:
|
||||||
log.Printf("Error watching Docker events: %v", err)
|
log.Printf("Error watching Docker events: %v", err)
|
||||||
return
|
return
|
||||||
|
|
@ -204,7 +198,6 @@ func watchDockerEvents(cli *client.Client) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// monitorContainers sets up monitoring for containers based on the specified interval
|
|
||||||
func monitorContainers(cli *client.Client, interval time.Duration) {
|
func monitorContainers(cli *client.Client, interval time.Duration) {
|
||||||
ticker := time.NewTicker(interval)
|
ticker := time.NewTicker(interval)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
@ -212,7 +205,19 @@ func monitorContainers(cli *client.Client, interval time.Duration) {
|
||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ticker.C:
|
case <-ticker.C:
|
||||||
compareContainers(cli)
|
compareContainers(cli, "monitor")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func reportContainers(cli *client.Client, interval time.Duration) {
|
||||||
|
ticker := time.NewTicker(interval)
|
||||||
|
defer ticker.Stop()
|
||||||
|
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-ticker.C:
|
||||||
|
compareContainers(cli, "report")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -232,16 +237,24 @@ func main() {
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, container := range containers {
|
for _, container := range containers {
|
||||||
if container.Labels["oculus.mode"] == "monitor" {
|
if mode, ok := container.Labels["oculus.mode"]; ok {
|
||||||
intervalStr := container.Labels["oculus.interval"]
|
intervalStr := container.Labels["oculus.interval"]
|
||||||
interval, err := time.ParseDuration(intervalStr)
|
interval, err := time.ParseDuration(intervalStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Invalid interval format for container %s: %v", container.ID, err)
|
log.Fatalf("Invalid interval format for container %s: %v", container.ID, err)
|
||||||
}
|
}
|
||||||
go monitorContainers(cli, interval)
|
|
||||||
|
if mode == "monitor" {
|
||||||
|
go monitorContainers(cli, interval)
|
||||||
|
} else if mode == "report" {
|
||||||
|
go reportContainers(cli, interval)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the program running
|
// Graceful shutdown handling
|
||||||
select {}
|
sigs := make(chan os.Signal, 1)
|
||||||
|
signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
<-sigs
|
||||||
|
log.Println("Shutting down...")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue