1
0
mirror of https://shylinux.com/x/ContextOS synced 2025-04-25 16:58:06 +08:00

opt readme

This commit is contained in:
shaoying 2019-07-30 20:34:57 +08:00
parent 3fde8557e7
commit bff17facfb
10 changed files with 267 additions and 20 deletions

227
README.md
View File

@ -21,13 +21,15 @@ $ curl https://shylinux.com/publish/boot.sh | bash -s install context
```
install后面的参数context就是指定的下载目录
进入下载目录,可以看到的有个文件。
进入下载目录,可以看到的有个文件。
在bin目录下就是各种执行文件
- bin/benchcontext的执行程序
- bin/boot.shcontext的启动脚本
- bin/node.sh简化版的启动脚本
- bin/zone.sh启动区域节点
- bin/user.sh启动用户节点
- bin/node.sh启动工作节点
context内部实现了语法解析通过自定义的脚本语言实现功能的灵活控制。
@ -37,7 +39,226 @@ context内部实现了语法解析通过自定义的脚本语言实现功
- etc/exit.shy结束时运行的脚本
- etc/common.shyinit.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内部实现了很多功能模块每个模块下有很多命令每条命令就是一种应用。

View File

@ -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

View File

@ -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"))
}

View File

@ -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,
}

View File

@ -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

View File

@ -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
}
}

View File

@ -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
}

View File

@ -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")

View File

@ -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))

View File

@ -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"}},