Various fixes

* UI: abbility to start container in exited state
* Fix all Where() method usages
* Container state is updated every list and get operation
This commit is contained in:
Adam Štrauch 2020-07-23 23:50:20 +02:00
parent 7d6e9c0ae6
commit 60f99d52b0
Signed by: cx
GPG key ID: 018304FFA8988F8D
5 changed files with 91 additions and 14 deletions

View file

@ -2,9 +2,9 @@ POST http://localhost:1323/v1/apps
Content-type: application/json
{
"name": "test_1234",
"ssh_port": 46500,
"http_port": 46501,
"name": "test_1235",
"ssh_port": 46502,
"http_port": 46503,
"image": "docker.io/rosti/runtime:2020.04-1",
"cpu": 100,
"memory": 128
@ -63,7 +63,7 @@ Content-type: application/json
# Get
GET http://localhost:1323/v1/apps/test_1234
GET http://localhost:1323/v1/apps/test_1235
Content-type: application/json

View file

@ -16,7 +16,7 @@ func Get(name string) (*App, error) {
db := common.GetDBConnection()
err := db.Preload("Labels").First(&app).Where("name = ?", name).Error
err := db.Preload("Labels").Where("name = ?", name).First(&app).Error
if err != nil {
return nil, err
}
@ -71,7 +71,7 @@ func Update(name string, SSHPort int, HTTPPort int, image string, CPU int, memor
db := common.GetDBConnection()
err := db.First(&app).Where("name = ?", name).Error
err := db.Where("name = ?", name).First(&app).Error
if err != nil {
return &app, err
}
@ -115,13 +115,23 @@ func Update(name string, SSHPort int, HTTPPort int, image string, CPU int, memor
func UpdateState(name string, state string, CPUUsage float64, memory int, diskUsageBytes int, diskUsageInodes int) error {
db := common.GetDBConnection()
err := db.Model(&App{}).Updates(App{
err := db.Model(&App{}).Where("name = ?", name).Updates(App{
State: state,
CPUUsage: CPUUsage,
MemoryUsage: memory,
DiskUsageBytes: diskUsageBytes,
DiskUsageInodes: diskUsageInodes,
}).Where("name = ?", name).Error
}).Error
return err
}
// UpdateContainerState sets container's state
func UpdateContainerState(name string, state string) error {
db := common.GetDBConnection()
err := db.Model(&App{}).Where("name = ?", name).Updates(App{
State: state,
}).Error
return err
}
@ -129,7 +139,18 @@ func UpdateState(name string, state string, CPUUsage float64, memory int, diskUs
func Delete(name string) error {
db := common.GetDBConnection()
err := db.Delete(App{}).Where("name = ?", name).Error
app, err := Get(name)
if err != nil {
return err
}
err = db.Where("app_id = ?", app.ID).Delete(&Label{}).Error
if err != nil {
return err
}
err = db.Where("id = ?", app.ID).Delete(App{}).Error
return err
}
@ -139,7 +160,7 @@ func AddLabel(appName string, label string) error {
db := common.GetDBConnection()
err := db.First(&app).Where("name = ?", appName).Error
err := db.Where("name = ?", appName).First(&app).Error
if err != nil {
return err
}
@ -165,10 +186,10 @@ func RemoveLabel(appName string, label string) error {
db := common.GetDBConnection()
err := db.First(&app).Where("name = ?", appName).Error
err := db.Where("name = ?", appName).First(&app).Error
if err != nil {
return err
}
return db.Delete(&Label{}).Where("label = ? AND app_id = ?", label, app.ID).Error
return db.Where("label = ? AND app_id = ?", label, app.ID).Delete(&Label{}).Error
}

15
main.go
View file

@ -56,6 +56,11 @@ func main() {
return c.Render(http.StatusOK, "index.html", "")
})
e.GET("/v1/apps", func(c echo.Context) error {
err := gatherContainersStates()
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
applications, err := apps.List()
if err != nil {
@ -74,6 +79,16 @@ func main() {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
err = updateContainerState(app)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
app, err = apps.Get(name)
if err != nil {
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
}
return c.JSON(http.StatusOK, app)
})

View file

@ -7,6 +7,24 @@ import (
"github.com/rosti-cz/node-api/docker"
)
// Updates only container's state
func updateContainerState(app *apps.App) error {
container := docker.Container{
App: app,
}
state, err := container.Status()
if err != nil {
return err
}
err = apps.UpdateContainerState(
app.Name,
state,
)
return err
}
// Updates info about all containers
func updateContainerStats(app *apps.App) error {
container := docker.Container{
App: app,
@ -24,7 +42,7 @@ func updateContainerStats(app *apps.App) error {
state.DiskUsageBytes,
state.DiskUsageInodes,
)
return nil
return err
}
// gatherContainersStats gathers information about containers and saves it into the database
@ -43,3 +61,20 @@ func gatherContainersStats() error {
return nil
}
// gatherContainersStates refreshes all container's state
func gatherContainersStates() error {
appList, err := apps.List()
if err != nil {
return err
}
for _, app := range *appList {
err := updateContainerState(&app)
if err != nil {
log.Println("STATE ERROR:", err.Error())
}
}
return nil
}

View file

@ -82,7 +82,7 @@
<span v-for="label in app.labels" class="label label-info">{( label.value )}</span>
</td>
<td>
<button class="btn btn-success btn-sm" v-on:click="start(app.name)" v-if="['stopped', 'created'].includes(app.state)">Start</button>
<button class="btn btn-success btn-sm" v-on:click="start(app.name)" v-if="['stopped', 'created', 'exited'].includes(app.state)">Start</button>
<button class="btn btn-warning btn-sm" v-on:click="stop(app.name)" v-if="['running'].includes(app.state)">Stop</button>
<button class="btn btn-warning btn-sm" v-on:click="restart(app.name)" v-if="['running'].includes(app.state)">Restart</button>
<button class="btn btn-warning btn-sm" v-on:click="rebuild(app.name)">Rebuild</button>
@ -122,6 +122,12 @@
hasError: () => {
return this.api_status_code >= 400 && this.api_status_code < 505
},
refresh: () => {
fetch('/v1/apps').then(response => response.json())
.then(data => this.apps = data);
fetch('/v1/node').then(response => response.json())
.then(data => this.node = data);
},
start: (id) => {
app.api_response = "working"
fetch('/v1/apps/'+id+'/start', {method: 'PUT'})