From bff17facfb1dd2a2896f80ab1635849f737a90df Mon Sep 17 00:00:00 2001 From: shaoying Date: Tue, 30 Jul 2019 20:34:57 +0800 Subject: [PATCH] opt readme --- README.md | 227 +++++++++++++++++++++++++++++++++++- bin/boot.sh | 7 +- src/contexts/cli/cli.go | 22 +++- src/contexts/cli/version.go | 2 +- src/contexts/ctx/ctx.go | 4 +- src/contexts/ctx/misc.go | 1 - src/contexts/ctx/type.go | 2 +- src/contexts/ssh/ssh.go | 8 ++ src/contexts/tcp/tcp.go | 12 +- src/contexts/yac/yac.go | 2 +- 10 files changed, 267 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 1558f851..393a0de4 100644 --- a/README.md +++ b/README.md @@ -21,13 +21,15 @@ $ curl https://shylinux.com/publish/boot.sh | bash -s install context ``` install后面的参数context,就是指定的下载目录, -进入下载目录,可以看到的有六个文件。 +进入下载目录,可以看到的有八个文件。 在bin目录下,就是各种执行文件 - bin/bench,context的执行程序 - bin/boot.sh,context的启动脚本 -- bin/node.sh,简化版的启动脚本 +- bin/zone.sh,启动区域节点 +- bin/user.sh,启动用户节点 +- bin/node.sh,启动工作节点 context内部实现了语法解析,通过自定义的脚本语言,实现功能的灵活控制。 @@ -37,7 +39,226 @@ context内部实现了语法解析,通过自定义的脚本语言,实现功 - etc/exit.shy,结束时运行的脚本 - etc/common.shy,init.shy调用到的脚本 -## 使用方式 +## 创建集群 +context是一种分布式框架,可以运行在任意设备上,并且实现了自动组网、自动路由、自动认证。 +远程命令与本地命令,无差别的运行,从而实现无限扩容的分布式计算。 + +context每个启动的进程都是一个独立的节点,根据网络框架中的功能作用,可以分为区域节点、用户节点、工作节点、分机节点。 +这几种节点,除了网络框架中的作用外,其它的功能模块与命令都完全一样,没有差别。 + +个人使用,可以创建一个区域节点,下挂多个工作节点。 + +团队使用,需要创建一个区域节点,多个用户节点,每个用户节点下,可以挂多个工作节点。 + +如果用户节点或工作节点过多,可以创建分机节点,通过增加层级来降低单机负载。 + +### 个人使用 +#### 启动区域节点 +打开终端,进入context目录,执行如下命令, +``` +$ bin/zone.sh +0[13:26:27]nfs> +``` + +#### 启动工作节点 +再打开终端,进入context目录,执行如下命令, +``` +$ bin/node.sh create app/hello + +0[13:26:27]nfs> remote +create_time pod type +2019-07-30 13:26:27 com master +``` +启动context后,调用remote命令,可以查看到有一个上级节点。 + +#### 启动工作节点 +再打开终端,进入context目录,执行如下命令, +``` +$ bin/node.sh create app/world + +0[13:26:27]nfs> remote +create_time pod type +2019-07-30 13:26:27 com master +``` + +#### 分布式命令 +启动两种节点节点后,就可以在任意节点上调用命令,也可以调用远程节点的命令。 +如在区域节点上调用remote,就可以看到两个工作节点。 +``` +4[13:27:26]nfs> remote +create_time pod type +2019-07-30 13:26:27 hello worker +2019-07-30 13:26:30 world worker +``` + +查看当前路径 +``` +3[13:39:29]nfs> pwd +D:\context/var +4[13:40:03]nfs> +``` + +查看当时目录 +``` +4[13:40:03]nfs> dir +time size line path +2019-07-23 21:36:36 387 4 var/hi.png +2019-07-27 13:41:56 4096 4 var/log/ +2019-06-15 10:58:03 0 1 var/run/ +2019-07-30 12:55:19 4096 8 var/tmp/ +5[13:40:20]nfs> +``` + +执行远程命令,只需要在命令前加上节点名与冒号。 +``` +6[13:41:28]nfs> hello:pwd +D:\context\hello/var +6[13:41:28]nfs> world:pwd +D:\context\world/var +``` + +在任意随机节点上执行命令,用百分号作节点名。 +``` +5[13:40:20]nfs> %:pwd +D:\context\hello/var +5[13:40:20]nfs> %:pwd +D:\context\world/var +``` + +在所有节点上执行命令,用星号作节点名。 +``` +7[13:41:36]nfs> *:pwd +D:\context\hello/var D:\context\hello/var +``` + +## 团队使用 +context也可以支持团队协作使用,这时候就需要将区域节点部署到公共主机上。 +区域节点的作用就是生成动态域名,分发路由,解决命名冲突,与权限分配等功能。 + +### 启动用户节点 +在公共主机上启动区域节点后,每个组员就可以在自己主机上启动用户节点,但需要指定区域节点的地址。 +如下命令,ip换成自己的公共主机,9095端口保留,这是context默认的web端口。 +``` +$ ctx_dev=http://192.168.88.102:9095 bin/user.sh +``` + +### 启动工作节点 +同样每个用户都可以启动多用工作节点。 +``` +$ bin/node.sh create world +``` + +### 启动团队协作 +当有多个用户连接到公共节点后,用户与用户之间就可以相互访问对方的所有节点。 +但是默认启用了节点认证,所有命令都没有权限。所以调用对应节点上的命令,需要对方开启命令权限。 + +每个用户随时都可以在自己节点上,为其它用户设置任意角色,给每个角色分配任意命令。 +从而实现安全快速的资源共享。 + + +## 启动分机节点 +当区域的用户节点过多,就可以启动分机节点。 +启动分机节点,只需要指定上级节点即可。 +用户在连接公共节点时,指定这个新节点的ip即可。 +context会自动生成新的网络路由。 + +``` +$ ctx_dev=http://192.168.88.102:9095 bin/boot.sh +``` + +## 创建群聊 +除了命令行的使用的方式之外,context还有自己的前端框架。 +不仅降低了使用难度,还提供更加场景化、自动化的应用界面。 + +用户可以访问区域节点或是任意用户节点的网页服务。 + +http://127.0.0.29:9095 + +输入用户名与初始密码,即可登录,如果用户与主机上的用户名相同,则是管理员权限,如果不同,则是普通用户,只有最小的功能权限。 + +所以任意节点都支持多用户共享使用,但只有管理用户有所有权限,进行资源的管理与分配。 + +打开应用界面,就可以看到context以办公聊天软件的形式提供各种丰富的功能。 + +左边框是用户群组列表,用户可以选择群聊或是创建新的群聊。 +中间就是聊天记录与输入框,用户可以自由的聊天收发消息。 + +与其它聊天软件不同的是,context提供了自定义的功能列表。 +右边框中,就是此群组的功能列表。 +每个用户都可以将自己设备上的命令添加到这个群组的功能列表中,分享给本组员使用。 +每个组员都可以根据自己的需求组合这些命令,生成自己的应用界面。 + +以每个群聊作为场景,进行资源的共享与应用的开发,从而实现更加场景化与个性化应用。 + +通过这种精细化的应用场景,进行工具化、标准化、流程化。提高各行各业的工作效率。 + +## 应用开发 + +网络框架与应用界面,已经实现了标准化与自动化,剩下就是应用的开发了。 + +开发者,可以在任意机器上开发自己的应用。以模块与函数为单位进行开发与上线。 +一个函数,即使只有几行代码,也是一个独立完整的应用,可以随时上线,被任意用户使用。 + +用户还可以在任意群聊中转发此应用,更自由的传播出去。 +从而将软件开发的速度提升成千上万倍,将代码的使用效率提升成千上万倍。 + +### 创建项目 +在任意节点上,执行project命令,指定项目名,即可创建应用目录。 +``` +$ bin/user.sh +8[13:41:41]nfs> project hello +time line hash path +2019-07-30 14:27:09 35 eba8eda2 src/plugin/hello/index.go +2019-07-30 14:27:09 1 b858cb28 src/plugin/hello/index.shy +2019-07-30 14:27:09 1 b858cb28 src/plugin/hello/local.shy +2019-07-30 14:27:09 4 407265b6 src/plugin/hello/index.js +9[14:27:09]nfs> +``` +每个项目,都可以用go语言开发低层应用,用js开发前端交互。 +除此,context有自己的通用语法解析器,开者完全可以随时自定义语法,定制自己的解析器。 +用自己喜欢的语法开发应用。 + +默认的shy语法,提供了一个完整的前后端应用框架。创建项目时,自动创建的模块如下。 +``` +fun hello world "" "" \ + public \ + text "" \ + button "执行" + copy pwd +end +``` + +这个模板就是一个完整的应用,fun关键字开关,end关键字结束。 +前四行就是定义应用界面,剩下代码就是后端脚本。 +public代表,这个应用是公共的,所以有人都可以访问。也可以是private,只有管理用户可以访问。 + +text与button,就是需要前端展示的控件。用户在前端点击此button,就会将请求发送到后端,执行此脚本。 +然后将执行结果返回给前端界面。 + +### 加载项目 +切换到cli模块,使用upgrade命令,加载新的项目应用。 +``` +8[13:41:41]nfs> ~cli +8[13:41:41]cli> upgrade plugin hello +3[15:55:53]cli> ~ +names ctx msg status stream helps +ctx 0 start stdio 模块中心 +cli ctx 4 begin 管理中心 +hello cli 5958 start shy +4[15:57:00]cli> +``` + +切换到hello模块,使用command命令,可以查看到hello模块下的命令列表,然后就可以调用hello命令。 +``` +8[13:41:41]cli> ~hello +6[15:58:42]hello> command +key name +hello hello world public text button 执行 +7[20:27:32]nice> hello +D:\context/var +``` + +同时在前端界面上添加功能,即可看到此函数。 context内部实现了很多功能模块,每个模块下有很多命令,每条命令就是一种应用。 diff --git a/bin/boot.sh b/bin/boot.sh index 35409212..98976215 100755 --- a/bin/boot.sh +++ b/bin/boot.sh @@ -9,6 +9,7 @@ ctx_bin=${ctx_app} && [ -f bin/${ctx_app} ] && ctx_bin=$(pwd)/bin/${ctx_app} ctx_dev=${ctx_dev:="https://shylinux.com"} ctx_root=${ctx_root:=/usr/local/context} ctx_home=${ctx_home:=~/context} +# ctx_type= # node_cert= # node_key= # web_port= @@ -40,7 +41,7 @@ install() { target=system && [ -n "$2" ] && target=$2 wget -O ${ctx_app} "$ctx_dev/publish/${ctx_app}?GOOS=$GOOS&GOARCH=$GOARCH" && chmod a+x ${ctx_app} \ - && ${md5} ${ctx_app} && ./${ctx_app} upgrade ${target} \ + && ${md5} ${ctx_app} && ./${ctx_app} upgrade ${target} && ./${ctx_app} upgrade portal \ && mv ${ctx_app} bin/${ctx_app} mkdir -p usr/script && touch usr/script/local.shy && cd etc && ln -s ../usr/script/local.shy . @@ -53,7 +54,7 @@ main() { log "\nstarting..." while true; do date && ${ctx_bin} "$@" && break - log "\nrestarting..." && sleep 1 + log "\n\nrestarting..." && sleep 1 done } action() { @@ -78,6 +79,6 @@ case $1 in restart) action 30;; upgrade) action 31;; quit) action QUIT;; - term) action TERM;; + term) action TERM esac diff --git a/src/contexts/cli/cli.go b/src/contexts/cli/cli.go index 733d3419..f2d539c7 100644 --- a/src/contexts/cli/cli.go +++ b/src/contexts/cli/cli.go @@ -62,6 +62,7 @@ var Index = &ctx.Context{Name: "cli", Help: "管理中心", "ctx_ups", "ctx_box", "ctx_dev", "ctx_cas", "ctx_root", "ctx_home", + "ctx_type", "web_port", "ssh_port", }, "boot": map[string]interface{}{ @@ -142,7 +143,14 @@ func main() { {init: function(page, pane, field, option, output) { kit.Log("hello world") }} -`}, map[string]interface{}{"name": "index.shy", "text": ` `}, map[string]interface{}{"name": "local.shy", "text": ` `}, +`}, map[string]interface{}{"name": "index.shy", "text": ` +fun hello world "" "" \ + public \ + text "" \ + button "执行" + copy pwd +end +`}, map[string]interface{}{"name": "local.shy", "text": ` `}, }, }, "script": map[string]interface{}{ "path": "usr/script", @@ -163,6 +171,8 @@ func main() { "publish": &ctx.Config{Name: "publish", Value: map[string]interface{}{ "path": "usr/publish", "list": map[string]interface{}{ "boot_sh": "bin/boot.sh", + "zone_sh": "bin/zone.sh", + "user_sh": "bin/user.sh", "node_sh": "bin/node.sh", "init_shy": "etc/init.shy", "common_shy": "etc/common.shy", @@ -177,12 +187,14 @@ func main() { }, }, Help: "版本发布"}, "upgrade": &ctx.Config{Name: "upgrade", Value: map[string]interface{}{ - "system": []interface{}{"boot.sh", "node.sh", "init.shy", "common.shy", "exit.shy"}, + "system": []interface{}{"boot.sh", "zone.sh", "user.sh", "node.sh", "init.shy", "common.shy", "exit.shy"}, "portal": []interface{}{"template.tar.gz", "librarys.tar.gz"}, "script": []interface{}{"test.php"}, "list": map[string]interface{}{ "bench": "bin/bench.new", "boot_sh": "bin/boot.sh", + "zone_sh": "bin/zone.sh", + "user_sh": "bin/user.sh", "node_sh": "bin/node.sh", "init_shy": "etc/init.shy", "common_shy": "etc/common.shy", @@ -1003,7 +1015,11 @@ func main() { } msg.Optionv("bio.ctx", msg.Target()) - if p := msg.Cmdx("nfs.path", path.Join(msg.Conf("publish", "path"), arg[0], "index.shy")); p != "" { + p := msg.Cmdx("nfs.path", path.Join(msg.Conf("project", "plugin.path"), arg[0], "index.shy")) + if p == "" { + p = msg.Cmdx("nfs.path", path.Join(msg.Conf("publish", "path"), arg[0], "index.shy")) + } + if p != "" { msg.Cmdy("nfs.source", p) msg.Confv("ssh.componet", arg[0], msg.Confv("_index")) } diff --git a/src/contexts/cli/version.go b/src/contexts/cli/version.go index 28ef01f4..4d62ac65 100644 --- a/src/contexts/cli/version.go +++ b/src/contexts/cli/version.go @@ -4,5 +4,5 @@ var version = struct { host string self int }{ - "2019-07-30 08:27:51", "mac", 238, + "2019-07-30 15:55:14", "ZYB-20190522USI", 316, } diff --git a/src/contexts/ctx/ctx.go b/src/contexts/ctx/ctx.go index 46884c28..bbff5a06 100644 --- a/src/contexts/ctx/ctx.go +++ b/src/contexts/ctx/ctx.go @@ -45,6 +45,7 @@ func (ctx *CTX) Begin(m *Message, arg ...string) Server { } func (ctx *CTX) Start(m *Message, arg ...string) bool { if m.Optionv("bio.ctx", Index); len(arg) == 0 { + kit.DisableLog = false m.Optionv("bio.msg", m) m.Optionv("bio.ctx", m.Target()) m.Option("bio.modal", "active") @@ -58,7 +59,7 @@ func (ctx *CTX) Start(m *Message, arg ...string) bool { m.Cmd("ctx._init") m.Cmd("aaa.role", "root", "user", m.Option("username", m.Conf("runtime", "boot.username"))) m.Option("sessid", m.Cmdx("aaa.user", "session", "select")) - m.Cmd("nfs.source", m.Conf("system", "script.init")).Cmd("nfs.source", "stdio").Cmd("nfs.source", m.Conf("system", "script.exit")) + m.Cmd("nfs.source", m.Conf("cli.system", "script.init")).Cmd("nfs.source", "stdio").Cmd("nfs.source", m.Conf("cli.system", "script.exit")) } else { m.Option("bio.modal", "action") @@ -95,7 +96,6 @@ var Index = &Context{Name: "ctx", Help: "模块中心", Server: &CTX{}, Commands: map[string]*Command{ "_init": &Command{Name: "_init", Help: "启动", Hand: func(m *Message, c *Context, key string, arg ...string) (e error) { for _, x := range []string{"lex", "cli", "yac", "nfs", "aaa", "ssh", "web"} { - kit.Log("error", "%v", x) m.Cmd(x + "._init") } return diff --git a/src/contexts/ctx/misc.go b/src/contexts/ctx/misc.go index daec24e8..57c06abd 100644 --- a/src/contexts/ctx/misc.go +++ b/src/contexts/ctx/misc.go @@ -222,7 +222,6 @@ func (m *Message) Find(name string, root ...bool) *Message { } else if target.Name == v { continue } else { - m.Log("error", "context not find %s", name) return nil } } diff --git a/src/contexts/ctx/type.go b/src/contexts/ctx/type.go index df5134d8..a74dcd50 100644 --- a/src/contexts/ctx/type.go +++ b/src/contexts/ctx/type.go @@ -515,7 +515,7 @@ func (m *Message) Cmd(args ...interface{}) *Message { }) if !msg.Hand { - msg.Log("error", "cmd run error %s", msg.Format()) + // msg.Log("error", "cmd run error %s", msg.Format()) } return msg } diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index 1cb1f711..d8ac0433 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -574,6 +574,14 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Cmd("web.serve", "usr", m.Conf("runtime", "boot.web_port")) } + switch m.Conf("runtime", "boot.ctx_type") { + case "work": + m.Cmd("ssh.work", "serve") + case "user": + m.Cmd("ssh.work", "create") + case "node": + } + // 监听连接 case "listen": m.Cmd("ssh._node", "init") diff --git a/src/contexts/tcp/tcp.go b/src/contexts/tcp/tcp.go index 14b00e95..d5f820eb 100644 --- a/src/contexts/tcp/tcp.go +++ b/src/contexts/tcp/tcp.go @@ -20,7 +20,7 @@ type TCP struct { *ctx.Context } -func (tcp *TCP) parse(m *ctx.Message, arg ...string) ([]string, []string) { +func (tcp *TCP) parse(m *ctx.Message, arg ...string) ([]string, []string, bool) { defer func() { if e := recover(); e != nil { m.Log("warn", "%v", e) @@ -32,7 +32,9 @@ func (tcp *TCP) parse(m *ctx.Message, arg ...string) ([]string, []string) { m.Cmd("web.get", arg[1], arg[2], "temp", "ports", "format", "object").Table(func(line map[string]string) { address = append(address, line["value"]) }) - m.Assert(len(address) > 0, "dial failure") + if len(address) == 0 { + return nil, nil, false + } for i := 2; i < len(arg)-1; i++ { arg[i] = arg[i+1] @@ -43,7 +45,7 @@ func (tcp *TCP) parse(m *ctx.Message, arg ...string) ([]string, []string) { } else { address = append(address, m.Cap("address", m.Confx("address", arg, 1))) } - return address, arg + return address, arg, true } func (tcp *TCP) retry(m *ctx.Message, address []string, action func(address string) (net.Conn, error)) net.Conn { var count int32 @@ -107,8 +109,8 @@ func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { return tcp } func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { - address, arg := tcp.parse(m, arg...) - if len(address) == 0 { + address, arg, ok := tcp.parse(m, arg...) + if len(address) == 0 || !ok { return true } m.Cap("security", m.Confx("security", arg, 2)) diff --git a/src/contexts/yac/yac.go b/src/contexts/yac/yac.go index 68153ad9..b742ad14 100644 --- a/src/contexts/yac/yac.go +++ b/src/contexts/yac/yac.go @@ -322,7 +322,7 @@ var Index = &ctx.Context{Name: "yac", Help: "语法中心", map[string]interface{}{"page": "stm", "hash": "return", "word": []interface{}{"return", "rep{", "exp", "}"}}, // 命令语句 - map[string]interface{}{"page": "word", "hash": "word", "word": []interface{}{"mul{", "~", "!", "\\?", "\\?\\?", "exe", "str", "[\\-a-zA-Z0-9_:/.]+", "=", "<", ">$", ">@", ">", "\\|", "%", "}"}}, + map[string]interface{}{"page": "word", "hash": "word", "word": []interface{}{"mul{", "~", "!", "\\?", "\\?\\?", "exe", "str", "[\\-a-zA-Z0-9_:/.%*]+", "=", "<", ">$", ">@", ">", "\\|", "}"}}, map[string]interface{}{"page": "cmd", "hash": "cmd", "word": []interface{}{"rep{", "word", "}"}}, map[string]interface{}{"page": "com", "hash": "com", "word": []interface{}{"mul{", ";", "#[^\n]*\n?", "\n", "}"}}, map[string]interface{}{"page": "line", "hash": "line", "word": []interface{}{"opt{", "mul{", "stm", "cmd", "}", "}", "com"}},