Giving up tonight.
ci/woodpecker/push/woodpecker Pipeline was successful
Details
ci/woodpecker/push/woodpecker Pipeline was successful
Details
This commit is contained in:
parent
ccc908525b
commit
5ebd0a46eb
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
Build failed for linux/amd64
|
||||
Static build failed for linux/amd64
|
||||
Build failed for linux/arm64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
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 darwin/arm64
|
||||
Build failed for windows/amd64
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# oculus
|
||||
./main.go:274:21: syntax error: cannot use id, container := watchedContainers.containers as value
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
173
main.go
173
main.go
|
|
@ -6,6 +6,7 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
"os/exec"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
|
@ -23,6 +24,11 @@ var notifiedChanges = struct {
|
|||
changes map[string]string
|
||||
}{changes: make(map[string]string)}
|
||||
|
||||
var watchedContainers = struct {
|
||||
sync.RWMutex
|
||||
containers map[string]ContainerInfo
|
||||
}{containers: make(map[string]ContainerInfo)}
|
||||
|
||||
func main() {
|
||||
// Check if GLITCHTIP_DSN environment variable is set
|
||||
glitchtipDSN := os.Getenv("GLITCHTIP_DSN")
|
||||
|
|
@ -32,6 +38,8 @@ func main() {
|
|||
|
||||
log.Println("Starting Oculus...")
|
||||
|
||||
go monitorContainerList()
|
||||
|
||||
for {
|
||||
containers, err := getContainers()
|
||||
if err != nil {
|
||||
|
|
@ -41,8 +49,17 @@ func main() {
|
|||
}
|
||||
|
||||
for _, container := range containers {
|
||||
log.Printf("Monitoring container: %s (%s) every %s", container.Name, container.ID, container.Interval)
|
||||
go monitorContainer(container)
|
||||
watchedContainers.RLock()
|
||||
_, watched := watchedContainers.containers[container.ID]
|
||||
watchedContainers.RUnlock()
|
||||
|
||||
if !watched {
|
||||
log.Printf("Monitoring container: %s (%s) every %s", container.Name, container.ID, container.Interval)
|
||||
watchedContainers.Lock()
|
||||
watchedContainers.containers[container.ID] = container
|
||||
watchedContainers.Unlock()
|
||||
go monitorContainer(container, true)
|
||||
}
|
||||
}
|
||||
|
||||
// Sleep for 1 minute before checking for new containers again
|
||||
|
|
@ -90,6 +107,8 @@ func getContainers() ([]ContainerInfo, error) {
|
|||
ignores = strings.Split(parts[4], ",")
|
||||
}
|
||||
|
||||
log.Printf("Container ID: %s, Name: %s, Interval: %s, Ignores: %v", id, cname, interval, ignores)
|
||||
|
||||
containers = append(containers, ContainerInfo{
|
||||
ID: id,
|
||||
Name: cname,
|
||||
|
|
@ -102,56 +121,81 @@ func getContainers() ([]ContainerInfo, error) {
|
|||
return containers, nil
|
||||
}
|
||||
|
||||
func monitorContainer(container ContainerInfo) {
|
||||
func monitorContainer(container ContainerInfo, initial bool) {
|
||||
ticker := time.NewTicker(container.Interval)
|
||||
defer ticker.Stop()
|
||||
|
||||
for {
|
||||
log.Printf("Checking diffs for container: %s (%s)", container.Name, container.ID)
|
||||
checkDiff(container)
|
||||
time.Sleep(container.Interval)
|
||||
select {
|
||||
case <-ticker.C:
|
||||
log.Printf("Checking diffs for container: %s (%s)", container.Name, container.ID)
|
||||
diffOutput, err := getDiffOutput(container.ID)
|
||||
if err != nil {
|
||||
log.Printf("Error getting diffs for container %s (%s): %v", container.Name, container.ID, err)
|
||||
return
|
||||
}
|
||||
|
||||
filteredOutput, err := filterDiffOutput(diffOutput, container.Ignores)
|
||||
if err != nil {
|
||||
log.Printf("Error filtering diffs for container %s (%s): %v", container.Name, container.ID, err)
|
||||
return
|
||||
}
|
||||
log.Printf("Filtered diff output for container %s: %s", container.Name, filteredOutput)
|
||||
|
||||
err = handleDiffOutput(container, filteredOutput, initial)
|
||||
if err != nil {
|
||||
log.Printf("Error handling diff output for container %s (%s): %v", container.Name, container.ID, err)
|
||||
return
|
||||
}
|
||||
initial = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func checkDiff(container ContainerInfo) {
|
||||
cmd := exec.Command("docker", "diff", container.ID)
|
||||
func getDiffOutput(containerID string) (string, error) {
|
||||
cmd := exec.Command("docker", "diff", containerID)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Printf("Error running docker diff for container %s: %v", container.ID, err)
|
||||
return
|
||||
return "", fmt.Errorf("docker diff failed: %w", err)
|
||||
}
|
||||
return string(output), nil
|
||||
}
|
||||
|
||||
diffOutput := string(output)
|
||||
|
||||
for _, ignore := range container.Ignores {
|
||||
diffOutput = removeIgnoredPaths(diffOutput, ignore)
|
||||
}
|
||||
|
||||
if diffOutput != "" {
|
||||
diffHash := fmt.Sprintf("%x", md5.Sum([]byte(diffOutput)))
|
||||
func handleDiffOutput(container ContainerInfo, filteredOutput string, initial bool) error {
|
||||
if filteredOutput != "" {
|
||||
// Calculate a hash of the filtered diff output
|
||||
diffHash := fmt.Sprintf("%x", md5.Sum([]byte(filteredOutput)))
|
||||
log.Printf("Diff hash for container %s: %s", container.Name, diffHash)
|
||||
|
||||
notifiedChanges.RLock()
|
||||
lastNotifiedHash, notified := notifiedChanges.changes[container.ID]
|
||||
notifiedChanges.RUnlock()
|
||||
|
||||
if !notified || lastNotifiedHash != diffHash {
|
||||
if initial {
|
||||
// For the initial check, just store the hash and don't send a notification
|
||||
notifiedChanges.Lock()
|
||||
notifiedChanges.changes[container.ID] = diffHash
|
||||
notifiedChanges.Unlock()
|
||||
log.Printf("Initial check, storing hash for container: %s (%s)", container.Name, container.ID)
|
||||
} else if !notified || lastNotifiedHash != diffHash {
|
||||
log.Printf("Writing diff output for container: %s (%s)", container.Name, container.ID)
|
||||
// Write diff output to a file
|
||||
filename := fmt.Sprintf("%s.diff", container.Name)
|
||||
err = writeToFile(filename, diffOutput)
|
||||
err := writeToFile(filename, filteredOutput)
|
||||
if err != nil {
|
||||
log.Printf("Error writing diff to file for container %s: %v", container.ID, err)
|
||||
return fmt.Errorf("error writing diff to file: %w", err)
|
||||
}
|
||||
|
||||
// Send notification using go-glitch
|
||||
log.Printf("Sending notification for container: %s (%s)", container.Name, container.ID)
|
||||
cmd = exec.Command("go-glitch")
|
||||
cmd.Stdin = strings.NewReader(diffOutput)
|
||||
output, err = cmd.CombinedOutput()
|
||||
err = sendNotification(filteredOutput)
|
||||
if err != nil {
|
||||
log.Printf("Error sending notification for container %s: %v", container.ID, err)
|
||||
log.Printf("go-glitch output: %s", output)
|
||||
} else {
|
||||
notifiedChanges.Lock()
|
||||
notifiedChanges.changes[container.ID] = diffHash
|
||||
notifiedChanges.Unlock()
|
||||
log.Printf("Notification sent and hash updated for container: %s (%s)", container.Name, container.ID)
|
||||
}
|
||||
} else {
|
||||
log.Printf("No new changes detected for container: %s (%s)", container.Name, container.ID)
|
||||
|
|
@ -159,17 +203,47 @@ func checkDiff(container ContainerInfo) {
|
|||
} else {
|
||||
log.Printf("No significant changes detected for container: %s (%s)", container.Name, container.ID)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func removeIgnoredPaths(diffOutput string, ignore string) string {
|
||||
lines := strings.Split(diffOutput, "\n")
|
||||
filteredLines := []string{}
|
||||
for _, line := range lines {
|
||||
if !strings.Contains(line, ignore) {
|
||||
filteredLines = append(filteredLines, line)
|
||||
func filterDiffOutput(diffOutput string, ignores []string) (string, error) {
|
||||
tempFile, err := os.CreateTemp("", "diff_output")
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
defer os.Remove(tempFile.Name())
|
||||
|
||||
_, err = tempFile.WriteString(diffOutput)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
tempFile.Close()
|
||||
|
||||
for _, ignore := range ignores {
|
||||
cmd := exec.Command("sed", "-i", fmt.Sprintf("/%s/d", ignore), tempFile.Name())
|
||||
err := cmd.Run()
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error running sed command: %w", err)
|
||||
}
|
||||
}
|
||||
return strings.Join(filteredLines, "\n")
|
||||
|
||||
filteredOutput, err := os.ReadFile(tempFile.Name())
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(filteredOutput), nil
|
||||
}
|
||||
|
||||
func matchPath(path, pattern string) bool {
|
||||
match, err := filepath.Match(pattern, filepath.Base(path))
|
||||
if err != nil {
|
||||
log.Printf("Error matching pattern: %s with path: %s, error: %v", pattern, path, err)
|
||||
return false
|
||||
}
|
||||
log.Printf("Matching path %s with pattern %s: %v", path, pattern, match)
|
||||
return match
|
||||
}
|
||||
|
||||
func writeToFile(filename, content string) error {
|
||||
|
|
@ -182,3 +256,38 @@ func writeToFile(filename, content string) error {
|
|||
_, err = file.WriteString(content)
|
||||
return err
|
||||
}
|
||||
|
||||
func sendNotification(content string) error {
|
||||
cmd := exec.Command("go-glitch")
|
||||
cmd.Stdin = strings.NewReader(content)
|
||||
output, err := cmd.CombinedOutput()
|
||||
if err != nil {
|
||||
log.Printf("go-glitch output: %s", output)
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func monitorContainerList() {
|
||||
for {
|
||||
watchedContainers.Lock()
|
||||
for id, container := watchedContainers.containers {
|
||||
if !isContainerRunning(id) {
|
||||
log.Printf("Removing stopped container from watch list: %s (%s)", container.Name, id)
|
||||
delete(watchedContainers.containers, id)
|
||||
}
|
||||
}
|
||||
watchedContainers.Unlock()
|
||||
time.Sleep(1 * time.Minute)
|
||||
}
|
||||
}
|
||||
|
||||
func isContainerRunning(containerID string) bool {
|
||||
cmd := exec.Command("docker", "inspect", "--format", "{{.State.Running}}", containerID)
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
log.Printf("Error inspecting container %s: %v", containerID, err)
|
||||
return false
|
||||
}
|
||||
return strings.TrimSpace(string(output)) == "true"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,3 +0,0 @@
|
|||
A /newfile2.txt
|
||||
A /newfile3.txt
|
||||
A /newfile.txt
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
A /file1.txt
|
||||
A /file2.txt
|
||||
A /file3.txt
|
||||
Loading…
Reference in New Issue