launch oc-monitor locally or in a container

This commit is contained in:
pb 2024-07-25 18:48:25 +02:00
parent f7eb7e4b81
commit 7ecfee1154
6 changed files with 174 additions and 17 deletions

17
Dockerfile Normal file
View File

@ -0,0 +1,17 @@
FROM golang:alpine AS builder
WORKDIR /app
COPY . .
RUN go build .
RUN mkdir workflows/
FROM scratch
WORKDIR /app
COPY conf/ocmonitor_conf.json /app/conf/
COPY --from=builder /app/oc-monitor .
COPY --from=builder /app/workflows/ .
ENTRYPOINT [ "/app/oc-monitor" ]

View File

@ -1,2 +1,16 @@
# oc-monitor # oc-monitor
## Deploy in k8s (dev)
While a registry with all of the OC docker images has not been set-up we can export this image to k3s ctr
> docker save oc-monitor:latest | sudo k3s ctr images import -
Then in the pod manifest for oc-monitor use :
```
image: docker.io/library/oc-monitor
imagePullPolicy: Never
```
Not doing so will end up in the pod having a `ErrorImagePull`

30
conf/conf.go Normal file
View File

@ -0,0 +1,30 @@
package conf
import "sync"
// declare the flag to use for each variable
var map_arguments = map[string]string {
"LokiURL" : "u",
"ArgoFile": "f",
"ContainerName" : "n",
}
type Config struct {
LokiURL string
ArgoFile string
ContainerName string
}
var instance *Config
var once sync.Once
func GetConfig() *Config {
once.Do(func() {
instance = &Config{}
})
return instance
}
func GetConfFromArgs(argument string){
}

1
conf/ocmonitor_conf.json Normal file
View File

@ -0,0 +1 @@
{}

15
go.mod
View File

@ -2,11 +2,16 @@ module oc-monitor
go 1.22.0 go 1.22.0
require github.com/grafana/loki-client-go v0.0.0-20230116142646-e7494d0ef70c require (
cloud.o-forge.io/core/oc-lib v0.0.0-20240725103514-2891dc8a6819
github.com/akamensky/argparse v1.4.0
github.com/goraz/onion v0.1.3
github.com/rs/zerolog v1.33.0
)
require ( require (
github.com/blang/semver v3.5.1+incompatible // indirect github.com/mattn/go-colorable v0.1.13 // indirect
github.com/gogo/protobuf v1.3.2 // indirect github.com/mattn/go-isatty v0.0.20 // indirect
github.com/golang/snappy v0.0.4 // indirect github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect golang.org/x/sys v0.22.0 // indirect
) )

114
main.go
View File

@ -2,24 +2,114 @@ package main
import ( import (
"log" "log"
"os/exec" "os"
"oc-monitor/conf"
"cloud.o-forge.io/core/oc-lib/logs"
"github.com/akamensky/argparse"
"github.com/goraz/onion"
"github.com/rs/zerolog"
) )
var logger zerolog.Logger
var parser argparse.Parser
const defaultConfigFile = "/etc/oc/ocmonitor_conf.json"
const localConfigFile = "./conf/ocmonitor_conf.json"
func main() { func main() {
// Initialize LokiLogger
lokiLogger := NewLokiLogger("http://localhost:3100/loki/api/v1/push") // Replace with your Loki URL // Test if monitor is launched outside (with parameters) or in a k8s environment (env variables sets)
if os.Getenv("KUBERNETES_SERVICE_HOST") == ""{
// Not in a k8s environment, get conf from parameters
parser = *argparse.NewParser("oc-monitor","Launch the execution of a workflow given as a parameter and sends the produced logs to a loki database")
loadConfig(false, &parser)
} else {
// Executed in a k8s environment
loadConfig(true,nil)
}
logger = logs.CreateLogger("oc-monitor", conf.GetConfig().LokiURL)
logger.Debug().Msg("Loki URL : " + conf.GetConfig().LokiURL)
logger.Debug().Msg("Filename : " + conf.GetConfig().ArgoFile)
logger.Debug().Msg("Container Name : " + conf.GetConfig().ContainerName)
// Wait for the argo file to be copied to the pod
wf_found := false
for(!wf_found){
if _, err := os.Stat("./workflows/" + conf.GetConfig().ArgoFile); err == nil {
wf_found = true
}
}
logger.Debug().Msg("Submitting the argo workflow : " + conf.GetConfig().ArgoFile)
// // Initialize LokiLogger
// lokiLogger := NewLokiLogger("http://localhost:3100/loki/api/v1/push") // Replace with your Loki URL
// Run the Argo command // Run the Argo command
cmd := exec.Command("argo", "submit", "your-workflow.yaml") // cmd := exec.Command("argo", "submit", "your-workflow.yaml")
output, err := cmd.CombinedOutput() // output, err := cmd.CombinedOutput()
if err != nil { // if err != nil {
log.Fatalf("failed to run Argo command: %v", err) // log.Fatalf("failed to run Argo command: %v", err)
} // }
// Send logs to Loki // logger.Info().Msg(string(output))
if err := lokiLogger.Log(`{job="argo"}`, string(output)); err != nil { // // Send logs to Loki
log.Fatalf("failed to send logs to Loki: %v", err) // if err := lokiLogger.Log(`{job="argo"}`, string(output)); err != nil {
} // log.Fatalf("failed to send logs to Loki: %v", err)
// }
log.Println("Logs sent to Loki successfully.") log.Println("Logs sent to Loki successfully.")
} }
func loadConfig(is_k8s bool, parser *argparse.Parser){
var o *onion.Onion
logger = logs.CreateLogger("oc-monitor","")
configFile := ""
l3 := onion.NewEnvLayerPrefix("_", "OCMONITOR")
l2, err := onion.NewFileLayer(defaultConfigFile, nil)
if err == nil {
logger.Info().Msg("Config file found : " + defaultConfigFile)
configFile = defaultConfigFile
}
l1, err := onion.NewFileLayer(localConfigFile, nil)
if err == nil {
logger.Info().Msg("Local config file found " + localConfigFile + ", overriding default file")
configFile = localConfigFile
}
if configFile == "" {
logger.Info().Msg("No config file found, using env")
o = onion.New(l3)
} else if l1 == nil && l2 == nil {
o = onion.New(l1, l2, l3)
} else if l1 == nil {
o = onion.New(l2, l3)
} else if l2 == nil {
o = onion.New(l1, l3)
}
// These variables can only be retrieved in the onion
// Variables that don't depend on the environmen (from conf file), can be loaded after
if (is_k8s){
// We can't use underscore in the env variable names because it's the delimitor with OCMONITOR too
conf.GetConfig().LokiURL = o.GetStringDefault("lokiurl", "http://127.0.0.1:3100")
conf.GetConfig().ArgoFile = o.GetString("argofile")
conf.GetConfig().ContainerName = o.GetString("containername")
} else{
url := parser.String("u", "url", &argparse.Options{Required: true,Default: "http://127.0.0.1:3100"})
conf.GetConfig().LokiURL = *url
file := parser.String("f", "file", &argparse.Options{Required: true})
conf.GetConfig().ArgoFile = *file
name := parser.String("n", "name", &argparse.Options{Required: true})
conf.GetConfig().ContainerName = *name
err := parser.Parse(os.Args)
if err != nil {
logger.Fatal().Msg(parser.Usage(err))
}
}
}