package daemons import ( "bytes" "encoding/json" "fmt" "io" "net/http" "oc-schedulerd/conf" "github.com/rs/zerolog" ) type ContainerMonitor struct { Monitor LocalMonitor KubeCA string KubeCert string KubeData string KubeHost string KubePort string } func NewContainerMonitor(executionsId string, peerId string, duration int) (Executor){ return &ContainerMonitor{ Monitor: LocalMonitor{ ExecutionID: executionsId, PeerID: peerId, Duration: duration, LokiUrl: conf.GetConfig().LokiUrl, MongoUrl: conf.GetConfig().MongoUrl, DBName: conf.GetConfig().DBName, }, KubeCA: conf.GetConfig().KubeCA, KubeCert: conf.GetConfig().KubeCert, KubeData: conf.GetConfig().KubeData, KubeHost: conf.GetConfig().KubeHost, KubePort: conf.GetConfig().KubePort, } } func (cm *ContainerMonitor) PrepareMonitorExec() []string { args := []string{ "-e", cm.Monitor.ExecutionID, "-p", cm.Monitor.PeerID, "-u", cm.Monitor.LokiUrl, "-m", cm.Monitor.MongoUrl, "-d", cm.Monitor.DBName, "-M", "kubernetes", "-H", cm.KubeHost, "-P", cm.KubePort, "-C", cm.KubeCert, "-D", cm.KubeData, "-c", cm.KubeCA, } if cm.Monitor.Duration > 0 { args = append(args, "-t", fmt.Sprintf("%d", cm.Monitor.Duration)) } return args } // Contact the docker's API at the KubeHost's URL to : // - Check if the image exists // - Create the container // - Start the container func (cm *ContainerMonitor) LaunchMonitor(args []string, l zerolog.Logger) { var containerID string imageName := "oc-monitord" url := "http://" + conf.GetConfig().KubeHost + ":2375" resp, err := http.Get(url + "/images/" + imageName + "/json") if err != nil { l.Fatal().Msg("Error when contacting the docker API on " + conf.GetConfig().KubeHost + ": " + err.Error()) } if resp.StatusCode != http.StatusOK { d, _ := io.ReadAll(resp.Body) l.Fatal().Msg("Couldn't find the oc-monitord image : " + string(d)) } dataCreation := map[string]interface{}{"Image": imageName, "Cmd" : args} byteData, err := json.Marshal(dataCreation) if err != nil { l.Fatal().Msg("Error when contacting the creating request body : " + err.Error()) } r, _ := http.NewRequest("POST",url + "/containers/create", bytes.NewBuffer(byteData)) r.Header.Add("Content-Type","application/json") resp, err = http.DefaultClient.Do(r) if err != nil { l.Fatal().Msg("Error when contacting the docker API on " + conf.GetConfig().KubeHost + ": " + err.Error()) } if resp.StatusCode == 201 { var d map[string]interface{} b, err := io.ReadAll(resp.Body) if err != nil { l.Fatal().Msg(err.Error()) } err = json.Unmarshal(b, &d) if err != nil { l.Fatal().Msg(err.Error()) } containerID = d["Id"].(string) } else { d, _ := io.ReadAll(resp.Body) l.Fatal().Msg("Error when creating the container on " + conf.GetConfig().KubeHost + "\n " + string(d)) } resp, err = http.Post( url + "/containers/" + containerID + "/start", "", nil) if err != nil { l.Fatal().Msg("Error when contacting the docker API on " + conf.GetConfig().KubeHost + ": " + err.Error()) } if resp.StatusCode >= 300 { d, _ := io.ReadAll(resp.Body) l.Fatal().Msg("Error when starting the container on " + conf.GetConfig().KubeHost + "\n " + string(d)) } l.Info().Msg("Started container " + containerID) // we can add logging with GET /containers/id/logs?stdout=true&follow=true // logExecution(stdoutMonitord, l) }