1
0
mirror of https://shylinux.com/x/icebergs synced 2025-04-25 17:18:05 +08:00
icebergs/base/cli/cli.go
2020-03-19 15:51:37 +08:00

156 lines
5.2 KiB
Go

package cli
import (
"github.com/shylinux/icebergs"
"github.com/shylinux/toolkits"
"bytes"
"fmt"
"os"
"os/exec"
"os/user"
"path"
"runtime"
"strings"
)
var Index = &ice.Context{Name: "cli", Help: "命令模块",
Caches: map[string]*ice.Cache{},
Configs: map[string]*ice.Config{
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Value: kit.Dict()},
ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Value: kit.Data()},
"daemon": {Name: "daemon", Help: "守护进程", Value: kit.Data(kit.MDB_SHORT, "name")},
"python": {Name: "python", Help: "系统命令", Value: kit.Data("python", "python", "pip", "pip")},
},
Commands: map[string]*ice.Command{
ice.ICE_INIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Load()
// 启动配置
m.Conf(ice.CLI_RUNTIME, "conf.ctx_self", os.Getenv("ctx_self"))
m.Conf(ice.CLI_RUNTIME, "conf.ctx_dev", os.Getenv("ctx_dev"))
m.Conf(ice.CLI_RUNTIME, "conf.ctx_shy", os.Getenv("ctx_shy"))
m.Conf(ice.CLI_RUNTIME, "conf.ctx_pid", os.Getenv("ctx_pid"))
// 主机信息
m.Conf(ice.CLI_RUNTIME, "host.GOARCH", runtime.GOARCH)
m.Conf(ice.CLI_RUNTIME, "host.GOOS", runtime.GOOS)
m.Conf(ice.CLI_RUNTIME, "host.pid", os.Getpid())
// 启动信息
if name, e := os.Hostname(); e == nil {
m.Conf(ice.CLI_RUNTIME, "boot.hostname", kit.Select(name, os.Getenv("HOSTNAME")))
}
if user, e := user.Current(); e == nil {
m.Conf(ice.CLI_RUNTIME, "boot.username", path.Base(kit.Select(user.Name, os.Getenv("USER"))))
m.Cmd(ice.AAA_ROLE, "root", m.Conf(ice.CLI_RUNTIME, "boot.username"))
}
if name, e := os.Getwd(); e == nil {
name = path.Base(kit.Select(name, os.Getenv("PWD")))
ls := strings.Split(name, "/")
name = ls[len(ls)-1]
ls = strings.Split(name, "\\")
name = ls[len(ls)-1]
m.Conf(ice.CLI_RUNTIME, "boot.pathname", name)
}
// 启动记录
count := m.Confi(ice.CLI_RUNTIME, "boot.count") + 1
m.Conf(ice.CLI_RUNTIME, "boot.count", count)
// 节点信息
m.Conf(ice.CLI_RUNTIME, "node.time", m.Time())
m.Conf(ice.CLI_RUNTIME, "node.type", ice.WEB_WORKER)
m.Conf(ice.CLI_RUNTIME, "node.name", m.Conf(ice.CLI_RUNTIME, "boot.pathname"))
m.Log("info", "runtime %v", kit.Formats(m.Confv(ice.CLI_RUNTIME)))
}},
ice.ICE_EXIT: {Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Save(ice.CLI_RUNTIME, ice.CLI_SYSTEM)
}},
ice.CLI_RUNTIME: {Name: "runtime", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
}},
ice.CLI_SYSTEM: {Name: "system", Help: "系统命令", Hand: func(m *ice.Message, c *ice.Context, key string, arg ...string) {
cmd := exec.Command(arg[0], arg[1:]...)
// 运行目录
cmd.Dir = m.Option("cmd_dir")
if len(cmd.Dir) > 0 {
m.Info("dir: %s", cmd.Dir)
if _, e := os.Stat(cmd.Dir); e != nil && os.IsNotExist(e) {
os.MkdirAll(cmd.Dir, 0777)
}
}
// 环境变量
env := kit.Simple(m.Optionv("cmd_env"))
for i := 0; i < len(env)-1; i += 2 {
cmd.Env = append(cmd.Env, fmt.Sprintf("%s=%s", env[i], env[i+1]))
}
if len(cmd.Env) > 0 {
m.Info("env: %s", cmd.Env)
}
switch m.Option("cmd_type") {
case "daemon":
// 守护进程
cmd.Env = append(cmd.Env, fmt.Sprintf("PATH=%s", os.Getenv("PATH")))
if e := cmd.Start(); e != nil {
m.Warn(e != nil, "%v start: %s", arg, e)
return
}
m.Rich("daemon", nil, kit.Dict(kit.MDB_NAME, cmd.Process.Pid, "status", "running"))
m.Echo("%d", cmd.Process.Pid)
m.Gos(m, func(m *ice.Message) {
if e := cmd.Wait(); e != nil {
m.Warn(e != nil, "%v wait: %s", arg, e)
} else {
m.Cost("%v exit: %v", arg, cmd.ProcessState.ExitCode())
m.Rich("daemon", nil, func(key string, value map[string]interface{}) {
value["status"] = "exited"
})
}
})
default:
// 系统命令
out := bytes.NewBuffer(make([]byte, 0, 1024))
err := bytes.NewBuffer(make([]byte, 0, 1024))
cmd.Stdout = out
cmd.Stderr = err
if e := cmd.Run(); e != nil {
m.Warn(e != nil, "%v run: %s", arg, kit.Select(e.Error(), err.String()))
} else {
m.Cost("%v exit: %v", arg, cmd.ProcessState.ExitCode())
}
m.Push("code", int(cmd.ProcessState.ExitCode()))
m.Echo(out.String())
}
}},
"daemon": {Name: "daemon", Help: "守护进程", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
switch arg[0] {
case "exit":
}
}},
"python": {Name: "python", Help: "运行环境", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
prefix := []string{ice.CLI_SYSTEM, m.Conf("python", "meta.python")}
switch arg[0] {
case "qrcode":
m.Cmdy(prefix, "-c", fmt.Sprintf(`import pyqrcode; print(pyqrcode.create("%s").terminal(quiet_zone=1))`, arg[1]))
case "install":
m.Cmdy(prefix[:1], m.Conf("python", "meta.pip"), "install", arg[1:])
default:
m.Cmdy(prefix, arg)
}
}},
"qrcode": {Name: "qrcode text", Help: "二", Hand: func(m *ice.Message, c *ice.Context, cmd string, arg ...string) {
m.Render(ice.RENDER_QRCODE, kit.Select("hello world", arg, 0))
}},
},
}
func init() { ice.Index.Register(Index, nil) }