mirror of
https://github.com/langhuihui/monibuca.git
synced 2025-10-01 12:02:10 +08:00
Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b9e19e75c8 |
43
main.go
43
main.go
@@ -44,10 +44,11 @@ func main() {
|
||||
}
|
||||
addr := flag.String("port", "8000", "http server port")
|
||||
flag.Parse()
|
||||
http.HandleFunc("/list", listInstance)
|
||||
http.HandleFunc("/create", initInstance)
|
||||
http.HandleFunc("/upgrade/engine", upgradeEngine)
|
||||
http.HandleFunc("/restart/instance", restartInstance)
|
||||
|
||||
http.HandleFunc("/instance/list", listInstance)
|
||||
http.HandleFunc("/instance/create", initInstance)
|
||||
http.HandleFunc("/instance/restart", restartInstance)
|
||||
http.HandleFunc("/instance/shutdown", shutdownInstance)
|
||||
http.HandleFunc("/", website)
|
||||
fmt.Printf("start listen at %s", *addr)
|
||||
if err := http.ListenAndServe(":"+*addr, nil); err != nil {
|
||||
@@ -140,28 +141,41 @@ func initInstance(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
instances[instanceDesc.Name] = instanceDesc
|
||||
}
|
||||
func upgradeEngine(w http.ResponseWriter, r *http.Request) {
|
||||
sse := util.NewSSE(w, r.Context())
|
||||
func shutdownInstance(w http.ResponseWriter, r *http.Request) {
|
||||
instanceName := r.URL.Query().Get("instance")
|
||||
if instance, ok := instances[instanceName]; ok {
|
||||
if err := instance.writeExecSSE(sse, exec.Command("go", "get", "-u", "github.com/langhuihui/monibuca/monica")); err != nil {
|
||||
sse.WriteEvent("failed", []byte(err.Error()))
|
||||
if err := instance.command("kill", "-9", "`cat pid`").Run(); err == nil {
|
||||
w.Write([]byte("success"))
|
||||
} else {
|
||||
sse.Write([]byte("success"))
|
||||
w.Write([]byte(err.Error()))
|
||||
}
|
||||
} else {
|
||||
sse.WriteEvent("failed", []byte("no such instance"))
|
||||
w.Write([]byte("no such instance"))
|
||||
}
|
||||
}
|
||||
func restartInstance(w http.ResponseWriter, r *http.Request) {
|
||||
sse := util.NewSSE(w, r.Context())
|
||||
instanceName := r.URL.Query().Get("instance")
|
||||
needUpdate := r.URL.Query().Get("update") != ""
|
||||
needBuild := r.URL.Query().Get("build") != ""
|
||||
if instance, ok := instances[instanceName]; ok {
|
||||
if needUpdate {
|
||||
if err := instance.writeExecSSE(sse, exec.Command("go", "get", "-u")); err != nil {
|
||||
sse.WriteEvent("failed", []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
if needBuild {
|
||||
if err := instance.writeExecSSE(sse, exec.Command("go", "build")); err != nil {
|
||||
sse.WriteEvent("failed", []byte(err.Error()))
|
||||
return
|
||||
}
|
||||
}
|
||||
if err := instance.writeExecSSE(sse, exec.Command("sh", "restart.sh")); err != nil {
|
||||
sse.WriteEvent("failed", []byte(err.Error()))
|
||||
} else {
|
||||
sse.Write([]byte("success"))
|
||||
return
|
||||
}
|
||||
sse.Write([]byte("success"))
|
||||
} else {
|
||||
sse.WriteEvent("failed", []byte("no such instance"))
|
||||
}
|
||||
@@ -170,6 +184,11 @@ func (p *InstanceDesc) writeExecSSE(sse *util.SSE, cmd *exec.Cmd) error {
|
||||
cmd.Dir = p.Path
|
||||
return sse.WriteExec(cmd)
|
||||
}
|
||||
func (p *InstanceDesc) command(name string, args ...string) (cmd *exec.Cmd) {
|
||||
cmd = exec.Command(name, args...)
|
||||
cmd.Dir = p.Path
|
||||
return
|
||||
}
|
||||
func (p *InstanceDesc) createDir(sse *util.SSE, clearDir bool) (err error) {
|
||||
if clearDir {
|
||||
os.RemoveAll(p.Path)
|
||||
|
@@ -4,12 +4,17 @@ import (
|
||||
"encoding/json"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"time"
|
||||
|
||||
"github.com/BurntSushi/toml"
|
||||
)
|
||||
|
||||
var ConfigRaw []byte
|
||||
var Version = "0.2.2"
|
||||
var Version = "0.2.3"
|
||||
var EngineInfo = &struct {
|
||||
Version string
|
||||
StartTime time.Time
|
||||
}{Version, time.Now()}
|
||||
|
||||
func Run(configFile string) (err error) {
|
||||
log.Printf("start monibuca version:%s", Version)
|
||||
|
@@ -1,28 +1,27 @@
|
||||
package QoS
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
. "github.com/langhuihui/monibuca/monica"
|
||||
)
|
||||
|
||||
var (
|
||||
selectMap = map[string][]string{
|
||||
"low": {"low", "medium", "high"},
|
||||
"medium": {"medium", "low", "high"},
|
||||
"high": {"high", "medium", "low"},
|
||||
}
|
||||
)
|
||||
// var (
|
||||
// selectMap = map[string][]string{
|
||||
// "low": {"low", "medium", "high"},
|
||||
// "medium": {"medium", "low", "high"},
|
||||
// "high": {"high", "medium", "low"},
|
||||
// }
|
||||
// )
|
||||
|
||||
func getQualityName(name string, qualityLevel string) string {
|
||||
if qualityLevel == "" {
|
||||
return name
|
||||
}
|
||||
for _, l := range selectMap[qualityLevel] {
|
||||
if _, ok := AllRoom.Load(name + "/" + l); ok {
|
||||
return name + "/" + l
|
||||
}
|
||||
}
|
||||
return name + "/" + qualityLevel
|
||||
}
|
||||
// func getQualityName(name string, qualityLevel string) string {
|
||||
// for _, l := range selectMap[qualityLevel] {
|
||||
// if _, ok := AllRoom.Load(name + "/" + l); ok {
|
||||
// return name + "/" + l
|
||||
// }
|
||||
// }
|
||||
// return name + "/" + qualityLevel
|
||||
// }
|
||||
|
||||
var config = struct {
|
||||
Suffix []string
|
||||
@@ -39,8 +38,23 @@ func init() {
|
||||
func run() {
|
||||
OnDropHooks.AddHook(func(s *OutputStream) {
|
||||
if s.TotalDrop > s.TotalPacket>>2 {
|
||||
//TODO
|
||||
//s.Control<-&ChangeRoomCmd{s,AllRoom.Get()}
|
||||
var newStreamPath = ""
|
||||
for i, suf := range config.Suffix {
|
||||
if strings.HasSuffix(s.StreamPath, suf) {
|
||||
if i < len(config.Suffix)-1 {
|
||||
newStreamPath = s.StreamPath + "/" + config.Suffix[i+1]
|
||||
break
|
||||
}
|
||||
} else {
|
||||
newStreamPath = s.StreamPath + "/" + suf
|
||||
break
|
||||
}
|
||||
}
|
||||
if newStreamPath != "" {
|
||||
if _, ok := AllRoom.Load(newStreamPath); ok {
|
||||
s.Control <- &ChangeRoomCmd{s, AllRoom.Get(newStreamPath)}
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@@ -15,8 +15,8 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
config = new(ListenerConfig)
|
||||
|
||||
config = new(ListenerConfig)
|
||||
startTime = time.Now()
|
||||
dashboardPath string
|
||||
)
|
||||
|
||||
@@ -99,7 +99,7 @@ func summary(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
func sysInfo(w http.ResponseWriter, r *http.Request) {
|
||||
bytes, err := json.Marshal(&struct{ Version string }{Version: Version})
|
||||
bytes, err := json.Marshal(EngineInfo)
|
||||
if err == nil {
|
||||
_, err = w.Write(bytes)
|
||||
}
|
||||
|
2
pm/dist/index.html
vendored
2
pm/dist/index.html
vendored
@@ -1 +1 @@
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Monibuca Instance Manager</title><script src=ajax.js></script><link href=/css/app.200d2f8f.css rel=preload as=style><link href=/css/chunk-vendors.22ebf426.css rel=preload as=style><link href=/js/app.c617bcf5.js rel=preload as=script><link href=/js/chunk-vendors.6b87e1b5.js rel=preload as=script><link href=/css/chunk-vendors.22ebf426.css rel=stylesheet><link href=/css/app.200d2f8f.css rel=stylesheet></head><body><noscript><strong>We're sorry but pm doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.6b87e1b5.js></script><script src=/js/app.c617bcf5.js></script></body></html>
|
||||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta http-equiv=X-UA-Compatible content="IE=edge"><meta name=viewport content="width=device-width,initial-scale=1"><link rel=icon href=/favicon.ico><title>Monibuca Instance Manager</title><script src=ajax.js></script><link href=/css/app.200d2f8f.css rel=preload as=style><link href=/css/chunk-vendors.22ebf426.css rel=preload as=style><link href=/js/app.9b5890f5.js rel=preload as=script><link href=/js/chunk-vendors.f701a5a3.js rel=preload as=script><link href=/css/chunk-vendors.22ebf426.css rel=stylesheet><link href=/css/app.200d2f8f.css rel=stylesheet></head><body><noscript><strong>We're sorry but pm doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id=app></div><script src=/js/chunk-vendors.f701a5a3.js></script><script src=/js/app.9b5890f5.js></script></body></html>
|
2
pm/dist/js/app.9b5890f5.js
vendored
Normal file
2
pm/dist/js/app.9b5890f5.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
pm/dist/js/app.9b5890f5.js.map
vendored
Normal file
1
pm/dist/js/app.9b5890f5.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
2
pm/dist/js/app.c617bcf5.js
vendored
2
pm/dist/js/app.c617bcf5.js
vendored
File diff suppressed because one or more lines are too long
1
pm/dist/js/app.c617bcf5.js.map
vendored
1
pm/dist/js/app.c617bcf5.js.map
vendored
File diff suppressed because one or more lines are too long
1
pm/dist/js/chunk-vendors.6b87e1b5.js.map
vendored
1
pm/dist/js/chunk-vendors.6b87e1b5.js.map
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
pm/dist/js/chunk-vendors.f701a5a3.js.map
vendored
Normal file
1
pm/dist/js/chunk-vendors.f701a5a3.js.map
vendored
Normal file
File diff suppressed because one or more lines are too long
5
pm/package-lock.json
generated
5
pm/package-lock.json
generated
@@ -979,6 +979,11 @@
|
||||
"@hapi/hoek": "8.5.0"
|
||||
}
|
||||
},
|
||||
"@iarna/toml": {
|
||||
"version": "2.2.3",
|
||||
"resolved": "https://registry.npm.taobao.org/@iarna/toml/download/@iarna/toml-2.2.3.tgz",
|
||||
"integrity": "sha1-8GC/bqr65NVqfaxhiYCDiwaW4qs="
|
||||
},
|
||||
"@intervolga/optimize-cssnano-plugin": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npm.taobao.org/@intervolga/optimize-cssnano-plugin/download/@intervolga/optimize-cssnano-plugin-1.0.6.tgz",
|
||||
|
@@ -8,6 +8,7 @@
|
||||
"lint": "vue-cli-service lint"
|
||||
},
|
||||
"dependencies": {
|
||||
"@iarna/toml": "^2.2.3",
|
||||
"core-js": "^3.4.4",
|
||||
"view-design": "^4.0.0",
|
||||
"vue": "^2.6.10",
|
||||
|
@@ -30,7 +30,7 @@ export default {
|
||||
start() {
|
||||
this.status = "process";
|
||||
eventSource = new EventSource(
|
||||
"/create?info=" +
|
||||
"/instance/create?info=" +
|
||||
JSON.stringify(this.info) +
|
||||
(this.clearDir ? "&clear=true" : "")
|
||||
);
|
||||
|
@@ -1,60 +0,0 @@
|
||||
<template>
|
||||
<div class="hello">
|
||||
<h1>{{ msg }}</h1>
|
||||
<p>
|
||||
For a guide and recipes on how to configure / customize this project,<br>
|
||||
check out the
|
||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
||||
</p>
|
||||
<h3>Installed CLI Plugins</h3>
|
||||
<ul>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
||||
</ul>
|
||||
<h3>Essential Links</h3>
|
||||
<ul>
|
||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
||||
</ul>
|
||||
<h3>Ecosystem</h3>
|
||||
<ul>
|
||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'HelloWorld',
|
||||
props: {
|
||||
msg: String
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
||||
<style scoped lang="less">
|
||||
h3 {
|
||||
margin: 40px 0 0;
|
||||
}
|
||||
ul {
|
||||
list-style-type: none;
|
||||
padding: 0;
|
||||
}
|
||||
li {
|
||||
display: inline-block;
|
||||
margin: 0 10px;
|
||||
}
|
||||
a {
|
||||
color: #42b983;
|
||||
}
|
||||
</style>
|
108
pm/src/components/InstanceList.vue
Normal file
108
pm/src/components/InstanceList.vue
Normal file
@@ -0,0 +1,108 @@
|
||||
<template>
|
||||
<List border>
|
||||
<ListItem v-for="item in instances" :key="item.Name">
|
||||
<ListItemMeta :title="item.Name" :description="item.Path"></ListItemMeta>
|
||||
<template v-if="hasGateway(item)">
|
||||
{{item.Info}}
|
||||
</template>
|
||||
<template slot="action">
|
||||
<li v-if="hasGateway(item)" @click="window.open(gateWayHref(item),'_blank')">
|
||||
<Icon type="md-browsers"/>
|
||||
管理界面
|
||||
</li>
|
||||
<li @click="restart(item)">
|
||||
<Icon type="ios-refresh"/>
|
||||
重启
|
||||
</li>
|
||||
<li @click="shutdown(item)">
|
||||
<Icon type="ios-power"/>
|
||||
关闭
|
||||
</li>
|
||||
</template>
|
||||
</ListItem>
|
||||
<Modal v-model="showRestart">
|
||||
<Checkbox v-model="update">go get -u</Checkbox>
|
||||
<Checkbox v-model="build">go build</Checkbox>
|
||||
</Modal>
|
||||
</List>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import toml from "@iarna/toml"
|
||||
|
||||
export default {
|
||||
name: "InstanceList",
|
||||
data() {
|
||||
return {instances: {}, showRestart: false, update: false, build: false}
|
||||
},
|
||||
mounted() {
|
||||
window.ajax.getJSON("/instance/list").then(x => {
|
||||
for (let name in x) {
|
||||
let instance = x[name]
|
||||
instance.Config = toml.parse(instance.Config)
|
||||
if (this.hasGateway(instance)) {
|
||||
window.ajax.getJSON("//" + this.gateWayHref(instance) + "/api/sysInfo").then(x => {
|
||||
instance.Info = "引擎版本:" + x.Version + "启动时间:" + x.StartTime
|
||||
}).catch(() => {
|
||||
instance.Info = "无法访问实例"
|
||||
})
|
||||
} else {
|
||||
instance.Info = "实例未配置网关插件"
|
||||
}
|
||||
}
|
||||
this.instances = x;
|
||||
});
|
||||
}, methods: {
|
||||
hasGateway(item) {
|
||||
return item.Config.Plugins.hasOwnProperty("GateWay")
|
||||
},
|
||||
gateWayHref(item) {
|
||||
return location.hostname + ":" + item.Config.Plugins.GateWay.split(":").pop()
|
||||
},
|
||||
restart(item) {
|
||||
const msg = this.$Message.loading({
|
||||
content: 'restart ' + item.Name + '...',
|
||||
duration: 0
|
||||
});
|
||||
let arg = item.Name
|
||||
if (this.update) {
|
||||
arg += "&update=true"
|
||||
}
|
||||
if (this.build) {
|
||||
arg += "&build=true"
|
||||
}
|
||||
const es = new EventSource("/instance/restart?instance=" + arg)
|
||||
es.onmessage = evt => {
|
||||
if (evt.data == "success") {
|
||||
this.$Message.success("重启成功!")
|
||||
msg()
|
||||
} else {
|
||||
this.$Message.info(evt.data)
|
||||
}
|
||||
}
|
||||
es.addEventListener("failed", evt => {
|
||||
this.$Message.error(evt.data)
|
||||
msg()
|
||||
})
|
||||
es.onerror = e => {
|
||||
if (e) this.$Message.error(e);
|
||||
msg()
|
||||
es.close()
|
||||
}
|
||||
},
|
||||
shutdown(item) {
|
||||
window.ajax.get("/instance/shutdown?instance=" + item.Name).then(x => {
|
||||
if (x == "success") {
|
||||
this.$Message.success("已关闭实例")
|
||||
} else {
|
||||
this.$Message.error(x)
|
||||
}
|
||||
})
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
@@ -1,18 +0,0 @@
|
||||
<template>
|
||||
<div class="home">
|
||||
<img alt="Vue logo" src="../assets/logo.png">
|
||||
<HelloWorld msg="Welcome to Your Vue.js App"/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
// @ is an alias to /src
|
||||
import HelloWorld from '@/components/HelloWorld.vue'
|
||||
|
||||
export default {
|
||||
name: 'home',
|
||||
components: {
|
||||
HelloWorld
|
||||
}
|
||||
}
|
||||
</script>
|
@@ -4,19 +4,7 @@
|
||||
<Content class="content">
|
||||
<Tabs value="name1">
|
||||
<TabPane label="实例" name="name1">
|
||||
<List border>
|
||||
<ListItem v-for="item in instances" :key="item.Name">
|
||||
<ListItemMeta :title="item.Name" :description="item.Path"></ListItemMeta>
|
||||
<template slot="action">
|
||||
<li @click="restart(item)">
|
||||
<Icon type="ios-refresh" />重启
|
||||
</li>
|
||||
<li @click="upgrade(item)">
|
||||
<Icon type="ios-sync" />升级引擎
|
||||
</li>
|
||||
</template>
|
||||
</ListItem>
|
||||
</List>
|
||||
<InstanceList></InstanceList>
|
||||
</TabPane>
|
||||
<TabPane label="创建" name="name2">
|
||||
<Steps :current="createStep">
|
||||
@@ -34,7 +22,8 @@
|
||||
{{item.Config}}
|
||||
<template slot="action">
|
||||
<li @click="removePlugin(name)">
|
||||
<Icon type="ios-trash" />移除
|
||||
<Icon type="ios-trash"/>
|
||||
移除
|
||||
</li>
|
||||
</template>
|
||||
</ListItem>
|
||||
@@ -42,8 +31,8 @@
|
||||
<div v-else>
|
||||
<h3>实例名称:</h3>
|
||||
<i-input
|
||||
v-model="instanceName"
|
||||
:placeholder="createPath.split('/').pop()"
|
||||
v-model="instanceName"
|
||||
:placeholder="createPath.split('/').pop()"
|
||||
></i-input>
|
||||
<h4>安装路径:</h4>
|
||||
<div>
|
||||
@@ -60,27 +49,28 @@
|
||||
</div>
|
||||
<ButtonGroup style="display:table;margin:50px auto;">
|
||||
<Button
|
||||
size="large"
|
||||
type="primary"
|
||||
@click="createStep--"
|
||||
v-if="createStep!=0"
|
||||
size="large"
|
||||
type="primary"
|
||||
@click="createStep--"
|
||||
v-if="createStep!=0"
|
||||
>
|
||||
<Icon type="ios-arrow-back"></Icon>上一步
|
||||
<Icon type="ios-arrow-back"></Icon>
|
||||
上一步
|
||||
</Button>
|
||||
<Button
|
||||
size="large"
|
||||
type="success"
|
||||
@click="showAddPlugin=true"
|
||||
v-if="createStep==1"
|
||||
size="large"
|
||||
type="success"
|
||||
@click="showAddPlugin=true"
|
||||
v-if="createStep==1"
|
||||
>
|
||||
+
|
||||
添加插件
|
||||
</Button>
|
||||
<Button
|
||||
size="large"
|
||||
type="primary"
|
||||
@click="createStep++"
|
||||
v-if="createStep!=2"
|
||||
size="large"
|
||||
type="primary"
|
||||
@click="createStep++"
|
||||
v-if="createStep!=2"
|
||||
>
|
||||
下一步
|
||||
<Icon type="ios-arrow-forward"></Icon>
|
||||
@@ -103,8 +93,8 @@
|
||||
</i-input>
|
||||
</FormItem>
|
||||
<Alert
|
||||
type="show-icon"
|
||||
v-if="!Object.values(builtinPlugins).includes(formPlugin.Path)"
|
||||
type="show-icon"
|
||||
v-if="!Object.values(builtinPlugins).includes(formPlugin.Path)"
|
||||
>
|
||||
如果该插件是私有仓库,请到服务器上输入:echo "machine {{privateHost}} login 用户名 password 密码" >> ~/.netrc
|
||||
并且添加环境变量GOPRIVATE={{privateHost}}
|
||||
@@ -120,7 +110,8 @@
|
||||
<ListItemMeta :title="name" :description="item"></ListItemMeta>
|
||||
<template slot="action">
|
||||
<li @click="addBuiltin(name,item)">
|
||||
<Icon type="ios-add" />添加
|
||||
<Icon type="ios-add"/>
|
||||
添加
|
||||
</li>
|
||||
</template>
|
||||
</ListItem>
|
||||
@@ -131,164 +122,114 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import CreateInstance from "../components/CreateInstance";
|
||||
import CreateInstance from "../components/CreateInstance";
|
||||
import InstanceList from "../components/InstanceList";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CreateInstance
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
instanceName: "",
|
||||
createStep: 0,
|
||||
showCreate: false,
|
||||
createInfo: null,
|
||||
createPath: "/opt/monibuca",
|
||||
instances: {},
|
||||
plugins: {},
|
||||
showAddPlugin: false,
|
||||
formPlugin: {},
|
||||
showBuiltinPlugin: false,
|
||||
builtinPlugins: {
|
||||
Auth: "github.com/langhuihui/monibuca/plugins/auth",
|
||||
Cluster: "github.com/langhuihui/monibuca/plugins/cluster",
|
||||
GateWay: "github.com/langhuihui/monibuca/plugins/gateway",
|
||||
HDL: "github.com/langhuihui/monibuca/plugins/HDL",
|
||||
Jessica: "github.com/langhuihui/monibuca/plugins/jessica",
|
||||
QoS: "github.com/langhuihui/monibuca/plugins/QoS",
|
||||
RecordFlv: "github.com/langhuihui/monibuca/plugins/record",
|
||||
RTMP: "github.com/langhuihui/monibuca/plugins/rtmp"
|
||||
},
|
||||
defaultConfig: {
|
||||
Auth: 'Key = "www.monibuca.com"',
|
||||
RecordFlv: 'Path="./resource"',
|
||||
QoS: 'Suffix = ["high","medium","low"]',
|
||||
Cluster: 'Master = "localhost:2019"\nListenAddr = ":2019"',
|
||||
GateWay: 'ListenAddr = ":8081"',
|
||||
RTMP: 'ListenAddr = ":1935"',
|
||||
Jessica: 'ListenAddr = ":8080"',
|
||||
HDL: 'ListenAddr = ":2020"'
|
||||
}
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
pluginStr() {
|
||||
return Object.values(this.plugins)
|
||||
.map(x => x.Path)
|
||||
.join("\n");
|
||||
|
||||
export default {
|
||||
components: {
|
||||
CreateInstance,InstanceList
|
||||
},
|
||||
configStr() {
|
||||
return Object.values(this.plugins)
|
||||
.map(
|
||||
x => `[Plugins.${x.Name}]
|
||||
${x.Config || ""}`
|
||||
)
|
||||
.join("\n");
|
||||
},
|
||||
privateHost() {
|
||||
return (
|
||||
(this.formPlugin.Path && this.formPlugin.Path.split("/")[0]) ||
|
||||
"仓库域名"
|
||||
);
|
||||
}
|
||||
},
|
||||
mounted() {
|
||||
window.ajax.getJSON("/list").then(x => {
|
||||
this.instances = x;
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
goUp() {
|
||||
let paths = this.createPath.split("/");
|
||||
paths.pop();
|
||||
this.createPath = paths.join("/");
|
||||
},
|
||||
createInstance() {
|
||||
this.showCreate = true;
|
||||
this.createInfo = {
|
||||
Name: this.instanceName || this.createPath.split("/").pop(),
|
||||
Path: this.createPath,
|
||||
Plugins: Object.values(this.plugins).map(x => x.Path),
|
||||
Config: this.configStr
|
||||
data() {
|
||||
return {
|
||||
instanceName: "",
|
||||
createStep: 0,
|
||||
showCreate: false,
|
||||
createInfo: null,
|
||||
createPath: "/opt/monibuca",
|
||||
plugins: {},
|
||||
showAddPlugin: false,
|
||||
formPlugin: {},
|
||||
showBuiltinPlugin: false,
|
||||
builtinPlugins: {
|
||||
Auth: "github.com/langhuihui/monibuca/plugins/auth",
|
||||
Cluster: "github.com/langhuihui/monibuca/plugins/cluster",
|
||||
GateWay: "github.com/langhuihui/monibuca/plugins/gateway",
|
||||
HDL: "github.com/langhuihui/monibuca/plugins/HDL",
|
||||
Jessica: "github.com/langhuihui/monibuca/plugins/jessica",
|
||||
QoS: "github.com/langhuihui/monibuca/plugins/QoS",
|
||||
RecordFlv: "github.com/langhuihui/monibuca/plugins/record",
|
||||
RTMP: "github.com/langhuihui/monibuca/plugins/rtmp"
|
||||
},
|
||||
defaultConfig: {
|
||||
Auth: 'Key = "www.monibuca.com"',
|
||||
RecordFlv: 'Path="./resource"',
|
||||
QoS: 'Suffix = ["high","medium","low"]',
|
||||
Cluster: 'Master = "localhost:2019"\nListenAddr = ":2019"',
|
||||
GateWay: 'ListenAddr = ":8081"',
|
||||
RTMP: 'ListenAddr = ":1935"',
|
||||
Jessica: 'ListenAddr = ":8080"',
|
||||
HDL: 'ListenAddr = ":2020"'
|
||||
}
|
||||
};
|
||||
},
|
||||
addPlugin() {
|
||||
this.plugins[this.formPlugin.Name] = this.formPlugin;
|
||||
this.formPlugin = {};
|
||||
},
|
||||
removePlugin(name) {
|
||||
delete this.plugins[name];
|
||||
this.$forceUpdate();
|
||||
},
|
||||
addBuiltin(name, item) {
|
||||
this.formPlugin.Name = name;
|
||||
this.formPlugin.Path = item;
|
||||
this.formPlugin.Config = this.defaultConfig[name];
|
||||
this.showBuiltinPlugin = false;
|
||||
},
|
||||
restart(item){
|
||||
const msg = this.$Message.loading({
|
||||
content: 'restart '+item.Name+'...',
|
||||
duration: 0
|
||||
});
|
||||
var es = new EventSource("/restart/instance?instance="+item.Name)
|
||||
es.onmessage = evt => {
|
||||
if(evt.data=="success"){
|
||||
this.$Message.success("重启成功!")
|
||||
msg()
|
||||
}else{
|
||||
this.$Message.info(evt.data)
|
||||
}
|
||||
}
|
||||
es.addEventListener("failed",evt=>{
|
||||
this.$Message.error(evt.data)
|
||||
msg()
|
||||
})
|
||||
es.onerror = e => {
|
||||
this.$Message.error(e);
|
||||
msg()
|
||||
es.close()
|
||||
computed: {
|
||||
pluginStr() {
|
||||
return Object.values(this.plugins)
|
||||
.map(x => x.Path)
|
||||
.join("\n");
|
||||
},
|
||||
configStr() {
|
||||
return Object.values(this.plugins)
|
||||
.map(
|
||||
x => `[Plugins.${x.Name}]
|
||||
${x.Config || ""}`
|
||||
)
|
||||
.join("\n");
|
||||
},
|
||||
privateHost() {
|
||||
return (
|
||||
(this.formPlugin.Path && this.formPlugin.Path.split("/")[0]) ||
|
||||
"仓库域名"
|
||||
);
|
||||
}
|
||||
},
|
||||
upgrade(item){
|
||||
const msg = this.$Message.loading({
|
||||
content: 'upgrade '+item.Name+'...',
|
||||
duration: 0
|
||||
});
|
||||
var es = new EventSource("/upgrade/engine?instance="+item.Name)
|
||||
es.onmessage = evt => {
|
||||
if(evt.data=="success"){
|
||||
this.$Message.success("更新完毕")
|
||||
msg()
|
||||
}else{
|
||||
this.$Message.info(evt.data)
|
||||
}
|
||||
}
|
||||
es.addEventListener("failed",evt=>{
|
||||
this.$Message.error(evt.data)
|
||||
msg()
|
||||
})
|
||||
es.onerror = e => {
|
||||
this.$Message.error(e);
|
||||
msg()
|
||||
es.close()
|
||||
}
|
||||
|
||||
methods: {
|
||||
|
||||
goUp() {
|
||||
let paths = this.createPath.split("/");
|
||||
paths.pop();
|
||||
this.createPath = paths.join("/");
|
||||
},
|
||||
createInstance() {
|
||||
this.showCreate = true;
|
||||
this.createInfo = {
|
||||
Name: this.instanceName || this.createPath.split("/").pop(),
|
||||
Path: this.createPath,
|
||||
Plugins: Object.values(this.plugins).map(x => x.Path),
|
||||
Config: this.configStr
|
||||
};
|
||||
},
|
||||
addPlugin() {
|
||||
this.plugins[this.formPlugin.Name] = this.formPlugin;
|
||||
this.formPlugin = {};
|
||||
},
|
||||
removePlugin(name) {
|
||||
delete this.plugins[name];
|
||||
this.$forceUpdate();
|
||||
},
|
||||
addBuiltin(name, item) {
|
||||
this.formPlugin.Name = name;
|
||||
this.formPlugin.Path = item;
|
||||
this.formPlugin.Config = this.defaultConfig[name];
|
||||
this.showBuiltinPlugin = false;
|
||||
},
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.content {
|
||||
background: white;
|
||||
}
|
||||
.content {
|
||||
background: white;
|
||||
}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
pre {
|
||||
white-space: pre-wrap;
|
||||
word-wrap: break-word;
|
||||
}
|
||||
|
||||
.ivu-tabs .ivu-tabs-tabpane {
|
||||
padding: 20px;
|
||||
}
|
||||
.ivu-tabs .ivu-tabs-tabpane {
|
||||
padding: 20px;
|
||||
}
|
||||
</style>
|
Reference in New Issue
Block a user