Node endpoints with container handling #1
1
container/container.go
Normal file
1
container/container.go
Normal file
@@ -0,0 +1 @@
|
|||||||
|
package container
|
||||||
8
docker-compose.yml
Normal file
8
docker-compose.yml
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
version: "3.9"
|
||||||
|
services:
|
||||||
|
simple-cluster-node:
|
||||||
|
build: .
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
4
go.mod
4
go.mod
@@ -5,7 +5,7 @@ go 1.25.6
|
|||||||
require (
|
require (
|
||||||
github.com/google/uuid v1.6.0
|
github.com/google/uuid v1.6.0
|
||||||
github.com/gorilla/mux v1.8.1
|
github.com/gorilla/mux v1.8.1
|
||||||
github.com/moby/moby/client v0.2.1
|
github.com/moby/moby/client v0.2.2
|
||||||
gitlab.com/gdulai/simpleloglvl v0.0.0-20250930234204-a64d074990c1
|
gitlab.com/gdulai/simpleloglvl v0.0.0-20250930234204-a64d074990c1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -21,7 +21,7 @@ require (
|
|||||||
github.com/go-logr/stdr v1.2.2 // indirect
|
github.com/go-logr/stdr v1.2.2 // indirect
|
||||||
github.com/joho/godotenv v1.5.1
|
github.com/joho/godotenv v1.5.1
|
||||||
github.com/moby/docker-image-spec v1.3.1 // indirect
|
github.com/moby/docker-image-spec v1.3.1 // indirect
|
||||||
github.com/moby/moby/api v1.52.0 // indirect
|
github.com/moby/moby/api v1.53.0 // indirect
|
||||||
github.com/opencontainers/go-digest v1.0.0 // indirect
|
github.com/opencontainers/go-digest v1.0.0 // indirect
|
||||||
github.com/opencontainers/image-spec v1.1.1 // indirect
|
github.com/opencontainers/image-spec v1.1.1 // indirect
|
||||||
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
go.opentelemetry.io/auto/sdk v1.1.0 // indirect
|
||||||
|
|||||||
4
go.sum
4
go.sum
@@ -31,8 +31,12 @@ github.com/moby/docker-image-spec v1.3.1 h1:jMKff3w6PgbfSa69GfNg+zN/XLhfXJGnEx3N
|
|||||||
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
github.com/moby/docker-image-spec v1.3.1/go.mod h1:eKmb5VW8vQEh/BAr2yvVNvuiJuY6UIocYsFu/DxxRpo=
|
||||||
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
|
github.com/moby/moby/api v1.52.0 h1:00BtlJY4MXkkt84WhUZPRqt5TvPbgig2FZvTbe3igYg=
|
||||||
github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
|
github.com/moby/moby/api v1.52.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
|
||||||
|
github.com/moby/moby/api v1.53.0 h1:PihqG1ncw4W+8mZs69jlwGXdaYBeb5brF6BL7mPIS/w=
|
||||||
|
github.com/moby/moby/api v1.53.0/go.mod h1:8mb+ReTlisw4pS6BRzCMts5M49W5M7bKt1cJy/YbAqc=
|
||||||
github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k=
|
github.com/moby/moby/client v0.2.1 h1:1Grh1552mvv6i+sYOdY+xKKVTvzJegcVMhuXocyDz/k=
|
||||||
github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=
|
github.com/moby/moby/client v0.2.1/go.mod h1:O+/tw5d4a1Ha/ZA/tPxIZJapJRUS6LNZ1wiVRxYHyUE=
|
||||||
|
github.com/moby/moby/client v0.2.2 h1:Pt4hRMCAIlyjL3cr8M5TrXCwKzguebPAc2do2ur7dEM=
|
||||||
|
github.com/moby/moby/client v0.2.2/go.mod h1:2EkIPVNCqR05CMIzL1mfA07t0HvVUUOl85pasRz/GmQ=
|
||||||
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
|
||||||
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||||
|
|||||||
107
node/node.go
Normal file
107
node/node.go
Normal file
@@ -0,0 +1,107 @@
|
|||||||
|
package node
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/moby/moby/api/types/container"
|
||||||
|
"github.com/moby/moby/client"
|
||||||
|
log "gitlab.com/gdulai/simpleloglvl"
|
||||||
|
)
|
||||||
|
|
||||||
|
type BuildCommand struct {
|
||||||
|
Repository string `json:"repository"`
|
||||||
|
Branch string `json:"branch"`
|
||||||
|
Descriptor string `json:"descriptor"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleBuild(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func build(command BuildCommand) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleStart(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func start() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleStop(w http.ResponseWriter, r *http.Request) {
|
||||||
|
decoder := json.NewDecoder(r.Body)
|
||||||
|
var containerId string
|
||||||
|
err := decoder.Decode(&containerId)
|
||||||
|
if err != nil {
|
||||||
|
log.LogError("Failed to decode node/stop request body!")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if containerId == "" {
|
||||||
|
log.LogError("Container id mus be specified for node/stop!")
|
||||||
|
w.WriteHeader(http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if stop(containerId) {
|
||||||
|
w.WriteHeader(http.StatusOK)
|
||||||
|
} else {
|
||||||
|
w.WriteHeader(http.StatusInternalServerError)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func stop(containerId string) bool {
|
||||||
|
cli := openDockerClient()
|
||||||
|
_, err := cli.ContainerStop(context.Background(), containerId, client.ContainerStopOptions{})
|
||||||
|
if err != nil {
|
||||||
|
log.LogError("Failed to stop container: %s\n%s", containerId, err)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
log.LogInfo("Successfully stopped container: %s", containerId)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
func HandleInfo(w http.ResponseWriter, r *http.Request) {
|
||||||
|
json.NewEncoder(w).Encode(info())
|
||||||
|
}
|
||||||
|
|
||||||
|
func info() []container.Summary {
|
||||||
|
cli := openDockerClient()
|
||||||
|
// List all containers (running and stopped)
|
||||||
|
containers, err := cli.ContainerList(context.Background(), client.ContainerListOptions{
|
||||||
|
All: true,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.LogFatalError("Failed to list containers: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var summaries []container.Summary
|
||||||
|
// Print container info
|
||||||
|
for _, c := range containers.Items {
|
||||||
|
summaries = append(summaries, c)
|
||||||
|
name := ""
|
||||||
|
if len(c.Names) > 0 {
|
||||||
|
name = c.Names[0]
|
||||||
|
}
|
||||||
|
log.LogInfo("ID: %s Name: %s Image: %s Status: %s\n",
|
||||||
|
c.ID[:12], name, c.Image, c.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
return summaries
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func openDockerClient() *client.Client {
|
||||||
|
cli, err := client.New(
|
||||||
|
client.FromEnv,
|
||||||
|
client.WithAPIVersionFromEnv(),
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
log.LogFatalError("Failed to create Docker client: %v", err)
|
||||||
|
}
|
||||||
|
return cli
|
||||||
|
}
|
||||||
@@ -5,6 +5,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
"simple-cluster-node/health"
|
"simple-cluster-node/health"
|
||||||
|
"simple-cluster-node/node"
|
||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
@@ -14,7 +15,9 @@ import (
|
|||||||
func SetupRouter() *mux.Router {
|
func SetupRouter() *mux.Router {
|
||||||
r := mux.NewRouter()
|
r := mux.NewRouter()
|
||||||
r.Use(identifyRequest, corsCheck, logRequest)
|
r.Use(identifyRequest, corsCheck, logRequest)
|
||||||
|
|
||||||
r.HandleFunc("/health", health.Handle).Methods("GET", "OPTIONS")
|
r.HandleFunc("/health", health.Handle).Methods("GET", "OPTIONS")
|
||||||
|
r.HandleFunc("/node/info", node.HandleInfo).Methods("GET", "OPTIONS")
|
||||||
|
|
||||||
/*
|
/*
|
||||||
r.HandleFunc("/album", handler.GetAlbums).Methods("GET", "OPTIONS")
|
r.HandleFunc("/album", handler.GetAlbums).Methods("GET", "OPTIONS")
|
||||||
|
|||||||
Reference in New Issue
Block a user