Compare commits
12 commits
Author | SHA1 | Date | |
---|---|---|---|
c7ed0f148f | |||
ec1f0d3f3a | |||
3d559fc94d | |||
0bc10b7154 | |||
0d81ffaa86 | |||
a94ccbc554 | |||
08f213e0de | |||
231441f980 | |||
622dd91ba6 | |||
bc875b83a4 | |||
27152bad72 | |||
27948ee5b6 |
7 changed files with 146 additions and 10 deletions
|
@ -11,7 +11,7 @@ jobs:
|
||||||
deploy-production:
|
deploy-production:
|
||||||
runs-on: [amd64, prod]
|
runs-on: [amd64, prod]
|
||||||
env:
|
env:
|
||||||
NODES: node-22.rosti.cz node-23.rosti.cz node-24.rosti.cz node-25.rosti.cz
|
NODES: node-22.rosti.cz node-23.rosti.cz node-24.rosti.cz node-25.rosti.cz node-28.rosti.cz node-29.rosti.cz
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- name: deploy
|
- name: deploy
|
||||||
|
|
|
@ -7,7 +7,7 @@ on:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
unittests:
|
unittests:
|
||||||
runs-on: [amd64, moon]
|
runs-on: [amd64, dev]
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: actions/setup-go@v3
|
- uses: actions/setup-go@v3
|
||||||
|
@ -36,11 +36,14 @@ jobs:
|
||||||
# - 9001:9001
|
# - 9001:9001
|
||||||
# options: server /data --console-address :9001
|
# options: server /data --console-address :9001
|
||||||
deploy-dev:
|
deploy-dev:
|
||||||
runs-on: [amd64, moon]
|
runs-on: [amd64, dev]
|
||||||
env:
|
env:
|
||||||
NODES: "192.168.1.33"
|
NODES: "192.168.1.199"
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
|
- uses: webfactory/ssh-agent@v0.9.0
|
||||||
|
with:
|
||||||
|
ssh-private-key: ${{ secrets.SSH_MASTER_KEY }}
|
||||||
- name: deploy
|
- name: deploy
|
||||||
run: |
|
run: |
|
||||||
# echo LS1
|
# echo LS1
|
||||||
|
|
|
@ -338,10 +338,13 @@ func (d *Driver) Create(name string, image string, volumePath string, HTTPPort i
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OOMKillDisable := false
|
// OOMKillDisable := false
|
||||||
if memory < 1500 {
|
// if memory < 1500 {
|
||||||
OOMKillDisable = true
|
// OOMKillDisable = true
|
||||||
}
|
// }
|
||||||
|
// We disable OOM killer because it keeps containers in resource heavy loop
|
||||||
|
// This is from some discussion: If OOM-killer is disabled, tasks under cgroup will hang/sleep in memory cgroup's OOM-waitqueue when they request accountable memory
|
||||||
|
OOMKillDisable := true
|
||||||
|
|
||||||
envList := []string{}
|
envList := []string{}
|
||||||
for key, value := range env {
|
for key, value := range env {
|
||||||
|
|
|
@ -100,6 +100,9 @@ func (p *Processor) waitForApp() error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if status.Status == "running" {
|
if status.Status == "running" {
|
||||||
|
if i > 0 {
|
||||||
|
time.Sleep(sleepFor) // We wait a little bit more to make sure the container is fully started
|
||||||
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
119
handlers.go
119
handlers.go
|
@ -3,7 +3,6 @@ package main
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -236,7 +235,7 @@ func clearPasswordHandler(c echo.Context) error {
|
||||||
func setKeysHandler(c echo.Context) error {
|
func setKeysHandler(c echo.Context) error {
|
||||||
name := c.Param("name")
|
name := c.Param("name")
|
||||||
|
|
||||||
body, err := ioutil.ReadAll(c.Request().Body)
|
body, err := io.ReadAll(c.Request().Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
@ -495,3 +494,119 @@ func metricsHandler(c echo.Context) error {
|
||||||
|
|
||||||
return c.String(http.StatusOK, metrics)
|
return c.String(http.StatusOK, metrics)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func CreateSnapshotHandler(c echo.Context) error {
|
||||||
|
name := c.Param("name")
|
||||||
|
|
||||||
|
body := createSnapshotBody{}
|
||||||
|
err := c.Bind(body)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
processor := glue.Processor{
|
||||||
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
|
DockerSock: config.DockerSocket,
|
||||||
|
BindIPHTTP: config.AppsBindIPHTTP,
|
||||||
|
BindIPSSH: config.AppsBindIPSSH,
|
||||||
|
AppsPath: config.AppsPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err = processor.CreateSnapshot(body.Labels)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSONPretty(http.StatusOK, Message{Message: "ok"}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func RestoreFromSnapshotHandler(c echo.Context) error {
|
||||||
|
name := c.Param("name")
|
||||||
|
snapshot := c.Param("snapshot")
|
||||||
|
|
||||||
|
processor := glue.Processor{
|
||||||
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
|
DockerSock: config.DockerSocket,
|
||||||
|
BindIPHTTP: config.AppsBindIPHTTP,
|
||||||
|
BindIPSSH: config.AppsBindIPSSH,
|
||||||
|
AppsPath: config.AppsPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
err := processor.RestoreFromSnapshot(snapshot)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSONPretty(http.StatusOK, Message{Message: "ok"}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListSnapshotsHandler(c echo.Context) error {
|
||||||
|
name := c.Param("name")
|
||||||
|
|
||||||
|
processor := glue.Processor{
|
||||||
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
|
DockerSock: config.DockerSocket,
|
||||||
|
BindIPHTTP: config.AppsBindIPHTTP,
|
||||||
|
BindIPSSH: config.AppsBindIPSSH,
|
||||||
|
AppsPath: config.AppsPath,
|
||||||
|
}
|
||||||
|
|
||||||
|
snapshots, err := processor.ListSnapshots()
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, snapshots)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListAppsSnapshotsHandler(c echo.Context) error {
|
||||||
|
name := c.Param("name")
|
||||||
|
apps := []string{}
|
||||||
|
|
||||||
|
err := c.Bind(&apps)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusBadRequest, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
processor := glue.Processor{
|
||||||
|
AppName: name,
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
|
DockerSock: config.DockerSocket,
|
||||||
|
BindIPHTTP: config.AppsBindIPHTTP,
|
||||||
|
BindIPSSH: config.AppsBindIPSSH,
|
||||||
|
AppsPath: config.AppsPath,
|
||||||
|
}
|
||||||
|
snapshots, err := processor.ListAppsSnapshots(apps)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, snapshots)
|
||||||
|
}
|
||||||
|
|
||||||
|
func ListSnapshotsByLabelHandler(c echo.Context) error {
|
||||||
|
label := c.Param("label")
|
||||||
|
|
||||||
|
processor := glue.Processor{
|
||||||
|
AppName: "",
|
||||||
|
DB: common.GetDBConnection(),
|
||||||
|
SnapshotProcessor: &snapshotProcessor,
|
||||||
|
DockerSock: config.DockerSocket,
|
||||||
|
BindIPHTTP: config.AppsBindIPHTTP,
|
||||||
|
BindIPSSH: config.AppsBindIPSSH,
|
||||||
|
AppsPath: config.AppsPath,
|
||||||
|
}
|
||||||
|
snapshots, err := processor.ListSnapshotsByLabel(label)
|
||||||
|
if err != nil {
|
||||||
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
|
}
|
||||||
|
|
||||||
|
return c.JSON(http.StatusOK, snapshots)
|
||||||
|
}
|
||||||
|
|
7
main.go
7
main.go
|
@ -198,6 +198,13 @@ func main() {
|
||||||
// Delete one app
|
// Delete one app
|
||||||
e.DELETE("/v1/apps/:name", deleteAppHandler)
|
e.DELETE("/v1/apps/:name", deleteAppHandler)
|
||||||
|
|
||||||
|
// Snapshots
|
||||||
|
e.POST("/v1/apps/:name/snapshots", CreateSnapshotHandler)
|
||||||
|
e.POST("/v1/apps/:name/snapshots/restore/:snapshot", RestoreFromSnapshotHandler)
|
||||||
|
e.GET("/v1/apps/:name/snapshots", ListSnapshotsHandler)
|
||||||
|
e.GET("/v1/snapshots", ListAppsSnapshotsHandler)
|
||||||
|
e.GET("/v1/snapshots/by-label", ListSnapshotsByLabelHandler)
|
||||||
|
|
||||||
// Orphans returns directories in /srv that doesn't match any hosted application
|
// Orphans returns directories in /srv that doesn't match any hosted application
|
||||||
e.GET("/v1/orphans", getOrphansHander)
|
e.GET("/v1/orphans", getOrphansHander)
|
||||||
|
|
||||||
|
|
5
types.go
5
types.go
|
@ -56,6 +56,7 @@ type QuickServices struct {
|
||||||
PHP bool `json:"php"`
|
PHP bool `json:"php"`
|
||||||
Ruby bool `json:"ruby"`
|
Ruby bool `json:"ruby"`
|
||||||
Deno bool `json:"deno"`
|
Deno bool `json:"deno"`
|
||||||
|
Bun bool `json:"bun"`
|
||||||
Memcached bool `json:"memcached"`
|
Memcached bool `json:"memcached"`
|
||||||
Redis bool `json:"redis"`
|
Redis bool `json:"redis"`
|
||||||
}
|
}
|
||||||
|
@ -65,3 +66,7 @@ type Technology struct {
|
||||||
Name string
|
Name string
|
||||||
Version string
|
Version string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type createSnapshotBody struct {
|
||||||
|
Labels []string `json:"labels"`
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue