From 47d01ecea9e482c1191d307d31635994ab16f866 Mon Sep 17 00:00:00 2001 From: shy Date: Sat, 24 Feb 2024 20:39:38 +0800 Subject: [PATCH] add some --- base/cli/runtime.go | 14 +++++++++----- base/web/matrix.go | 3 ++- base/web/route.go | 6 ++++++ misc/ssh/relay/matrix.css | 25 +++++++++++++++++++++++++ misc/ssh/relay/matrix.go | 18 ++++++++++++++++++ misc/ssh/relay/matrix.js | 37 +++++++++++++++++++++++++++++++++++++ misc/ssh/relay/relay.go | 15 ++++++++++----- 7 files changed, 107 insertions(+), 11 deletions(-) create mode 100644 misc/ssh/relay/matrix.css create mode 100644 misc/ssh/relay/matrix.go create mode 100644 misc/ssh/relay/matrix.js diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 3659518a..2d6bff1d 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -270,15 +270,19 @@ func IsWindows() bool { return runtime.GOOS == WINDOWS } func ParseMake(str string) []string { res := kit.UnMarshal(str) data := kit.Value(res, MAKE) + version := kit.Format(kit.Value(data, nfs.VERSION)) + if kit.Format(kit.Value(data, "forword")) != "0" { + version = kit.Join(kit.TrimArg(kit.Simple( + kit.Format(kit.Value(data, nfs.VERSION)), + kit.Format(kit.Value(data, "forword")), + kit.Cut(kit.Format(kit.Value(data, mdb.HASH)), 6), + )...), "-") + } return kit.Simple( mdb.TIME, kit.Format(kit.Value(data, mdb.TIME)), ice.SPACE, kit.Format(kit.Value(res, kit.Keys(NODE, mdb.NAME))), nfs.MODULE, kit.Format(kit.Value(data, nfs.MODULE)), - nfs.VERSION, kit.Join(kit.TrimArg(kit.Simple( - kit.Format(kit.Value(data, nfs.VERSION)), - kit.Format(kit.Value(data, "forword")), - kit.Cut(kit.Format(kit.Value(data, mdb.HASH)), 6), - )...), "-"), + nfs.VERSION, version, COMMIT_TIME, kit.Format(kit.Value(data, "when")), COMPILE_TIME, kit.Format(kit.Value(data, mdb.TIME)), BOOT_TIME, kit.Format(kit.Value(res, kit.Keys(BOOT, mdb.TIME))), diff --git a/base/web/matrix.go b/base/web/matrix.go index 73611391..ea9c132e 100644 --- a/base/web/matrix.go +++ b/base/web/matrix.go @@ -106,7 +106,8 @@ func init() { value = kit.MergeURL(strings.Split(value, "?")[0], ice.POD, kit.Keys(m.Appendv(DOMAIN)[index], m.Appendv(mdb.NAME)[index])) } return value - }).Sort("type,status,name,domain", []string{SERVER, WORKER, ""}, []string{cli.START, cli.STOP, ""}, "str_r", "str_r") + }) + m.Sort("type,status,name,domain", []string{SERVER, WORKER, ""}, []string{cli.START, cli.STOP, ""}, "str_r", "str_r") m.StatusTimeCountStats(mdb.TYPE, mdb.STATUS) return nil }).Action(html.FILTER, mdb.CREATE).Display("") diff --git a/base/web/route.go b/base/web/route.go index adf999cd..1056ed02 100644 --- a/base/web/route.go +++ b/base/web/route.go @@ -142,6 +142,7 @@ func init() { } else { m.OptionFields("") list := m.CmdMap(SPACE, mdb.NAME) + lists := m.CmdMap(DREAM, mdb.NAME) mem, disk, stat := 0, 0, map[string]int{} m.Table(func(value ice.Maps) { disk += kit.Int(kit.Select("", kit.Split(value[nfs.SIZE], nfs.PS), 2)) @@ -153,6 +154,11 @@ func init() { m.Push(mdb.STATUS, OFFLINE) stat[OFFLINE]++ } + if v, ok := lists[value[SPACE]]; ok { + m.Push(mdb.ICONS, v[mdb.ICONS]) + } else { + m.Push(mdb.ICONS, "") + } }).Sort("status,space", ice.STR_R, ice.STR).StatusTimeCount(stat, nfs.SIZE, kit.Format("%s/%s", kit.FmtSize(mem), kit.FmtSize(disk))).Options(ice.MSG_ACTION, "") } }}, diff --git a/misc/ssh/relay/matrix.css b/misc/ssh/relay/matrix.css new file mode 100644 index 00000000..be232485 --- /dev/null +++ b/misc/ssh/relay/matrix.css @@ -0,0 +1,25 @@ +fieldset.ssh.matrix>div.output>table.content th { padding:var(--input-padding); } +fieldset.ssh.matrix>div.output>table.content th i { padding:var(--input-padding); } +fieldset.ssh.matrix>div.output>table.content th i:hover { background-color:var(--hover-bg-color); color:var(--hover-fg-color); } +fieldset.ssh.matrix>div.output>table.content td { padding:var(--input-padding); } +fieldset.ssh.matrix>div.output>table.content td:hover { color:unset; } +fieldset.ssh.matrix>div.output>table.content div.item { display:flex; align-items:center; cursor:default; } +fieldset.ssh.matrix>div.output>table.content div.item img { height:var(--header-height); width:var(--header-height); margin:var(--input-margin); cursor:pointer; } +fieldset.ssh.matrix>div.output>table.content div.item div.title { text-align:left; padding:var(--input-padding); } +fieldset.ssh.matrix>div.output>table.content div.item div.title>span { cursor:pointer; } +fieldset.ssh.matrix>div.output>table.content div.item div.status i { font-size:var(--status-font-size); padding:0; } +fieldset.ssh.matrix>div.output>table.content div.item div.action { margin-top:var(--input-margin); overflow:hidden; } +fieldset.ssh.matrix>div.output>table.content div.item div.action input.icons { display:none; } +fieldset.ssh.matrix>div.output>table.content div.item div.title:hover { background-color:unset; } +fieldset.ssh.matrix>div.output>table.content div.item div.title span:hover { background-color:var(--hover-bg-color); } +fieldset.ssh.matrix>div.output>table.content div.item div.status div.item:hover { background-color:var(--hover-bg-color); } +fieldset.ssh.matrix>div.output>table.content div.item:hover { background-color:unset; color:unset; } +fieldset.ssh.matrix>div.output>table.content div.item.notice { background-color:var(--notice-bg-color); color:var(--notice-fg-color); } +fieldset.ssh.matrix>div.output>table.content div.item.danger { background-color:var(--danger-bg-color); color:var(--danger-fg-color); } +fieldset.ssh.matrix>div.output>table.content div.item.danger div.status div.item { color:var(--danger-fg-color); } +fieldset.ssh.matrix>div.output>table.content div.item.notice div.status div.item { color:var(--notice-fg-color); } +fieldset.ssh.matrix>div.output>table.content div.item.stop div.title>span { color:var(--disable-fg-color); } +fieldset.ssh.matrix>div.output>table.content tr:not(:hover) div.action { visibility:hidden; } +body:not(.mobile) fieldset.ssh.matrix>div.output>table.content th:first-child { position:sticky; left:2px; z-index:2; } +body:not(.mobile) fieldset.ssh.matrix>div.output>table.content td:first-child { background-color:var(--plugin-bg-color); position:sticky; left:2px; z-index:1; } +body:not(.mobile) fieldset.ssh.matrix>div.output>table.content tr.danger td:first-child { background-color:transparent; } diff --git a/misc/ssh/relay/matrix.go b/misc/ssh/relay/matrix.go new file mode 100644 index 00000000..5e13b725 --- /dev/null +++ b/misc/ssh/relay/matrix.go @@ -0,0 +1,18 @@ +package relay + +import ( + "shylinux.com/x/ice" + "shylinux.com/x/icebergs/base/cli" + "shylinux.com/x/icebergs/base/web" +) + +type matrix struct { + list string `data:"list refresh"` +} + +func (s matrix) List(m *ice.Message, arg ...string) *ice.Message { + m.Cmdy("ssh.relay", "dream").Display("") + m.Sort("type,status,space,machine", []string{web.SERVER, web.WORKER, ""}, []string{cli.START, cli.STOP, ""}, "str_r", "str_r") + return m +} +func init() { ice.Cmd("ssh.matrix", matrix{}) } diff --git a/misc/ssh/relay/matrix.js b/misc/ssh/relay/matrix.js new file mode 100644 index 00000000..879e1c71 --- /dev/null +++ b/misc/ssh/relay/matrix.js @@ -0,0 +1,37 @@ +Volcanos(chat.ONIMPORT, { + _init: function(can, msg) { var list = {"contexts": {}}, machine = [] + msg.Table(function(value) { var space = value.space, _machine = value.machine; + machine.indexOf(_machine) == -1 && (machine.push(_machine)) + list[space] = list[space]||{}, list[space][_machine] = value }) + can.ui = can.page.Appends(can, can._output, [{view: [wiki.CONTENT, html.TABLE], list: [ + {type: html.THEAD, list: [{type: html.TR, list: can.core.List(machine, function(machine) { + return {type: html.TH, list: [can.onimport.item(can, list["contexts"][machine], list)]} + }) }]}, + {type: html.TBODY, list: can.core.Item(list, function(space, value) { if (space == "contexts") { return } + return {type: html.TR, list: can.core.List(machine, function(machine) { var item = value[machine] + return {type: html.TD, list: [item? can.onimport.item(can, item, list): can.onimport.void(can, space, machine, list)]} + })} + })}, + ] }]), can.onmotion.delay(can, function() { can.Status(mdb.COUNT, can.core.Item(list).length+"x"+can.core.Item(machine).length) }) + }, + void: function(can, space, machine, list) { + return {view: html.ACTION, _init: function(target) { var worker = list[space]["localhost"], server = list["contexts"][machine] + worker && can.onappend.input(can, {type: html.BUTTON, name: code.INSTALL, onclick: function(event) { + can.Update(can.request(event, {space: space, machine: machine}, worker), [ctx.ACTION, code.INSTALL]) + }}, "", target) + }} + }, + item: function(can, item, list) { + function cb(action) { return function(event) { can.Update(can.request(event, item), [ctx.ACTION, action]) } } + return {view: [[html.ITEM, item.type, item.status, can.onimport.style(can, item, list)]], list: [ + {img: can.misc.Resource(can, item.icons||nfs.USR_ICONS_ICEBERGS, item.machine), onclick: cb(web.DESKTOP)}, {view: wiki.TITLE, list: [ + {text: (item.type == web.SERVER? item.machine: item.space)||location.host, onclick: cb(web.OPEN)}, + item.status != cli.STOP && can.onappend.label(can, item, {version: icon.version, time: icon.compile}), + can.onappend.buttons(can, item), + ]}, + ]} + }, + style: function(can, item, list) { var space = item.space, machine = item.machine, worker = list[space]["localhost"] + return !worker? html.NOTICE: (worker.status != cli.STOP && item.status != cli.STOP && (item.version != worker.version || item.time < worker.time))? html.DANGER: "" + }, +}, [""]) diff --git a/misc/ssh/relay/relay.go b/misc/ssh/relay/relay.go index 9aa8e040..97d43feb 100644 --- a/misc/ssh/relay/relay.go +++ b/misc/ssh/relay/relay.go @@ -156,12 +156,17 @@ func (s relay) Dream(m *ice.Message) { m.ProcessOpen(web.HostPort(m.Message, m.Option(tcp.HOST), m.Option(web.PORTAL), "", web.DREAM)) return } - fields := "time,machine,host,space,type,status,module,version,commitTime,compileTime,bootTime,link" + // 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) { - if strings.HasPrefix(res, "status") { - } _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) { @@ -177,7 +182,7 @@ func (s relay) Dream(m *ice.Message) { if m.Action(s.Dream, "filter:text"); tcp.IsLocalHost(m.Message, m.Option(ice.MSG_USERIP)) { if _msg := m.Cmd(cli.SYSTEM, ice.BIN_ICE_BIN, web.ADMIN, cli.RUNTIME); len(_msg.Result()) > 0 { m.Push(MACHINE, tcp.LOCALHOST).Push(tcp.HOST, tcp.PublishLocalhost(m.Message, tcp.LOCALHOST)) - m.Push("", kit.Dict(cli.ParseMake(_msg.Result())), kit.Split("time,space,module,version,commitTime,compileTime,bootTime")) + m.Push("", kit.Dict(cli.ParseMake(_msg.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)) } if _msg := m.Spawn().SplitIndex(m.Cmdx(cli.SYSTEM, kit.Split(s.admin(m, web.ROUTE)))); _msg.Length() > 0 { @@ -360,7 +365,7 @@ func (s relay) Repos(m *ice.Message, arg ...string) { s.iframeCmd(m, web.CODE_GI 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 init() { ice.Cmd(SSH_RELAY, relay{}) } +func init() { ice.Cmd("ssh.relay", relay{}) } func (s relay) xterm(m *ice.Message) { xterm.AddCommand(m.Option(MACHINE), func(msg *icebergs.Message, arg ...string) (x xterm.XTerm, e error) {