diff --git a/base/cli/system.go b/base/cli/system.go index 2a3c442e..39e69e29 100644 --- a/base/cli/system.go +++ b/base/cli/system.go @@ -143,6 +143,8 @@ const ( CMD_OUT = "cmd_out" SH = "sh" + GO = "go" + GIT = "git" MAN = "man" RUN = "run" KILL = "kill" diff --git a/base/mdb/zone.go b/base/mdb/zone.go index ac7decdf..071296cb 100644 --- a/base/mdb/zone.go +++ b/base/mdb/zone.go @@ -55,6 +55,7 @@ func _zone_select(m *ice.Message, prefix, chain, zone string, id string) { Grows(m, prefix, chain, ID, id, func(value ice.Map) { _mdb_select(m, m.OptionCB(""), key, value, fields, val) }) + m.StatusTimeCountTotal(val[COUNT], "step", "0") }) } func _zone_export(m *ice.Message, prefix, chain, file string) { @@ -236,13 +237,14 @@ func ZoneModify(m *ice.Message, arg ...Any) { } func ZoneSelect(m *ice.Message, arg ...string) *ice.Message { arg = kit.Slice(arg, 0, 2) - m.Fields(len(arg), kit.Select(kit.Fields(TIME, Config(m, SHORT), COUNT), Config(m, FIELD)), ZoneField(m)) + short, field, fields := Config(m, SHORT), Config(m, FIELD), ZoneField(m) + m.Fields(len(arg), kit.Select(kit.Fields(TIME, short, COUNT), field), fields) if m.Cmdy(SELECT, m.PrefixKey(), "", ZONE, arg, logs.FileLineMeta(-1)); len(arg) == 0 { - m.Sort(ZoneShort(m)).PushAction(Config(m, ACTION), REMOVE).Action(CREATE) + m.Sort(short).PushAction(REMOVE).Action(CREATE) } else if len(arg) == 1 { - m.Action(INSERT).StatusTimeCountTotal(_zone_meta(m, m.PrefixKey(), kit.Keys(HASH, HashSelectField(m, arg[0], HASH)), COUNT), "step", "0") + m.Action(INSERT) } else { - sortByField(m, ZoneField(m)) + sortByField(m, fields) } return m } diff --git a/base/tcp/host.go b/base/tcp/host.go index 8f7e1105..e566693f 100644 --- a/base/tcp/host.go +++ b/base/tcp/host.go @@ -51,10 +51,11 @@ const ( MAC_ADDRESS = "mac-address" MASK = "mask" + DOMAIN = "domain" + GATEWAY = "gateway" + MACHINE = "machine" ISLOCAL = "islocal" PUBLISH = "publish" - GATEWAY = "gateway" - DOMAIN = "domain" ) const HOST = "host" diff --git a/base/web/dream.go b/base/web/dream.go index 4297aeba..7f376954 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -370,7 +370,7 @@ func init() { }}, VERSION: {Hand: func(m *ice.Message, arg ...string) { m.Cmdy("web.code.version") }}, FOR_FLOW: {Name: "forFlow name cmd*='sh etc/miss.sh'", Help: "流程", Icon: "bi bi-terminal", Hand: func(m *ice.Message, arg ...string) { - m.Options(ctx.DISPLAY, PLUGIN_XTERM, cli.CMD_OUTPUT, nfs.NewWriteCloser(func(buf []byte) (int, error) { + m.Options(ctx.DISPLAY, html.PLUGIN_XTERM, cli.CMD_OUTPUT, nfs.NewWriteCloser(func(buf []byte) (int, error) { PushNoticeGrow(m.Options( ice.MSG_COUNT, "0", ice.LOG_DEBUG, ice.FALSE, diff --git a/base/web/html/html.go b/base/web/html/html.go index ae90738a..ab60697d 100644 --- a/base/web/html/html.go +++ b/base/web/html/html.go @@ -84,12 +84,14 @@ const ( REFRESH = "refresh" CONFIRM = "confirm" - PLUGIN_LOCAL_CODE_INNER = "/plugin/local/code/inner.js" - PLUGIN_STORY_JSON = "/plugin/story/json.js" + PLUGIN_JSON = "/plugin/story/json.js" + PLUGIN_INNER = "/plugin/local/code/inner.js" + PLUGIN_XTERM = "/plugin/local/code/xterm.js" + ICONS_SSH = "usr/icons/ssh.png" + ICONS_MAIL = "usr/icons/Mail.png" + ICONS_DREAM = "usr/icons/Launchpad.png" + ICONS_SETTINGS = "usr/icons/System Settings.png" - ICONS_MAIL = "usr/icons/Mail.png" - ICONS_DREAM = "usr/icons/Launchpad.png" - ICONS_SETTINGS = "usr/icons/System Settings.png" GetLocation = "getLocation" ConnectWifi = "ConnectWifi" GetClipboardData = "getClipboardData" diff --git a/base/web/render.go b/base/web/render.go index a8067400..1d394991 100644 --- a/base/web/render.go +++ b/base/web/render.go @@ -199,13 +199,11 @@ const ( CHAT_POD = "web.chat.pod" CHAT_CMD = "web.chat.cmd" TEAM_PLAN = "web.team.plan" - - PLUGIN_XTERM = "/plugin/local/code/xterm.js" ) func MessageInsertJSON(m *ice.Message, zone, name, text string, arg ...string) { MessageInsert(m, zone, kit.Simple(mdb.TYPE, html.TEXT, mdb.NAME, kit.Select(m.CommandKey(), name), - mdb.TEXT, text, ctx.DISPLAY, html.PLUGIN_STORY_JSON, arg)...) + mdb.TEXT, text, ctx.DISPLAY, html.PLUGIN_JSON, arg)...) } func MessageInsert(m *ice.Message, zone string, arg ...string) { m.Cmd(MESSAGE, mdb.INSERT, zone, tcp.DIRECT, tcp.RECV, arg) diff --git a/core/wiki/spark.go b/core/wiki/spark.go index d178e3b7..9933aa03 100644 --- a/core/wiki/spark.go +++ b/core/wiki/spark.go @@ -95,7 +95,7 @@ func init() { arg = append(arg, kit.Simple(ctx.ARGS, kit.Join(nfs.SplitPath(m, p), lex.SP))...) arg[0] = m.Cmdx(nfs.CAT, p) } - m.Cmdy(FIELD, "", web.CODE_INNER, ice.MSG_RESULT, arg[0], ctx.DISPLAY, html.PLUGIN_LOCAL_CODE_INNER, ctx.STYLE, html.OUTPUT, arg[1:]) + m.Cmdy(FIELD, "", web.CODE_INNER, ice.MSG_RESULT, arg[0], ctx.DISPLAY, html.PLUGIN_INNER, ctx.STYLE, html.OUTPUT, arg[1:]) }}, PROJECT: {Hand: func(m *ice.Message, arg ...string) { _spark_project(m, arg...) }}, PRODUCT: {Hand: func(m *ice.Message, arg ...string) { _spark_product(m, arg...) }}, diff --git a/misc/ssh/relay/relay.go b/misc/ssh/relay/relay.go index 01c26e98..0f2b25a0 100644 --- a/misc/ssh/relay/relay.go +++ b/misc/ssh/relay/relay.go @@ -38,15 +38,15 @@ const ( const ( MACHINE = "machine" PACKAGE = "package" - KERNEL = "kernel" SHELL = "shell" + KERNEL = "kernel" ARCH = "arch" - NCPU = "ncpu" VCPU = "vcpu" + NCPU = "ncpu" MHZ = "mhz" MEM = "mem" - MEM_FREE = "mem_free" MEM_TOTAL = "mem_total" + MEM_FREE = "mem_free" DISK = "disk" DISK_USED = "disk_used" DISK_TOTAL = "disk_total" @@ -61,34 +61,29 @@ type relay struct { ice.Code checkbox string `data:"true"` short string `data:"machine"` - tools string `data:"ssh.matrix"` - field string `data:"time,icons,machine,username,host,port,portal,dream,module,version,commitTime,compileTime,bootTime,go,git,package,shell,kernel,arch,ncpu,vcpu,mhz,mem,disk,network,listen,socket,proc,vendor"` - statsTables string `name:"statsTables" event:"stats.tables"` - create string `name:"create machine* username* host* port*=22" icons` + field string `data:"time,icons,machine,username,host,port,portal,dream,module,version,commitTime,compileTime,bootTime,go,git,package,shell,kernel,arch,vcpu,ncpu,mhz,mem,disk,network,listen,socket,proc,vendor"` + create string `name:"create host* port=22 username machine icons"` stats string `name:"stats machine" help:"采集" icon:"bi bi-card-list"` - dream string `name:"dream" help:"空间" icon:"bi bi-grid-3x3-gap"` + publish string `name:"publish" help:"发布" icon:"bi bi-send-check"` + pubkey string `name:"pubkey" help:"公钥" icon:"bi bi-person-vcard"` forEach string `name:"forEach machine cmd*:textarea=pwd"` forFlow string `name:"forFlow machine cmd*:textarea=pwd"` - pubkey string `name:"pubkey" help:"公钥" icon:"bi bi-person-vcard"` - publish string `name:"publish" help:"发布" icon:"bi bi-send-check"` + statsTables string `name:"statsTables" event:"stats.tables"` list string `name:"list machine auto" help:"机器" icon:"relay.png"` - install string `name:"install dream param" help:"安装"` + install string `name:"install dream param='forever start' dev portal=9020 nodename" help:"安装"` pushbin string `name:"pushbin dream param" help:"部署" icon:"bi bi-box-arrow-in-up"` adminCmd string `name:"adminCmd cmd" help:"命令" icon:"bi bi-terminal-plus"` } -func (s relay) StatsTables(m *ice.Message, arg ...string) { - web.PushStats(m.Message, "", mdb.HashSelects(m.Spawn().Message).Length(), "", "服务器数量") -} func (s relay) Init(m *ice.Message, arg ...string) { - s.Hash.Init(m).TransInput(MACHINE, "机器", - PACKAGE, "软件包", SHELL, "命令行", KERNEL, "内核", ARCH, "架构", - NCPU, "处理器", VCPU, "虚拟核", MHZ, "频率", - MEM, "内存", DISK, "磁盘", NETWORK, "流量", - LISTEN, "服务", SOCKET, "连接", PROC, "进程", + s.Hash.Init(m).TransInput( + MACHINE, "机器", + PACKAGE, "软件包", SHELL, "命令行", KERNEL, "内核", ARCH, "架构", VCPU, "虚拟核", NCPU, "处理器", MHZ, "频率", + MEM, "内存", DISK, "磁盘", NETWORK, "流量", LISTEN, "服务", SOCKET, "连接", PROC, "进程", + ice.DEV, "上位机", tcp.NODENAME, "节点名", ) - msg := m.Spawn(ice.Maps{ice.MSG_FIELDS: ""}) - m.GoSleep3s(func() { s.Hash.List(msg).Table(func(value ice.Maps) { s.xterm(m.Spawn(value)) }) }) + msg := m.Spawn() + m.GoSleep3s(func() { s.Hash.List(msg).Table(func(value ice.Maps) { s.xterm(msg.Spawn(value)) }) }) } func (s relay) Inputs(m *ice.Message, arg ...string) { switch s.Hash.Inputs(m, arg...); arg[0] { @@ -102,19 +97,31 @@ func (s relay) Inputs(m *ice.Message, arg ...string) { m.Message.Copy(m.Options(ice.MSG_FIELDS, web.CLIENT_HOSTNAME).Cmd(web.SPIDE).CutTo(web.CLIENT_HOSTNAME, arg[0])) case tcp.PORT: m.Push(arg[0], tcp.PORT_22, tcp.PORT_9022) + case cli.PARAM: + m.Push(arg[0], `forever start`) + case ice.DEV: + s.Hash.List(m).CutTo(web.LINK, arg[0]) + m.Push(arg[0], "http://localhost:9020") case web.PORTAL: kit.If(m.Option(tcp.LISTEN), func(p string) { m.Push(arg[0], kit.Split(p)) }) - m.Push(arg[0], tcp.PORT_443, tcp.PORT_80, tcp.PORT_9020) - case cli.PARAM: - m.Push(arg[0], `forever start dev "" port 9020`) + m.Push(arg[0], tcp.PORT_443, tcp.PORT_80, tcp.PORT_9020, "9030", "9040", "9050") } } +func (s relay) Create(m *ice.Message, arg ...string) { + s.Hash.Create(m, kit.Simple(arg, + tcp.PORT, m.OptionDefault(tcp.PORT, tcp.PORT_22), + aaa.USERNAME, m.OptionDefault(aaa.USERNAME, m.Option(ice.MSG_USERNAME)), + tcp.MACHINE, m.OptionDefault(tcp.MACHINE, kit.Split(m.Option(tcp.HOST), nfs.PT)[0]), + mdb.ICONS, m.OptionDefault(mdb.ICONS, html.ICONS_SSH), + )...) +} func (s relay) Stats(m *ice.Message) { - cmds := []string{"go", `go version`, "git", `git version`, + cmds := []string{ + cli.GO, `go version`, cli.GIT, `git version`, PACKAGE, `if yum -h &>/dev/null; then echo yum; elif apk version &>/dev/null; then echo apk; elif opkg -v &>/dev/null; then echo opkg; elif apt -h &>/dev/null; then echo apt; fi`, SHELL, `echo $SHELL`, KERNEL, `uname -s`, ARCH, `uname -m`, - NCPU, `cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l`, VCPU, `cat /proc/cpuinfo | grep "processor" | sort | uniq | wc -l`, + NCPU, `cat /proc/cpuinfo | grep "physical id" | sort | uniq | wc -l`, MHZ, `cat /proc/cpuinfo | grep "\(cpu MHz\|BogoMIPS\)" | grep -o "[0-9.]\+" | sort -nr | head -n1`, MEM, `cat /proc/meminfo | head -n3 | grep -o "[0-9.]*"`, DISK, `df | grep "^/dev/"`, NETWORK, `cat /proc/net/dev | grep "eth0\|eth1" | sort -r | head -n1`, @@ -122,8 +129,8 @@ func (s relay) Stats(m *ice.Message) { SOCKET, `netstat -nt 2>/dev/null | grep "^tcp" | wc -l`, PROC, `ps aux | wc -l 2>/dev/null`, } trans := map[string]func([]string) string{ - "go": func(ls []string) string { return kit.Select("", ls, 2) }, - "git": func(ls []string) string { return kit.Select("", ls, 2) }, + cli.GO: func(ls []string) string { return kit.TrimPrefix(kit.Select("", ls, 2), cli.GO) }, + cli.GIT: func(ls []string) string { return kit.Select("", ls, 2) }, MEM: func(ls []string) string { return kit.FmtSize(kit.Int(kit.Select("", ls, 2))*1024, kit.Int(kit.Select("", ls, 0))*1024) }, @@ -133,9 +140,7 @@ func (s relay) Stats(m *ice.Message) { NETWORK: func(ls []string) string { return kit.FmtSize(kit.Int(kit.Select("", ls, 1)), kit.Int(kit.Select("", ls, 9))) }, - PROC: func(ls []string) string { - return kit.Format(kit.Int(ls[0])) - }, + PROC: func(ls []string) string { return kit.Format(kit.Int(ls[0])) }, } machine := m.Option(MACHINE) m.GoToast(func(toast func(string, int, int)) { @@ -145,70 +150,34 @@ func (s relay) Stats(m *ice.Message) { }) }).ProcessInner() s.foreach(m.Spawn(ice.Maps{MACHINE: machine}), func(msg *ice.Message, cmd []string) { - ssh.CombinedOutput(msg.Message, s.admins(msg, cli.RUNTIME), func(res string) { + msg.CombinedOutput(s.admins(msg, cli.RUNTIME), func(res string) { if !strings.HasPrefix(res, "warn: ") { s.Modify(m, kit.Simple(MACHINE, msg.Option(MACHINE), kit.Dict(cli.ParseMake(res)))...) } }) }) } -func (s relay) Dream(m *ice.Message) { - if m.Option(web.PORTAL) != "" { - m.ProcessOpen(web.HostPort(m.Message, m.Option(tcp.HOST), m.Option(web.PORTAL), "", web.DREAM)) +func (s relay) Publish(m *ice.Message, arg ...string) { + if m.Option(MACHINE) == "" { + s.Hash.ForEach(m, "", func(msg *ice.Message) { s.Publish(msg) }) + m.Cmdy(nfs.DIR, ice.USR_PUBLISH).Set(ctx.ACTION) return } - s.foreach(m, func(msg *ice.Message, cmd []string) { - ssh.CombinedOutput(msg.Message, s.admins(msg, cli.RUNTIME), func(res string) { - if !strings.HasPrefix(res, "warn: ") { - s.Modify(m, kit.Simple(MACHINE, msg.Option(MACHINE), kit.Dict(cli.ParseMake(res)))...) - } - }) - }) - - fields := "time,machine,host,space,type,status,module,version,commitTime,compileTime,bootTime,link,icons" - s.foreach(m, func(msg *ice.Message, cmd []string) { - m.Push("", kit.Dict(msg.OptionSimple(fields), mdb.TYPE, web.SERVER, mdb.STATUS, web.ONLINE, web.SPACE, ice.CONTEXTS, web.LINK, web.HostPort(m.Message, msg.Option(tcp.HOST), msg.Option(web.PORTAL))), kit.Split(fields)) - ssh.CombinedOutput(msg.Message, s.admins(msg, web.ROUTE), func(res string) { - _msg := m.Spawn().SplitIndex(res) - m.Message.Copy(_msg.Table(func(value ice.Maps) { - switch _msg.Push(MACHINE, msg.Option(MACHINE)).Push(tcp.HOST, msg.Option(tcp.HOST)); msg.Option(web.PORTAL) { - case "": - _msg.Push(web.LINK, "") - default: - _msg.Push(web.LINK, web.HostPort(m.Message, msg.Option(tcp.HOST), msg.Option(web.PORTAL), value[web.SPACE])) - } - }).Cut(fields)) - }) - }) - - m.Push(MACHINE, tcp.LOCALHOST).Push(tcp.HOST, tcp.PublishLocalhost(m.Message, tcp.LOCALHOST)) - m.Push("", kit.Dict(cli.ParseMake(m.AdminCmd(cli.RUNTIME).Result()), ice.SPACE, ice.CONTEXTS), kit.Split("time,space,module,version,commitTime,compileTime,bootTime")) - m.Push(mdb.TYPE, web.SERVER).Push(mdb.STATUS, web.ONLINE).Push(web.LINK, web.UserHost(m.Message)) - m.Push(mdb.ICONS, ice.SRC_MAIN_ICO) - _msg := m.AdminCmd(web.ROUTE) - m.Message.Copy(_msg.Table(func(value ice.Maps) { - _msg.Push(MACHINE, tcp.LOCALHOST).Push(tcp.HOST, tcp.PublishLocalhost(m.Message, tcp.LOCALHOST)) - _msg.Push(web.LINK, web.UserHost(m.Message)+web.S(value[web.SPACE])) - }).Cut(fields)) - - m.RewriteAppend(func(value, key string, index int) string { - if key == mdb.ICONS { - if value == "" { - value = kit.MergeURL2(m.Appendv(web.LINK)[index], nfs.REQUIRE+nfs.USR_ICONS_ICEBERGS) - } else if strings.HasPrefix(value, nfs.REQUIRE) && m.Appendv(MACHINE)[index] != tcp.LOCALHOST { - value = kit.MergeURL2(m.Appendv(web.LINK)[index], value) - } else if kit.HasPrefix(value, nfs.USR, nfs.SRC) { - value = m.Option(ice.MSG_USERHOST) + nfs.REQUIRE + value - } - } - return value - }).Action(s.Dream, "filter:text").Options(ice.MSG_PROCESS, "") + kit.If(!nfs.Exists(m.Message, path.Join(ice.USR_PUBLISH, RELAY)), func() { s.Compile(m) }) + os.Symlink(RELAY, ice.USR_PUBLISH+m.Option(MACHINE)) + m.Cmd(nfs.SAVE, kit.HomePath(".ssh/"+m.Option(MACHINE)+".json"), kit.Formats(kit.Dict(m.OptionSimple("username,host,port")))+ice.NL) +} +func (s relay) Compile(m *ice.Message) { + m.Cmdy(code.COMPILE, SRC_RELAY_GO, path.Join(ice.USR_PUBLISH, RELAY)).ProcessInner() +} +func (s relay) Pubkey(m *ice.Message, arg ...string) { + m.EchoScript(m.Cmdx(nfs.CAT, kit.HomePath(ssh.ID_RSA_PUB))).ProcessInner() } func (s relay) ForEach(m *ice.Message, arg ...string) *ice.Message { s.foreach(m, func(msg *ice.Message, cmd []string) { kit.For(cmd, func(cmd string) { begin := time.Now() - ssh.CombinedOutput(msg.Message, cmd, func(res string) { + msg.CombinedOutput(cmd, func(res string) { m.Push(mdb.TIME, begin.Format(ice.MOD_TIME)) m.Push(MACHINE, msg.Option(MACHINE)).Push(tcp.HOST, msg.Option(tcp.HOST)) m.Push(cli.COST, kit.FmtDuration(time.Now().Sub(begin))) @@ -221,32 +190,19 @@ func (s relay) ForEach(m *ice.Message, arg ...string) *ice.Message { func (s relay) ForFlow(m *ice.Message) { s.foreach(m, func(msg *ice.Message, cmd []string) { ssh.PushShell(msg.Message, cmd, func(res string) { - web.PushNoticeGrow(m.Options(ctx.DISPLAY, web.PLUGIN_XTERM).Message, res) + web.PushNoticeGrow(m.Options(ctx.DISPLAY, html.PLUGIN_XTERM).Message, res) }) }) } -func (s relay) Compile(m *ice.Message) { - m.Cmdy(code.COMPILE, SRC_RELAY_GO, path.Join(ice.USR_PUBLISH, RELAY)).ProcessInner() -} -func (s relay) Publish(m *ice.Message, arg ...string) { - if m.Option(MACHINE) == "" { - s.Hash.ForEach(m, "", func(msg *ice.Message) { s.Publish(msg) }) - m.Cmdy(nfs.DIR, ice.USR_PUBLISH).Set(ctx.ACTION) - return - } - kit.If(!nfs.Exists(m.Message, path.Join(ice.USR_PUBLISH, RELAY)), func() { s.Compile(m) }) - os.Symlink(RELAY, ice.USR_PUBLISH+m.Option(MACHINE)) - m.Cmd(nfs.SAVE, kit.HomePath(".ssh/"+m.Option(MACHINE)+".json"), kit.Formats(kit.Dict(m.OptionSimple("username,host,port")))+ice.NL) -} -func (s relay) Pubkey(m *ice.Message, arg ...string) { - m.EchoScript(m.Cmdx(nfs.CAT, kit.HomePath(ssh.ID_RSA_PUB))).ProcessInner() +func (s relay) StatsTables(m *ice.Message, arg ...string) { + web.PushStats(m.Message, "", mdb.HashSelects(m.Spawn().Message).Length(), "", "服务器数量") } func (s relay) List(m *ice.Message, arg ...string) *ice.Message { if s.Hash.List(m, arg...); len(arg) == 0 { if m.Length() == 0 { m.Action(s.Create) } else { - m.Action(s.Create, s.Upgrade, s.Version, s.Stats, s.Dream) + m.Action(s.Create, s.Upgrade, s.Version, s.Stats, s.Publish) } } stats := map[string]int{} @@ -267,7 +223,7 @@ func (s relay) List(m *ice.Message, arg ...string) *ice.Message { return } m.Push(web.LINK, web.HostPort(m.Message, value[tcp.HOST], value[web.PORTAL])) - m.PushButton(s.Admin, s.Dream, s.Vimer, s.Login, s.Upgrade, s.Pushbin, s.AdminCmd, s.Xterm, s.Remove) + m.PushButton(s.Portal, s.Desktop, s.Dream, s.Admin, s.Vimer, s.Login, s.AdminCmd, s.Upgrade, s.Pushbin, s.Xterm, s.Remove) kit.If(len(arg) > 0, func() { m.PushQRCode(cli.QRCODE, m.Append(web.LINK)) }) }) _stats := kit.Dict(MEM, kit.FmtSize(stats[MEM_FREE], stats[MEM_TOTAL]), DISK, kit.FmtSize(stats[DISK_USED], stats[DISK_TOTAL])) @@ -282,6 +238,17 @@ func (s relay) List(m *ice.Message, arg ...string) *ice.Message { }) return m } +func (s relay) Install(m *ice.Message, arg ...string) { + m.Options(web.DOMAIN, m.SpideOrigin(ice.SHY), ice.MSG_USERPOD, m.Option(web.DREAM)) + m.Options(nfs.SOURCE, kit.Value(kit.UnMarshal(m.AdminCmd(cli.RUNTIME).Result()), "make.remote")) + m.Spawn().DreamList().Table(func(value ice.Maps) { + kit.If(value[mdb.NAME] == m.Option(web.DREAM), func() { m.Option(nfs.SOURCE, value[nfs.REPOS]) }) + }) + s.shell(m, m.PublishScript(nfs.SOURCE)+lex.SP+kit.JoinCmds(ice.DEV, m.Option(ice.DEV), tcp.PORT, m.Option(web.PORTAL), tcp.NODENAME, m.OptionDefault(tcp.NODENAME, m.Option(MACHINE))), arg...) + s.Modify(m, kit.Simple(m.OptionSimple(MACHINE, web.DREAM, web.PORTAL))...) +} +func (s relay) Upgrade(m *ice.Message, arg ...string) { s.foreachScript(m, UPGRADE_SH, arg...) } +func (s relay) Version(m *ice.Message, arg ...string) { s.foreachScript(m, VERSION_SH, arg...) } func (s relay) Pushbin(m *ice.Message, arg ...string) { bin := "ice" switch m.Option(KERNEL) { @@ -306,78 +273,85 @@ func (s relay) Pushbin(m *ice.Message, arg ...string) { s.shell(m, m.Template(PUSHBIN_SH), arg...) s.Modify(m, kit.Simple(m.OptionSimple(MACHINE, web.DREAM))...) } + +func (s relay) AdminCmd(m *ice.Message, arg ...string) { + s.shell(m, "cd "+kit.Select(ice.CONTEXTS, m.Option(web.DREAM))+"; "+s.admin(m, m.Option(ice.CMD)), arg...) +} +func (s relay) Xterm(m *ice.Message, arg ...string) { + m.ProcessXterm(kit.JoinWord(m.Option(MACHINE), + ice.INIT, kit.Format("%q", "cd "+kit.Select(ice.CONTEXTS, m.Option(web.DREAM))), + ), arg...) +} func (s relay) Login(m *ice.Message, arg ...string) { if m.Options(s.Hash.List(m.Spawn(), m.Option(MACHINE)).AppendSimple()); m.Option(ice.BACK) == "" { - defer web.ToastProcess(m.Message)() - ssh.CombinedOutput(m.Message, s.admins(m, kit.JoinCmds(web.CHAT_HEADER, mdb.CREATE, + defer m.ToastProcess()() + m.CombinedOutput(s.admins(m, kit.JoinCmds(web.HEADER, mdb.CREATE, "--", mdb.TYPE, "oauth", mdb.NAME, m.CommandKey(), mdb.ICONS, "usr/icons/ssh.png", mdb.ORDER, "100", web.LINK, m.MergePodCmd("", "", ctx.ACTION, m.ActionKey(), MACHINE, m.Option(MACHINE)), )), func(res string) { m.ProcessHold() }) - m.ProcessOpen(kit.MergeURL2(m.Option(mdb.LINK), web.C(web.CHAT_HEADER))) + m.ProcessOpen(kit.MergeURL2(m.Option(mdb.LINK), web.C(web.HEADER))) } else if m.Option(ice.MSG_METHOD) == http.MethodGet { m.EchoInfoButton("") } else { - defer web.ToastProcess(m.Message)() - ssh.CombinedOutput(m.Message, s.admins(m, kit.JoinCmds(web.SHARE, mdb.CREATE, mdb.TYPE, aaa.LOGIN, "--", mdb.TEXT, m.Option(ice.BACK))), func(res string) { + defer m.ToastProcess()() + m.CombinedOutput(s.admins(m, kit.JoinCmds(web.SHARE, mdb.CREATE, mdb.TYPE, aaa.LOGIN, "--", mdb.TEXT, m.Option(ice.BACK))), func(res string) { m.ProcessReplace(kit.MergeURL2(m.Option(ice.BACK), "/share/"+strings.TrimSpace(res))) }) } } -func (s relay) Install(m *ice.Message, arg ...string) { - m.Options(web.DOMAIN, "https://shylinux.com", ice.MSG_USERPOD, m.Option(web.DREAM)) - m.Options(nfs.SOURCE, kit.Value(kit.UnMarshal(web.AdminCmd(m.Message, cli.RUNTIME).Result()), "make.remote")) - web.DreamList(m.Spawn().Message).Table(func(value ice.Maps) { - kit.If(value[mdb.NAME] == m.Option(web.DREAM), func() { m.Option(nfs.SOURCE, value[nfs.REPOS]) }) - }) - s.shell(m, m.Cmdx(web.CODE_PUBLISH, ice.CONTEXTS, nfs.SOURCE, kit.Dict("format", "raw")), arg...) - s.Modify(m, kit.Simple(m.OptionSimple(MACHINE, web.DREAM))...) -} -func (s relay) Upgrade(m *ice.Message, arg ...string) { - m.Option(ice.MSG_TITLE, kit.Keys(m.Option(ice.MSG_USERPOD), m.CommandKey(), m.ActionKey())) - if len(arg) == 0 && (m.Option(MACHINE) == "" || strings.Contains(m.Option(MACHINE), ",")) { - s.foreach(m, func(msg *ice.Message, cmd []string) { - if msg.Option("go") == "" { - return - } - ssh.PushShell(msg.Message, strings.Split(msg.Template(UPGRADE_SH), lex.NL), func(res string) { - web.PushNoticeGrow(m.Options( - ctx.DISPLAY, web.PLUGIN_XTERM, - ice.MSG_COUNT, "0", - ice.MSG_DEBUG, ice.FALSE, - ice.LOG_DISABLE, ice.TRUE, - ).Message, res) - }) - }) - } else { - s.shell(m, m.Template(UPGRADE_SH), arg...) - } -} -func (s relay) Version(m *ice.Message, arg ...string) { - m.Option(ice.MSG_TITLE, kit.Keys(m.Option(ice.MSG_USERPOD), m.CommandKey(), m.ActionKey())) - s.foreach(m, func(msg *ice.Message, cmd []string) { - if msg.Option("go") == "" { - return - } - ssh.PushShell(msg.Message, strings.Split(msg.Template(VERSION_SH), lex.NL), func(res string) { - web.PushNoticeGrow(m.Options( - ctx.DISPLAY, web.PLUGIN_XTERM, - ice.MSG_COUNT, "0", - ice.MSG_DEBUG, ice.FALSE, - ice.LOG_DISABLE, ice.TRUE, - ).Message, res) - }) - }) -} -func (s relay) AdminCmd(m *ice.Message, arg ...string) { - s.shell(m, s.admins(m, m.Option(ice.CMD)), arg...) -} -func (s relay) Xterm(m *ice.Message, arg ...string) { s.Code.Xterm(m, m.Option(MACHINE), arg...) } -func (s relay) Repos(m *ice.Message, arg ...string) { s.iframeCmd(m, web.CODE_GIT_STATUS, arg...) } -func (s relay) Vimer(m *ice.Message, arg ...string) { s.iframeCmd(m, web.CODE_VIMER, arg...) } -func (s relay) Admin(m *ice.Message, arg ...string) { s.iframeCmd(m, web.ADMIN, arg...) } +func (s relay) Repos(m *ice.Message, arg ...string) { s.iframe(m, web.CODE_GIT_STATUS, arg...) } +func (s relay) Vimer(m *ice.Message, arg ...string) { s.iframe(m, "", arg...) } +func (s relay) Admin(m *ice.Message, arg ...string) { s.iframe(m, "", arg...) } +func (s relay) Dream(m *ice.Message, arg ...string) { s.iframe(m, "", arg...) } +func (s relay) Desktop(m *ice.Message, arg ...string) { s.iframe(m, "", arg...) } +func (s relay) Portal(m *ice.Message, arg ...string) { s.iframe(m, "", arg...) } func init() { ice.Cmd("ssh.relay", relay{}) } +func (s relay) iframe(m *ice.Message, cmd string, arg ...string) { + p := kit.MergeURL2(m.Option(web.LINK), web.C(kit.Select(m.ActionKey(), cmd))) + if strings.HasPrefix(m.Option(ice.MSG_USERWEB), ice.HTTPS) { + m.ProcessIframe(m.Option(MACHINE), p, arg...) + } else { + m.ProcessOpen(p) + } +} +func (s relay) shell(m *ice.Message, init string, arg ...string) { + m.ProcessXterm(kit.JoinWord(m.Option(MACHINE), ice.INIT, kit.Format("%q", strings.ReplaceAll(init, lex.NL, "; "))), arg...) +} +func (s relay) foreachScript(m *ice.Message, script string, arg ...string) { + m.Option(ice.MSG_TITLE, kit.Keys(m.Option(ice.MSG_USERPOD), m.CommandKey(), m.ActionKey())) + if len(arg) == 0 && (m.Option(MACHINE) == "" || strings.Contains(m.Option(MACHINE), ",")) { + s.foreach(m, func(msg *ice.Message, cmd []string) { + if msg.Option(cli.GO) == "" { + return + } + ssh.PushShell(msg.Message, strings.Split(msg.Template(script), lex.NL), func(res string) { + web.PushNoticeGrow(m.Options(ctx.DISPLAY, html.PLUGIN_XTERM, ice.MSG_COUNT, "0", ice.MSG_DEBUG, ice.FALSE, ice.LOG_DISABLE, ice.TRUE).Message, res) + }) + }) + } else { + s.shell(m, m.Template(script), arg...) + } +} +func (s relay) foreachModify(m *ice.Message, machine, key, cmd string, cb func([]string) string) { + kit.If(cb == nil, func() { cb = func(ls []string) string { return kit.Join(ls) } }) + s.ForEach(m.Spawn(ice.Maps{MACHINE: machine, ice.CMD: cmd, ice.MSG_DAEMON: ""})).Table(func(value ice.Maps) { + s.Modify(m, MACHINE, value[MACHINE], key, cb(kit.Split(value[ice.RES])), mdb.TIME, time.Now().Format(ice.MOD_TIME)) + m.Push(mdb.TIME, time.Now().Format(ice.MOD_TIME)).Push(MACHINE, value[MACHINE]).Push(tcp.HOST, value[tcp.HOST]) + m.Push(ice.CMD, cmd).Push(ice.RES, value[ice.RES]).PushButton(s.ForFlow, s.ForEach) + }) +} +func (s relay) foreach(m *ice.Message, cb func(*ice.Message, []string)) { + cmd := kit.Filters(strings.Split(m.Option(ice.CMD), lex.NL), "") + s.Hash.ForEach(m, MACHINE, func(msg *ice.Message) { cb(msg, cmd) }) +} +func (s relay) admins(m *ice.Message, arg ...string) string { + return kit.Select(ice.CONTEXTS, m.Option(web.DREAM)) + nfs.PS + s.admin(m, arg...) +} +func (s relay) admin(m *ice.Message, arg ...string) string { + return kit.JoinWord(kit.Simple(ice.BIN_ICE_BIN, web.ADMIN, arg)...) +} func (s relay) xterm(m *ice.Message) { xterm.AddCommand(m.Option(MACHINE), func(msg *icebergs.Message, arg ...string) (x xterm.XTerm, e error) { m.GoWait(func(done func()) { @@ -395,31 +369,3 @@ func (s relay) xterm(m *ice.Message) { return }) } -func (s relay) shell(m *ice.Message, init string, arg ...string) { - s.Code.Xterm(m, kit.JoinWord(m.Option(MACHINE), ice.INIT, kit.Format("%q", strings.ReplaceAll(init, lex.NL, "; "))), arg...) -} -func (s relay) foreach(m *ice.Message, cb func(*ice.Message, []string)) { - cmd := kit.Filters(strings.Split(m.Option(ice.CMD), lex.NL), "") - s.Hash.ForEach(m, MACHINE, func(msg *ice.Message) { cb(msg, cmd) }) -} -func (s relay) foreachModify(m *ice.Message, machine, key, cmd string, cb func([]string) string) { - kit.If(cb == nil, func() { cb = func(ls []string) string { return kit.Join(ls) } }) - s.ForEach(m.Spawn(ice.Maps{MACHINE: machine, ice.CMD: cmd, ice.MSG_DAEMON: ""})).Table(func(value ice.Maps) { - s.Modify(m, MACHINE, value[MACHINE], key, cb(kit.Split(value[ice.RES])), mdb.TIME, time.Now().Format(ice.MOD_TIME)) - m.Push(mdb.TIME, time.Now().Format(ice.MOD_TIME)).Push(MACHINE, value[MACHINE]).Push(tcp.HOST, value[tcp.HOST]) - m.Push(ice.CMD, cmd).Push(ice.RES, value[ice.RES]).PushButton(s.ForFlow, s.ForEach) - }) -} -func (s relay) iframeCmd(m *ice.Message, cmd string, arg ...string) { - if p := kit.MergeURL2(m.Option(web.LINK), web.C(cmd)); kit.HasPrefix(m.Option(ice.MSG_USERWEB), "https://") { - s.Code.Iframe(m, m.Option(MACHINE), p, arg...) - } else { - m.ProcessOpen(p) - } -} -func (s relay) admin(m *ice.Message, arg ...string) string { - return kit.JoinWord(kit.Simple(ice.BIN_ICE_BIN, web.ADMIN, arg)...) -} -func (s relay) admins(m *ice.Message, arg ...string) string { - return kit.Select(ice.CONTEXTS, m.Option(web.DREAM)) + nfs.PS + s.admin(m, arg...) -}