UI enhancements, stats gathering done
This commit is contained in:
parent
c728f4f2af
commit
57c0ddd71d
9
api.http
9
api.http
@ -31,6 +31,7 @@ Content-type: application/json
|
|||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
|
# Stop
|
||||||
|
|
||||||
PUT http://localhost:1323/v1/apps/test_1234/stop
|
PUT http://localhost:1323/v1/apps/test_1234/stop
|
||||||
Content-type: application/json
|
Content-type: application/json
|
||||||
@ -58,6 +59,14 @@ Content-type: application/json
|
|||||||
GET http://localhost:1323/v1/apps/test_1234/stats
|
GET http://localhost:1323/v1/apps/test_1234/stats
|
||||||
Content-type: application/json
|
Content-type: application/json
|
||||||
|
|
||||||
|
###
|
||||||
|
|
||||||
|
# Get
|
||||||
|
|
||||||
|
GET http://localhost:1323/v1/apps/test_1234
|
||||||
|
Content-type: application/json
|
||||||
|
|
||||||
|
|
||||||
###
|
###
|
||||||
|
|
||||||
# List of all apps
|
# List of all apps
|
||||||
|
@ -26,8 +26,10 @@ type Label struct {
|
|||||||
// AppState contains info about runnint application, it's not saved in the database
|
// AppState contains info about runnint application, it's not saved in the database
|
||||||
type AppState struct {
|
type AppState struct {
|
||||||
State string `json:"state"`
|
State string `json:"state"`
|
||||||
CPUUsage int `json:"cpu_usage"`
|
CPUUsage float64 `json:"cpu_usage"` // in percents
|
||||||
MemoryUsage int `json:"memory_usage"`
|
MemoryUsage int `json:"memory_usage"` // in MB
|
||||||
|
DiskUsageBytes int `json:"disk_usage_bytes"`
|
||||||
|
DiskUsageinodes int `json:"disk_usage_inodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// App keeps info about hosted application
|
// App keeps info about hosted application
|
||||||
@ -42,7 +44,11 @@ type App struct {
|
|||||||
Memory int `json:"memory"` // Limit in MB
|
Memory int `json:"memory"` // Limit in MB
|
||||||
// Labels []Label `json:"labels"` // username:cx or user_id:1
|
// Labels []Label `json:"labels"` // username:cx or user_id:1
|
||||||
|
|
||||||
State AppState `json:"state" gorm:"-"`
|
State string `json:"state"`
|
||||||
|
CPUUsage float64 `json:"cpu_usage"` // in percents
|
||||||
|
MemoryUsage int `json:"memory_usage"` // in MB
|
||||||
|
DiskUsageBytes int `json:"disk_usage_bytes"`
|
||||||
|
DiskUsageinodes int `json:"disk_usage_inodes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate do basic checks of the struct values
|
// Validate do basic checks of the struct values
|
||||||
|
@ -2,6 +2,7 @@ package docker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"io"
|
"io"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -18,6 +19,9 @@ import (
|
|||||||
"github.com/docker/go-connections/nat"
|
"github.com/docker/go-connections/nat"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// Stats delay in seconds
|
||||||
|
const statsDelay = 5
|
||||||
|
|
||||||
// Docker timeout
|
// Docker timeout
|
||||||
const dockerTimeout = 10
|
const dockerTimeout = 10
|
||||||
|
|
||||||
@ -118,9 +122,12 @@ func (d *Driver) Stats(name string) (float64, int, error) {
|
|||||||
return 0.0, 0, err
|
return 0.0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rows := make([]ContainerStats, 2)
|
||||||
|
|
||||||
|
for idx := range rows {
|
||||||
stats, err := cli.ContainerStats(context.TODO(), containerID, false)
|
stats, err := cli.ContainerStats(context.TODO(), containerID, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0.0, 0, nil
|
return 0.0, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(stats.Body)
|
data, err := ioutil.ReadAll(stats.Body)
|
||||||
@ -129,9 +136,20 @@ func (d *Driver) Stats(name string) (float64, int, error) {
|
|||||||
}
|
}
|
||||||
// It returns one JSON:
|
// It returns one JSON:
|
||||||
// {"read":"2020-07-11T20:42:31.486726241Z","preread":"2020-07-11T20:42:30.484048602Z","pids_stats":{"current":7},"blkio_stats":{"io_service_bytes_recursive":[{"major":253,"minor":0,"op":"Read","value":0},{"major":253,"minor":0,"op":"Write","value":20480},{"major":253,"minor":0,"op":"Sync","value":12288},{"major":253,"minor":0,"op":"Async","value":8192},{"major":253,"minor":0,"op":"Discard","value":0},{"major":253,"minor":0,"op":"Total","value":20480}],"io_serviced_recursive":[{"major":253,"minor":0,"op":"Read","value":0},{"major":253,"minor":0,"op":"Write","value":5},{"major":253,"minor":0,"op":"Sync","value":3},{"major":253,"minor":0,"op":"Async","value":2},{"major":253,"minor":0,"op":"Discard","value":0},{"major":253,"minor":0,"op":"Total","value":5}],"io_queue_recursive":[],"io_service_time_recursive":[],"io_wait_time_recursive":[],"io_merged_recursive":[],"io_time_recursive":[],"sectors_recursive":[]},"num_procs":0,"storage_stats":{},"cpu_stats":{"cpu_usage":{"total_usage":758392753,"percpu_usage":[302688474,0,11507116,124238500,222136766,5656446,3009320,0,19406386,1397028,6201423,62151294,0,0,0,0],"usage_in_kernelmode":100000000,"usage_in_usermode":640000000},"system_cpu_usage":119385810000000,"online_cpus":12,"throttling_data":{"periods":21,"throttled_periods":1,"throttled_time":2995938}},"precpu_stats":{"cpu_usage":{"total_usage":758282347,"percpu_usage":[302688474,0,11507116,124238500,222026360,5656446,3009320,0,19406386,1397028,6201423,62151294,0,0,0,0],"usage_in_kernelmode":100000000,"usage_in_usermode":640000000},"system_cpu_usage":119373720000000,"online_cpus":12,"throttling_data":{"periods":21,"throttled_periods":1,"throttled_time":2995938}},"memory_stats":{"usage":21626880,"max_usage":22630400,"stats":{"active_anon":15949824,"active_file":0,"cache":0,"dirty":0,"hierarchical_memory_limit":144179200,"hierarchical_memsw_limit":288358400,"inactive_anon":0,"inactive_file":0,"mapped_file":0,"pgfault":13167,"pgmajfault":0,"pgpgin":7293,"pgpgout":3406,"rss":15900672,"rss_huge":0,"total_active_anon":15949824,"total_active_file":0,"total_cache":0,"total_dirty":0,"total_inactive_anon":0,"total_inactive_file":0,"total_mapped_file":0,"total_pgfault":13167,"total_pgmajfault":0,"total_pgpgin":7293,"total_pgpgout":3406,"total_rss":15900672,"total_rss_huge":0,"total_unevictable":0,"total_writeback":0,"unevictable":0,"writeback":0},"limit":144179200},"name":"/test_1234","id":"576878d645efecc8e5e2a57b88351f7b5c551e3fc72dc8473fd965d10dfddbec","networks":{"eth0":{"rx_bytes":6150,"rx_packets":37,"rx_errors":0,"rx_dropped":0,"tx_bytes":0,"tx_packets":0,"tx_errors":0,"tx_dropped":0}}}
|
// {"read":"2020-07-11T20:42:31.486726241Z","preread":"2020-07-11T20:42:30.484048602Z","pids_stats":{"current":7},"blkio_stats":{"io_service_bytes_recursive":[{"major":253,"minor":0,"op":"Read","value":0},{"major":253,"minor":0,"op":"Write","value":20480},{"major":253,"minor":0,"op":"Sync","value":12288},{"major":253,"minor":0,"op":"Async","value":8192},{"major":253,"minor":0,"op":"Discard","value":0},{"major":253,"minor":0,"op":"Total","value":20480}],"io_serviced_recursive":[{"major":253,"minor":0,"op":"Read","value":0},{"major":253,"minor":0,"op":"Write","value":5},{"major":253,"minor":0,"op":"Sync","value":3},{"major":253,"minor":0,"op":"Async","value":2},{"major":253,"minor":0,"op":"Discard","value":0},{"major":253,"minor":0,"op":"Total","value":5}],"io_queue_recursive":[],"io_service_time_recursive":[],"io_wait_time_recursive":[],"io_merged_recursive":[],"io_time_recursive":[],"sectors_recursive":[]},"num_procs":0,"storage_stats":{},"cpu_stats":{"cpu_usage":{"total_usage":758392753,"percpu_usage":[302688474,0,11507116,124238500,222136766,5656446,3009320,0,19406386,1397028,6201423,62151294,0,0,0,0],"usage_in_kernelmode":100000000,"usage_in_usermode":640000000},"system_cpu_usage":119385810000000,"online_cpus":12,"throttling_data":{"periods":21,"throttled_periods":1,"throttled_time":2995938}},"precpu_stats":{"cpu_usage":{"total_usage":758282347,"percpu_usage":[302688474,0,11507116,124238500,222026360,5656446,3009320,0,19406386,1397028,6201423,62151294,0,0,0,0],"usage_in_kernelmode":100000000,"usage_in_usermode":640000000},"system_cpu_usage":119373720000000,"online_cpus":12,"throttling_data":{"periods":21,"throttled_periods":1,"throttled_time":2995938}},"memory_stats":{"usage":21626880,"max_usage":22630400,"stats":{"active_anon":15949824,"active_file":0,"cache":0,"dirty":0,"hierarchical_memory_limit":144179200,"hierarchical_memsw_limit":288358400,"inactive_anon":0,"inactive_file":0,"mapped_file":0,"pgfault":13167,"pgmajfault":0,"pgpgin":7293,"pgpgout":3406,"rss":15900672,"rss_huge":0,"total_active_anon":15949824,"total_active_file":0,"total_cache":0,"total_dirty":0,"total_inactive_anon":0,"total_inactive_file":0,"total_mapped_file":0,"total_pgfault":13167,"total_pgmajfault":0,"total_pgpgin":7293,"total_pgpgout":3406,"total_rss":15900672,"total_rss_huge":0,"total_unevictable":0,"total_writeback":0,"unevictable":0,"writeback":0},"limit":144179200},"name":"/test_1234","id":"576878d645efecc8e5e2a57b88351f7b5c551e3fc72dc8473fd965d10dfddbec","networks":{"eth0":{"rx_bytes":6150,"rx_packets":37,"rx_errors":0,"rx_dropped":0,"tx_bytes":0,"tx_packets":0,"tx_errors":0,"tx_dropped":0}}}
|
||||||
log.Println(string(data))
|
|
||||||
|
|
||||||
return 0.0, 0, nil
|
err = json.Unmarshal(data, &rows[idx])
|
||||||
|
if err != nil {
|
||||||
|
return 0.0, 0, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if idx == 0 {
|
||||||
|
time.Sleep(statsDelay * time.Second)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cpuUsage := (float64(rows[1].CPU.Usage.Total) - float64(rows[0].CPU.Usage.Total)) / statsDelay / 10000000
|
||||||
|
|
||||||
|
return cpuUsage, rows[1].Memory.Usage, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove removes container represented by containerID
|
// Remove removes container represented by containerID
|
||||||
|
@ -1 +0,0 @@
|
|||||||
package docker
|
|
19
docker/stats.go
Normal file
19
docker/stats.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package docker
|
||||||
|
|
||||||
|
// ContainerStats contains fields returned in docker stats function stream
|
||||||
|
type ContainerStats struct {
|
||||||
|
Pids struct {
|
||||||
|
Current int `json:"current"`
|
||||||
|
} `json:"pids_stats"`
|
||||||
|
CPU struct {
|
||||||
|
Usage struct {
|
||||||
|
Total int `json:"total_usage"`
|
||||||
|
} `json:"cpu_usage"`
|
||||||
|
} `json:"cpu_stats"`
|
||||||
|
Memory struct {
|
||||||
|
Usage int `json:"usage"`
|
||||||
|
MaxUsage int `json:"max_usage"`
|
||||||
|
Limit int `json:"limit"`
|
||||||
|
} `json:"memory_stats"`
|
||||||
|
ID string `json:"id"`
|
||||||
|
}
|
@ -2,6 +2,7 @@ package docker
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"os/exec"
|
"os/exec"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -15,14 +16,19 @@ func du(path string) (int, int, error) {
|
|||||||
|
|
||||||
// Occupied space
|
// Occupied space
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
command := exec.Command("/usr/bin/du -m -s " + path)
|
var errOut bytes.Buffer
|
||||||
|
command := exec.Command("/usr/bin/du", "-m", "-s", path)
|
||||||
command.Stdout = &out
|
command.Stdout = &out
|
||||||
|
command.Stderr = &errOut
|
||||||
err := command.Run()
|
err := command.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(errOut.String())
|
||||||
|
log.Println("/usr/bin/du -m -s " + path)
|
||||||
return space, inodes, err
|
return space, inodes, err
|
||||||
}
|
}
|
||||||
fields := strings.Fields(strings.TrimSpace(out.String()))
|
fields := strings.Fields(strings.TrimSpace(out.String()))
|
||||||
out.Reset()
|
out.Reset()
|
||||||
|
errOut.Reset()
|
||||||
|
|
||||||
if len(fields) == 2 {
|
if len(fields) == 2 {
|
||||||
space, err = strconv.Atoi(fields[0])
|
space, err = strconv.Atoi(fields[0])
|
||||||
@ -32,17 +38,21 @@ func du(path string) (int, int, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Occupied inodes
|
// Occupied inodes
|
||||||
command = exec.Command("/usr/bin/du --inodes -s " + path)
|
command = exec.Command("/usr/bin/du", "--inodes", "-s", path)
|
||||||
command.Stdout = &out
|
command.Stdout = &out
|
||||||
|
command.Stderr = &errOut
|
||||||
err = command.Run()
|
err = command.Run()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Println(errOut.String())
|
||||||
|
log.Println("/usr/bin/du --inodes -s " + path)
|
||||||
return space, inodes, err
|
return space, inodes, err
|
||||||
}
|
}
|
||||||
fields = strings.Fields(strings.TrimSpace(out.String()))
|
fields = strings.Fields(strings.TrimSpace(out.String()))
|
||||||
out.Reset()
|
out.Reset()
|
||||||
|
errOut.Reset()
|
||||||
|
|
||||||
if len(fields) == 2 {
|
if len(fields) == 2 {
|
||||||
space, err = strconv.Atoi(fields[0])
|
inodes, err = strconv.Atoi(fields[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return inodes, inodes, err
|
return inodes, inodes, err
|
||||||
}
|
}
|
||||||
|
@ -23,21 +23,31 @@ func (c *Container) volumeHostPath() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetApp app object with populated state fields
|
// GetApp app object with populated state fields
|
||||||
func (c *Container) GetApp() (*apps.App, error) {
|
func (c *Container) GetApp() (*apps.AppState, error) {
|
||||||
status, err := c.Status()
|
status, err := c.Status()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cpu, memory, err := c.ResourceUsage()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes, inodes, err := c.DiskUsage()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
state := apps.AppState{
|
state := apps.AppState{
|
||||||
State: status,
|
State: status,
|
||||||
CPUUsage: 0,
|
CPUUsage: cpu,
|
||||||
MemoryUsage: 0,
|
MemoryUsage: memory,
|
||||||
|
DiskUsageBytes: bytes,
|
||||||
|
DiskUsageinodes: inodes,
|
||||||
}
|
}
|
||||||
|
|
||||||
c.App.State = state
|
return &state, nil
|
||||||
|
|
||||||
return c.App, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Status returns state of the container
|
// Status returns state of the container
|
||||||
|
22
main.go
22
main.go
@ -41,19 +41,7 @@ func main() {
|
|||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
populatedApps := []*apps.App{}
|
return c.JSON(http.StatusOK, applications)
|
||||||
for _, app := range *applications {
|
|
||||||
container := docker.Container{
|
|
||||||
App: &app,
|
|
||||||
}
|
|
||||||
populatedApp, err := container.GetApp()
|
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
populatedApps = append(populatedApps, populatedApp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, populatedApps)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// Returns one app
|
// Returns one app
|
||||||
@ -65,14 +53,6 @@ func main() {
|
|||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
||||||
}
|
}
|
||||||
|
|
||||||
container := docker.Container{
|
|
||||||
App: app,
|
|
||||||
}
|
|
||||||
_, err = container.GetApp()
|
|
||||||
if err != nil {
|
|
||||||
return c.JSONPretty(http.StatusInternalServerError, Message{Message: err.Error()}, JSONIndent)
|
|
||||||
}
|
|
||||||
|
|
||||||
return c.JSON(http.StatusOK, app)
|
return c.JSON(http.StatusOK, app)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -13,6 +13,20 @@
|
|||||||
<!-- Bootstrap core CSS -->
|
<!-- Bootstrap core CSS -->
|
||||||
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
|
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.success {
|
||||||
|
color: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: red;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
@ -32,6 +46,10 @@
|
|||||||
<div class="col-lg-12">
|
<div class="col-lg-12">
|
||||||
<h1 class="mt-5">Applications</h1>
|
<h1 class="mt-5">Applications</h1>
|
||||||
|
|
||||||
|
<div v-if="api_response">
|
||||||
|
<strong>Response:</strong> <span v-bind:class="{ success: isSuccess, error: hasError }">{( api_response )}</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
@ -50,18 +68,18 @@
|
|||||||
<tr v-for="app in apps">
|
<tr v-for="app in apps">
|
||||||
<td><strong>{( app.name )}</strong></td>
|
<td><strong>{( app.name )}</strong></td>
|
||||||
<td>{( app.state.state )}</td>
|
<td>{( app.state.state )}</td>
|
||||||
<td>{( app.image )}</td>
|
<td>{( app.image.replace("docker.io/", "") )}</td>
|
||||||
<td>- / {( app.cpu )} %</td>
|
<td>- / {( app.cpu )} %</td>
|
||||||
<td>- / {( app.memory )} MB</td>
|
<td>- / {( app.memory )} MB</td>
|
||||||
<td>- GB</td>
|
<td>- GB</td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
<td>-</td>
|
<td>-</td>
|
||||||
<td>
|
<td>
|
||||||
<button class="btn btn-warning btn-sm">Rebuild</button>
|
<button class="btn btn-success btn-sm" v-on:click="start(app.name)" v-if="['stopped'].includes(app.state.state)">Start</button>
|
||||||
<button class="btn btn-success btn-sm">Start</button>
|
<button class="btn btn-warning btn-sm" v-on:click="stop(app.name)" v-if="['running'].includes(app.state.state)">Stop</button>
|
||||||
<button class="btn btn-warning btn-sm">Stop</button>
|
<button class="btn btn-warning btn-sm" v-on:click="restart(app.name)" v-if="['running'].includes(app.state.state)">Restart</button>
|
||||||
<button class="btn btn-warning btn-sm">Destroy</button>
|
<button class="btn btn-warning btn-sm" v-on:click="rebuild(app.name)">Rebuild</button>
|
||||||
<button class="btn btn-danger btn-sm">Delete</button>
|
<button class="btn btn-danger btn-sm" v-on:click="remove(app.name)">Delete</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
@ -80,11 +98,68 @@
|
|||||||
delimiters: ['{(', ')}'],
|
delimiters: ['{(', ')}'],
|
||||||
data: {
|
data: {
|
||||||
apps: [],
|
apps: [],
|
||||||
|
api_status_code: 0,
|
||||||
|
api_response: "",
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
fetch('/v1/apps').then(response => response.json())
|
fetch('/v1/apps').then(response => response.json())
|
||||||
.then(data => this.apps = data);
|
.then(data => this.apps = data);
|
||||||
}
|
},
|
||||||
|
methods: {
|
||||||
|
isSuccess: () => {
|
||||||
|
return this.api_status_code >= 200 && this.api_status_code <= 299
|
||||||
|
},
|
||||||
|
hasError: () => {
|
||||||
|
return this.api_status_code >= 400 && this.api_status_code < 505
|
||||||
|
},
|
||||||
|
start: (id) => {
|
||||||
|
app.api_response = "working"
|
||||||
|
fetch('/v1/apps/'+id+'/start', {method: 'PUT'})
|
||||||
|
.then(response => {
|
||||||
|
app.api_status_code = response.status
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then(data => app.api_response = data)
|
||||||
|
},
|
||||||
|
stop: (id) => {
|
||||||
|
app.api_response = "working"
|
||||||
|
fetch('/v1/apps/'+id+'/stop', {method: 'PUT'})
|
||||||
|
.then(response => {
|
||||||
|
app.api_status_code = response.status
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then(data => app.api_response = data)
|
||||||
|
},
|
||||||
|
restart: (id) => {
|
||||||
|
app.api_response = "working"
|
||||||
|
fetch('/v1/apps/'+id+'/restart', {method: 'PUT'})
|
||||||
|
.then(response => {
|
||||||
|
app.api_status_code = response.status
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then(data => app.api_response = data)
|
||||||
|
},
|
||||||
|
rebuild: (id) => {
|
||||||
|
app.api_response = "working"
|
||||||
|
fetch('/v1/apps/'+id+'/rebuild', {method: 'PUT'})
|
||||||
|
.then(response => {
|
||||||
|
app.api_status_code = response.status
|
||||||
|
return response.json()
|
||||||
|
})
|
||||||
|
.then(data => {
|
||||||
|
app.api_response = data
|
||||||
|
})
|
||||||
|
},
|
||||||
|
remove: (id) => {
|
||||||
|
app.api_response = "working"
|
||||||
|
fetch('/v1/apps/'+id, {method: 'DELETE'})
|
||||||
|
.then(response => {
|
||||||
|
response.json()
|
||||||
|
app.api_status_code = response.status
|
||||||
|
})
|
||||||
|
.then(data => app.api_response = data)
|
||||||
|
},
|
||||||
|
},
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user