1
0
forked from x/icebergs
This commit is contained in:
shaoying 2020-01-12 15:35:12 +08:00
parent 5783c5f09a
commit f3b78ae6c5
26 changed files with 382 additions and 268 deletions

View File

@ -2,9 +2,24 @@
icebergs是一个后端框架通过模块化、集群化实现资源的无限的扩展与自由的组合。 icebergs是一个后端框架通过模块化、集群化实现资源的无限的扩展与自由的组合。
使用icebergs可以将各种模块或项目集成到一起快速开发出集中式的服务器。
使用icebergs可以将各种设备自由的组合在一起快速搭建起分布式的服务器。
所以通过icebergs开发出来的模块无需任何多余代码就可以独立运行可以成为系统命令可以远程调用可以成为前端插件可以成为小程序页面。
## 项目开发
开发环境需要安装gitgolang
一键创建项目 一键创建项目
``` ```
mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh mkdir miss; cd miss && curl -s https://shylinux.com/publish/template.sh | sh
```
运行环境如需前端页面访问服务需要安装git
一键复制项目
```
export ctx_dev=http://127.0.0.1:9020 && curl -s $ctx_dev/publish/ice.sh
``` ```
## 1 原型 type.go ## 1 原型 type.go

View File

@ -88,15 +88,17 @@ var Index = &Context{Name: "ice", Help: "冰山模块",
}}, }},
"init": {Name: "init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "init": {Name: "init", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.root.Cost("_init") m.root.Cost("_init")
m.Start("log", arg...) m.Start("log")
m.Start("gdb", arg...) m.Start("gdb")
m.Start("ssh", arg...) m.Start("ssh")
m.Cmd("ssh.scan", "init.shy", "启动配置", "etc/init.shy")
m.Cmd(arg) m.Cmd(arg)
}}, }},
"help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "help": {Name: "help", Help: "帮助", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n")) m.Echo(strings.Join(kit.Simple(m.Confv("help", "index")), "\n"))
}}, }},
"exit": {Name: "exit", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) { "exit": {Name: "exit", Help: "hello", Hand: func(m *Message, c *Context, cmd string, arg ...string) {
m.Cmd("ssh.scan", "exit.shy", "退出配置", "etc/exit.shy")
f := m.root.target.server.(*Frame) f := m.root.target.server.(*Frame)
f.code = kit.Int(kit.Select("0", arg, 0)) f.code = kit.Int(kit.Select("0", arg, 0))
m.root.Cmd(ICE_EXIT) m.root.Cmd(ICE_EXIT)

View File

@ -87,6 +87,16 @@ var Index = &ice.Context{Name: "aaa", Help: "认证模块",
}}, }},
ice.AAA_USER: {Name: "user", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.AAA_USER: {Name: "user", Help: "用户", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] { switch arg[0] {
case "first":
if m.Richs(ice.AAA_USER, nil, "%", nil) == nil {
m.Rich(ice.AAA_USER, nil, kit.Dict("username", arg[1],
"usernode", m.Conf(ice.CLI_RUNTIME, "boot.hostname"),
))
user := m.Richs(ice.AAA_USER, nil, arg[1], nil)
m.Info("create user: %s %s", arg[1], kit.Format(user))
m.Event(ice.USER_CREATE, arg[1])
}
case "login": case "login":
// 用户认证 // 用户认证
user := m.Richs(ice.AAA_USER, nil, arg[1], nil) user := m.Richs(ice.AAA_USER, nil, arg[1], nil)

View File

@ -116,7 +116,14 @@ var Index = &ice.Context{Name: "ctx", Help: "配置模块",
} }
} }
default: default:
m.Echo(kit.Formats(m.Confv(arg[0]))) if len(arg) > 2 {
m.Conf(arg[0], arg[1], arg[2])
}
if len(arg) > 1 {
m.Echo(m.Conf(arg[0], arg[1]))
} else {
m.Echo(kit.Formats(m.Confv(arg[0])))
}
} }
}}, }},
}, },

View File

@ -7,6 +7,7 @@ import (
"bytes" "bytes"
"encoding/csv" "encoding/csv"
"encoding/json" "encoding/json"
"os"
"sort" "sort"
"strings" "strings"
) )
@ -54,6 +55,11 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
case kit.MDB_LIST: case kit.MDB_LIST:
buf := bytes.NewBufferString(msg.Append("text")) buf := bytes.NewBufferString(msg.Append("text"))
r := csv.NewReader(buf) r := csv.NewReader(buf)
if msg.Append("file") != "" {
if f, e := os.Open(msg.Append("file")); m.Assert(e) {
r = csv.NewReader(f)
}
}
head, _ := r.Read() head, _ := r.Read()
for { for {
@ -79,7 +85,7 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
} }
} }
}}, }},
ice.MDB_EXPORT: {Name: "export", Help: "导出数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.MDB_EXPORT: {Name: "export conf key list|hash", Help: "导出数据", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
name := kit.Select(kit.Select(arg[0], arg[0]+":"+arg[1], arg[1] != ""), arg, 3) name := kit.Select(kit.Select(arg[0], arg[0]+":"+arg[1], arg[1] != ""), arg, 3)
switch arg[2] { switch arg[2] {
@ -89,7 +95,7 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
buf := bytes.NewBuffer(make([]byte, 0, 1024)) buf := bytes.NewBuffer(make([]byte, 0, 1024))
w := csv.NewWriter(buf) w := csv.NewWriter(buf)
head := []string{} head := []string{}
m.Confm(arg[0], arg[1], func(index int, value map[string]interface{}) { m.Grows(arg[0], arg[1], "", "", func(index int, value map[string]interface{}) {
if index == 0 { if index == 0 {
// 输出表头 // 输出表头
for k := range value { for k := range value {
@ -108,10 +114,10 @@ var Index = &ice.Context{Name: "mdb", Help: "数据模块",
}) })
w.Flush() w.Flush()
m.Cmd(ice.WEB_STORY, "add", "csv", name, string(buf.Bytes())) m.Cmdy(ice.WEB_STORY, "add", "csv", name, string(buf.Bytes()))
case kit.MDB_HASH: case kit.MDB_HASH:
m.Cmd(ice.WEB_STORY, "add", "json", name, kit.Formats(m.Confv(arg[0], arg[1]))) m.Cmdy(ice.WEB_STORY, "add", "json", name, kit.Formats(m.Confv(arg[0], arg[1])))
} }
}}, }},
}, },

View File

@ -40,10 +40,18 @@ func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
} }
func (f *Frame) Start(m *ice.Message, arg ...string) bool { func (f *Frame) Start(m *ice.Message, arg ...string) bool {
switch kit.Select("stdio", arg, 0) { switch kit.Select("stdio", arg, 0) {
default: case "stdio":
f.in = os.Stdin f.in = os.Stdin
f.out = os.Stdout f.out = os.Stdout
m.Cap(ice.CTX_STREAM, "stdio") m.Cap(ice.CTX_STREAM, "stdio")
default:
if n, e := os.Open(arg[0]); m.Warn(e != nil, "%s", e) {
return true
} else {
f.in = n
f.out = os.Stderr
m.Cap(ice.CTX_STREAM, arg[0])
}
} }
f.count = 0 f.count = 0
@ -105,6 +113,9 @@ var Index = &ice.Context{Name: "ssh", Help: "终端模块",
m.Done() m.Done()
} }
}}, }},
"scan": {Name: "scan", Help: "解析", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Starts(arg[0], arg[1], arg[2:]...)
}},
}, },
} }

View File

@ -828,7 +828,8 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
m.Sort("status") m.Sort("status")
}}, }},
ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Meta: kit.Dict("remote", "you", "exports", []string{"hot", "favor"}, "detail", []string{"执行", "编辑", "收录", "下载"}), List: kit.List( ice.WEB_FAVOR: {Name: "favor", Help: "收藏夹", Meta: kit.Dict("remote", "you", "exports", []string{"hot", "favor"},
"detail", []string{"执行", "编辑", "收录", "导出", "下载"}), List: kit.List(
kit.MDB_INPUT, "text", "name", "hot", "action", "auto", kit.MDB_INPUT, "text", "name", "hot", "action", "auto",
kit.MDB_INPUT, "text", "name", "id", "action", "auto", kit.MDB_INPUT, "text", "name", "id", "action", "auto",
kit.MDB_INPUT, "button", "value", "查看", "action", "auto", kit.MDB_INPUT, "button", "value", "查看", "action", "auto",
@ -858,6 +859,8 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
case "执行": case "执行":
m.Event(ice.FAVOR_START, m.Option("you"), kit.Select(m.Option("hot"), arg[3], arg[2] == "favor")) m.Event(ice.FAVOR_START, m.Option("you"), kit.Select(m.Option("hot"), arg[3], arg[2] == "favor"))
arg = arg[:0] arg = arg[:0]
case "导出":
arg = []string{"export", m.Option("hot")}
} }
} }
@ -876,8 +879,9 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
if len(arg) == 1 { if len(arg) == 1 {
m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.MDB_HASH, kit.MDB_HASH, "favor.json") m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.MDB_HASH, kit.MDB_HASH, "favor.json")
} else { } else {
m.Option("cache.limit", "1000")
m.Richs(ice.WEB_FAVOR, nil, arg[1], func(key string, value map[string]interface{}) { m.Richs(ice.WEB_FAVOR, nil, arg[1], func(key string, value map[string]interface{}) {
m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key, kit.MDB_LIST), kit.MDB_LIST, arg[1]+".csv") m.Cmdy(ice.MDB_EXPORT, ice.WEB_FAVOR, kit.Keys(kit.MDB_HASH, key), kit.MDB_LIST, arg[1]+".csv")
}) })
} }
return return
@ -1028,7 +1032,8 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
m.Push("data", h) m.Push("data", h)
} }
}}, }},
ice.WEB_STORY: {Name: "story", Help: "故事会", Meta: kit.Dict("remote", "you", "exports", []string{"top", "story"}, "detail", []string{"归档", "共享", "下载"}), List: kit.List( ice.WEB_STORY: {Name: "story", Help: "故事会", Meta: kit.Dict("remote", "you", "exports", []string{"top", "story"},
"detail", []string{"归档", "共享", "导出", "下载"}), List: kit.List(
kit.MDB_INPUT, "text", "name", "top", "action", "auto", kit.MDB_INPUT, "text", "name", "top", "action", "auto",
kit.MDB_INPUT, "text", "name", "list", "action", "auto", kit.MDB_INPUT, "text", "name", "list", "action", "auto",
kit.MDB_INPUT, "button", "value", "查看", "action", "auto", kit.MDB_INPUT, "button", "value", "查看", "action", "auto",
@ -1048,6 +1053,11 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
msg.Append("story"), arg[3], "pod", pod, "data", arg[3]) msg.Append("story"), arg[3], "pod", pod, "data", arg[3])
return return
} }
case "导出":
switch arg[2] {
case "story", "list":
arg = []string{ice.STORY_WATCH, arg[3], m.Option("story")}
}
} }
} }
@ -1177,6 +1187,7 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
case ice.STORY_WATCH: case ice.STORY_WATCH:
msg := m.Cmd(ice.WEB_STORY, "index", arg[1]) msg := m.Cmd(ice.WEB_STORY, "index", arg[1])
name := kit.Select(arg[1], arg, 2) name := kit.Select(arg[1], arg, 2)
os.Remove(kit.Keys(name, "bak"))
os.Rename(name, kit.Keys(name, "bak")) os.Rename(name, kit.Keys(name, "bak"))
if msg.Append("file") != "" { if msg.Append("file") != "" {
os.Link(msg.Append("file"), name) os.Link(msg.Append("file"), name)
@ -1211,7 +1222,11 @@ var Index = &ice.Context{Name: "web", Help: "网络模块",
} }
// 保存数据 // 保存数据
if m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), nil) == nil { if m.Richs(ice.WEB_CACHE, nil, kit.Select("", arg, 3), func(key string, value map[string]interface{}) {
if len(arg) > 3 {
arg[3] = key
}
}) == nil {
m.Cmdy(ice.WEB_CACHE, arg) m.Cmdy(ice.WEB_CACHE, arg)
arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")} arg = []string{arg[0], m.Append("type"), m.Append("name"), m.Append("data")}
} }

View File

@ -35,6 +35,17 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "favor") m.Cmd(ice.WEB_FAVOR, "river.root", "field", "favor")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "story") m.Cmd(ice.WEB_FAVOR, "river.root", "field", "story")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "share") m.Cmd(ice.WEB_FAVOR, "river.root", "field", "share")
m.Cmd(ice.WEB_FAVOR, "river.root", "storm", "misc")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "buffer", "cli.tmux")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "session", "cli.tmux")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "image", "cli.docker")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "container", "cli.docker")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "command", "cli.docker")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "repos", "cli.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "total", "cli.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "branch", "cli.git")
m.Cmd(ice.WEB_FAVOR, "river.root", "field", "status", "cli.git")
} }
// 用户权限 // 用户权限
@ -46,6 +57,8 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/action") m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "/action")
m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "dream") m.Cmd(ice.AAA_ROLE, "white", ice.ROLE_VOID, "enable", "dream")
m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "dream.停止") m.Cmd(ice.AAA_ROLE, "black", ice.ROLE_VOID, "enable", "dream.停止")
m.Cmd(ice.AAA_USER, "first", m.Conf(ice.CLI_RUNTIME, "boot.username"))
} }
}}, }},
@ -95,6 +108,7 @@ var Index = &ice.Context{Name: "chat", Help: "聊天中心",
m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"])) m.Option(ice.MSG_USERROLE, m.Cmdx(ice.AAA_ROLE, "check", value["username"]))
storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", kit.Select(arg[1], value["nickname"])+"@"+m.Conf(ice.CLI_RUNTIME, "boot.hostname"), m.Option(ice.MSG_USERNAME))) storm, river := "", m.Option(ice.MSG_RIVER, m.Cmdx("/ocean", "spawn", kit.Select(arg[1], value["nickname"])+"@"+m.Conf(ice.CLI_RUNTIME, "boot.hostname"), m.Option(ice.MSG_USERNAME)))
m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) { m.Richs(ice.WEB_FAVOR, nil, kit.Keys("river", m.Option(ice.MSG_USERROLE)), func(key string, value map[string]interface{}) {
m.Option("cache.limit", "100")
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) { m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) {
switch value["type"] { switch value["type"] {
case "storm": case "storm":

View File

@ -37,8 +37,8 @@ var Index = &ice.Context{Name: "code", Help: "编程中心",
kit.MDB_HASH, kit.Dict( kit.MDB_HASH, kit.Dict(
"system", kit.Dict( "system", kit.Dict(
kit.MDB_LIST, kit.List( kit.MDB_LIST, kit.List(
kit.MDB_INPUT, "bin", "file", "ice.sh", "path", "ice.sh", kit.MDB_INPUT, "bin", "file", "ice.sh", "path", "bin/ice.sh",
kit.MDB_INPUT, "bin", "file", "ice.bin", "path", "ice.bin", kit.MDB_INPUT, "bin", "file", "ice.bin", "path", "bin/ice.bin",
), ),
), ),
), ),
@ -48,7 +48,7 @@ var Index = &ice.Context{Name: "code", Help: "编程中心",
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "load", "code.json") m.Cmd(ice.CTX_CONFIG, "load", "code.json")
m.Watch(ice.SYSTEM_INIT, "compile", "linux") m.Watch(ice.SYSTEM_INIT, "compile", "linux")
m.Watch(ice.SYSTEM_INIT, "publish", "ice.sh") m.Watch(ice.SYSTEM_INIT, "publish", "bin/ice.sh")
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "code.json", "web.code.login") m.Cmd(ice.CTX_CONFIG, "save", "code.json", "web.code.login")
@ -62,7 +62,7 @@ var Index = &ice.Context{Name: "code", Help: "编程中心",
} }
// 编译目标 // 编译目标
main := kit.Select("main.go", arg, 2) main := kit.Select("src/main.go", arg, 2)
arch := kit.Select(m.Conf(ice.CLI_RUNTIME, "host.GOARCH"), arg, 1) arch := kit.Select(m.Conf(ice.CLI_RUNTIME, "host.GOARCH"), arg, 1)
goos := kit.Select(m.Conf(ice.CLI_RUNTIME, "host.GOOS"), arg, 0) goos := kit.Select(m.Conf(ice.CLI_RUNTIME, "host.GOOS"), arg, 0)
file := path.Join(m.Conf("compile", "meta.path"), kit.Keys("ice", goos, arch)) file := path.Join(m.Conf("compile", "meta.path"), kit.Keys("ice", goos, arch))

View File

@ -22,12 +22,6 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心",
if m.Richs(ice.WEB_SPIDE, nil, "12306", nil) == nil { if m.Richs(ice.WEB_SPIDE, nil, "12306", nil) == nil {
m.Cmd(ice.WEB_SPIDE, "add", "12306", "https://kyfw.12306.cn") m.Cmd(ice.WEB_SPIDE, "add", "12306", "https://kyfw.12306.cn")
} }
if !m.Confs("railway", "meta.site") {
list := strings.Split(strings.TrimPrefix(m.Cmdx(ice.WEB_SPIDE, "12306", "raw", "GET", "/otn/resources/js/framework/station_name.js?station_version=1.9090"), "var statuion_names ='"), "|")
for i := 0; i < len(list)-5; i += 5 {
m.Conf("railway", kit.Keys("meta.site", list[i+1]), list[i+2])
}
}
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Cmd(ice.CTX_CONFIG, "save", "mall.json", "web.mall.railway") m.Cmd(ice.CTX_CONFIG, "save", "mall.json", "web.mall.railway")
@ -57,6 +51,13 @@ var Index = &ice.Context{Name: "mall", Help: "贸易中心",
kit.MDB_INPUT, "text", "name", "to", "value", "曲阜", kit.MDB_INPUT, "text", "name", "to", "value", "曲阜",
kit.MDB_INPUT, "button", "name", "查询", kit.MDB_INPUT, "button", "name", "查询",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
if !m.Confs("railway", "meta.site") {
list := strings.Split(strings.TrimPrefix(m.Cmdx(ice.WEB_SPIDE, "12306", "raw", "GET", "/otn/resources/js/framework/station_name.js?station_version=1.9090"), "var statuion_names ='"), "|")
for i := 0; i < len(list)-5; i += 5 {
m.Conf("railway", kit.Keys("meta.site", list[i+1]), list[i+2])
}
}
date := time.Now().Add(time.Hour * 24).Format("2006-01-02") date := time.Now().Add(time.Hour * 24).Format("2006-01-02")
if len(arg) > 0 { if len(arg) > 0 {
date, arg = arg[0], arg[1:] date, arg = arg[0], arg[1:]

View File

@ -32,8 +32,10 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
m.Cmd(ice.CTX_CONFIG, "save", "team.json", "web.team.miss") m.Cmd(ice.CTX_CONFIG, "save", "team.json", "web.team.miss")
}}, }},
ice.APP_MISS: {Name: "miss", Help: "任务", Meta: kit.Dict( ice.APP_MISS: {Name: "miss", Help: "任务", Meta: kit.Dict("remote", "you"), List: kit.List(
"remote", "you", kit.MDB_INPUT, "text", "name", "id",
kit.MDB_INPUT, "button", "name", "执行",
kit.MDB_INPUT, "button", "name", "返回", "cb", "Last",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
hot := kit.Select(ice.FAVOR_MISS, m.Option("hot")) hot := kit.Select(ice.FAVOR_MISS, m.Option("hot"))
if len(arg) > 1 { if len(arg) > 1 {
@ -59,11 +61,20 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
}) })
return return
} }
if len(arg) == 1 {
// 任务详情
m.Richs(ice.WEB_FAVOR, nil, hot, func(key string, value map[string]interface{}) {
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "id", arg[0], func(index int, value map[string]interface{}) {
m.Push("detail", value)
})
})
return
}
// 添加任务 // 添加任务
m.Cmdy(ice.WEB_FAVOR, hot, ice.TYPE_DRIVE, arg[0], arg[1], m.Cmdy(ice.WEB_FAVOR, hot, ice.TYPE_DRIVE, arg[0], arg[1],
"begin_time", m.Time(), "close_time", m.Time(), "begin_time", m.Time(), "close_time", m.Time(),
"status", kit.Select("准备中", arg, 3), "status", kit.Select("准备中", arg, 2),
) )
}}, }},
"date": {Name: "date", Help: "日历", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { "date": {Name: "date", Help: "日历", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
@ -109,11 +120,20 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
} }
}}, }},
"stat": {Name: "stat", Help: "统计", Meta: kit.Dict( "stat": {Name: "stat", Help: "统计", Meta: kit.Dict(
"display", "demo.wasm",
// "display", "github.com/shylinux/icebergs/core/team/stat", // "display", "github.com/shylinux/icebergs/core/team/stat",
), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) { ), Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
m.Push("weekly", 10) hot := kit.Select(ice.FAVOR_MISS, m.Option("hot"))
m.Push("month", 100) stat := map[string]int{}
m.Push("year", 1000) m.Option("cache.limit", "1000")
m.Richs(ice.WEB_FAVOR, nil, hot, func(key string, value map[string]interface{}) {
m.Grows(ice.WEB_FAVOR, kit.Keys("hash", key), "", "", func(index int, value map[string]interface{}) {
stat[kit.Format(kit.Value(value, "extra.status"))] += 1
})
})
for k, v := range stat {
m.Push(k, v)
}
}}, }},
"progress": {Name: "progress", Help: "进度", Meta: kit.Dict( "progress": {Name: "progress", Help: "进度", Meta: kit.Dict(
"remote", "you", "remote", "you",
@ -135,11 +155,13 @@ var Index = &ice.Context{Name: "team", Help: "团队中心",
} }
if next := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "next")); next != "" { if next := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "next")); next != "" {
value["status"] = next value["status"] = next
kit.Value(value, "change.-2", kit.Dict("time", m.Time(), "status", next))
} }
case "回退": case "回退":
if prev := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "prev")); prev != "" { if prev := m.Conf(ice.APP_MISS, kit.Keys("meta.fsm", value["status"], "prev")); prev != "" {
value["status"] = prev value["status"] = prev
kit.Value(value, "change.-2", kit.Dict("time", m.Time(), "status", prev))
} }
case "取消": case "取消":

View File

@ -1,2 +0,0 @@
all:
go build -o bin/ice.bin main.go && chmod u+x bin/ice.bin && ./ice.sh restart

View File

@ -1,62 +0,0 @@
#! /bin/sh
ice_sh=${ice_sh:="ice.sh"}
prepare() {
[ -f main.go ] || cat >> main.go <<END
package main
import (
"github.com/shylinux/icebergs"
_ "github.com/shylinux/icebergs/base"
_ "github.com/shylinux/icebergs/core"
_ "github.com/shylinux/icebergs/misc"
)
func main() {
println(ice.Run())
}
END
[ -f go.mod ] || go mod init ${PWD##**/}
[ -f ${ice_sh} ] || cat >> ${ice_sh} <<END
#! /bin/sh
export PATH=\${PWD}/bin:\${PWD}:\$PATH
prepare() {
which ice.bin && return
curl -s https://shylinux.com/publish/ice.bin -o bin/ice.bin
}
start() {
prepare && while true; do
date && ice.bin \$@ 2>boot.log && echo -e "\n\nrestarting..." || break
done
}
restart() {
kill -2 \`cat var/run/shy.pid\`
}
shutdown() {
kill -3 \`cat var/run/shy.pid\`
}
cmd=\$1 && shift
[ -z "\$cmd" ] && cmd=start
\$cmd \$*
END
chmod u+x ${ice_sh}
[ -f Makefile ] || cat >> Makefile <<END
all:
go build -o bin/ice.bin main.go && chmod u+x bin/ice.bin && ./${ice_sh} restart
END
}
build() {
[ "$1" != "" ] && mdkir $1 && cd $1
prepare && go build -o bin/ice.bin main.go && chmod u+x bin/ice.bin && ./${ice_sh}
}
cmd=$1 && shift
[ -z "$cmd" ] && cmd=build
$cmd $*

View File

@ -1,13 +0,0 @@
module github.com/shylinux/icebergs/demo
go 1.13
require (
github.com/shylinux/icebergs v0.0.0-20191212145348-fe6226481eaa
github.com/shylinux/toolkits v0.0.0-20191225132906-3c11db083b5b
)
replace (
github.com/shylinux/icebergs => ../
github.com/shylinux/toolkits => ../../toolkits
)

View File

@ -1,12 +0,0 @@
package main
import (
"github.com/shylinux/icebergs"
_ "github.com/shylinux/icebergs/base"
_ "github.com/shylinux/icebergs/core"
_ "github.com/shylinux/icebergs/misc"
)
func main() {
println(ice.Run())
}

View File

@ -1,53 +0,0 @@
# {{title "hello world"}}
{{shell "开机时长" "" "uptime"}}
{{title "premenu"}}
## {{chapter "项目总览"}}
{{order "总览" `
volcano iceberg
context toolkit
preload appframe
`}}
{{table "总览" `
volcano iceberg
context toolkit
preload appframe
`}}
## {{chapter "项目详情"}}
{{chain "详情" `
context
volcanos
proto.js
frame.js bg blue
Page
Pane
Plugin
Inputs
Output
order.js
icebergs bg blue
type.go
base.go bg red
code
wiki
chat
team
mall
conf.go
toolkits
type.go
core.go bg blue
Split
Parse
Value
Fetch
Favor
misc.go
`}}
{{title "endmenu"}}

View File

@ -16,43 +16,71 @@ var Index = &ice.Context{Name: "docker", Help: "容器管理",
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}}, ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {}},
"docker": {Name: "docker", Help: "docker", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "image": {Name: "image", Help: "镜像管理", Meta: kit.Dict("detail", []string{"运行", "清理", "删除"}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Echo("hello world")
}},
"image": {Name: "image", Help: "镜像管理", Meta: kit.Dict(
"detail", []string{"运行", "清理", "删除"},
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "docker", "image"} prefix := []string{ice.CLI_SYSTEM, "docker", "image"}
if len(arg) > 2 { if len(arg) > 2 {
switch arg[1] { switch arg[1] {
case "运行": case "运行":
m.Cmdy(prefix[:2], "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")) m.Cmdy(prefix[:2], "run", "-dt", m.Option("REPOSITORY")+":"+m.Option("TAG")).Set("append")
m.Set("append")
return return
case "清理": case "清理":
m.Cmd(prefix, "prune", "-f") m.Cmdy(prefix, "prune", "-f").Set("append")
return
case "delete": case "delete":
switch arg[2] { m.Cmdy(prefix, "rm", m.Option("IMAGE_ID")).Set("append")
case "NAMES": return
m.Cmd(prefix, "rename", arg[4], arg[3])
}
} }
} }
if len(arg) > 0 {
// 下载镜像
m.Cmdy(prefix, "pull", arg[0]+":"+kit.Select("latest", arg, 1)).Set("append")
return
}
// 镜像列表
m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n") m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "IMAGE ID", "IMAGE_ID", 1), "index", " ", "\n")
m.Sort("REPOSITORY")
}}, }},
"container": {Name: "container", Help: "容器管理", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "container": {Name: "container", Help: "容器管理", Meta: kit.Dict(
"exports", []string{"CONTAINER_ID", "CONTAINER_ID"},
"detail", []string{"进入", "启动", "停止", "重启", "清理", "编辑", "删除"}), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "docker", "container"} prefix := []string{ice.CLI_SYSTEM, "docker", "container"}
if len(arg) > 2 { if len(arg) > 2 {
switch arg[1] { switch arg[1] {
case "进入":
m.Cmdy(ice.CLI_SYSTEM, "tmux", "new-window", "-t", "", "-n", m.Option("NAMES"),
"-PF", "#{session_name}:#{window_name}.1", "docker exec -it "+m.Option("NAMES")+" sh").Set("append")
return
case "停止":
m.Cmd(prefix, "stop", m.Option("CONTAINER_ID"))
case "启动":
m.Cmd(prefix, "start", m.Option("CONTAINER_ID"))
case "重启":
m.Cmd(prefix, "restart", m.Option("CONTAINER_ID"))
case "清理":
m.Cmd(prefix, "prune", "-f")
case "modify": case "modify":
switch arg[2] { switch arg[2] {
case "NAMES": case "NAMES":
m.Cmd(prefix, "rename", arg[4], arg[3]) m.Cmd(prefix, "rename", arg[4], arg[3])
} }
case "delete":
m.Cmdy(prefix, "rm", m.Option("CONTAINER_ID")).Set("append")
return
} }
} }
m.Split(strings.Replace(m.Cmdx(prefix, "ls"), "CONTAINER ID", "CONTAINER_ID", 1), "index", " ", "\n")
// 容器列表
m.Split(strings.Replace(m.Cmdx(prefix, "ls", "-a"), "CONTAINER ID", "CONTAINER_ID", 1), "index", " ", "\n")
m.Sort("NAMES")
}},
"command": {Name: "command", Help: "命令", List: kit.List(
kit.MDB_INPUT, "text", "name", "CONTAINER_ID", "imports", "CONTAINER_ID",
kit.MDB_INPUT, "text", "name", "command",
kit.MDB_INPUT, "button", "name", "执行",
), Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "docker", "container"}
m.Cmdy(prefix, "exec", arg[0], arg[1:]).Set("append")
}}, }},
}, },
} }

View File

@ -5,6 +5,7 @@ import (
"github.com/shylinux/icebergs/base/cli" "github.com/shylinux/icebergs/base/cli"
"github.com/shylinux/toolkits" "github.com/shylinux/toolkits"
"os" "os"
"path"
"strings" "strings"
"time" "time"
) )
@ -21,14 +22,93 @@ var Index = &ice.Context{Name: "git", Help: "代码管理",
"name", "volcanos", "path", "usr/volcanos", "branch", "master", "name", "volcanos", "path", "usr/volcanos", "branch", "master",
"remote", "https://github.com/shylinux/volcanos", "remote", "https://github.com/shylinux/volcanos",
)) ))
m.Rich("repos", nil, kit.Data(
"name", "icebergs", "path", "../../icebergs", "branch", "master",
"remote", "https://github.com/shylinux/icebergs",
))
m.Rich("repos", nil, kit.Data(
"name", "toolkits", "path", "../../toolkits", "branch", "master",
"remote", "https://github.com/shylinux/toolkits",
))
m.Rich("repos", nil, kit.Data(
"name", "contexts", "path", "../../contexts", "branch", "master",
"remote", "https://github.com/shylinux/context",
))
m.Cmd("nfs.dir", m.Conf(ice.WEB_DREAM, "meta.path"), "name path").Table(func(index int, value map[string]string, head []string) {
if s, e := os.Stat(path.Join(value["path"], ".git")); e == nil && s.IsDir() {
m.Rich("repos", nil, kit.Data(
"name", value["name"], "path", value["path"], "branch", "master",
"remote", m.Cmdx(ice.CLI_SYSTEM, "git", "remote", "get-url", "origin"),
))
}
})
m.Watch(ice.SYSTEM_INIT, "cli.git.check", "volcanos") m.Watch(ice.SYSTEM_INIT, "cli.git.check", "volcanos")
}}, }},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}}, }},
"repos": {Name: "repos", Help: "仓库", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs("repos", nil, "*", func(key string, value map[string]interface{}) {
m.Push(key, value["meta"], []string{"time", "name", "branch", "path", "remote"})
})
m.Sort("name")
}},
"branch": {Name: "branch", Help: "分支", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "git", "branch"}
m.Richs("repos", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) {
m.Option("cmd_dir", kit.Value(value, "meta.path"))
for _, v := range strings.Split(m.Cmdx(prefix, "-v"), "\n") {
if len(v) > 0 {
m.Push("repos", kit.Value(value, "meta.name"))
m.Push("tags", v[:2])
vs := strings.SplitN(strings.TrimSpace(v[2:]), " ", 2)
m.Push("branch", vs[0])
vs = strings.SplitN(strings.TrimSpace(vs[1]), " ", 2)
m.Push("hash", vs[0])
m.Push("note", strings.TrimSpace(vs[1]))
}
}
})
m.Sort("repos")
}},
"status": {Name: "status", Help: "状态", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, "git", "status"}
m.Richs("repos", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) {
m.Option("cmd_dir", kit.Value(value, "meta.path"))
for _, v := range strings.Split(strings.TrimSpace(m.Cmdx(prefix, "-sb")), "\n") {
vs := strings.SplitN(strings.TrimSpace(v), " ", 2)
m.Push("repos", kit.Value(value, "meta.name"))
m.Push("tags", vs[0])
m.Push("file", vs[1])
}
})
}},
"total": {Name: "total", Help: "统计", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
days := 0
commit, adds, dels, rest := 0, 0, 0, 0
m.Richs("repos", nil, kit.Select("*", arg, 0), func(key string, value map[string]interface{}) {
m.Push("repos", kit.Value(value, "meta.name"))
m.Copy(m.Cmd("sum", "total", kit.Value(value, "meta.path"), "10000").Table(func(index int, value map[string]string, head []string) {
if kit.Int(value["days"]) > days {
days = kit.Int(value["days"])
}
commit += kit.Int(value["commit"])
adds += kit.Int(value["adds"])
dels += kit.Int(value["dels"])
rest += kit.Int(value["rest"])
}))
})
m.Push("repos", "total")
m.Push("days", days)
m.Push("commit", commit)
m.Push("adds", adds)
m.Push("dels", dels)
m.Push("rest", rest)
m.Sort("commit", "int_r")
}},
"check": {Name: "check", Help: "检查", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) { "check": {Name: "check", Help: "检查", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Richs("repos", nil, arg[0], func(key string, value map[string]interface{}) { m.Richs("repos", nil, arg[0], func(key string, value map[string]interface{}) {
if _, e := os.Stat(kit.Format(kit.Value(value, "meta.path"))); e != nil && os.IsNotExist(e) { if _, e := os.Stat(kit.Format(kit.Value(value, "meta.path"))); e != nil && os.IsNotExist(e) {
m.Cmd("cli.system", "git", "clone", kit.Value(value, "meta.remote"), m.Cmd(ice.CLI_SYSTEM, "git", "clone", kit.Value(value, "meta.remote"),
"-b", kit.Value(value, "meta.branch"), kit.Value(value, "meta.path")) "-b", kit.Value(value, "meta.branch"), kit.Value(value, "meta.path"))
} }
}) })

View File

@ -1,6 +1,7 @@
package misc package misc
import ( import (
_ "github.com/shylinux/icebergs/misc/docker"
_ "github.com/shylinux/icebergs/misc/git" _ "github.com/shylinux/icebergs/misc/git"
_ "github.com/shylinux/icebergs/misc/tmux" _ "github.com/shylinux/icebergs/misc/tmux"
) )

View File

@ -244,7 +244,10 @@ var Index = &ice.Context{Name: "tmux", Help: "终端管理",
} }
m.Option("cmd_env", "TMUX", "") m.Option("cmd_env", "TMUX", "")
m.Option("cmd_dir", path.Join(m.Conf(ice.WEB_DREAM, "meta.path"), arg[0])) p := path.Join(m.Conf(ice.WEB_DREAM, "meta.path"), arg[0])
if s, e := os.Stat(p); e == nil && s.IsDir() {
m.Option("cmd_dir", p)
}
// 创建会话 // 创建会话
if m.Cmd(prefix, "has-session", "-t", arg[0]).Append("code") != "0" { if m.Cmd(prefix, "has-session", "-t", arg[0]).Append("code") != "0" {

3
miss/Makefile Normal file
View File

@ -0,0 +1,3 @@
all:
@echo && date
go build -o bin/ice.bin src/main.go && chmod u+x bin/ice.bin && ./bin/ice.sh restart

View File

@ -1,5 +1,5 @@
# {{title "ICEBERGS"}} {{title "ICEBERGS"}}
icebergs是一个后端框架通过模块化、集群化实现资源的无限的扩展与自由的组合。 {{brief `icebergs是一个后端框架通过模块化、集群化实现资源的无限的扩展与自由的组合。`}}
{{chain "icebergs" ` {{chain "icebergs" `
icebergs icebergs
@ -41,85 +41,85 @@ icebergs
file file
` "" "" 16}} ` "" "" 16}}
一键创建项目 {{shell "一键创建项目" "usr" "install" `mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh`}}
```
mkdir miss; cd miss && curl -s https://shylinux.com/publish/build.sh | sh
```
一键启动项目
```
mkdir miss; cd miss && curl -s https://shylinux.com/publish/ice.sh | sh
```
## {{chapter "配置模块 base/ctx"}} {{shell "一键启动项目" "usr" "install" `mkdir miss; cd miss && curl -s https://shylinux.com/publish/ice.sh | sh`}}
## {{chapter "命令模块 base/cli"}} {{chapter "配置模块 base/ctx"}}
{{chapter "命令模块 base/cli"}}
cli模块用于与系统进行交互。 cli模块用于与系统进行交互。
- 系统信息 ice.CLI_RUNTIME {{order "命令" `
- 系统命令 ice.CLI_SYSTEM 系统信息 ice.CLI_RUNTIME
系统命令 ice.CLI_SYSTEM
`}}
## {{chapter "通信模块 base/tcp"}} {{chapter "通信模块 base/tcp"}}
tcp模块用于管理网络的读写 tcp模块用于管理网络的读写
## {{chapter "存储模块 base/nfs"}} {{chapter "存储模块 base/nfs"}}
nfs模块用于管理文件的读写。 nfs模块用于管理文件的读写。
## {{chapter "终端模块 base/ssh"}} {{chapter "终端模块 base/ssh"}}
ssh模块用于与终端交互。 ssh模块用于与终端交互。
## {{chapter "数据模块 base/mdb"}} {{chapter "数据模块 base/mdb"}}
mdb模块用于管理数据的读写。 mdb模块用于管理数据的读写。
## {{chapter "词法模块 base/lex"}} {{chapter "词法模块 base/lex"}}
## {{chapter "语法模块 base/yac"}} {{chapter "语法模块 base/yac"}}
## {{chapter "日志模块 base/log"}} {{chapter "日志模块 base/log"}}
log模块负责输出日志。 log模块负责输出日志。
## {{chapter "事件模块 base/gdb"}} {{chapter "事件模块 base/gdb"}}
gdb模块会根据各种触发条件择机执行各种命令。 gdb模块会根据各种触发条件择机执行各种命令。
- 信号器 ice.SIGNAL {{order "命令" `
- 定时器 ice.TIMER 信号器 ice.SIGNAL
- 触发器 ice.EVENT 定时器 ice.TIMER
触发器 ice.EVENT
`}}
## {{chapter "认证模块 base/aaa"}} {{chapter "认证模块 base/aaa"}}
aaa模块用于各种权限管理与身份认证。 aaa模块用于各种权限管理与身份认证。
- 角色 ice.AAA_ROLE {{order "命令" `
- 用户 ice.AAA_USER 角色 ice.AAA_ROLE
- 会话 ice.AAA_SESS 用户 ice.AAA_USER
会话 ice.AAA_SESS
`}}
## {{chapter "网络模块 base/web"}} {{chapter "网络模块 base/web"}}
web模块用于组织网络节点与生成前端网页 web模块用于组织网络节点与生成前端网页
### {{section "网络爬虫 ice.WEB_SPIDE"}} {{section "网络爬虫 ice.WEB_SPIDE"}}
WEB_SPIDE功能用于发送网络请求获取相关数据。 WEB_SPIDE功能用于发送网络请求获取相关数据。
### {{section "网络服务 ice.WEB_SERVE"}} {{section "网络服务 ice.WEB_SERVE"}}
WEB_SERVE功能用于启动网络服务器接收网络请求。 WEB_SERVE功能用于启动网络服务器接收网络请求。
### {{section "网络节点 ice.WEB_SPACE"}} {{section "网络节点 ice.WEB_SPACE"}}
WEB_SPACE功能用于与相连网络节点进行通信。 WEB_SPACE功能用于与相连网络节点进行通信。
### {{section "网络任务 ice.WEB_DREAM"}} {{section "网络任务 ice.WEB_DREAM"}}
WEB_DREAM功能用于启动本地节点管理各种任务的相关资源。 WEB_DREAM功能用于启动本地节点管理各种任务的相关资源。
### {{section "网络收藏 ice.WEB_FAVOR"}} {{section "网络收藏 ice.WEB_FAVOR"}}
WEB_FAVOR功能用于收藏各种实时数据进行分类管理。 WEB_FAVOR功能用于收藏各种实时数据进行分类管理。
### {{section "网络缓存 ice.WEB_CACHE"}} {{section "网络缓存 ice.WEB_CACHE"}}
WEB_CACHE功能用于管理缓存数据自动存储与传输。 WEB_CACHE功能用于管理缓存数据自动存储与传输。
### {{section "网络存储 ice.WEB_STORY"}} {{section "网络存储 ice.WEB_STORY"}}
WEB_STORY功能用于记录数据的历史变化可以查看任意历史版本。 WEB_STORY功能用于记录数据的历史变化可以查看任意历史版本。
### {{section "网络共享 ice.WEB_SHARE"}} {{section "网络共享 ice.WEB_SHARE"}}
WEB_SHARE功能用于数据与应用的共享可以查到所有数据流通记录。 WEB_SHARE功能用于数据与应用的共享可以查到所有数据流通记录。
### {{section "网络路由 ice.WEB_ROUTE"}} {{section "网络路由 ice.WEB_ROUTE"}}
### {{section "网络代理 ice.WEB_PROXY"}} {{section "网络代理 ice.WEB_PROXY"}}
### {{section "网络分组 ice.WEB_GROUP"}} {{section "网络分组 ice.WEB_GROUP"}}
### {{section "网络标签 ice.WEB_LABEL"}} {{section "网络标签 ice.WEB_LABEL"}}

View File

@ -1,10 +0,0 @@
module miss
go 1.13
require github.com/shylinux/icebergs v0.1.0
replace (
github.com/shylinux/icebergs => ../
github.com/shylinux/toolkits => ../../toolkits
)

View File

@ -1,14 +0,0 @@
package main
import (
"github.com/shylinux/icebergs"
_ "github.com/shylinux/icebergs/base"
_ "github.com/shylinux/icebergs/core"
_ "github.com/shylinux/icebergs/misc"
_ "github.com/shylinux/icebergs/misc/docker"
)
func main() {
println(ice.Run())
}

View File

@ -1,7 +1,20 @@
#! /bin/sh #! /bin/sh
ice_sh="bin/ice.sh"
ice_bin="bin/ice.bin"
ice_mod="${PWD##**/}"
init_shy="etc/init.shy"
exit_shy="etc/exit.shy"
main_go="src/main.go"
readme="README.md"
prepare() { prepare() {
[ -f main.go ] || cat >> main.go <<END [ -f ${readme} ] || cat >> ${readme} <<END
hello ice world
END
[ -d src ] || mkdir src
[ -f ${main_go} ] || cat >> ${main_go} <<END
package main package main
import ( import (
@ -16,24 +29,32 @@ func main() {
} }
END END
[ -f go.mod ] || go mod init ${PWD##**/} [ -f src/go.mod ] || cd src && go mod init ${ice_mod} && cd ..
[ -f Makefile ] || cat >> Makefile <<END [ -f Makefile ] || cat >> Makefile <<END
all: all:
@echo && date @echo && date
go build -o ice.bin main.go && chmod u+x ice.bin && ./ice.sh restart go build -o ${ice_bin} ${main_go} && chmod u+x ${ice_bin} && ./${ice_sh} restart
END END
[ -f ice.sh ] || cat >> ice.sh <<END [ -d etc ] || mkdir etc
[ -f ${init_shy} ] || cat >> ${init_shy} <<END
END
[ -f ${exit_shy} ] || cat >> "${exit_shy}" <<END
END
[ -d bin ] || mkdir bin
[ -f ${ice_sh} ] || cat >> ${ice_sh} <<END
#! /bin/sh #! /bin/sh
export PATH=\${PWD}:\$PATH export PATH=\${PWD}:\${PWD}/bin:\$PATH
export ctx_pid=\${ctx_pid:=var/run/ice.pid} export ctx_pid=\${ctx_pid:=var/run/ice.pid}
export ctx_log=\${ctx_log:=boot.log} export ctx_log=\${ctx_log:=bin/boot.log}
prepare() { prepare() {
[ -e ice.sh ] || curl \$ctx_dev/publish/ice.sh -o ice.sh && chmod u+x ice.sh [ -d etc ] || mkdir bin
[ -e ice.bin ] && chmod u+x ice.bin && return [ -e ${ice_sh} ] || curl \$ctx_dev/publish/ice.sh -o ${ice_sh} && chmod u+x ${ice_sh}
[ -e ${ice_bin} ] && chmod u+x ${ice_bin} && return
bin="ice" bin="ice"
case \`uname -s\` in case \`uname -s\` in
@ -46,11 +67,11 @@ prepare() {
i686) bin=\${bin}.386 ;; i686) bin=\${bin}.386 ;;
arm*) bin=\${bin}.arm ;; arm*) bin=\${bin}.arm ;;
esac esac
curl \$ctx_dev/publish/\${bin} -o ice.bin && chmod u+x ice.bin curl \$ctx_dev/publish/\${bin} -o ${ice_bin} && chmod u+x ${ice_bin}
} }
start() { start() {
trap HUP hup && while true; do trap HUP hup && while true; do
date && ice.bin \$@ 2>\$ctx_log && echo -e "\n\nrestarting..." || break date && ./${ice_bin} \$@ 2>\$ctx_log && echo -e "\n\nrestarting..." || break
done done
} }
serve() { serve() {
@ -66,12 +87,12 @@ shutdown() {
cmd=\$1 && [ -n "\$cmd" ] && shift || cmd=serve cmd=\$1 && [ -n "\$cmd" ] && shift || cmd=serve
\$cmd \$* \$cmd \$*
END END
chmod u+x ice.sh chmod u+x ${ice_sh}
} }
build() { build() {
miss=./ && [ "$1" != "" ] && miss=$1 && shift && mkdir $miss miss=./ && [ "$1" != "" ] && miss=$1 && shift && mkdir $miss
cd $miss && prepare && go build -o ice.bin main.go && chmod u+x ice.bin && ./ice.sh start serve dev cd $miss && prepare && go build -o ${ice_bin} ${main_go} && chmod u+x ${ice_bin} && ./${ice_sh} start serve dev
} }
tutor() { tutor() {

43
type.go
View File

@ -100,6 +100,16 @@ func (c *Context) Register(s *Context, x Server) *Context {
return s return s
} }
func (c *Context) Spawn(m *Message, name string, help string, arg ...string) *Context {
s := &Context{Name: name, Help: help, Caches: map[string]*Cache{}}
if m.target.Server != nil {
c.Register(s, m.target.server.Spawn(m, s, arg...))
} else {
c.Register(s, nil)
}
m.target = s
return s
}
func (c *Context) Begin(m *Message, arg ...string) *Context { func (c *Context) Begin(m *Message, arg ...string) *Context {
c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""} c.Caches[CTX_STATUS] = &Cache{Name: CTX_STATUS, Value: ""}
c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""} c.Caches[CTX_STREAM] = &Cache{Name: CTX_STREAM, Value: ""}
@ -357,6 +367,7 @@ func (m *Message) Copy(msg *Message) *Message {
} }
func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message { func (m *Message) Push(key string, value interface{}, arg ...interface{}) *Message {
switch value := value.(type) { switch value := value.(type) {
case map[string]string:
case map[string]interface{}: case map[string]interface{}:
if key == "detail" { if key == "detail" {
value = kit.KeyValue(map[string]interface{}{}, "", value) value = kit.KeyValue(map[string]interface{}{}, "", value)
@ -555,8 +566,30 @@ func (m *Message) Render(str string, arg ...interface{}) *Message {
return m return m
} }
func (m *Message) Split(str string, field string, space string, enter string) *Message { func (m *Message) Split(str string, field string, space string, enter string) *Message {
indexs := []int{}
fields := kit.Split(field, space) fields := kit.Split(field, space)
for _, l := range kit.Split(str, enter) { for i, l := range kit.Split(str, enter) {
if i == 0 && (field == "" || field == "index") {
fields = kit.Split(l, space)
if field == "index" {
for _, v := range fields {
indexs = append(indexs, strings.Index(l, v))
}
}
continue
}
if len(indexs) > 0 {
for i, v := range indexs {
if i == len(indexs)-1 {
m.Push(kit.Select("some", fields, i), l[v:])
} else {
m.Push(kit.Select("some", fields, i), l[v:indexs[i+1]])
}
}
continue
}
for i, v := range kit.Split(l, space) { for i, v := range kit.Split(l, space) {
m.Push(kit.Select("some", fields, i), v) m.Push(kit.Select("some", fields, i), v)
} }
@ -762,6 +795,10 @@ func (m *Message) Start(key string, arg ...string) *Message {
}) })
return m return m
} }
func (m *Message) Starts(name string, help string, arg ...string) *Message {
m.target.Spawn(m, name, help, arg...).Begin(m, arg...).Start(m, arg...)
return m
}
func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message { func (m *Message) Call(sync bool, cb func(*Message) *Message) *Message {
if sync { if sync {
wait := make(chan bool) wait := make(chan bool)
@ -779,6 +816,10 @@ func (m *Message) Back(sub *Message) *Message {
} }
return m return m
} }
func (m *Message) Sleep(arg string) *Message {
time.Sleep(kit.Duration(arg))
return m
}
func (m *Message) Travel(cb interface{}) *Message { func (m *Message) Travel(cb interface{}) *Message {
list := []*Context{m.target} list := []*Context{m.target}