Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 20459b81c8 | |||
| 79cd8fc9fd |
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 (
|
||||
github.com/google/uuid v1.6.0
|
||||
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
|
||||
)
|
||||
|
||||
@@ -21,7 +21,7 @@ require (
|
||||
github.com/go-logr/stdr v1.2.2 // indirect
|
||||
github.com/joho/godotenv v1.5.1
|
||||
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/image-spec v1.1.1 // 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/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.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/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/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
|
||||
github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040=
|
||||
|
||||
8
license
Normal file
8
license
Normal file
@@ -0,0 +1,8 @@
|
||||
The MIT License (MIT)
|
||||
Copyright © 2026 Gergő Dulai
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
138
node/node.go
Normal file
138
node/node.go
Normal file
@@ -0,0 +1,138 @@
|
||||
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) {
|
||||
requestId := r.Context().Value("requestId")
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
var containerId string
|
||||
err := decoder.Decode(&containerId)
|
||||
if err != nil {
|
||||
log.LogError("Failed to decode node/start request body! (%s)\n%s", requestId, err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if containerId == "" {
|
||||
log.LogError("Container id mus be specified for node/start! (%s)", requestId)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = start(containerId)
|
||||
if err == nil {
|
||||
log.LogInfo("Successfully container start: %s (%s)", containerId, requestId)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
log.LogInfo("Failed container start! (%s)\n%s", requestId, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func start(containerId string) error {
|
||||
cli := openDockerClient()
|
||||
_, err := cli.ContainerStart(context.Background(), containerId, client.ContainerStartOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func HandleStop(w http.ResponseWriter, r *http.Request) {
|
||||
requestId := r.Context().Value("requestId")
|
||||
|
||||
decoder := json.NewDecoder(r.Body)
|
||||
var containerId string
|
||||
err := decoder.Decode(&containerId)
|
||||
if err != nil {
|
||||
log.LogError("Failed to decode node/stop request body! (%s)", requestId)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if containerId == "" {
|
||||
log.LogError("Container id must be specified for node/stop! (%s)", requestId)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
err = stop(containerId)
|
||||
if err == nil {
|
||||
log.LogInfo("Successfully container stop: %s (%s)", containerId, requestId)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
log.LogInfo("Failed container stop! (%s)\n%s", requestId, err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
}
|
||||
|
||||
func stop(containerId string) error {
|
||||
cli := openDockerClient()
|
||||
_, err := cli.ContainerStop(context.Background(), containerId, client.ContainerStopOptions{})
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
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.NewClientWithOpts(
|
||||
client.FromEnv,
|
||||
client.WithHost("unix:///var/run/docker.sock"),
|
||||
)
|
||||
if err != nil {
|
||||
log.LogFatalError("Failed to create Docker client: %v", err)
|
||||
}
|
||||
return cli
|
||||
}
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"net/http"
|
||||
"os"
|
||||
"simple-cluster-node/health"
|
||||
"simple-cluster-node/node"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
@@ -14,15 +15,11 @@ import (
|
||||
func SetupRouter() *mux.Router {
|
||||
r := mux.NewRouter()
|
||||
r.Use(identifyRequest, corsCheck, logRequest)
|
||||
r.HandleFunc("/health", health.Handle).Methods("GET", "OPTIONS")
|
||||
|
||||
/*
|
||||
r.HandleFunc("/album", handler.GetAlbums).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/album", handler.SaveAlbum).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/album/{albumId}", handler.DeleteAlbum).Methods("DELETE", "OPTIONS")
|
||||
r.HandleFunc("/album/{albumId}", handler.GetAlbum).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/shareAlbum/{albumId}/{userId}", handler.ShareAlbum).Methods("POST", "OPTIONS")
|
||||
*/
|
||||
r.HandleFunc("/health", health.Handle).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/node/info", node.HandleInfo).Methods("GET", "OPTIONS")
|
||||
r.HandleFunc("/node/start", node.HandleStart).Methods("POST", "OPTIONS")
|
||||
r.HandleFunc("/node/stop", node.HandleStop).Methods("POST", "OPTIONS")
|
||||
|
||||
return r
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user