mirror of
https://shylinux.com/x/icebergs
synced 2025-04-28 18:22:02 +08:00
opt ssh.connect
This commit is contained in:
parent
fbe99a51bd
commit
122c3295ff
@ -85,7 +85,7 @@ func init() {
|
|||||||
m.Push("code", _totp_get(value[SECRET], kit.Int(value[NUMBER]), period))
|
m.Push("code", _totp_get(value[SECRET], kit.Int(value[NUMBER]), period))
|
||||||
|
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
m.PushQRCode("show", kit.Format(m.Conf(TOTP, kit.Keym(kit.MDB_LINK)), value[kit.MDB_NAME], value[SECRET]))
|
m.PushQRCode("scan", kit.Format(m.Conf(TOTP, kit.Keym(kit.MDB_LINK)), value[kit.MDB_NAME], value[SECRET]))
|
||||||
m.Echo(_totp_get(value[SECRET], kit.Int(value[NUMBER]), kit.Int64(value[PERIOD])))
|
m.Echo(_totp_get(value[SECRET], kit.Int(value[NUMBER]), kit.Int64(value[PERIOD])))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -13,12 +13,33 @@ import (
|
|||||||
|
|
||||||
func NodeInfo(m *ice.Message, kind, name string) {
|
func NodeInfo(m *ice.Message, kind, name string) {
|
||||||
name = strings.ReplaceAll(name, ".", "_")
|
name = strings.ReplaceAll(name, ".", "_")
|
||||||
m.Conf(RUNTIME, "node.type", kind)
|
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TYPE), kind)
|
||||||
m.Conf(RUNTIME, "node.name", name)
|
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_NAME), name)
|
||||||
ice.Info.NodeName = name
|
ice.Info.NodeName = name
|
||||||
ice.Info.NodeType = kind
|
ice.Info.NodeType = kind
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
MAKE = "make"
|
||||||
|
CONF = "conf"
|
||||||
|
HOST = "host"
|
||||||
|
BOOT = "boot"
|
||||||
|
NODE = "node"
|
||||||
|
)
|
||||||
|
const (
|
||||||
|
HOSTNAME = "hostname"
|
||||||
|
PATHNAME = "pathname"
|
||||||
|
USERNAME = "username"
|
||||||
|
)
|
||||||
|
const (
|
||||||
|
CTX_SELF = "ctx_self"
|
||||||
|
CTX_DEV = "ctx_dev"
|
||||||
|
CTX_SHY = "ctx_shy"
|
||||||
|
CTX_PID = "ctx_pid"
|
||||||
|
CTX_USER = "ctx_user"
|
||||||
|
CTX_SHARE = "ctx_share"
|
||||||
|
CTX_RIVER = "ctx_river"
|
||||||
|
)
|
||||||
const CLI = "cli"
|
const CLI = "cli"
|
||||||
|
|
||||||
var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
||||||
@ -27,18 +48,18 @@ var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
|||||||
m.Load()
|
m.Load()
|
||||||
|
|
||||||
// 启动配置
|
// 启动配置
|
||||||
for _, k := range []string{"ctx_self", "ctx_dev", "ctx_shy", "ctx_pid", "ctx_user", "ctx_share", "ctx_river"} {
|
for _, k := range []string{CTX_SELF, CTX_DEV, CTX_SHY, CTX_PID, CTX_USER, CTX_SHARE, CTX_RIVER} {
|
||||||
m.Conf(RUNTIME, kit.Keys("conf", k), os.Getenv(k))
|
m.Conf(RUNTIME, kit.Keys(CONF, k), os.Getenv(k))
|
||||||
}
|
}
|
||||||
|
|
||||||
// 主机信息
|
// 主机信息
|
||||||
m.Conf(RUNTIME, "host.GOARCH", runtime.GOARCH)
|
m.Conf(RUNTIME, kit.Keys(HOST, "GOARCH"), runtime.GOARCH)
|
||||||
m.Conf(RUNTIME, "host.GOOS", runtime.GOOS)
|
m.Conf(RUNTIME, kit.Keys(HOST, "GOOS"), runtime.GOOS)
|
||||||
m.Conf(RUNTIME, "host.pid", os.Getpid())
|
m.Conf(RUNTIME, kit.Keys(HOST, "pid"), os.Getpid())
|
||||||
|
|
||||||
// 启动信息
|
// 启动信息
|
||||||
if name, e := os.Hostname(); e == nil {
|
if name, e := os.Hostname(); e == nil {
|
||||||
m.Conf(RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
|
m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), kit.Select(name, os.Getenv("HOSTNAME")))
|
||||||
}
|
}
|
||||||
if name, e := os.Getwd(); e == nil {
|
if name, e := os.Getwd(); e == nil {
|
||||||
name = path.Base(kit.Select(name, os.Getenv("PWD")))
|
name = path.Base(kit.Select(name, os.Getenv("PWD")))
|
||||||
@ -46,36 +67,36 @@ var Index = &ice.Context{Name: CLI, Help: "命令模块",
|
|||||||
name = ls[len(ls)-1]
|
name = ls[len(ls)-1]
|
||||||
ls = strings.Split(name, "\\")
|
ls = strings.Split(name, "\\")
|
||||||
name = ls[len(ls)-1]
|
name = ls[len(ls)-1]
|
||||||
m.Conf(RUNTIME, "boot.pathname", name)
|
m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME), name)
|
||||||
}
|
}
|
||||||
if m.Conf(RUNTIME, "boot.username", kit.Select(os.Getenv("USER"), os.Getenv("ctx_user"))) == "" {
|
if m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(os.Getenv(USER), os.Getenv(CTX_USER))) == "" {
|
||||||
if user, e := user.Current(); e == nil && user.Name != "" {
|
if user, e := user.Current(); e == nil && user.Name != "" {
|
||||||
m.Conf(RUNTIME, "boot.username", kit.Select(user.Name, os.Getenv("ctx_user")))
|
m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME), kit.Select(user.Name, os.Getenv(CTX_USER)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ice.Info.HostName = m.Conf(RUNTIME, "boot.hostname")
|
ice.Info.HostName = m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME))
|
||||||
ice.Info.PathName = m.Conf(RUNTIME, "boot.pathname")
|
ice.Info.PathName = m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME))
|
||||||
ice.Info.UserName = m.Conf(RUNTIME, "boot.username")
|
ice.Info.UserName = m.Conf(RUNTIME, kit.Keys(BOOT, USERNAME))
|
||||||
|
|
||||||
ice.Info.CtxShare = m.Conf(RUNTIME, "conf.ctx_share")
|
ice.Info.CtxShare = m.Conf(RUNTIME, kit.Keys(CONF, CTX_SHARE))
|
||||||
ice.Info.CtxRiver = m.Conf(RUNTIME, "conf.ctx_river")
|
ice.Info.CtxRiver = m.Conf(RUNTIME, kit.Keys(CONF, CTX_RIVER))
|
||||||
|
|
||||||
// 启动次数
|
// 启动次数
|
||||||
count := kit.Int(m.Conf(RUNTIME, "boot.count")) + 1
|
count := kit.Int(m.Conf(RUNTIME, kit.Keys(BOOT, kit.MDB_COUNT))) + 1
|
||||||
m.Conf(RUNTIME, "boot.count", count)
|
m.Conf(RUNTIME, kit.Keys(BOOT, kit.MDB_COUNT), count)
|
||||||
|
|
||||||
// 节点信息
|
// 节点信息
|
||||||
m.Conf(RUNTIME, "node.time", m.Time())
|
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_TIME), m.Time())
|
||||||
NodeInfo(m, "worker", m.Conf(RUNTIME, "boot.pathname"))
|
NodeInfo(m, "worker", m.Conf(RUNTIME, kit.Keys(BOOT, PATHNAME)))
|
||||||
m.Info("runtime %v", kit.Formats(m.Confv(RUNTIME)))
|
m.Info("runtime %v", kit.Formats(m.Confv(RUNTIME)))
|
||||||
|
|
||||||
n := kit.Int(kit.Select("1", m.Conf(RUNTIME, "host.GOMAXPROCS")))
|
n := kit.Int(kit.Select("1", m.Conf(RUNTIME, kit.Keys(HOST, "GOMAXPROCS"))))
|
||||||
m.Logs("host", "gomaxprocs", n)
|
m.Logs(HOST, "GOMAXPROCS", n)
|
||||||
runtime.GOMAXPROCS(n)
|
runtime.GOMAXPROCS(n)
|
||||||
|
|
||||||
// 版本信息
|
// 版本信息
|
||||||
kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Build)), func(key string, value interface{}) {
|
kit.Fetch(kit.UnMarshal(kit.Format(ice.Info.Build)), func(key string, value interface{}) {
|
||||||
m.Conf(RUNTIME, kit.Keys("make", strings.ToLower(key)), value)
|
m.Conf(RUNTIME, kit.Keys(MAKE, strings.ToLower(key)), value)
|
||||||
})
|
})
|
||||||
}},
|
}},
|
||||||
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
ice.CTX_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
|
@ -37,7 +37,7 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
|
|||||||
|
|
||||||
m.Go(func() {
|
m.Go(func() {
|
||||||
h := m.Cmdx(mdb.INSERT, DAEMON, "", mdb.HASH,
|
h := m.Cmdx(mdb.INSERT, DAEMON, "", mdb.HASH,
|
||||||
kit.MDB_STATUS, Status.Start, kit.SSH_PID, cmd.Process.Pid,
|
kit.MDB_STATUS, START, kit.SSH_PID, cmd.Process.Pid,
|
||||||
kit.SSH_CMD, strings.Join(cmd.Args, " "),
|
kit.SSH_CMD, strings.Join(cmd.Args, " "),
|
||||||
kit.SSH_DIR, cmd.Dir, kit.SSH_ENV, kit.Select("", cmd.Env),
|
kit.SSH_DIR, cmd.Dir, kit.SSH_ENV, kit.Select("", cmd.Env),
|
||||||
mdb.CACHE_CLEAR_ON_EXIT, m.Option(mdb.CACHE_CLEAR_ON_EXIT),
|
mdb.CACHE_CLEAR_ON_EXIT, m.Option(mdb.CACHE_CLEAR_ON_EXIT),
|
||||||
@ -46,11 +46,11 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
|
|||||||
|
|
||||||
if e := cmd.Wait(); m.Warn(e != nil, cmd.Args, " ", e) {
|
if e := cmd.Wait(); m.Warn(e != nil, cmd.Args, " ", e) {
|
||||||
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h,
|
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h,
|
||||||
kit.MDB_STATUS, Status.Error, kit.MDB_ERROR, e)
|
kit.MDB_STATUS, ERROR, kit.MDB_ERROR, e)
|
||||||
} else {
|
} else {
|
||||||
m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode())
|
m.Cost("args", cmd.Args, "code", cmd.ProcessState.ExitCode())
|
||||||
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h,
|
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, h,
|
||||||
kit.MDB_STATUS, Status.Stop)
|
kit.MDB_STATUS, STOP)
|
||||||
}
|
}
|
||||||
|
|
||||||
if w, ok := m.Optionv(CMD_OUTPUT).(io.Closer); ok {
|
if w, ok := m.Optionv(CMD_OUTPUT).(io.Closer); ok {
|
||||||
@ -62,12 +62,6 @@ func _daemon_show(m *ice.Message, cmd *exec.Cmd, out, err string) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
var Status = struct{ Error, Start, Stop string }{
|
|
||||||
Error: "error",
|
|
||||||
Start: "start",
|
|
||||||
Stop: "stop",
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
DIR = "dir"
|
DIR = "dir"
|
||||||
ENV = "env"
|
ENV = "env"
|
||||||
@ -80,6 +74,7 @@ const (
|
|||||||
const (
|
const (
|
||||||
RESTART = "restart"
|
RESTART = "restart"
|
||||||
START = "start"
|
START = "start"
|
||||||
|
ERROR = "error"
|
||||||
STOP = "stop"
|
STOP = "stop"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -120,7 +115,7 @@ func init() {
|
|||||||
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
|
STOP: {Name: "stop", Help: "停止", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir,env")
|
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir,env")
|
||||||
m.Cmd(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)).Table(func(index int, value map[string]string, head []string) {
|
m.Cmd(mdb.SELECT, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH)).Table(func(index int, value map[string]string, head []string) {
|
||||||
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), kit.MDB_STATUS, Status.Stop)
|
m.Cmd(mdb.MODIFY, DAEMON, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH), kit.MDB_STATUS, STOP)
|
||||||
m.Cmdy(SYSTEM, "kill", "-9", value[kit.SSH_PID])
|
m.Cmdy(SYSTEM, "kill", "-9", value[kit.SSH_PID])
|
||||||
})
|
})
|
||||||
}},
|
}},
|
||||||
@ -129,8 +124,8 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir,env")
|
m.Option(mdb.FIELDS, "time,hash,status,pid,cmd,dir,env")
|
||||||
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, Status.Error)
|
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, ERROR)
|
||||||
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, Status.Stop)
|
m.Cmdy(mdb.PRUNES, DAEMON, "", mdb.HASH, kit.MDB_STATUS, STOP)
|
||||||
}},
|
}},
|
||||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
if len(arg) == 0 { // 进程列表
|
if len(arg) == 0 { // 进程列表
|
||||||
@ -138,7 +133,7 @@ func init() {
|
|||||||
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH)
|
m.Cmdy(mdb.SELECT, DAEMON, "", mdb.HASH)
|
||||||
m.Table(func(index int, value map[string]string, head []string) {
|
m.Table(func(index int, value map[string]string, head []string) {
|
||||||
switch value[kit.MDB_STATUS] {
|
switch value[kit.MDB_STATUS] {
|
||||||
case Status.Start:
|
case START:
|
||||||
m.PushButton(RESTART, STOP)
|
m.PushButton(RESTART, STOP)
|
||||||
default:
|
default:
|
||||||
m.PushButton(mdb.REMOVE)
|
m.PushButton(mdb.REMOVE)
|
||||||
|
@ -14,7 +14,6 @@ import (
|
|||||||
const (
|
const (
|
||||||
DISKINFO = "diskinfo"
|
DISKINFO = "diskinfo"
|
||||||
IFCONFIG = "ifconfig"
|
IFCONFIG = "ifconfig"
|
||||||
HOSTNAME = "hostname"
|
|
||||||
HOSTINFO = "hostinfo"
|
HOSTINFO = "hostinfo"
|
||||||
USERINFO = "userinfo"
|
USERINFO = "userinfo"
|
||||||
PROCINFO = "procinfo"
|
PROCINFO = "procinfo"
|
||||||
@ -41,8 +40,8 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
HOSTNAME: {Name: "hostname", Help: "主机域名", Hand: func(m *ice.Message, arg ...string) {
|
HOSTNAME: {Name: "hostname", Help: "主机域名", Hand: func(m *ice.Message, arg ...string) {
|
||||||
if len(arg) > 0 {
|
if len(arg) > 0 {
|
||||||
m.Conf(RUNTIME, "boot.hostname", arg[0])
|
m.Conf(RUNTIME, kit.Keys(NODE, kit.MDB_NAME), arg[0])
|
||||||
m.Conf(RUNTIME, "node.name", arg[0])
|
m.Conf(RUNTIME, kit.Keys(BOOT, HOSTNAME), arg[0])
|
||||||
ice.Info.HostName = arg[0]
|
ice.Info.HostName = arg[0]
|
||||||
}
|
}
|
||||||
m.Echo(ice.Info.HostName)
|
m.Echo(ice.Info.HostName)
|
||||||
|
@ -20,7 +20,7 @@ func (f *Frame) Spawn(m *ice.Message, c *ice.Context, arg ...string) ice.Server
|
|||||||
return &Frame{}
|
return &Frame{}
|
||||||
}
|
}
|
||||||
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
|
func (f *Frame) Begin(m *ice.Message, arg ...string) ice.Server {
|
||||||
f.t = time.Tick(kit.Duration(m.Cap(ice.CTX_STREAM, ice.MOD_TICK)))
|
f.t = time.Tick(kit.Duration(m.Conf(TIMER, kit.Keym("tick"))))
|
||||||
f.s = make(chan os.Signal, ice.MOD_CHAN)
|
f.s = make(chan os.Signal, ice.MOD_CHAN)
|
||||||
f.e = make(chan bool, 1)
|
f.e = make(chan bool, 1)
|
||||||
return f
|
return f
|
||||||
@ -65,7 +65,8 @@ const GDB = "gdb"
|
|||||||
var Index = &ice.Context{Name: GDB, Help: "事件模块",
|
var Index = &ice.Context{Name: GDB, Help: "事件模块",
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
ice.CTX_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
m.Cmd(nfs.SAVE, kit.Select(m.Conf(SIGNAL, kit.META_PATH), m.Conf(cli.RUNTIME, "conf.ctx_pid")), m.Conf(cli.RUNTIME, "host.pid"))
|
m.Cmd(nfs.SAVE, kit.Select(m.Conf(SIGNAL, kit.META_PATH), m.Conf(cli.RUNTIME, kit.Keys(cli.CONF, cli.CTX_PID))),
|
||||||
|
m.Conf(cli.RUNTIME, kit.Keys(cli.HOST, "pid")))
|
||||||
|
|
||||||
m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", kit.SSH_CMD, "exit 0")
|
m.Cmd(SIGNAL, LISTEN, SIGNAL, "3", kit.MDB_NAME, "退出", kit.SSH_CMD, "exit 0")
|
||||||
m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", kit.SSH_CMD, "exit 1")
|
m.Cmd(SIGNAL, LISTEN, SIGNAL, "2", kit.MDB_NAME, "重启", kit.SSH_CMD, "exit 1")
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
package gdb
|
package gdb
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
|
"path"
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
ice "github.com/shylinux/icebergs"
|
ice "github.com/shylinux/icebergs"
|
||||||
@ -23,6 +25,18 @@ func _signal_action(m *ice.Message, s int) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SignalNotify(m *ice.Message, sig int, cb func()) {
|
||||||
|
ch := make(chan os.Signal)
|
||||||
|
signal.Notify(ch, syscall.Signal(sig))
|
||||||
|
m.Go(func() {
|
||||||
|
for {
|
||||||
|
if _, ok := <-ch; ok {
|
||||||
|
cb()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
LISTEN = "listen"
|
LISTEN = "listen"
|
||||||
ACTION = "action"
|
ACTION = "action"
|
||||||
@ -33,7 +47,7 @@ func init() {
|
|||||||
Index.Merge(&ice.Context{
|
Index.Merge(&ice.Context{
|
||||||
Configs: map[string]*ice.Config{
|
Configs: map[string]*ice.Config{
|
||||||
SIGNAL: {Name: SIGNAL, Help: "信号器", Value: kit.Data(
|
SIGNAL: {Name: SIGNAL, Help: "信号器", Value: kit.Data(
|
||||||
kit.MDB_PATH, "var/run/ice.pid", kit.MDB_SHORT, SIGNAL,
|
kit.MDB_PATH, path.Join(ice.VAR_RUN, "ice.pid"), kit.MDB_SHORT, SIGNAL,
|
||||||
)},
|
)},
|
||||||
},
|
},
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func _timer_create(m *ice.Message, arg ...string) {
|
func _timer_create(m *ice.Message, arg ...string) {
|
||||||
m.Cmdy(mdb.INSERT, TIMER, "", mdb.HASH, "delay", "10ms", "interval", "10m", "order", 1, "next", m.Time(m.Option("delay")), arg)
|
m.Cmdy(mdb.INSERT, TIMER, "", mdb.HASH, DELAY, "10ms", INTERVAL, "10m", ORDER, 1, NEXT, m.Time(m.Option(DELAY)), arg)
|
||||||
}
|
}
|
||||||
func _timer_action(m *ice.Message, arg ...string) {
|
func _timer_action(m *ice.Message, arg ...string) {
|
||||||
now := time.Now().UnixNano()
|
now := time.Now().UnixNano()
|
||||||
@ -20,19 +20,25 @@ func _timer_action(m *ice.Message, arg ...string) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
order := kit.Int(value["order"])
|
order := kit.Int(value[ORDER])
|
||||||
if n := kit.Time(kit.Format(value["next"])); now > n && order > 0 {
|
if n := kit.Time(kit.Format(value[NEXT])); now > n && order > 0 {
|
||||||
m.Logs(TIMER, "key", key, "order", order)
|
m.Logs(TIMER, kit.MDB_KEY, key, ORDER, order)
|
||||||
|
|
||||||
msg := m.Cmd(value[kit.SSH_CMD])
|
msg := m.Cmd(value[kit.SSH_CMD])
|
||||||
m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict("res", msg.Result()))
|
m.Grow(TIMER, kit.Keys(kit.MDB_HASH, key), kit.Dict("res", msg.Result()))
|
||||||
if value["order"] = kit.Format(order - 1); order > 1 {
|
if value[ORDER] = kit.Format(order - 1); order > 1 {
|
||||||
value["next"] = msg.Time(value["interval"])
|
value[NEXT] = msg.Time(value[INTERVAL])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const (
|
||||||
|
DELAY = "delay"
|
||||||
|
INTERVAL = "interval"
|
||||||
|
ORDER = "order"
|
||||||
|
NEXT = "next"
|
||||||
|
)
|
||||||
const TIMER = "timer"
|
const TIMER = "timer"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -53,7 +59,7 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Option(mdb.FIELDS, "time,hash,delay,interval,order,next,cmd")
|
m.Option(mdb.FIELDS, "time,hash,delay,interval,order,next,cmd")
|
||||||
m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, "order", 0)
|
m.Cmdy(mdb.PRUNES, TIMER, "", mdb.HASH, ORDER, 0)
|
||||||
}},
|
}},
|
||||||
|
|
||||||
ACTION: {Name: "action", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
|
ACTION: {Name: "action", Help: "执行", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func _file_name(m *ice.Message, arg ...string) string {
|
func _file_name(m *ice.Message, arg ...string) string {
|
||||||
return kit.Select(path.Join(m.Option(ice.MSG_LOCAL), "usr/local/export", path.Join(arg[:2]...), arg[2]), arg, 3)
|
return kit.Select(path.Join(m.Option(ice.MSG_LOCAL), ice.USR_LOCAL, EXPORT, path.Join(arg[:2]...), arg[2]), arg, 3)
|
||||||
}
|
}
|
||||||
func _domain_chain(m *ice.Message, chain string) string {
|
func _domain_chain(m *ice.Message, chain string) string {
|
||||||
return kit.Keys(m.Option(ice.MSG_DOMAIN), chain)
|
return kit.Keys(m.Option(ice.MSG_DOMAIN), chain)
|
||||||
@ -157,7 +157,7 @@ func _list_select(m *ice.Message, prefix, chain, field, value string) {
|
|||||||
}
|
}
|
||||||
fields := _list_fields(m)
|
fields := _list_fields(m)
|
||||||
cb := m.Optionv(kit.Keycb(SELECT))
|
cb := m.Optionv(kit.Keycb(SELECT))
|
||||||
m.Grows(prefix, chain, kit.Select(m.Option("cache.field"), field), kit.Select(m.Option(CACHE_VALUE), value), func(index int, val map[string]interface{}) {
|
m.Grows(prefix, chain, kit.Select(m.Option(CACHE_FIELD), field), kit.Select(m.Option(CACHE_VALUE), value), func(index int, val map[string]interface{}) {
|
||||||
val = kit.GetMeta(val)
|
val = kit.GetMeta(val)
|
||||||
switch cb := cb.(type) {
|
switch cb := cb.(type) {
|
||||||
case func(fields []string, value map[string]interface{}):
|
case func(fields []string, value map[string]interface{}):
|
||||||
@ -263,7 +263,7 @@ func _list_inputs(m *ice.Message, prefix, chain string, field, value string) {
|
|||||||
m.Push(field, k)
|
m.Push(field, k)
|
||||||
m.Push(kit.MDB_COUNT, i)
|
m.Push(kit.MDB_COUNT, i)
|
||||||
}
|
}
|
||||||
m.Sort(kit.MDB_COUNT, "int_r")
|
m.SortIntR(kit.MDB_COUNT)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _zone_fields(m *ice.Message) []string {
|
func _zone_fields(m *ice.Message) []string {
|
||||||
@ -404,6 +404,7 @@ const (
|
|||||||
SELECT = "select"
|
SELECT = "select"
|
||||||
DELETE = "delete"
|
DELETE = "delete"
|
||||||
REMOVE = "remove"
|
REMOVE = "remove"
|
||||||
|
REVERT = "revert"
|
||||||
|
|
||||||
EXPORT = "export"
|
EXPORT = "export"
|
||||||
IMPORT = "import"
|
IMPORT = "import"
|
||||||
@ -412,14 +413,9 @@ const (
|
|||||||
)
|
)
|
||||||
const (
|
const (
|
||||||
CACHE_LIMIT = "cache.limit"
|
CACHE_LIMIT = "cache.limit"
|
||||||
CACHE_FILED = "cache.field"
|
CACHE_FIELD = "cache.field"
|
||||||
CACHE_VALUE = "cache.value"
|
CACHE_VALUE = "cache.value"
|
||||||
|
|
||||||
CACHE_STATUS = "cache.status"
|
|
||||||
CACHE_ACTION = "cache.action"
|
|
||||||
CACHE_BEGIN = "cache.begin"
|
|
||||||
CACHE_HASH = "cache.hash"
|
|
||||||
|
|
||||||
CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit"
|
CACHE_CLEAR_ON_EXIT = "cache.clear.on.exit"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -178,7 +178,7 @@ func init() {
|
|||||||
_dir_search(m, arg[0], arg[1])
|
_dir_search(m, arg[0], arg[1])
|
||||||
}},
|
}},
|
||||||
mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
|
mdb.RENDER: {Name: "render type name text", Help: "渲染", Hand: func(m *ice.Message, arg ...string) {
|
||||||
_dir_show(m, arg[2], arg[1], 0, m.Option(DIR_DEEP) == "true", kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)),
|
_dir_show(m, arg[2], arg[1], 0, m.Option(DIR_DEEP) == ice.TRUE, kit.Select(TYPE_BOTH, m.Option(DIR_TYPE)),
|
||||||
nil, kit.Split("time,size,type,path"))
|
nil, kit.Split("time,size,type,path"))
|
||||||
}},
|
}},
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ func _tail_create(m *ice.Message, arg ...string) {
|
|||||||
|
|
||||||
m.Option(cli.CMD_OUTPUT, w)
|
m.Option(cli.CMD_OUTPUT, w)
|
||||||
m.Option(cli.CMD_ERRPUT, w)
|
m.Option(cli.CMD_ERRPUT, w)
|
||||||
m.Option(mdb.CACHE_CLEAR_ON_EXIT, "true")
|
m.Option(mdb.CACHE_CLEAR_ON_EXIT, ice.TRUE)
|
||||||
m.Cmd(cli.DAEMON, TAIL, "-n", "0", "-f", file)
|
m.Cmd(cli.DAEMON, TAIL, "-n", "0", "-f", file)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -55,7 +55,6 @@ func init() {
|
|||||||
offend = total - kit.Int(kit.Select("10", arg, 2))
|
offend = total - kit.Int(kit.Select("10", arg, 2))
|
||||||
m.Toast("已经是最后一页啦!")
|
m.Toast("已经是最后一页啦!")
|
||||||
}
|
}
|
||||||
|
|
||||||
m.ProcessRewrite("offend", offend)
|
m.ProcessRewrite("offend", offend)
|
||||||
}},
|
}},
|
||||||
"next": {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
|
"next": {Name: "next", Help: "下一页", Hand: func(m *ice.Message, arg ...string) {
|
||||||
@ -68,7 +67,7 @@ func init() {
|
|||||||
}},
|
}},
|
||||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0))
|
m.Option(mdb.FIELDS, kit.Select("time,hash,count,name,file", kit.Select("time,id,file,text", mdb.DETAIL, len(arg) > 1 && arg[1] != ""), len(arg) > 0))
|
||||||
m.Option("cache.limit", kit.Select("10", arg, 2))
|
m.Option(mdb.CACHE_LIMIT, kit.Select("10", arg, 2))
|
||||||
m.Option("cache.offend", kit.Select("0", arg, 3))
|
m.Option("cache.offend", kit.Select("0", arg, 3))
|
||||||
|
|
||||||
if m.Cmdy(mdb.SELECT, TAIL, "", mdb.ZONE, arg); len(arg) == 0 {
|
if m.Cmdy(mdb.SELECT, TAIL, "", mdb.ZONE, arg); len(arg) == 0 {
|
||||||
|
@ -44,7 +44,7 @@ func init() {
|
|||||||
},
|
},
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
TRASH: {Name: "trash file auto prunes", Help: "回收站", Action: map[string]*ice.Action{
|
TRASH: {Name: "trash file auto prunes", Help: "回收站", Action: map[string]*ice.Action{
|
||||||
"recover": {Name: "recover", Help: "恢复", Hand: func(m *ice.Message, arg ...string) {
|
mdb.REVERT: {Name: "revert", Help: "恢复", Hand: func(m *ice.Message, arg ...string) {
|
||||||
os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM))
|
os.Rename(m.Option(kit.MDB_FILE), m.Option(kit.MDB_FROM))
|
||||||
m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
m.Cmd(mdb.DELETE, TRASH, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||||
}},
|
}},
|
||||||
@ -59,7 +59,7 @@ func init() {
|
|||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
m.Option(mdb.FIELDS, "time,hash,file,from")
|
m.Option(mdb.FIELDS, "time,hash,file,from")
|
||||||
m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH)
|
m.Cmdy(mdb.SELECT, TRASH, "", mdb.HASH)
|
||||||
m.PushAction("recover", mdb.REMOVE)
|
m.PushAction(mdb.REVERT, mdb.REMOVE)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_trash_create(m, arg[0])
|
_trash_create(m, arg[0])
|
||||||
|
@ -8,11 +8,11 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path"
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
|
||||||
ice "github.com/shylinux/icebergs"
|
ice "github.com/shylinux/icebergs"
|
||||||
"github.com/shylinux/icebergs/base/aaa"
|
"github.com/shylinux/icebergs/base/aaa"
|
||||||
"github.com/shylinux/icebergs/base/cli"
|
"github.com/shylinux/icebergs/base/cli"
|
||||||
|
"github.com/shylinux/icebergs/base/gdb"
|
||||||
"github.com/shylinux/icebergs/base/mdb"
|
"github.com/shylinux/icebergs/base/mdb"
|
||||||
"github.com/shylinux/icebergs/base/nfs"
|
"github.com/shylinux/icebergs/base/nfs"
|
||||||
"github.com/shylinux/icebergs/base/tcp"
|
"github.com/shylinux/icebergs/base/tcp"
|
||||||
@ -21,72 +21,103 @@ import (
|
|||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/crypto/ssh/terminal"
|
||||||
)
|
)
|
||||||
|
|
||||||
func _ssh_tick(m *ice.Message, pw io.Writer) {
|
func _ssh_open(m *ice.Message, arg ...string) {
|
||||||
if m.Option("tick") == "" {
|
// 加载配置
|
||||||
return
|
if f, e := os.Open(m.Option("authfile")); e == nil {
|
||||||
}
|
|
||||||
m.Go(func() {
|
|
||||||
for {
|
|
||||||
m.Sleep(m.Option("tick"))
|
|
||||||
pw.Write([]byte("# " + time.Now().Format(ice.MOD_TIME) + "\n"))
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
func _ssh_password(m *ice.Message, file string) {
|
|
||||||
if f, e := os.Open(file); e == nil {
|
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
|
|
||||||
var data interface{}
|
var data interface{}
|
||||||
json.NewDecoder(f).Decode(&data)
|
json.NewDecoder(f).Decode(&data)
|
||||||
|
|
||||||
kit.Fetch(data, func(key string, value string) { m.Option(key, value) })
|
kit.Fetch(data, func(key string, value interface{}) { m.Option(key, kit.Simple(value)) })
|
||||||
}
|
|
||||||
}
|
|
||||||
func _ssh_stream(m *ice.Message, stdin *os.File) (io.Reader, io.Writer) {
|
|
||||||
pr, pw := io.Pipe()
|
|
||||||
m.Go(func() {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
for {
|
|
||||||
if n, e := stdin.Read(buf); m.Assert(e) {
|
|
||||||
pw.Write(buf[:n])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return pr, pw
|
|
||||||
}
|
|
||||||
func _ssh_store(stdio *os.File) func() {
|
|
||||||
fd := int(stdio.Fd())
|
|
||||||
oldState, err := terminal.MakeRaw(fd)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
return func() { terminal.Restore(fd, oldState) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func _ssh_session(m *ice.Message, client *ssh.Client, w, h int, stdin io.Reader, stdout, stderr io.Writer) *ssh.Session {
|
_ssh_dial(m, func(c net.Conn) {
|
||||||
|
// 保存界面
|
||||||
|
fd := int(os.Stdin.Fd())
|
||||||
|
if oldState, err := terminal.MakeRaw(fd); err == nil {
|
||||||
|
defer terminal.Restore(fd, oldState)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置宽高
|
||||||
|
w, h, _ := terminal.GetSize(fd)
|
||||||
|
c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w)))
|
||||||
|
|
||||||
|
// 初始命令
|
||||||
|
for _, item := range kit.Simple(m.Optionv("list")) {
|
||||||
|
m.Sleep("10ms")
|
||||||
|
c.Write([]byte(item + "\n"))
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Go(func() { io.Copy(os.Stdout, c) })
|
||||||
|
io.Copy(c, os.Stdin)
|
||||||
|
}, arg...)
|
||||||
|
}
|
||||||
|
func _ssh_dial(m *ice.Message, cb func(net.Conn), arg ...string) {
|
||||||
|
p := path.Join(os.Getenv(cli.HOME), ".ssh/", fmt.Sprintf("%s@%s:%s", m.Option(aaa.USERNAME), m.Option(tcp.HOST), m.Option(tcp.PORT)))
|
||||||
|
if _, e := os.Stat(p); e == nil {
|
||||||
|
if c, e := net.Dial("unix", p); e == nil {
|
||||||
|
cb(c) // 会话连接
|
||||||
|
return
|
||||||
|
}
|
||||||
|
os.Remove(p)
|
||||||
|
}
|
||||||
|
|
||||||
|
var client *ssh.Client
|
||||||
|
if l, e := net.Listen("unix", p); m.Assert(e) {
|
||||||
|
defer func() { os.Remove(p) }()
|
||||||
|
defer l.Close()
|
||||||
|
|
||||||
|
m.Go(func() {
|
||||||
|
for {
|
||||||
|
c, e := l.Accept()
|
||||||
|
m.Assert(e)
|
||||||
|
|
||||||
|
func(c net.Conn) {
|
||||||
|
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
||||||
|
buf := make([]byte, ice.MOD_BUFS)
|
||||||
|
if n, e := c.Read(buf); m.Assert(e) {
|
||||||
|
fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w)
|
||||||
|
}
|
||||||
|
|
||||||
|
m.Go(func() {
|
||||||
|
defer c.Close()
|
||||||
|
|
||||||
session, e := client.NewSession()
|
session, e := client.NewSession()
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
|
|
||||||
session.Stdin = stdin
|
session.Stdin = c
|
||||||
session.Stdout = stdout
|
session.Stdout = c
|
||||||
session.Stderr = stderr
|
session.Stderr = c
|
||||||
|
|
||||||
modes := ssh.TerminalModes{
|
session.RequestPty(os.Getenv("TERM"), h, w, ssh.TerminalModes{
|
||||||
ssh.ECHO: 1,
|
ssh.ECHO: 1,
|
||||||
ssh.TTY_OP_ISPEED: 14400,
|
ssh.TTY_OP_ISPEED: 14400,
|
||||||
ssh.TTY_OP_OSPEED: 14400,
|
ssh.TTY_OP_OSPEED: 14400,
|
||||||
|
})
|
||||||
|
|
||||||
|
gdb.SignalNotify(m, 28, func() {
|
||||||
|
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
||||||
|
session.WindowChange(h, w)
|
||||||
|
})
|
||||||
|
|
||||||
|
session.Shell()
|
||||||
|
session.Wait()
|
||||||
|
})
|
||||||
|
}(c)
|
||||||
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
session.RequestPty(os.Getenv("TERM"), h, w, modes)
|
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
||||||
session.Shell()
|
client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT))
|
||||||
return session
|
|
||||||
}
|
if c, e := net.Dial("unix", p); e == nil {
|
||||||
func _ssh_init(m *ice.Message, pw io.Writer) {
|
cb(c) // 会话连接
|
||||||
for _, k := range []string{"one", "two"} {
|
|
||||||
if m.Sleep("100ms"); m.Option(k) != "" {
|
|
||||||
pw.Write([]byte(m.Option(k) + "\n"))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(tcp.HOST),
|
||||||
|
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg)
|
||||||
}
|
}
|
||||||
func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Client {
|
func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Client {
|
||||||
methods := []ssh.AuthMethod{}
|
methods := []ssh.AuthMethod{}
|
||||||
@ -128,76 +159,6 @@ func _ssh_conn(m *ice.Message, conn net.Conn, username, hostport string) *ssh.Cl
|
|||||||
return ssh.NewClient(c, chans, reqs)
|
return ssh.NewClient(c, chans, reqs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _ssh_open(m *ice.Message, arg ...string) {
|
|
||||||
var client *ssh.Client
|
|
||||||
w, h, _ := terminal.GetSize(int(os.Stdin.Fd()))
|
|
||||||
|
|
||||||
_ssh_password(m, m.Option("authfile"))
|
|
||||||
p := path.Join(os.Getenv("HOME"), ".ssh/", fmt.Sprintf("%s@%s", m.Option("username"), m.Option("host")))
|
|
||||||
if _, e := os.Stat(p); e == nil {
|
|
||||||
if c, e := net.Dial("unix", p); e == nil {
|
|
||||||
|
|
||||||
pr, pw := _ssh_stream(m, os.Stdin)
|
|
||||||
defer _ssh_store(os.Stdout)()
|
|
||||||
defer _ssh_store(os.Stdin)()
|
|
||||||
|
|
||||||
c.Write([]byte(fmt.Sprintf("height:%d,width:%d\n", h, w)))
|
|
||||||
|
|
||||||
m.Go(func() { io.Copy(c, pr) })
|
|
||||||
_ssh_init(m, pw)
|
|
||||||
m.Echo("logout\n")
|
|
||||||
io.Copy(os.Stdout, c)
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
os.Remove(p)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if l, e := net.Listen("unix", p); m.Assert(e) {
|
|
||||||
defer func() { os.Remove(p) }()
|
|
||||||
defer l.Close()
|
|
||||||
|
|
||||||
m.Go(func() {
|
|
||||||
for {
|
|
||||||
if c, e := l.Accept(); e == nil {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
if n, e := c.Read(buf); m.Assert(e) {
|
|
||||||
fmt.Sscanf(string(buf[:n]), "height:%d,width:%d", &h, &w)
|
|
||||||
}
|
|
||||||
|
|
||||||
session := _ssh_session(m, client, w, h, c, c, c)
|
|
||||||
func(session *ssh.Session) {
|
|
||||||
m.Go(func() {
|
|
||||||
defer c.Close()
|
|
||||||
session.Wait()
|
|
||||||
})
|
|
||||||
}(session)
|
|
||||||
} else {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
|
||||||
client = _ssh_conn(m, c, m.Option(aaa.USERNAME), m.Option(tcp.HOST)+":"+m.Option(tcp.PORT))
|
|
||||||
|
|
||||||
pr, pw := _ssh_stream(m, os.Stdin)
|
|
||||||
defer _ssh_store(os.Stdout)()
|
|
||||||
defer _ssh_store(os.Stdin)()
|
|
||||||
|
|
||||||
session := _ssh_session(m, client, w, h, pr, os.Stdout, os.Stderr)
|
|
||||||
_ssh_init(m, pw)
|
|
||||||
_ssh_tick(m, pw)
|
|
||||||
session.Wait()
|
|
||||||
})
|
|
||||||
|
|
||||||
m.Cmdy(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, "ssh", kit.MDB_NAME, m.Option(tcp.HOST),
|
|
||||||
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST), arg)
|
|
||||||
|
|
||||||
m.Echo("exit %s\n", m.Option(tcp.HOST))
|
|
||||||
}
|
|
||||||
|
|
||||||
const CONNECT = "connect"
|
const CONNECT = "connect"
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
@ -207,6 +168,9 @@ func init() {
|
|||||||
},
|
},
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{
|
CONNECT: {Name: "connect hash auto dial prunes", Help: "连接", Action: map[string]*ice.Action{
|
||||||
|
tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
_ssh_open(m, arg...)
|
||||||
|
}},
|
||||||
tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
tcp.DIAL: {Name: "dial username=shy host=shylinux.com port=22 private=.ssh/id_rsa", Help: "添加", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
m.Option(kit.Keycb(tcp.DIAL), func(c net.Conn) {
|
||||||
client := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)),
|
client := _ssh_conn(m, c, kit.Select("shy", m.Option(aaa.USERNAME)),
|
||||||
@ -225,9 +189,6 @@ func init() {
|
|||||||
m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME),
|
m.Cmds(tcp.CLIENT, tcp.DIAL, kit.MDB_TYPE, SSH, kit.MDB_NAME, m.Option(aaa.USERNAME),
|
||||||
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST))
|
tcp.PORT, m.Option(tcp.PORT), tcp.HOST, m.Option(tcp.HOST))
|
||||||
}},
|
}},
|
||||||
tcp.OPEN: {Name: "open authfile= username=shy password= verfiy= host=shylinux.com port=22 private=.ssh/id_rsa tick=", Help: "终端", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
_ssh_open(m, arg...)
|
|
||||||
}},
|
|
||||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
m.Cmdy(mdb.DELETE, CONNECT, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||||
}},
|
}},
|
||||||
@ -243,7 +204,7 @@ func init() {
|
|||||||
|
|
||||||
h := m.Rich(SESSION, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, CONNECT, key))
|
h := m.Rich(SESSION, "", kit.Data(kit.MDB_STATUS, tcp.OPEN, CONNECT, key))
|
||||||
|
|
||||||
if session, e := _ssh_sess(m, h, client); m.Assert(e) {
|
if session, e := _ssh_session(m, h, client); m.Assert(e) {
|
||||||
session.Shell()
|
session.Shell()
|
||||||
session.Wait()
|
session.Wait()
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package ssh
|
|||||||
import (
|
import (
|
||||||
"golang.org/x/crypto/ssh"
|
"golang.org/x/crypto/ssh"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
|
|
||||||
ice "github.com/shylinux/icebergs"
|
ice "github.com/shylinux/icebergs"
|
||||||
"github.com/shylinux/icebergs/base/ctx"
|
"github.com/shylinux/icebergs/base/ctx"
|
||||||
@ -12,7 +11,7 @@ import (
|
|||||||
kit "github.com/shylinux/toolkits"
|
kit "github.com/shylinux/toolkits"
|
||||||
)
|
)
|
||||||
|
|
||||||
func _ssh_sess(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, error) {
|
func _ssh_session(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, error) {
|
||||||
session, e := client.NewSession()
|
session, e := client.NewSession()
|
||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
|
|
||||||
@ -23,14 +22,13 @@ func _ssh_sess(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, erro
|
|||||||
m.Assert(e)
|
m.Assert(e)
|
||||||
|
|
||||||
m.Go(func() {
|
m.Go(func() {
|
||||||
for {
|
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, 4096)
|
||||||
|
for {
|
||||||
n, e := out.Read(buf)
|
n, e := out.Read(buf)
|
||||||
if e != nil {
|
if e != nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Debug(string(buf[:n]))
|
|
||||||
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, h), kit.Dict(
|
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, h), kit.Dict(
|
||||||
kit.MDB_TYPE, RES, kit.MDB_TEXT, string(buf[:n]),
|
kit.MDB_TYPE, RES, kit.MDB_TEXT, string(buf[:n]),
|
||||||
))
|
))
|
||||||
@ -38,35 +36,24 @@ func _ssh_sess(m *ice.Message, h string, client *ssh.Client) (*ssh.Session, erro
|
|||||||
})
|
})
|
||||||
|
|
||||||
m.Richs(SESSION, "", h, func(key string, value map[string]interface{}) {
|
m.Richs(SESSION, "", h, func(key string, value map[string]interface{}) {
|
||||||
kit.Value(value, "meta.output", out)
|
kit.Value(value, kit.Keym(OUTPUT), out)
|
||||||
kit.Value(value, "meta.input", in)
|
kit.Value(value, kit.Keym(INPUT), in)
|
||||||
})
|
})
|
||||||
|
|
||||||
return session, nil
|
return session, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func _watch(m *ice.Message, from io.Reader, to io.Writer, cb func([]byte)) {
|
|
||||||
m.Go(func() {
|
|
||||||
buf := make([]byte, 1024)
|
|
||||||
for {
|
|
||||||
n, e := from.Read(buf)
|
|
||||||
if e != nil {
|
|
||||||
cb(nil)
|
|
||||||
break
|
|
||||||
}
|
|
||||||
cb(buf[:n])
|
|
||||||
to.Write(buf[:n])
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
TTY = "tty"
|
TTY = "tty"
|
||||||
ENV = "env"
|
ENV = "env"
|
||||||
ARG = "arg"
|
|
||||||
CMD = "cmd"
|
CMD = "cmd"
|
||||||
|
ARG = "arg"
|
||||||
RES = "res"
|
RES = "res"
|
||||||
)
|
)
|
||||||
|
const (
|
||||||
|
INPUT = "input"
|
||||||
|
OUTPUT = "output"
|
||||||
|
)
|
||||||
|
|
||||||
const SESSION = "session"
|
const SESSION = "session"
|
||||||
|
|
||||||
@ -77,9 +64,16 @@ func init() {
|
|||||||
},
|
},
|
||||||
Commands: map[string]*ice.Command{
|
Commands: map[string]*ice.Command{
|
||||||
SESSION: {Name: "session hash id auto command prunes", Help: "会话", Action: map[string]*ice.Action{
|
SESSION: {Name: "session hash id auto command prunes", Help: "会话", Action: map[string]*ice.Action{
|
||||||
|
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Cmdy(mdb.DELETE, SESSION, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
||||||
|
}},
|
||||||
|
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
||||||
|
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.ERROR)
|
||||||
|
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
||||||
|
}},
|
||||||
ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
|
ctx.COMMAND: {Name: "command cmd=pwd", Help: "命令", Hand: func(m *ice.Message, arg ...string) {
|
||||||
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
||||||
if w, ok := kit.Value(value, "meta.input").(io.Writer); ok {
|
if w, ok := kit.Value(value, kit.Keym(INPUT)).(io.Writer); ok {
|
||||||
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD)))
|
m.Grow(SESSION, kit.Keys(kit.MDB_HASH, key), kit.Dict(kit.MDB_TYPE, CMD, kit.MDB_TEXT, m.Option(CMD)))
|
||||||
n, e := w.Write([]byte(m.Option(CMD) + "\n"))
|
n, e := w.Write([]byte(m.Option(CMD) + "\n"))
|
||||||
m.Debug("%v %v", n, e)
|
m.Debug("%v %v", n, e)
|
||||||
@ -87,42 +81,19 @@ func init() {
|
|||||||
})
|
})
|
||||||
m.ProcessRefresh("300ms")
|
m.ProcessRefresh("300ms")
|
||||||
}},
|
}},
|
||||||
"bind": {Name: "bind", Help: "绑定", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
m.Richs(SESSION, "", m.Option(kit.MDB_HASH), func(key string, value map[string]interface{}) {
|
|
||||||
value = kit.GetMeta(value)
|
|
||||||
|
|
||||||
input := value["input"].(io.Writer)
|
|
||||||
_watch(m, os.Stdin, input, func(buf []byte) {
|
|
||||||
m.Debug("input %v", string(buf))
|
|
||||||
})
|
|
||||||
|
|
||||||
output := value["output"].(io.Reader)
|
|
||||||
_watch(m, output, os.Stdout, func(buf []byte) {
|
|
||||||
m.Debug("output %v", string(buf))
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}},
|
|
||||||
|
|
||||||
mdb.REMOVE: {Name: "remove", Help: "删除", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
m.Cmdy(mdb.DELETE, SESSION, "", mdb.HASH, kit.MDB_HASH, m.Option(kit.MDB_HASH))
|
|
||||||
}},
|
|
||||||
mdb.PRUNES: {Name: "prunes", Help: "清理", Hand: func(m *ice.Message, arg ...string) {
|
|
||||||
m.Cmdy(mdb.PRUNES, SESSION, "", mdb.HASH, kit.MDB_STATUS, tcp.CLOSE)
|
|
||||||
}},
|
|
||||||
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
}, Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
|
||||||
if len(arg) == 0 {
|
if len(arg) == 0 {
|
||||||
m.Option(mdb.FIELDS, "time,hash,status,count,connect")
|
m.Option(mdb.FIELDS, "time,hash,status,count,connect")
|
||||||
if m.Cmdy(mdb.SELECT, SESSION, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
if m.Cmdy(mdb.SELECT, SESSION, "", mdb.HASH, kit.MDB_HASH, arg); len(arg) == 0 {
|
||||||
m.Table(func(index int, value map[string]string, head []string) {
|
m.Table(func(index int, value map[string]string, head []string) {
|
||||||
m.PushButton(kit.Select("bind", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE))
|
m.PushButton(kit.Select("", mdb.REMOVE, value[kit.MDB_STATUS] == tcp.CLOSE))
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
m.Option(mdb.FIELDS, kit.Select("time,id,type,text", mdb.DETAIL, len(arg) > 1))
|
m.Fields(len(arg) == 1, "time,id,type,text")
|
||||||
m.Cmdy(mdb.SELECT, SESSION, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
|
m.Cmdy(mdb.SELECT, SESSION, kit.Keys(kit.MDB_HASH, arg[0]), mdb.LIST, kit.MDB_ID, arg[1:])
|
||||||
m.Sort(kit.MDB_ID)
|
|
||||||
}},
|
}},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
1
conf.go
1
conf.go
@ -40,6 +40,7 @@ const ( // DIR
|
|||||||
INDEX_SH = "index.sh"
|
INDEX_SH = "index.sh"
|
||||||
|
|
||||||
VAR_TMP = "var/tmp"
|
VAR_TMP = "var/tmp"
|
||||||
|
VAR_RUN = "var/run"
|
||||||
VAR_LOG = "var/log"
|
VAR_LOG = "var/log"
|
||||||
VAR_CONF = "var/conf"
|
VAR_CONF = "var/conf"
|
||||||
VAR_DATA = "var/data"
|
VAR_DATA = "var/data"
|
||||||
|
6
exec.go
6
exec.go
@ -1,13 +1,13 @@
|
|||||||
package ice
|
package ice
|
||||||
|
|
||||||
import (
|
import (
|
||||||
kit "github.com/shylinux/toolkits"
|
|
||||||
"github.com/shylinux/toolkits/task"
|
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
kit "github.com/shylinux/toolkits"
|
||||||
|
"github.com/shylinux/toolkits/task"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
|
func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) *Message {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user