mirror of
https://shylinux.com/x/ContextOS
synced 2025-04-25 16:58:06 +08:00
add m.Cmdp
This commit is contained in:
parent
78df5d2ba3
commit
b3486b5e37
@ -34,8 +34,10 @@ install() {
|
||||
"armv7l") GOARCH=arm;;
|
||||
esac
|
||||
|
||||
target=system && [ -n "$2" ] && target=$2
|
||||
|
||||
wget -O ${ctx_app} "$ctx_dev/publish/${ctx_app}?GOOS=$GOOS&GOARCH=$GOARCH" && chmod a+x ${ctx_app} \
|
||||
&& ./${ctx_app} upgrade system && ${md5} ${ctx_app} \
|
||||
&& ./${ctx_app} upgrade ${target} && ${md5} ${ctx_app} \
|
||||
&& mv ${ctx_app} bin/${ctx_app}
|
||||
}
|
||||
main() {
|
||||
|
@ -1,11 +1,11 @@
|
||||
~cli
|
||||
config load var/tmp/runtime.json runtime
|
||||
config load tmp/runtime.json runtime
|
||||
~aaa
|
||||
config load var/tmp/auth.json auth
|
||||
config load tmp/auth.json auth
|
||||
~ssh
|
||||
config load var/tmp/cert.json work flow trust
|
||||
config load tmp/cert.json work flow trust
|
||||
~wiki
|
||||
config load var/tmp/wiki.json wiki_visit
|
||||
config load tmp/wiki.json wiki_visit
|
||||
source etc/common.shy
|
||||
~ssh
|
||||
remote auto
|
||||
|
@ -130,6 +130,20 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
"daemon": &ctx.Config{Name: "daemon", Value: map[string]interface{}{}, Help: "守护任务"},
|
||||
"action": &ctx.Config{Name: "action", Value: map[string]interface{}{}, Help: "交互任务"},
|
||||
|
||||
"project": &ctx.Config{Name: "project", Value: map[string]interface{}{
|
||||
"github": "https://github.com/shylinux/context",
|
||||
"env": map[string]interface{}{
|
||||
"GOPATH": "https://github.com/shylinux/context",
|
||||
},
|
||||
"import": []interface{}{
|
||||
"github.com/nsf/termbox-go",
|
||||
"github.com/skip2/go-qrcode",
|
||||
"github.com/go-sql-driver/mysql",
|
||||
"github.com/gomarkdown/markdown",
|
||||
"github.com/PuerkitoBio/goquery",
|
||||
"github.com/go-cas/cas",
|
||||
},
|
||||
}, Help: "运行环境"},
|
||||
"compile": &ctx.Config{Name: "compile", Value: map[string]interface{}{
|
||||
"bench": "src/examples/app/bench.go",
|
||||
"env": []interface{}{"GOPATH", "PATH"},
|
||||
@ -216,6 +230,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
if name, e := os.Getwd(); e == nil {
|
||||
_, file := path.Split(kit.Select(name, os.Getenv("PWD")))
|
||||
m.Conf("runtime", "boot.pathname", file)
|
||||
m.Conf("runtime", "boot.ctx_path", name)
|
||||
}
|
||||
return
|
||||
}},
|
||||
@ -501,6 +516,28 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
return
|
||||
}},
|
||||
|
||||
"project": &ctx.Command{Name: "project", Help: "", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
switch arg[0] {
|
||||
case "init":
|
||||
m.Cmdp(time.Second, []string{"git init"}, []string{"cli.system", "git"}, [][]string{
|
||||
[]string{"git", "init"},
|
||||
[]string{"git", "remote", "add", kit.Select("origin", arg, 1), kit.Select(m.Conf("project", "github"), arg, 2)},
|
||||
[]string{"git", "stash"},
|
||||
[]string{"git", "pull"},
|
||||
[]string{"git", "checkout", "-f", "master"},
|
||||
[]string{"git", "stash", "pop"},
|
||||
})
|
||||
|
||||
list := [][]string{}
|
||||
m.Confm("project", "import", func(index int, value string) {
|
||||
list = append(list, []string{value})
|
||||
})
|
||||
|
||||
m.Cmdp(time.Second, []string{"go init"}, []string{"cli.system", "go", "get",
|
||||
"cmd_env", "GOPATH", m.Conf("runtime", "boot.ctx_path")}, list)
|
||||
}
|
||||
return
|
||||
}},
|
||||
"compile": &ctx.Command{Name: "compile [OS [ARCH]]", Help: "解析脚本, script: 脚本文件, stdio: 命令终端, snippet: 代码片段", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) > 0 && arg[0] == "self" {
|
||||
if m.Cmdy("cli.system", "go", "install", m.Cmdx("nfs.path", m.Conf("compile", "bench"))); m.Result(0) == "" {
|
||||
@ -510,13 +547,14 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
}
|
||||
|
||||
if len(arg) > 0 && arg[0] == "all" {
|
||||
m.Cmdy("cli.compile", "linux", "386")
|
||||
m.Cmdy("cli.compile", "linux", "amd64")
|
||||
m.Cmdy("cli.compile", "linux", "arm")
|
||||
m.Cmdy("cli.compile", "windows", "386")
|
||||
m.Cmdy("cli.compile", "windows", "amd64")
|
||||
m.Cmdy("cli.compile", "darwin", "amd64")
|
||||
m.Set("result").Table()
|
||||
m.Cmdp(time.Second, []string{"go build"}, []string{"cli.compile"}, [][]string{
|
||||
[]string{"linux", "386"},
|
||||
[]string{"linux", "amd64"},
|
||||
[]string{"linux", "arm"},
|
||||
[]string{"windows", "386"},
|
||||
[]string{"windows", "amd64"},
|
||||
[]string{"darwin", "amd64"},
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
@ -547,7 +585,17 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
dir := m.Conf("publish", "path")
|
||||
m.Assert(os.MkdirAll(dir, 0777))
|
||||
|
||||
if len(arg) == 0 {
|
||||
list := [][]string{}
|
||||
m.Confm("publish", "list", func(key string, value string) {
|
||||
list = append(list, []string{key})
|
||||
})
|
||||
m.Cmdp(time.Second, []string{"copy"}, []string{"cli.publish"}, list)
|
||||
return
|
||||
}
|
||||
|
||||
for _, key := range arg {
|
||||
value := m.Conf("publish", []string{"list", key})
|
||||
p := m.Cmdx("nfs.path", value)
|
||||
if s, e := os.Stat(p); e == nil {
|
||||
if s.IsDir() {
|
||||
@ -555,18 +603,24 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心",
|
||||
} else {
|
||||
m.Cmd("nfs.copy", path.Join(dir, key), p)
|
||||
}
|
||||
return
|
||||
}
|
||||
})
|
||||
m.Cmdy("nfs.dir", dir, "dir_sort", "time", "time_r")
|
||||
}
|
||||
|
||||
// m.Cmdy("nfs.dir", dir, "dir_sort", "time", "time_r")
|
||||
|
||||
return
|
||||
}},
|
||||
"upgrade": &ctx.Command{Name: "upgrade bench|system|extend|plugin|portal|client|script", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
"upgrade": &ctx.Command{Name: "upgrade bench|system|extend|plugin|portal|client|script|project", Help: "服务升级", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmdy("ctx.config", "upgrade")
|
||||
return
|
||||
}
|
||||
if len(arg) > 0 && arg[0] == "project" {
|
||||
m.Cmd("cli.project", "init")
|
||||
m.Cmd("cli.compile", "all")
|
||||
m.Cmd("cli.publish")
|
||||
return
|
||||
}
|
||||
|
||||
restart := false
|
||||
for _, link := range kit.View([]string{arg[0]}, m.Confm("upgrade")) {
|
||||
|
@ -1230,6 +1230,14 @@ func (m *Message) Log(action string, str string, arg ...interface{}) *Message {
|
||||
|
||||
return m
|
||||
}
|
||||
func (m *Message) Show(args ...interface{}) *Message {
|
||||
if m.Option("cli.modal") == "action" {
|
||||
fmt.Printf(kit.Format(args...))
|
||||
} else if kit.STDIO != nil {
|
||||
kit.STDIO.Show(args...)
|
||||
}
|
||||
return m
|
||||
}
|
||||
func (m *Message) Assert(e interface{}, msg ...string) bool {
|
||||
switch v := e.(type) {
|
||||
case nil:
|
||||
@ -1541,6 +1549,19 @@ func (m *Message) Free(cbs ...func(msg *Message) (done bool)) *Message {
|
||||
return m
|
||||
}
|
||||
|
||||
func (m *Message) Cmdp(t time.Duration, head []string, prefix []string, suffix [][]string) *Message {
|
||||
if head != nil && len(head) > 0 {
|
||||
m.Show(strings.Join(head, " "), "...\n")
|
||||
}
|
||||
|
||||
for i, v := range suffix {
|
||||
m.Show(fmt.Sprintf("%v/%v %v...\n", i+1, len(suffix), v))
|
||||
m.Cmd(prefix, v)
|
||||
time.Sleep(t)
|
||||
}
|
||||
m.Show("\n")
|
||||
return m
|
||||
}
|
||||
func (m *Message) Cmdm(args ...interface{}) *Message {
|
||||
m.Log("info", "current: %v", m.Magic("session", "current"))
|
||||
|
||||
|
@ -151,7 +151,9 @@ var Index = &ctx.Context{Name: "log", Help: "日志中心",
|
||||
"search": map[string]interface{}{"value": []interface{}{"debug"}},
|
||||
"call": map[string]interface{}{"value": []interface{}{"debug"}},
|
||||
"back": map[string]interface{}{"value": []interface{}{"debug"}},
|
||||
|
||||
"send": map[string]interface{}{"value": []interface{}{"debug"}},
|
||||
"recv": map[string]interface{}{"value": []interface{}{"debug"}},
|
||||
|
||||
"bench": map[string]interface{}{"value": []interface{}{"bench"}},
|
||||
"begin": map[string]interface{}{"value": []interface{}{"bench", "red"}},
|
||||
|
@ -784,6 +784,10 @@ func (nfs *NFS) printf(arg ...interface{}) *NFS {
|
||||
}
|
||||
return nfs
|
||||
}
|
||||
func (nfs *NFS) Show(arg ...interface{}) bool {
|
||||
nfs.prompt(arg...)
|
||||
return true
|
||||
}
|
||||
|
||||
func (nfs *NFS) Recv(line string) (field string, value string) {
|
||||
m := nfs.Context.Message()
|
||||
@ -885,6 +889,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool {
|
||||
// 终端控制
|
||||
if nfs.in = m.Optionv("in").(*os.File); m.Has("out") {
|
||||
if nfs.out = m.Optionv("out").(*os.File); m.Cap("goos") != "windows" && !m.Options("daemon") {
|
||||
kit.STDIO = nfs
|
||||
nfs.Term(m, "init")
|
||||
defer nfs.Term(m, "exit")
|
||||
}
|
||||
|
@ -768,6 +768,15 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
return
|
||||
}},
|
||||
"brow": &ctx.Command{Name: "brow url", Help: "浏览网页", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
if len(arg) == 0 {
|
||||
m.Cmd("tcp.ifconfig").Table(func(index int, value map[string]string) {
|
||||
m.Append("index", index)
|
||||
m.Append("site", fmt.Sprintf("%s://%s%s", m.Conf("serve", "protocol"), value["ip"], m.Conf("runtime", "boot.web_port")))
|
||||
})
|
||||
m.Table()
|
||||
return
|
||||
}
|
||||
|
||||
switch runtime.GOOS {
|
||||
case "windows":
|
||||
m.Cmd("cli.system", "explorer", arg[0])
|
||||
@ -1113,6 +1122,22 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
m.Cmdy("web.get", "which", fields[2], "method", fields[3], strings.Join(fields, "/"))
|
||||
return
|
||||
}},
|
||||
|
||||
"/publish/": &ctx.Command{Name: "/publish/", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
key = strings.TrimPrefix(key, "/publish/")
|
||||
if strings.HasSuffix(key, "bench") {
|
||||
key = key + "." + m.Option("GOOS") + "." + m.Option("GOARCH")
|
||||
}
|
||||
key = strings.Replace(key, ".", "_", -1)
|
||||
p := m.Cmdx("nfs.path", path.Join(m.Conf("publish", "path"), key))
|
||||
if p == "" {
|
||||
p = m.Cmdx("nfs.path", m.Conf("publish", []string{"list", key}))
|
||||
}
|
||||
|
||||
m.Log("info", "publish %s %s", kit.Hashs(p), p)
|
||||
http.ServeFile(m.Optionv("response").(http.ResponseWriter), m.Optionv("request").(*http.Request), p)
|
||||
return
|
||||
}},
|
||||
"/shadow": &ctx.Command{Name: "/shadow", Help: "暗网", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
m.Confm("runtime", "node.port", func(index int, value string) {
|
||||
m.Add("append", "ports", value)
|
||||
@ -1149,22 +1174,6 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心",
|
||||
}
|
||||
return
|
||||
}},
|
||||
|
||||
"/publish/": &ctx.Command{Name: "/publish/", Help: "下载文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) (e error) {
|
||||
key = strings.TrimPrefix(key, "/publish/")
|
||||
if strings.HasSuffix(key, "bench") {
|
||||
key = key + "." + m.Option("GOOS") + "." + m.Option("GOARCH")
|
||||
}
|
||||
key = strings.Replace(key, ".", "_", -1)
|
||||
p := m.Cmdx("nfs.path", path.Join(m.Conf("publish", "path"), key))
|
||||
if p == "" {
|
||||
p = m.Cmdx("nfs.path", m.Conf("publish", []string{"list", key}))
|
||||
}
|
||||
|
||||
m.Log("info", "publish %s %s", kit.Hashs(p), p)
|
||||
http.ServeFile(m.Optionv("response").(http.ResponseWriter), m.Optionv("request").(*http.Request), p)
|
||||
return
|
||||
}},
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,8 @@ var Index = &ctx.Context{Name: "code", Help: "代码中心",
|
||||
map[string]interface{}{"name": "viewport", "content": "width=device-width, initial-scale=0.7, user-scalable=no"},
|
||||
}, "favicon": "favicon.ico", "styles": []interface{}{"example.css", "code.css"}},
|
||||
|
||||
map[string]interface{}{"componet_name": "login", "componet_help": "login", "componet_tmpl": "componet",
|
||||
map[string]interface{}{"componet_name": "login", "componet_help": "login",
|
||||
"componet_tmpl": "componet", "componet_init": "initLogin",
|
||||
"componet_ctx": "aaa", "componet_cmd": "auth", "componet_args": []interface{}{"@sessid", "ship", "username", "@username", "password", "@password"}, "inputs": []interface{}{
|
||||
map[string]interface{}{"type": "text", "name": "username", "value": "", "label": "username"},
|
||||
map[string]interface{}{"type": "password", "name": "password", "value": "", "label": "password"},
|
||||
|
@ -16,6 +16,12 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type TERM interface {
|
||||
Show(...interface{}) bool
|
||||
}
|
||||
|
||||
var STDIO TERM
|
||||
|
||||
var DisableLog = false
|
||||
var EnableDebug = false
|
||||
|
||||
|
@ -1,609 +1,4 @@
|
||||
var page = Page({
|
||||
initComList: function(page, field, option, append, result) {
|
||||
return
|
||||
},
|
||||
|
||||
initScheduleText: function(page, field, option, append, result) {
|
||||
option.ondaemon = function(msg) {
|
||||
page.reload()
|
||||
}
|
||||
},
|
||||
initScheduleList: function(page, field, option) {
|
||||
ctx.Runs(page, option)
|
||||
},
|
||||
|
||||
initFlashText: function(page, field, option, append, result) {
|
||||
option.ondaemon = function(msg) {
|
||||
page.reload()
|
||||
}
|
||||
},
|
||||
initFlashList: function(page, field, option) {
|
||||
option.dataset.flash_index = ctx.Search("flash_index")
|
||||
option.ondaemon = function(msg) {
|
||||
page.showFlashList(msg, field, option)
|
||||
}
|
||||
ctx.Runs(page, option)
|
||||
},
|
||||
showFlashList: function(msg, field, option) {
|
||||
var page = this
|
||||
var result = field.querySelector("div.result")
|
||||
|
||||
result.innerHTML = ""
|
||||
ctx.Table(msg, function(tip) {
|
||||
var ui = kit.AppendChild(result, [{"list": [
|
||||
{"text": [tip.text, "div", "detail"]},
|
||||
{"code": [tip.code, "result", "result"]},
|
||||
{"view": ["action"], "list": [
|
||||
{"button": ["查看详情", function(event) {
|
||||
ctx.Search("flash_index", tip.index)
|
||||
}]},
|
||||
{"button": ["执行代码", function(event) {
|
||||
tip.code && ctx.Run(page, option.dataset, [tip.index, "run"], function(msg) {
|
||||
ui.output.innerText = msg.result
|
||||
})
|
||||
}]},
|
||||
{"button": ["清空结果", function(event) {
|
||||
ui.output.innerText = ""
|
||||
}]},
|
||||
]},
|
||||
{"code": [tip.output, "output", "output"]},
|
||||
]}])
|
||||
})
|
||||
},
|
||||
|
||||
initKitList: function(page, field, option, append, result) {
|
||||
var ui = kit.AppendChild(field, [
|
||||
{"styles": {
|
||||
"fieldset.KitList": {
|
||||
"top": conf.toolkit_view.top, "left": conf.toolkit_view.left,
|
||||
},
|
||||
"fieldset.KitList:hover, fieldset.KitList.max": {
|
||||
"width": conf.toolkit_view.width, "height": conf.toolkit_view.height,
|
||||
},
|
||||
}},
|
||||
{"type": "ul", "list": [
|
||||
{"fork": ["粘贴板", [
|
||||
{"leaf": ["+ 保存粘贴板(Ctrl+S)", function(event) {
|
||||
console.log("save_txt")
|
||||
}]},
|
||||
{"leaf": ["+ 添加粘贴板(Ctrl+Y)", function(event) {
|
||||
console.log("create_txt")
|
||||
}]},
|
||||
{"leaf": ["+ 快捷粘贴板(Ctrl+P)", function(event) {
|
||||
console.log("quick_txt")
|
||||
}]},
|
||||
]]},
|
||||
{"fork": ["命令行", [
|
||||
{"leaf": ["+ 折叠命令行(Ctrl+Z)", function(event, target) {
|
||||
target.className = page.conf.show_result? "": "stick"
|
||||
page.showResult(page)
|
||||
}]},
|
||||
{"leaf": ["+ 添加命令行(Ctrl+M)", function(event) {
|
||||
page.addCmdList("cmd", page.conf.ncommand++)
|
||||
}]},
|
||||
]]},
|
||||
{"fork": ["工作流", [
|
||||
{"leaf": ["+ 刷新工作流(Ctrl+R)", function(event) {
|
||||
console.log("refresh_fly")
|
||||
}]},
|
||||
{"leaf": ["+ 添加工作流(Ctrl+T)", function(event) {
|
||||
console.log("create_fly")
|
||||
}]},
|
||||
{"leaf": ["+ 命名工作流", function(event) {
|
||||
console.log("rename_fly")
|
||||
}]},
|
||||
{"leaf": ["+ 删除工作流", function(event) {
|
||||
console.log("remove_fly")
|
||||
}]},
|
||||
]]},
|
||||
]},
|
||||
])
|
||||
/*
|
||||
<li><div>命令行</div>
|
||||
<ul class="cmd">
|
||||
{{range $name, $cmd := conf . "toolkit"}}
|
||||
<li>{{$name}} <input type="text" data-cmd="{{$name}}" onkeyup="onaction(event, 'toolkit')"><label class="result"></label></li>
|
||||
{{end}}
|
||||
|
||||
<li class="stick" data-action="shrink_cmd">+ 折叠命令行(Ctrl+Z)</li>
|
||||
<li data-action="create_cmd">+ 添加命令行(Ctrl+M)</li>
|
||||
{{range $index, $cmd := index $bench_data "commands"}}
|
||||
<li class="cmd{{$index}}" data-cmd="{{$index}}">{{index $cmd "now"|option}} {{$index}}: {{index $cmd "cmd"|option}}</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</li>
|
||||
<li><div>工作流</div>
|
||||
<ul class="fly">
|
||||
<li data-action="refresh_fly">+ 刷新工作流(Ctrl+R)</li>
|
||||
<li data-action="create_fly">+ 添加工作流(Ctrl+T)</li>
|
||||
{{range $key, $item := work .}}
|
||||
<li data-key="{{$key}}">{{index $item "create_time"}} {{index $item "data" "name"}}({{slice $key 0 6}})</li>
|
||||
{{end}}
|
||||
<li data-action="rename_fly">+ 命名工作流</li>
|
||||
<li data-action="remove_fly">+ 删除工作流</li>
|
||||
</ul>
|
||||
</li>
|
||||
*/
|
||||
return
|
||||
|
||||
text = JSON.parse(bench_data.clipstack || "[]")
|
||||
for (var i = 0; i < text.length; i++) {
|
||||
copy_to_clipboard(text[i])
|
||||
}
|
||||
bench_data.board = bench_data.board || {}
|
||||
|
||||
document.querySelectorAll("div.workflow").forEach(function(workflow) {
|
||||
// 移动面板
|
||||
workflow.style.left = context.Cookie("toolkit_left")
|
||||
workflow.style.top = context.Cookie("toolkit_top")
|
||||
var moving = false, left0 = 0, top0 = 0, x0 = 0, y0 = 0
|
||||
workflow.onclick = function(event) {
|
||||
if (event.target != workflow) {
|
||||
return
|
||||
}
|
||||
moving = !moving
|
||||
if (moving) {
|
||||
left0 = workflow.offsetLeft
|
||||
top0 = workflow.offsetTop
|
||||
x0 = event.clientX
|
||||
y0 = event.clientY
|
||||
}
|
||||
}
|
||||
workflow.onmousemove = function(event) {
|
||||
if (moving) {
|
||||
workflow.style.left = (left0+(event.clientX-x0))+"px"
|
||||
workflow.style.top = (top0+(event.clientY-y0))+"px"
|
||||
context.Cookie("toolkit_left", workflow.style.left)
|
||||
context.Cookie("toolkit_top", workflow.style.top)
|
||||
}
|
||||
}
|
||||
|
||||
// 固定面板
|
||||
if (context.Cookie("toolkit_class")) {
|
||||
workflow.className = context.Cookie("toolkit_class")
|
||||
}
|
||||
var head = workflow.querySelector("div")
|
||||
head.onclick = function(event) {
|
||||
head.dataset["show"] = !right(head.dataset["show"])
|
||||
workflow.className = right(head.dataset["show"])? "workflow max": "workflow"
|
||||
context.Cookie("toolkit_class", workflow.className)
|
||||
}
|
||||
|
||||
// 折叠目录
|
||||
var toolkit = workflow.querySelector("ul.toolkit")
|
||||
toolkit.querySelectorAll("li>div").forEach(function(menu) {
|
||||
menu.onclick = function(event) {
|
||||
menu.dataset["hide"] = !right(menu.dataset["hide"])
|
||||
menu.nextElementSibling.style.display = right(menu.dataset["hide"])? "none": ""
|
||||
}
|
||||
})
|
||||
|
||||
// 事件
|
||||
toolkit.querySelectorAll("li>ul>li").forEach(function(item) {
|
||||
// if (bench_data.board["key"] == item.dataset["key"]) {
|
||||
// // item.className = "stick"
|
||||
// }
|
||||
|
||||
item.onclick = function(event) {
|
||||
var target = event.target
|
||||
var data = item.dataset
|
||||
switch (data["action"]) {
|
||||
case "quick_txt":
|
||||
code.quick_txt = !code.quick_txt
|
||||
target.className= code.quick_txt? "stick": ""
|
||||
break
|
||||
case "copy_txt":
|
||||
if (event.altKey) {
|
||||
target.parentElement.removeChild(target)
|
||||
return
|
||||
}
|
||||
if (event.shiftKey) {
|
||||
var cmd = document.querySelector("form.option.cmd"+code.current_cmd+" input[name=cmd]")
|
||||
cmd && (cmd.value += " "+text)
|
||||
return
|
||||
}
|
||||
copy_to_clipboard(data["text"], true)
|
||||
break
|
||||
case "save_txt":
|
||||
save_clipboard(item)
|
||||
return
|
||||
case "create_txt":
|
||||
var text = prompt("text")
|
||||
text && copy_to_clipboard(text)
|
||||
return
|
||||
case "refresh_fly":
|
||||
location.reload()
|
||||
return
|
||||
case "create_fly":
|
||||
context.Command(["sess", "bench", "create"], function(msg) {
|
||||
context.Search("bench", msg.result[0])
|
||||
})
|
||||
return
|
||||
case "rename_fly":
|
||||
context.Command(["work", context.Search("bench"), "rename", prompt("name")], function() {
|
||||
location.reload()
|
||||
})
|
||||
return
|
||||
case "remove_fly":
|
||||
var b = ""
|
||||
document.querySelectorAll("div.workflow>ul.toolkit>li>ul.fly>li[data-key]").forEach(function(item){
|
||||
if (!b && item.dataset["key"] != context.Search("bench")) {
|
||||
b = item.dataset["key"]
|
||||
}
|
||||
})
|
||||
context.Search("bench", b)
|
||||
context.Command(["work", context.Search("bench"), "delete"])
|
||||
return
|
||||
}
|
||||
|
||||
// 切换工作流
|
||||
if (data["key"] && data["key"] != context.Search("bench")) {
|
||||
context.Search("bench", data["key"])
|
||||
return
|
||||
}
|
||||
|
||||
// 切换命令行
|
||||
var cmd = document.querySelector("form.option.cmd"+data["cmd"]+" input[name=cmd]")
|
||||
cmd && cmd.focus()
|
||||
}
|
||||
})
|
||||
})
|
||||
return
|
||||
},
|
||||
|
||||
initDirList: function(page, field, option, append, result) {
|
||||
var history = []
|
||||
function change(value) {
|
||||
return page.setCurrent(page, option, "dir", value)
|
||||
}
|
||||
function brow(value, dir, event) {
|
||||
page.setCurrent(page, option, "dir", value)
|
||||
page.setCurrent(page, option, "dir", dir)
|
||||
}
|
||||
return {
|
||||
"button": ["root", "back"], "action": function(value) {
|
||||
switch (value) {
|
||||
case "back": history.length > -1 && change(history.pop() || "/"); break
|
||||
case "root": change("/"); break
|
||||
}
|
||||
},
|
||||
"table": {"filename": function(value, key, row, index, event) {
|
||||
var dir = option.dir.value
|
||||
var file = dir + ((dir && !dir.endsWith("/"))? "/": "") + value
|
||||
file.endsWith("/")? history.push(change(file)): brow(file, dir, event)
|
||||
}},
|
||||
}
|
||||
},
|
||||
initPodList: function(page, field, option, append, result) {
|
||||
return {"button": ["local"], "action": function(value) {
|
||||
value == "local" && (value = "''")
|
||||
page.setCurrent(page, option, "pod", value)
|
||||
}, "table": {"key": function(value) {
|
||||
page.setCurrent(page, option, "pod", value)
|
||||
}}}
|
||||
},
|
||||
initCtxList: function(page, field, option, append, result) {
|
||||
return {"button": ["ctx", "shy", "web", "mdb"], "action": function(value) {
|
||||
page.setCurrent(page, option, "ctx", value)
|
||||
}, "table": {"names": function(value) {
|
||||
page.setCurrent(page, option, "ctx", value)
|
||||
}}}
|
||||
},
|
||||
setCurrent: function(page, option, type, value) {
|
||||
option[type].value = ctx.Current(type, value)
|
||||
page.History.add(type, value)
|
||||
ctx.Runs(page, option)
|
||||
return value
|
||||
},
|
||||
|
||||
initCmdList: function(page, field, option, append, result) {
|
||||
option.dataset["componet_name_alias"] = "cmd"
|
||||
option.dataset["componet_name_order"] = 0
|
||||
|
||||
var cmd = option.querySelector("input[name=cmd]")
|
||||
cmd.onkeyup = function(event) {
|
||||
page.onCmdList(event, cmd, "input", field, option, append, result)
|
||||
}
|
||||
|
||||
var action = conf.bench_data.action
|
||||
action && action["cmd"] && page.runCmdList(page, option, cmd, action["cmd"].cmd[1])
|
||||
|
||||
var max = 0
|
||||
for (var k in action) {
|
||||
var order = parseInt(action[k].order)
|
||||
order > max && (max = order)
|
||||
}
|
||||
|
||||
for (var i = 1; i <= max; i++) {
|
||||
var ui = page.addCmdList("cmd", i)
|
||||
action["cmd"+i] && page.runCmdList(page, ui.option, ui.cmd, action["cmd"+i].cmd[1])
|
||||
}
|
||||
page.conf.ncommand = i
|
||||
return
|
||||
},
|
||||
runCmdList: function(page, option, target, value) {
|
||||
target.value = value
|
||||
target.dataset.history_last = kit.History.add("cmd", target.value)
|
||||
ctx.Runs(page, option)
|
||||
},
|
||||
getCmdList: function(input, step, cmd) {
|
||||
var history = kit.History.get("cmd")
|
||||
var length = history.length
|
||||
var last = (parseInt(input.dataset["history_last"]||length)+step+length)%length
|
||||
if (0 <= last && last < length) {
|
||||
input.dataset["history_last"] = last
|
||||
cmd = history[last].data
|
||||
}
|
||||
return cmd
|
||||
},
|
||||
addCmdList: function(name, order) {
|
||||
var page = this
|
||||
var alias = name+order
|
||||
var ui = kit.AppendChild(document.body, [{"view": ["CmdList", "fieldset"], "list": [
|
||||
{"text": [alias, "legend"]},
|
||||
{"view": ["option "+alias, "form", "", "option"],
|
||||
"data": {"dataset": {
|
||||
"componet_group": "index", "componet_name": name, "componet_name_alias": alias, "componet_name_order": order,
|
||||
}},
|
||||
"list": [
|
||||
{"type": "input", "data": {"style": {"display": "none"}}},
|
||||
{"name": "cmd", "type": "input", "data": {"name": "cmd", "className": "cmd", "onkeyup": function(event) {
|
||||
page.onCmdList(event, ui.cmd, "input", ui.field, ui.option, ui.append, ui.result)
|
||||
}}},
|
||||
]
|
||||
},
|
||||
{"view": ["append "+alias, "table", "", "append"]},
|
||||
{"code": ["", "result", "result "+alias]},
|
||||
]}])
|
||||
|
||||
kit.OrderForm(page, ui.field, ui.option, ui.append, ui.result)
|
||||
kit.OrderTable(ui.append)
|
||||
kit.OrderCode(ui.result)
|
||||
ui.cmd.focus()
|
||||
return ui
|
||||
},
|
||||
delCmdList: function(name, order) {
|
||||
var option = document.querySelector("form.option.cmd"+order)
|
||||
option && document.body.removeChild(option.parentElement)
|
||||
|
||||
for (;order < page.conf.ncommand; order++) {
|
||||
var input = document.querySelector("form.option.cmd"+order+" input[name=cmd]")
|
||||
if (input) {
|
||||
input.focus()
|
||||
return
|
||||
}
|
||||
}
|
||||
for (;order >= 0; order--) {
|
||||
var input = document.querySelector("form.option.cmd"+(order? order: "")+" input[name=cmd]")
|
||||
page.conf.ncommand = order+1
|
||||
if (input) {
|
||||
input.focus()
|
||||
return
|
||||
}
|
||||
}
|
||||
},
|
||||
onCmdList: function(event, target, action, field, option, append, result) {
|
||||
var page = this
|
||||
var order = option.dataset.componet_name_order
|
||||
var prev_order = (parseInt(order)-1+page.conf.ncommand)%page.conf.ncommand||""
|
||||
var next_order = (parseInt(order)+1)%page.conf.ncommand||""
|
||||
|
||||
switch (action) {
|
||||
case "input":
|
||||
kit.History.add("key", (event.ctrlKey? "Control+": "")+(event.shiftKey? "Shift+": "")+event.key)
|
||||
|
||||
if (event.key == "Escape") {
|
||||
target.blur()
|
||||
|
||||
} else if (event.key == "Enter") {
|
||||
page.runCmdList(page, option, target, target.value)
|
||||
|
||||
} else if (event.ctrlKey) {
|
||||
switch (event.key) {
|
||||
case "0":
|
||||
var pre_pre = document.querySelector("code.result.cmd"+(event.shiftKey? next_order: prev_order)+" pre")
|
||||
pre_pre && (target.value += pre_pre.innerText)
|
||||
break
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7":
|
||||
case "8":
|
||||
case "9":
|
||||
if (code.quick_txt) {
|
||||
var item = document.querySelectorAll("div.workflow>ul>li>ul.txt>li[data-text]")
|
||||
target.value += item[parseInt(event.key)-1].dataset["text"]
|
||||
} else {
|
||||
var item = document.querySelectorAll("table.append.cmd"+(event.shiftKey? next_order: prev_order)+" td")
|
||||
target.value += item[parseInt(event.key)-1].innerText
|
||||
}
|
||||
break
|
||||
case "p":
|
||||
target.value = page.getCmdList(target, -1, target.value)
|
||||
break
|
||||
case "n":
|
||||
target.value = page.getCmdList(target, 1, target.value)
|
||||
break
|
||||
case "g":
|
||||
var value = target.value.substr(0, target.selectionStart)
|
||||
var last = parseInt(target.dataset.search_last || kit.History.get("cmd").length-1)
|
||||
for (var i = last; i >= 0; i--) {
|
||||
var cmd = kit.History.get("cmd", i).data
|
||||
if (cmd.startsWith(value)) {
|
||||
target.value = cmd
|
||||
target.dataset.search_last = i-1
|
||||
target.setSelectionRange(value.length, cmd.length)
|
||||
break
|
||||
}
|
||||
}
|
||||
target.dataset.search_last = ""
|
||||
break
|
||||
|
||||
case "y":
|
||||
case "v":
|
||||
case "s":
|
||||
case "t":
|
||||
break
|
||||
|
||||
case "a":
|
||||
case "e":
|
||||
case "f":
|
||||
case "b":
|
||||
case "h":
|
||||
case "d":
|
||||
break
|
||||
case "k":
|
||||
kit.DelText(target, target.selectionStart)
|
||||
break
|
||||
case "u":
|
||||
kit.DelText(target, 0, target.selectionEnd)
|
||||
break
|
||||
case "w":
|
||||
var start = target.selectionStart-2
|
||||
var end = target.selectionEnd-1
|
||||
for (var i = start; i >= 0; i--) {
|
||||
if (target.value[end] == " " && target.value[i] != " ") {
|
||||
break
|
||||
}
|
||||
if (target.value[end] != " " && target.value[i] == " ") {
|
||||
break
|
||||
}
|
||||
}
|
||||
kit.DelText(target, i+1, end-i)
|
||||
break
|
||||
|
||||
case "c":
|
||||
append.innerHTML = ""
|
||||
result.innerHTML = ""
|
||||
break
|
||||
case "r":
|
||||
append.innerHTML = ""
|
||||
result.innerHTML = ""
|
||||
case "j":
|
||||
page.runCmdList(page, option, target, target.value)
|
||||
break
|
||||
case "l":
|
||||
window.scrollTo(0, option.parentElement.offsetTop)
|
||||
break
|
||||
case "m":
|
||||
page.addCmdList("cmd", page.conf.ncommand++)
|
||||
break
|
||||
case "i":
|
||||
var input = document.querySelector("form.option.cmd"+next_order+" input[name=cmd]")
|
||||
input && input.focus()
|
||||
break
|
||||
case "o":
|
||||
var input = document.querySelector("form.option.cmd"+prev_order+" input[name=cmd]")
|
||||
input && input.focus()
|
||||
break
|
||||
case "x":
|
||||
result.style.height = result.style.height? "": page.conf.hide_height
|
||||
break
|
||||
case "z":
|
||||
result.style.height = result.style.height? "": page.conf.show_height
|
||||
break
|
||||
case "q":
|
||||
page.delCmdList("cmd", order)
|
||||
break
|
||||
default:
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (kit.HitText(target, "jk")) {
|
||||
kit.DelText(target, target.selectionStart-2, 2)
|
||||
target.blur()
|
||||
}
|
||||
}
|
||||
event.stopPropagation()
|
||||
}
|
||||
},
|
||||
|
||||
onaction: function(event, target, action) {
|
||||
var page = this
|
||||
switch (action) {
|
||||
case "scroll":
|
||||
break
|
||||
case "keymap":
|
||||
if (event.key == "Escape") {
|
||||
|
||||
} else if (event.key == "Enter") {
|
||||
|
||||
} else if (event.ctrlKey) {
|
||||
switch (event.key) {
|
||||
case "m":
|
||||
page.addCmdList("cmd", page.conf.ncommand++)
|
||||
break
|
||||
case "z":
|
||||
page.showResult(page)
|
||||
break
|
||||
case "0":
|
||||
case "1":
|
||||
case "2":
|
||||
case "3":
|
||||
case "4":
|
||||
case "5":
|
||||
case "6":
|
||||
case "7":
|
||||
case "8":
|
||||
case "9":
|
||||
document.querySelector("form.option.cmd"+(event.key||"")+" input[name=cmd]").focus()
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
showResult: function(page, type) {
|
||||
page.conf.show_result = !page.conf.show_result
|
||||
document.querySelectorAll("body>fieldset>code.result>pre").forEach(function(result) {
|
||||
result.style.height = (page.conf.show_result || result.innerText=="")? "": page.conf.show_height
|
||||
})
|
||||
},
|
||||
init: function(exp) {
|
||||
var page = this
|
||||
var body = document.body
|
||||
body.onkeyup = function(event) {
|
||||
page.onaction(event, body, "keymap")
|
||||
}
|
||||
|
||||
document.querySelectorAll("body>fieldset").forEach(function(field) {
|
||||
var option = field.querySelector("form.option")
|
||||
var append = field.querySelector("table.append")
|
||||
var result = field.querySelector("code.result pre")
|
||||
kit.OrderForm(page, field, option, append, result)
|
||||
append && kit.OrderTable(append)
|
||||
result && kit.OrderCode(result)
|
||||
|
||||
var init = page[field.dataset.init]
|
||||
if (typeof init == "function") {
|
||||
var conf = init(page, field, option, append, result)
|
||||
if (conf && conf["button"]) {
|
||||
var buttons = []
|
||||
conf.button.forEach(function(value, index) {
|
||||
buttons.push({"button": [value, function(event) {
|
||||
typeof conf["action"] == "function" && conf["action"](value, event)
|
||||
}]})
|
||||
})
|
||||
kit.InsertChild(field, append, "div", buttons)
|
||||
}
|
||||
if (conf && conf["table"]) {
|
||||
option.daemon_action = conf["table"]
|
||||
ctx.Runs(page, option)
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
conf: {
|
||||
scroll_x: 50,
|
||||
scroll_y: 50,
|
||||
|
||||
ncommand: 1,
|
||||
show_result: true,
|
||||
show_height: "30px",
|
||||
hide_height: "14px",
|
||||
|
||||
quick_txt: false,
|
||||
page({
|
||||
init: function() {
|
||||
},
|
||||
})
|
||||
|
@ -5,7 +5,7 @@ ctx = context = {
|
||||
option[k] = dataset[k].split(",")
|
||||
}
|
||||
this.GET("", option, function(msg) {
|
||||
msg = msg && msg[0]
|
||||
msg[0] && (msg = msg[0])
|
||||
// msg && (msg.__proto__ = (page || {}))
|
||||
msg.Result = msg.result? msg.result.join(""): ""
|
||||
msg.Results = function() {
|
||||
|
@ -2,26 +2,271 @@
|
||||
|
||||
context是一种新的应用框架,通过模块化、集群化、自动化,实现软件的快速开发,快速共享,快速使用。
|
||||
|
||||
### 下载安装
|
||||
在Linux或Mac上,可以直接用脚本下载,在Windows上,可以先安装[GitBash](https://www.git-scm.com/download/),然后下载。
|
||||
## 下载安装
|
||||
在Linux或Mac上,可以直接用脚本下载,
|
||||
在Windows上,可以先安装[GitBash](https://www.git-scm.com/download/),然后在GitBash中执行命令下载。
|
||||
```
|
||||
$ mkdir context && cd context
|
||||
$ curl https://shylinux.com/publish/boot.sh | bash -s install
|
||||
$ curl https://shylinux.com/publish/boot.sh | bash -s install context
|
||||
```
|
||||
|
||||
### 使用方式
|
||||
install后面的参数context,就是指定的下载目录,
|
||||
进入下载目录,可以看到的有六个文件。
|
||||
|
||||
在bin目录下,就是各种执行文件
|
||||
|
||||
- bin/bench,context的执行程序
|
||||
- bin/boot.sh,context的启动脚本
|
||||
- bin/node.sh,简化版的启动脚本
|
||||
|
||||
context内部实现了语法解析,通过自定义的脚本语言,实现功能的灵活控制。
|
||||
|
||||
在etc目录下,就是context执行过程中用到的脚本。
|
||||
|
||||
- etc/init.shy,启动时加载的脚本
|
||||
- etc/exit.shy,结束时运行的脚本
|
||||
- etc/common.shy,init.shy调用到的脚本
|
||||
|
||||
## 使用方式
|
||||
|
||||
context内部实现了很多功能模块,每个模块下有很多命令,每条命令就是一种应用。
|
||||
|
||||
#### 命令模式
|
||||
context的使用方式有很多种,
|
||||
|
||||
- 可以直接调用,像Shell一样,去解析一条命令
|
||||
- 可以启动cli服务,像MySQL一样,交互式使用格式化命令
|
||||
- 可以启动web服务,像LabView一样,可以自定义各种图形界面
|
||||
- 可以自动组网,将任意台设备组合在一起,实现分布式应用
|
||||
- 可以自动建群,在群聊场景中,实现多用户、多会话、多任务、多设备的使用
|
||||
|
||||
### 命令模式
|
||||
如果只是使用一条命令,或是写在脚本文件中,可以使用这种方式。
|
||||
|
||||
例如,dir命令就是查看目录,
|
||||
```
|
||||
$ bin/bench dir
|
||||
time size line filename
|
||||
2019-06-16 10:35:18 324 11 common.shy
|
||||
2019-06-16 10:35:18 201 9 exit.shy
|
||||
2019-06-16 10:35:18 261 13 init.shy
|
||||
```
|
||||
|
||||
还可以加更多参数,dir_deep递归查询目录,dir_type文件类型过滤,dir_sort输出表排序。
|
||||
```
|
||||
$ bin/bench dir ../ dir_deep dir_type file dir_sort line int_r
|
||||
time size line filename
|
||||
2019-06-16 10:22:52 13256968 91314 bench
|
||||
2019-06-16 11:10:16 1535 66 boot.sh
|
||||
2019-06-16 11:10:16 613 31 node.sh
|
||||
2019-06-16 11:10:16 261 13 init.shy
|
||||
2019-06-16 11:10:16 324 11 common.shy
|
||||
2019-06-16 11:10:16 201 9 exit.shy
|
||||
|
||||
```
|
||||
|
||||
#### 交互模式
|
||||
### 交互模式
|
||||
|
||||
启动服务,可以提供更丰富的命令与环境。
|
||||
```
|
||||
$ bin/bench
|
||||
0[11:35:46]ssh> dir
|
||||
time size line filename
|
||||
2019-06-16 11:35:06 160 3 log/
|
||||
2019-06-16 11:35:06 96 1 run/
|
||||
2019-06-16 11:35:44 192 4 tmp/
|
||||
1[11:35:46]ssh>
|
||||
```
|
||||
|
||||
如果集中管理,命令越多,系统只会越复杂,学习成本越高,使用越低效,开发越困难。
|
||||
|
||||
所以通过模块化,分而治之,更高效的管理丰富的命令。
|
||||
|
||||
context命令就是用来管理模块,没有参数时,直接查看当前模块的信息。
|
||||
|
||||
如下,第二行是当前模块,第一行是当前模块的父模块,其它行都是当前模块的子模块。
|
||||
|
||||
```
|
||||
1[11:39:01]ssh> context
|
||||
names ctx msg status stream helps
|
||||
ctx 0 start shy 模块中心
|
||||
ssh ctx 10 begin ctx.nfs.file3 集群中心
|
||||
```
|
||||
|
||||
context第一个参数,可以指定当前模块,
|
||||
如下,切换到nfs模块,然后查看各种IO模块,
|
||||
切换到ctx根模块,查看所有模块。
|
||||
```
|
||||
2[11:43:57]ssh> context nfs
|
||||
|
||||
3[11:43:58]nfs> context
|
||||
names ctx msg status stream helps
|
||||
ctx 0 start shy 模块中心
|
||||
nfs ctx 9 begin 存储中心
|
||||
stdio nfs 1174 start stdio scan stdio
|
||||
|
||||
4[11:44:22]ssh> context ctx
|
||||
|
||||
5[11:45:17]ctx> context
|
||||
names ctx msg status stream helps
|
||||
ctx 0 start shy 模块中心
|
||||
aaa ctx 3 begin 认证中心
|
||||
cli ctx 4 begin 管理中心
|
||||
gdb ctx 232 start 调试中心
|
||||
lex ctx 6 begin 词法中心
|
||||
log ctx 31 start bench 日志中心
|
||||
mdb ctx 8 begin 数据中心
|
||||
nfs ctx 9 begin 存储中心
|
||||
ssh ctx 10 begin 集群中心
|
||||
tcp ctx 11 begin 网络中心
|
||||
web ctx 1094 start :9094 应用中心
|
||||
yac ctx 13 begin 35,14,23 语法中心
|
||||
shy cli 1171 start engine shell
|
||||
matrix1 lex 34 start 76,28,2 matrix
|
||||
stdio nfs 1174 start stdio scan stdio
|
||||
chat web 14 begin 会议中心
|
||||
code web 15 begin 代码中心
|
||||
wiki web 16 begin 文档中心
|
||||
engine yac 1173 start stdio parse
|
||||
|
||||
```
|
||||
|
||||
command命令,就是用来管理当前模块的命令,
|
||||
```
|
||||
17[11:52:02]nfs> context nfs
|
||||
|
||||
17[11:52:02]nfs> command
|
||||
key name
|
||||
_init _init
|
||||
action action cmd
|
||||
copy copy to from
|
||||
dir dir [path [fields...]]
|
||||
export export filename
|
||||
git git sum
|
||||
hash hash filename
|
||||
import import filename [index]
|
||||
json json str
|
||||
load load file [buf_size [pos]]
|
||||
open open file
|
||||
path path filename
|
||||
printf printf arg
|
||||
prompt prompt arg
|
||||
pwd pwd [all] | [[index] path]
|
||||
read read [buf_size [pos]]
|
||||
remote remote listen|dial args...
|
||||
save save file string...
|
||||
scan scan file name
|
||||
send send [file] args...
|
||||
temp temp data
|
||||
term term action args...
|
||||
trash trash file
|
||||
write write string [pos]
|
||||
|
||||
```
|
||||
|
||||
help子命令,查看命令帮助信息。
|
||||
```
|
||||
18[11:59:19]nfs> command help dir
|
||||
dir: dir [path [fields...]]
|
||||
查看目录, path: 路径, fields...: 查询字段, time|type|full|path|tree|filename|size|line|hash
|
||||
dir_deep: 递归查询
|
||||
dir_type both|file|dir|all: 文件类型
|
||||
dir_reg reg: 正则表达式
|
||||
dir_sort field order: 排序
|
||||
```
|
||||
|
||||
|
||||
### 集群模式
|
||||
|
||||
context提供自动化集群的功能,可以自动组网、自动认证。从而快速实现多台设备的协同工作。
|
||||
|
||||
#### 启动服务节点
|
||||
```
|
||||
$ bin/boot.sh
|
||||
0[11:35:12]ssh>
|
||||
```
|
||||
|
||||
#### 启动工作节点
|
||||
|
||||
新打开一个终端,启动工作节点,执行remote命令,查看上级节点,
|
||||
```
|
||||
$ bin/boot.sh create app/demo
|
||||
0[15:15:30]ssh> remote
|
||||
key type module create_time
|
||||
mac master ctx.nfs.file3 2019-06-16 15:15:23
|
||||
```
|
||||
|
||||
回到服务节点终端,执行remote命令,可以查看到所有远程节点。
|
||||
```
|
||||
2[15:15:31]ssh> remote
|
||||
key type module create_time
|
||||
com master ctx.nfs.file4 2019-06-16 14:25:10
|
||||
demo worker ctx.nfs.file7 2019-06-16 15:15:23
|
||||
```
|
||||
|
||||
默认配置中,子节点信任父,所以父节点可以调用子节点的命令。还有更复杂的认证机制,可以灵活配置。
|
||||
|
||||
远程命令和本地命令一样,没有任何区别。如下调用demo节点的pwd命令。还支持更复杂的多节点命令,可以更快速的同时管理多台设备。
|
||||
```
|
||||
2[15:15:31]ssh> remote demo pwd
|
||||
/Users/shaoying/context/app/demo/var
|
||||
```
|
||||
|
||||
#### 启动分机节点
|
||||
|
||||
在服务节点的终端,查看服务地址
|
||||
```
|
||||
3[15:49:00]ssh> web.brow
|
||||
index site
|
||||
0 http://192.168.199.139:9094
|
||||
```
|
||||
|
||||
同样,在另一台设备上下载context,然后启动服务节点。
|
||||
通过环境变量ctx_dev指定上级节点。
|
||||
```
|
||||
$ ctx_dev="http://192.168.199.139:9094" bin/boot.sh
|
||||
0[15:49:00]ssh> remote
|
||||
key type module create_time
|
||||
mac master ctx.nfs.file3 2019-06-16 15:15:23
|
||||
```
|
||||
|
||||
回到服务节点终端,执行remote命令,可以查看到新添加了一个服务子节点。
|
||||
```
|
||||
2[15:15:31]ssh> remote
|
||||
key type module create_time
|
||||
com master ctx.nfs.file4 2019-06-16 14:25:10
|
||||
demo worker ctx.nfs.file7 2019-06-16 15:15:23
|
||||
sub server ctx.nfs.file8 2019-06-16 16:15:23
|
||||
```
|
||||
|
||||
同样可以远程调用命令。
|
||||
```
|
||||
2[15:15:31]ssh> remote sub pwd
|
||||
/Users/shaoying/context/app/sub/var
|
||||
```
|
||||
|
||||
### 开源模式
|
||||
|
||||
context是一种通用的应用框架,可以快速开发出各种工具。
|
||||
```
|
||||
2[15:15:31]ssh> project init
|
||||
done
|
||||
2[15:15:31]ssh> project init
|
||||
```
|
||||
|
||||
### 网页模式
|
||||
### 工具链
|
||||
### 知识库
|
||||
### 信息流
|
||||
```
|
||||
$ bin/bench
|
||||
19[11:59:19]nfs> upgrade portal
|
||||
hash file
|
||||
ef1998b38af0888cb56dd5e1448a68ad usr/template.tar.gz
|
||||
6_043a93fa03273744be42c7ab898b2 usr/librarys.tar.gz
|
||||
|
||||
19[11:59:19]nfs> upgrade portal
|
||||
|
||||
```
|
||||
|
||||
#### 集群模式
|
||||
|
||||
#### 完整版
|
||||
如果对源码有兴趣,使用更丰富的功能,可以直接下载源码,
|
||||
@ -109,103 +354,6 @@ index name ip mask hard
|
||||
5 en0 192.168.0.106 24 c4:b3:01:cf:0b:51
|
||||
```
|
||||
|
||||
### 组建集群
|
||||
|
||||
context不仅只是一个shell,还可以用来组建集群。
|
||||
|
||||
#### 启动服务节点
|
||||
|
||||
启动服务节点,使用脚本boot.sh,
|
||||
与node.sh不同的是,boot.sh启动的context,
|
||||
会启动web模块监听9094端口,会启动ssh模块监听9090端口。
|
||||
```
|
||||
$ cd context
|
||||
$ bin/boot.sh
|
||||
0[11:23:03]ssh>
|
||||
```
|
||||
|
||||
#### 启动工作节点
|
||||
启动工作节点,使用脚本node.sh,
|
||||
它启动的context,会主动连接本地9090端口,向服务节点注册自己。
|
||||
|
||||
如下,新打开一个终端,调用boot.sh,创建并启动服务节点demo。
|
||||
```
|
||||
$ cd context
|
||||
$ bin/node.sh create app/demo
|
||||
0[11:23:03]ssh>
|
||||
```
|
||||
|
||||
如下,再打开一个终端,调用boot.sh,创建并启动服务节点led。
|
||||
```
|
||||
$ cd context
|
||||
$ bin/node.sh create app/led
|
||||
0[11:23:03]ssh>
|
||||
```
|
||||
|
||||
#### 调用远程命令
|
||||
如下回到服务节点终端,执行remote命令,可以查看到所有远程节点。
|
||||
```
|
||||
22[11:35:12]ssh> remote
|
||||
key create_time module name type
|
||||
com 2019-05-09 20:57:21 ctx.nfs.file4 com master
|
||||
led 2019-05-09 20:59:28 ctx.nfs.file5 led worker
|
||||
demo 2019-05-09 20:59:28 ctx.nfs.file5 demo worker
|
||||
```
|
||||
|
||||
远程命令只需要在命令前加上节点名与冒号即可。
|
||||
|
||||
如下,远程调用led节点的命令。
|
||||
```
|
||||
24[11:41:15]ssh> led:pwd
|
||||
/Users/shaoying/context/app/led/var
|
||||
```
|
||||
|
||||
如下,远程调用demo节点的命令。
|
||||
```
|
||||
24[11:41:15]ssh> demo:pwd
|
||||
/Users/shaoying/context/app/demo/var
|
||||
```
|
||||
|
||||
如下,远程调用所有子节点的命令。
|
||||
```
|
||||
29[11:44:09]ssh> *:pwd
|
||||
/Users/shaoying/context/app/led/var
|
||||
|
||||
/Users/shaoying/context/app/demo/var
|
||||
```
|
||||
|
||||
#### 启动分机服务
|
||||
|
||||
boot.sh不仅可以用来启动本地服务,还可以将不同的主机组建在一起。
|
||||
|
||||
在另外一台计算机上,重新下载安装一下context,然后启动服务节点。
|
||||
|
||||
其中环境变量ctx_dev,用来指定上级服务节点。
|
||||
|
||||
```
|
||||
$ cd context
|
||||
$ ctx_dev=http://192.168.0.106:9094 boot.sh
|
||||
0[11:53:11]ssh>
|
||||
```
|
||||
|
||||
回到原主机的服务节点终端,
|
||||
使用remote命令,可以查看到新加的从机节点。
|
||||
```
|
||||
30[11:55:38]ssh> remote
|
||||
key create_time module name type
|
||||
com 2019-05-09 20:57:21 ctx.nfs.file4 com master
|
||||
mac 2019-05-10 10:53:00 ctx.nfs.file13 mac server
|
||||
led 2019-05-09 20:59:28 ctx.nfs.file5 led worker
|
||||
demo 2019-05-09 20:59:28 ctx.nfs.file5 demo worker
|
||||
```
|
||||
|
||||
当然,也可以在本地启动多个服务节点,根据ctx_dev指定不同的上级节点,可以级联,也可以并联。
|
||||
```
|
||||
$ cd context
|
||||
$ ctx_dev=http://localhost:9094 boot.sh create app/sub
|
||||
```
|
||||
***注意,不指定ctx_dev时,默认连接 https://shylinux.com ,如果不信任此主机,记得设置ctx_dev***
|
||||
|
||||
### 网页服务
|
||||
|
||||
下载完整版的context,启动的服务节点,就会带有前端网页服务。
|
||||
|
Loading…
x
Reference in New Issue
Block a user