Skip to content

Commit

Permalink
UAP Ops Agent Golang Wrapper.
Browse files Browse the repository at this point in the history
  • Loading branch information
XuechunHou committed Nov 26, 2024
1 parent 19a24c5 commit a110915
Showing 1 changed file with 126 additions and 0 deletions.
126 changes: 126 additions & 0 deletions cmd/ops_agent_uap_wrapper/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package main

import (

"log"
"net"
"os"
"os/exec"
"os/signal"
"syscall"
"time"
)
const MaximumWaitForProcessStart = 5 * time.Second

func main() {
// Define the paths and commands from the systemd unit file.
prefix := "/opt/google-cloud-ops-agent" // @PREFIX@
sysconfdir := "/etc" // @SYSCONFDIR@
logsDirectory := "google-cloud-ops-agent"
fluentBitStateDiectory := "google-cloud-ops-agent/fluent-bit"
//fluentBitRuntimeDirectory := "google-cloud-ops-agent-fluent-bit"


// Wait for network to be online before starting the process
waitForNetwork()
// Start google-cloud-ops-agent.service

// Starting ExecStartPre commands
execStartPreCmd := exec.Command(
prefix+"/libexec/google_cloud_ops_agent_engine",
"-in", sysconfdir+"/google-cloud-ops-agent/config.yaml",
)
if err := runCommand(execStartPreCmd); err != nil {
log.Fatalf("config validation faile: ", err)

Check failure on line 34 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

log.Fatalf call has arguments but no formatting directives
}

execStartPreFluentBitCmd := exec.Command(
prefix+"/libexec/google_cloud_ops_agent_engine",
"-service", "fluentbit",
"-in", sysconfdir+"/google-cloud-ops-agent/config.yaml",
"-logs", logsDirectory, "-state", fluentBitStateDiectory)

if err := runCommand(execStartPreFluentBitCmd); err != nil {
log.Fatalf("exec pre command for FluentBit faile: ", err)

Check failure on line 44 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

log.Fatalf call has arguments but no formatting directives
}

execStartPreOtelCmd := exec.Command(
prefix+"/libexec/google_cloud_ops_agent_engine",
"-service", "otel",
"-in", sysconfdir+"/google-cloud-ops-agent/config.yaml",
"-logs", logsDirectory)

if err := runCommand(execStartPreOtelCmd); err != nil {
log.Fatalf("exec pre command for Otel faile: ", err)

Check failure on line 54 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

log.Fatalf call has arguments but no formatting directives
}


// Starting Diagnostics Service
execDiagnosticsCmd := exec.Command(
prefix+"/libexec/google_cloud_ops_agent_diagnostics",
"-config", sysconfdir+"/google-cloud-ops-agent/config.yaml",
)

restartCommand(execDiagnosticsCmd)

}



func handleSignals(cmd *exec.Cmd) {
// Relay signals that should be passed down to the subprocess we are wrapping.
sigs := make(chan os.Signal, 1)
signal.Notify(sigs, syscall.SIGTERM, syscall.SIGINT, syscall.SIGCONT)

Check failure on line 73 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (windows-latest)

undefined: syscall.SIGCONT
for {
sig := <-sigs
start := time.Now()
// It is possible that we receive a signal before the code for `cmd.Run()` set cmd.Process.
// In this case we wait up to MaximumWaitForProcessStart before giving up relaying the signal.
for {
if cmd.Process != nil {
cmd.Process.Signal(sig)
break
} else if time.Until(start.Add(MaximumWaitForProcessStart)) <= 0 {
// We waited MaximumWaitForProcessStart and the subprocess did not start. Give up on relaying the signal.
log.Printf("Failed to relay signal %v to subprocess as it has not started yet", sig)
break
}
time.Sleep(50 * time.Millisecond)
}
}
}

func runCommand(cmd *exec.Cmd) error {
cmd.SysProcAttr = &syscall.SysProcAttr{
Pdeathsig: syscall.SIGKILL,

Check failure on line 95 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (windows-latest)

unknown field Pdeathsig in struct literal of type syscall.SysProcAttr
Setpgid: true,

Check failure on line 96 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (windows-latest)

unknown field Setpgid in struct literal of type syscall.SysProcAttr
}
go handleSignals(cmd)
return cmd.Run()
}

func restartCommand(cmd *exec.Cmd) {
cmdToRestart := exec.Command(cmd.Path, cmd.Args...)
if err := runCommand(cmdToRestart); err != nil {
log.Fatalf("command failed: ", err)

Check failure on line 105 in cmd/ops_agent_uap_wrapper/main.go

View workflow job for this annotation

GitHub Actions / test (ubuntu-latest)

log.Fatalf call has arguments but no formatting directives
} else {
log.Print("command succeeded")
}
log.Print("Restarting command")

restartCommand(cmdToRestart)
}

func waitForNetwork() {
for {
// Try to connect to a known reliable host (e.g., Google DNS)
conn, err := net.DialTimeout("tcp", "8.8.8.8:53", 5*time.Second)
if err == nil {
conn.Close()
log.Print("Network online. Proceeding...")
break
}
log.Print("Waiting for network...")
time.Sleep(5 * time.Second)
}
}

0 comments on commit a110915

Please sign in to comment.