add edit support

master
codeskyblue 7 years ago
parent 7b76dfe86a
commit 54e02903e4

@ -25,7 +25,7 @@ I have been using python-supervisor for many years and there are something uncom
* [x] Start, Stop, Tail, Reload
* [x] Realtime log
* [x] Add program support
* [ ] Edit support
* [x] Edit support
* [x] Delete support
* [x] Memory and CPU monitor
* [ ] Path auto complete <https://github.com/twitter/typeahead.js>

@ -20,6 +20,7 @@ import (
"io"
"io/ioutil"
"os"
"os/user"
"path/filepath"
"runtime"
"strings"
@ -159,6 +160,11 @@ func (p *Program) RunNotification() {
}
}
func IsRoot() bool {
u, err := user.Current()
return err == nil && u.Uid == "0"
}
type Process struct {
*FSM `json:"-"`
Program `json:"program"`
@ -196,7 +202,7 @@ func (p *Process) buildCommand() *kexec.KCommand {
// config environ
cmd.Env = os.Environ() // inherit current vars
environ := map[string]string{}
if p.User != "" {
if p.User != "" && IsRoot() {
err := cmd.SetUser(p.User)
if err != nil {
log.Warnf("[%s] chusr to %s failed", p.Name, p.User)

@ -4,7 +4,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
<title>gosuv</title>
<title>GoSUV</title>
<link rel="shortcut icon" type="image/png" href="/res/images/favicon.ico" />
<link rel="stylesheet" type="text/css" href="/res/bootstrap-3.3.5/css/bootstrap.min.css">
<link rel="stylesheet" type="text/css" href="/res/font-awesome-4.6.3/css/font-awesome.min.css">
@ -22,7 +22,7 @@
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Go Supervisor <small class="user">[[.User]]</small></a>
<a class="navbar-brand" href="/">Go Supervisor 2.0 <small class="user">[[.User]]</small></a>
</div>
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-2">
<ul class="nav navbar-nav">
@ -64,6 +64,7 @@
<tr>
<td>Name</td>
<td>Status</td>
<td>View</td>
<td>Command</td>
</tr>
</thead>
@ -72,12 +73,6 @@
<td v-text="p.program.name"></td>
<td v-html="p.status | colorStatus"></td>
<td>
<button v-on:click="cmdStart(p.program.name)" class="btn btn-default btn-xs" :disabled='["running", "stopping"].indexOf(p.status) != -1'>
<span class="glyphicon glyphicon-play"></span> Start
</button>
<button class="btn btn-default btn-xs" v-on:click="cmdStop(p.program.name)" :disabled="!canStop(p.status)">
<span class="glyphicon glyphicon-stop"></span> Stop
</button>
<button class="btn btn-default btn-xs" v-on:click="cmdTail(p.program.name)">
<span class="fa fa-file-text-o"></span> Log
</button>
@ -87,37 +82,28 @@
<button class="btn btn-default btn-xs" data-toggle="tooltip" title="{{p.program.command}}">
<span class="glyphicon glyphicon-info-sign"></span> Info
</button>
<button class="btn btn-default btn-xs" v-on:click="cmdDelete(p.program.name)">
<span class="color-red glyphicon glyphicon-trash"></span> Delete
</button>
</td>
</tr>
<!-- <tr class="success">
<td>gohttpserver</td>
<td>
<span class="status">Running(2h)</span>
</td>
<td>
<button class="btn btn-default btn-xs">
<button v-on:click="cmdStart(p.program.name)" class="btn btn-default btn-xs" :disabled='["running", "stopping"].indexOf(p.status) != -1'>
<span class="glyphicon glyphicon-play"></span> Start
</button>
<button class="btn btn-default btn-xs">
<button class="btn btn-default btn-xs" v-on:click="cmdStop(p.program.name)" :disabled="!canStop(p.status)">
<span class="glyphicon glyphicon-stop"></span> Stop
</button>
<button class="btn btn-default btn-xs" disabled="true">
<span class="glyphicon glyphicon-minus"></span> Tail
<button v-on:click="showEditProgram(p.program)" class="btn btn-default btn-xs">
<span class="glyphicon glyphicon-edit"></span> Edit
</button>
<button class="btn btn-default btn-xs">
<span class="glyphicon glyphicon-cog"></span> Setting
<button class="btn btn-default btn-xs" v-on:click="cmdDelete(p.program.name)">
<span class="color-red glyphicon glyphicon-trash"></span> Delete
</button>
</td>
</tr> -->
</tr>
</tbody>
</table>
</div>
<div class="col-md-12">
<div id="footer" class="pull-right" style="margin: 2em 1em">
<a href="https://github.com/codeskyblue/gosuv">gosuv ([[.Version]])</a>, written by <a href="https://github.com/codeskyblue">codeskyblue</a>. 2016. go1.7
<a href="https://github.com/codeskyblue/gosuv">gosuv ([[.Version]])</a>, written by <a href="https://github.com/codeskyblue">codeskyblue</a>. 2017. go1.7
</div>
</div>
<!-- panels -->
@ -166,9 +152,50 @@
</div>
</form>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- model edit -->
<div class="modal" id="programEdit">
<div class="modal-dialog">
<div class="modal-content">
<form v-on:submit.prevent="editProgram">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
<h4 class="modal-title"><span class="glyphicon glyphicon-edit"></span> <span v-text="edit.program.name"></span></h4>
</div>
<div class="modal-body">
<div class="form-group">
<label>Command</label>
<input type="text" name="command" class="form-control" v-model="edit.program.command">
</div>
<div class="form-group">
<label>Directory</label>
<input type="text" name="dir" class="form-control" v-model="edit.program.directory">
</div>
<div class="form-group">
<label>User</label>
<input type="text" name="user" class="form-control" v-model="edit.program.user">
</div>
<div class="form-group">
<label>Fail Retries</label>
<input style="max-width: 5em" type="number" name="retries" class="form-control" min="0" step="1" v-model="edit.program.startRetries">
</div>
<div class="checkbox">
<label>
<input name="autostart" type="checkbox" v-model="edit.program.startAuto"> Auto start
</label>
</div>
<!-- <button type="submit" class="btn btn-Wdefault">Submit</button> -->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button type="submit" class="btn btn-primary">Update</button>
</div>
</form>
</div>
</div>
</div>
<!-- /.modal -->
<div class="modal" id="modalTailf">
@ -190,15 +217,10 @@
</label>
</div>
</div>
<!-- <div class="modal-footer">
</div> -->
</form>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
</div>
<script src="/res/js/jquery-3.1.0.min.js"></script>
<script src="/res/bootstrap-3.3.5/js/bootstrap.min.js"></script>

@ -21,19 +21,38 @@ var vm = new Vue({
line_count: 0,
},
programs: [],
edit: {
program: null,
}
},
methods: {
addNewProgram: function() {
console.log("Add")
var form = $("#formNewProgram");
form.submit(function(e) {
console.log("HellO")
e.preventDefault();
console.log(e);
$("#newProgram").modal('hide')
return false;
});
// console.log(this.program.name);
},
showEditProgram: function(p) {
this.edit.program = Object.assign({}, p);
$("#programEdit").modal('show');
console.log(p.name, p);
},
editProgram: function() {
console.log(this.edit.program);
var p = this.edit.program;
$.ajax({
url: "/api/programs/" + p.name,
method: "PUT",
data: JSON.stringify(p),
})
.then(function(ret) {
console.log(ret);
$("#programEdit").modal('hide');
})
// console.log(JSON.stringify(p));
},
updateBreadcrumb: function() {
var pathname = decodeURI(location.pathname || "/");

@ -136,6 +136,7 @@ func (s *Supervisor) addOrUpdateProgram(pg Program) error {
if isRunning {
newProc.Operate(StartEvent)
}
s.saveDB()
}()
} else {
s.names = append(s.names, pg.Name)
@ -377,6 +378,32 @@ func (s *Supervisor) hAddProgram(w http.ResponseWriter, r *http.Request) {
w.Write(data)
}
func (s *Supervisor) hUpdateProgram(w http.ResponseWriter, r *http.Request) {
// name := mux.Vars(r)["name"]
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
pg := Program{}
err := json.NewDecoder(r.Body).Decode(&pg)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{
"status": 1,
"error": err.Error(),
})
return
}
err = s.addOrUpdateProgram(pg)
if err != nil {
json.NewEncoder(w).Encode(map[string]interface{}{
"status": 2,
"error": err.Error(),
})
return
}
json.NewEncoder(w).Encode(map[string]interface{}{
"status": 0,
"description": "program updated",
})
}
func (s *Supervisor) hDelProgram(w http.ResponseWriter, r *http.Request) {
name := mux.Vars(r)["name"]
@ -631,6 +658,7 @@ func newSupervisorHandler() (suv *Supervisor, hdlr http.Handler, err error) {
r.HandleFunc("/api/programs", suv.hGetProgramList).Methods("GET")
r.HandleFunc("/api/programs/{name}", suv.hGetProgram).Methods("GET")
r.HandleFunc("/api/programs/{name}", suv.hDelProgram).Methods("DELETE")
r.HandleFunc("/api/programs/{name}", suv.hUpdateProgram).Methods("PUT")
r.HandleFunc("/api/programs", suv.hAddProgram).Methods("POST")
r.HandleFunc("/api/programs/{name}/start", suv.hStartProgram).Methods("POST")
r.HandleFunc("/api/programs/{name}/stop", suv.hStopProgram).Methods("POST")

Loading…
Cancel
Save