diff --git a/base/aaa/user.go b/base/aaa/user.go index 2a6c4f21..191545fc 100644 --- a/base/aaa/user.go +++ b/base/aaa/user.go @@ -59,7 +59,7 @@ func init() { m.Push(arg[0], m.Option(ice.MSG_USERNAME)) } }}, - mdb.CREATE: {Name: "create userrole=void,tech username* usernick language userzone", Hand: func(m *ice.Message, arg ...string) { + mdb.CREATE: {Name: "create userrole=void,tech username* usernick language userzone email", Hand: func(m *ice.Message, arg ...string) { _user_create(m, m.Option(USERNAME), m.OptionSimple(USERROLE, USERNICK, LANGUAGE, AVATAR, BACKGROUND, USERZONE, EMAIL)...) }}, mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { _user_remove(m, m.Option(USERNAME)) }}, @@ -96,10 +96,11 @@ func UserRoot(m *ice.Message, arg ...string) *ice.Message { username := kit.Select(ice.Info.Username, arg, 1) usernick := kit.Select(UserNick(m, username), arg, 2) language := kit.Select("", arg, 3) - userzone := kit.Select(ice.DEV, arg, 4) + userzone := kit.Select(ice.OPS, arg, 4) + email := kit.Select(UserEmail(m, username), arg, 5) if len(arg) > 0 { ice.Info.Username = username - m.Cmd(USER, mdb.CREATE, userrole, username, usernick, language, userzone) + m.Cmd(USER, mdb.CREATE, userrole, username, usernick, language, userzone, email) } return SessAuth(m, kit.Dict(USERROLE, userrole, USERNAME, username, USERNICK, usernick)) } diff --git a/base/cli/runtime.go b/base/cli/runtime.go index 3d99ffa9..efca6637 100644 --- a/base/cli/runtime.go +++ b/base/cli/runtime.go @@ -43,8 +43,9 @@ func _runtime_init(m *ice.Message) { kit.HashSeed = append(kit.HashSeed, ice.Info.Username) kit.HashSeed = append(kit.HashSeed, ice.Info.Hostname) kit.HashSeed = append(kit.HashSeed, ice.Info.Pathname) - aaa.UserRoot(ice.Pulse, "", ice.Info.Make.Username) - aaa.UserRoot(ice.Pulse, aaa.ROOT, ice.Info.Username, "", "", ice.OPS) + aaa.UserRoot(ice.Pulse, aaa.TECH, ice.Info.Make.Username, "", "", ice.DEV, ice.Info.Make.Email) + aaa.UserRoot(ice.Pulse, aaa.ROOT, ice.Info.Username) + aaa.UserRoot(ice.Pulse, aaa.ROOT, aaa.ROOT) ice.Info.Time = m.Time() m.Conf(RUNTIME, kit.Keys(BOOT, mdb.TIME), ice.Info.Time) if runtime.GOARCH != MIPSLE { diff --git a/base/mdb/hash.go b/base/mdb/hash.go index 6fcc59ef..22f9fd73 100644 --- a/base/mdb/hash.go +++ b/base/mdb/hash.go @@ -261,7 +261,9 @@ func HashInputs(m *ice.Message, arg ...Any) *ice.Message { return m.Cmdy(INPUTS, m.PrefixKey(), m.Option(SUBKEY), HASH, arg) } func HashCreate(m *ice.Message, arg ...Any) string { - kit.If(len(arg) == 0 || len(kit.Simple(arg...)) == 0, func() { arg = append(arg, m.OptionSimple(strings.Replace(HashField(m), "hash,", "", 1))) }) + kit.If(len(arg) == 0 || len(kit.Simple(arg...)) == 0, func() { + arg = append(arg, m.OptionSimple(kit.Filters(kit.Split(HashField(m)), TIME, HASH)...)) + }) kit.If(m.Option(SUBKEY) == "", func() { kit.If(Config(m, SHORTS), func(p string) { arg = append([]ice.Any{SHORT, p}, arg) }) }) return m.Echo(m.Cmdx(append(kit.List(INSERT, m.PrefixKey(), m.Option(SUBKEY), HASH, logs.FileLineMeta(-1)), arg...)...)).Result() } diff --git a/base/web/dream.go b/base/web/dream.go index 92eca38f..caf205ac 100644 --- a/base/web/dream.go +++ b/base/web/dream.go @@ -555,7 +555,9 @@ func DreamProcessIframe(m *ice.Message, arg ...string) { defer m.Push(TITLE, kit.Keys(m.Option(mdb.NAME), m.ShortKey())) } DreamProcess(m, CHAT_IFRAME, func() string { - return kit.MergeURL(S(kit.Keys(m.Option(ice.MSG_USERPOD), m.Option(mdb.NAME)))+C(m.ShortKey()), ice.MSG_DEBUG, m.Option(ice.MSG_DEBUG)) + p := S(kit.Keys(m.Option(ice.MSG_USERPOD), m.Option(mdb.NAME))) + kit.If(m.Option(mdb.TYPE) == ORIGIN && m.CommandKey() == PORTAL, func() { p = SpideOrigin(m, m.Option(mdb.NAME)) }) + return kit.MergeURL(p+C(m.ShortKey()), ice.MSG_DEBUG, m.Option(ice.MSG_DEBUG)) }, arg...) } func DreamProcess(m *ice.Message, cmd string, args ice.Any, arg ...string) { diff --git a/base/web/space.go b/base/web/space.go index 3336ff24..cd6c2948 100644 --- a/base/web/space.go +++ b/base/web/space.go @@ -1,6 +1,7 @@ package web import ( + "io" "math/rand" "net" "path" @@ -28,8 +29,9 @@ func _space_qrcode(m *ice.Message, dev string) { ssh.PrintQRCode(m, m.Cmdv(SPACE, dev, cli.PWD, mdb.LINK)) } func _space_dial(m *ice.Message, dev, name string, arg ...string) { - origin := m.Cmdv(SPIDE, dev, CLIENT_ORIGIN) - u := kit.ParseURL(kit.MergeURL2(strings.Replace(origin, HTTP, "ws", 1), PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, mdb.NAME, "", mdb.ICONS, ice.Info.NodeIcon, + msg := m.Cmd(SPIDE, dev) + origin := msg.Append(CLIENT_ORIGIN) + u := kit.ParseURL(kit.MergeURL2(strings.Replace(origin, HTTP, "ws", 1), PP(SPACE), mdb.TYPE, ice.Info.NodeType, mdb.NAME, name, TOKEN, msg.Append(TOKEN), mdb.ICONS, ice.Info.NodeIcon, mdb.TIME, ice.Info.Make.Time, nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), cli.GOOS, runtime.GOOS, cli.GOARCH, runtime.GOARCH, arg)) args := kit.SimpleKV("type,name,host,port", u.Scheme, dev, u.Hostname(), kit.Select(kit.Select(tcp.PORT_443, tcp.PORT_80, u.Scheme == "ws"), u.Port())) gdb.Go(m, func() { @@ -40,12 +42,16 @@ func _space_dial(m *ice.Message, dev, name string, arg ...string) { next := time.Duration(rand.Intn(a*i*i)+b*(i+1)) * time.Millisecond m.Cmd(tcp.CLIENT, tcp.DIAL, args, func(c net.Conn) { if c, e := websocket.NewClient(c, u); !m.WarnNotValid(e, tcp.DIAL, dev, SPACE, u.String()) { - defer mdb.HashCreateDeferRemove(m, kit.SimpleKV("", ORIGIN, dev, origin), kit.Dict(mdb.TARGET, c))() + mdb.HashCreate(m, kit.SimpleKV("", ORIGIN, dev, origin), kit.Dict(mdb.TARGET, c)) + defer mdb.HashRemove(m, mdb.HASH, dev) kit.If(ice.Info.Colors, func() { once.Do(func() { m.Go(func() { _space_qrcode(m, dev) }) }) }) _space_handle(m.Spawn(), true, dev, c) i = 0 } }).Cost(mdb.COUNT, i, mdb.NEXT, next, tcp.DIAL, dev, LINK, u.String()).Sleep(next) + if mdb.HashSelect(m.Spawn(), name).Append(mdb.STATUS) == cli.STOP { + break + } } }, kit.JoinWord(SPACE, dev)) } @@ -215,7 +221,7 @@ func _space_exec(m *ice.Message, name string, source, target []string, c *websoc } func _space_echo(m *ice.Message, source, target []string, c *websocket.Conn) { defer func() { m.WarnNotValid(recover()) }() - if m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:]); !m.WarnNotValid(c.WriteMessage(1, []byte(m.FormatsMeta(nil)))) { + if m.Options(ice.MSG_SOURCE, source, ice.MSG_TARGET, target[1:]); !m.WarnNotValid(c.WriteMessage(1, []byte(m.FormatMeta()))) { if source != nil { m.Log(kit.Select(tcp.SEND, tcp.DONE, m.Option(ice.MSG_HANDLE) == ice.TRUE), "%v->%v %v %v", source, target, kit.ReplaceAll(kit.Format("%v", m.Detailv()), "\r\n", "\\r\\n", "\t", "\\t", "\n", "\\n"), m.FormatMeta()) } @@ -224,7 +230,7 @@ func _space_echo(m *ice.Message, source, target []string, c *websocket.Conn) { func _space_send(m *ice.Message, name string, arg ...string) (h string) { withecho := m.Option(ice.SPACE_NOECHO) != ice.TRUE kit.If(len(arg) > 0 && arg[0] == TOAST, func() { withecho = false; m.Option(ice.MSG_DEBUG, ice.FALSE) }) - wait, done := m.Wait(kit.Select("", m.OptionDefault(ice.SPACE_TIMEOUT, "30s"), withecho), func(msg *ice.Message, arg ...string) { + wait, done := m.Wait(kit.Select("", m.OptionDefault(ice.SPACE_TIMEOUT, "180s"), withecho), func(msg *ice.Message, arg ...string) { m.Cost(kit.Format("%v->[%v] %v %v", m.Optionv(ice.MSG_SOURCE), name, m.Detailv(), msg.FormatSize())).Copy(msg) }) if withecho { @@ -316,8 +322,8 @@ func init() { m.Push(nfs.MODULE, ice.Info.Make.Module) m.Push(nfs.VERSION, ice.Info.Make.Versions()) m.Push(nfs.PATHNAME, ice.Info.Pathname) - m.Push(ORIGIN, m.Option(ice.MSG_USERHOST)) m.Push(tcp.HOSTPORT, HostPort(m, m.Cmd(tcp.HOST).Append(aaa.IP), m.Cmd(SERVER).Append(tcp.PORT))) + m.Push(ORIGIN, m.Option(ice.MSG_USERHOST)) }}, mdb.SEARCH: {Hand: func(m *ice.Message, arg ...string) { if mdb.IsSearchPreview(m, arg) { @@ -343,7 +349,14 @@ func init() { mdb.REMOVE: {Hand: func(m *ice.Message, arg ...string) { defer ToastProcess(m)() mdb.HashModify(m, m.OptionSimple(mdb.NAME), mdb.STATUS, cli.STOP) - m.Cmd("", m.Option(mdb.NAME), ice.EXIT).Sleep3s() + msg := mdb.HashSelect(m.Spawn(), m.Option(mdb.NAME)) + if msg.Append(mdb.TYPE) == ORIGIN { + if target, ok := mdb.HashSelectTarget(m, m.Option(mdb.NAME), nil).(io.Closer); ok { + target.Close() + } + } else { + m.Cmd("", m.Option(mdb.NAME), ice.EXIT).Sleep3s() + } }}, DOMAIN: {Hand: func(m *ice.Message, arg ...string) { m.Echo(_space_domain(m)) }}, LOGIN: {Help: "ζŽˆζƒ", Hand: func(m *ice.Message, arg ...string) { @@ -497,8 +510,7 @@ func SpaceName(name string) string { } func SpacePwd(m *ice.Message, name, text string) { m.Optionv(ice.MSG_OPTS, m.OptionSimple(ice.MSG_USERROLE, ice.MSG_USERNAME)) - m.Cmd(SPACE, name, cli.PWD, name, kit.Dict( - ice.SPACE_NOECHO, ice.TRUE, + m.Cmd(SPACE, name, cli.PWD, name, kit.Dict(ice.SPACE_NOECHO, ice.TRUE, mdb.ICONS, ice.Info.NodeIcon, mdb.TEXT, text, AGENT, "Go-http-client", cli.SYSTEM, runtime.GOOS, mdb.TIME, ice.Info.Make.Time, nfs.MODULE, ice.Info.Make.Module, nfs.VERSION, ice.Info.Make.Versions(), )) diff --git a/misc/ssh/relay/relay.go b/misc/ssh/relay/relay.go index d873b4ea..92267718 100644 --- a/misc/ssh/relay/relay.go +++ b/misc/ssh/relay/relay.go @@ -72,6 +72,7 @@ type relay struct { forEach string `name:"forEach machine cmd*:textarea=pwd"` forFlow string `name:"forFlow machine cmd*:textarea=pwd"` list string `name:"list machine auto" help:"ζœΊε™¨" icon:"relay.png"` + opsOriginOpen string `name:"opsOriginOpen" event:"ops.origin.open"` opsServerOpen string `name:"opsServerOpen" event:"ops.server.open"` opsDreamSpawn string `name:"opsDreamSpawn" event:"ops.dream.spawn"` install string `name:"install dream portal nodename dev"` @@ -245,12 +246,15 @@ func (s relay) List(m *ice.Message, arg ...string) *ice.Message { m.StatusTimeCount(m.Spawn().Options(stats, _stats).OptionSimple(VCPU, MEM, DISK, SOCKET, PROC)) return m } -func (s relay) OpsDreamSpawn(m *ice.Message, arg ...string) { - kit.If(m.Option(mdb.NAME) == ice.Info.NodeName, func() { s.sendData(m, kit.Keys(m.Option(web.DOMAIN), m.Option(mdb.NAME))) }) +func (s relay) OpsOriginOpen(m *ice.Message, arg ...string) { + kit.If(m.Option(nfs.MODULE) == ice.Info.Make.Module, func() { s.sendData(m, m.Option(mdb.NAME)) }) } func (s relay) OpsServerOpen(m *ice.Message, arg ...string) { kit.If(m.Option(nfs.MODULE) == ice.Info.Make.Module, func() { s.sendData(m, m.Option(mdb.NAME)) }) } +func (s relay) OpsDreamSpawn(m *ice.Message, arg ...string) { + kit.If(m.Option(mdb.NAME) == ice.Info.NodeName, func() { s.sendData(m, kit.Keys(m.Option(web.DOMAIN), m.Option(mdb.NAME))) }) +} func (s relay) sendData(m *ice.Message, space string) { if m.IsTech() { m.Cmd("").Table(func(value ice.Maps) { @@ -303,7 +307,7 @@ func (s relay) AdminCmd(m *ice.Message, arg ...string) { s.shell(m, s.admins(m, m.Option(ice.CMD)), arg...) } func (s relay) Spide(m *ice.Message, arg ...string) { - ssh.CombinedOutput(m.Message, s.admins(m, kit.JoinCmds(web.TOKEN, mdb.CREATE, "--", mdb.TYPE, web.SERVER, mdb.NAME, m.Option(aaa.USERNAME), mdb.TEXT, m.Option(MACHINE))), func(res string) { + ssh.CombinedOutput(m.Message, s.admins(m, kit.JoinCmds(web.TOKEN, mdb.CREATE, "--", mdb.TYPE, web.SERVER, mdb.NAME, aaa.ROOT, mdb.TEXT, ice.Info.Hostname)), func(res string) { m.AdminCmd(web.SPIDE, mdb.CREATE, m.Option(web.LINK), m.Option(MACHINE), "", nfs.REPOS, strings.TrimSpace(res)) m.AdminCmd(web.SPACE, tcp.DIAL, m.Option(MACHINE)) }) @@ -397,7 +401,7 @@ func (s relay) param(m *ice.Message, arg ...string) string { return kit.JoinCmdArgs(ice.DEV, m.Option(ice.DEV), tcp.PORT, m.Option(web.PORTAL), tcp.NODENAME, m.OptionDefault(tcp.NODENAME, m.Option(MACHINE)), ice.TCP_DOMAIN, m.Option(tcp.HOST)) } func (s relay) CmdArgs(m *ice.Message, init string, arg ...string) string { - kit.If(m.Option(web.PORTAL) != "" && init == "", func() { init = kit.Format("%q", "cd "+path.Base(m.DreamPath(m.Option(web.DREAM)))) }) + kit.If(m.Option(web.PORTAL) != "" && init == "", func() { init = "cd " + path.Base(m.DreamPath(m.Option(web.DREAM))) }) return strings.TrimPrefix(os.Args[0], kit.Path("")+nfs.PS) + " " + kit.JoinCmds(kit.Simple( SSH_CONNECT, tcp.OPEN, ssh.AUTHFILE, "", m.OptionSimple(aaa.USERNAME, tcp.HOST, tcp.PORT), ice.INIT, init, arg)...) }