func loadConfig(L *lua.LState, path string) (*config, error) { cfg := config{} err := L.DoFile(path) if err != nil { return nil, err } lcfg := L.GetGlobal(appName).(*lua.LTable) err = gluamapper.Map(lcfg, &cfg) if err != nil { return nil, err } mapper := gluamapper.NewMapper(gluamapper.Option{NameFunc: gluamapper.Id}) targets := luaMustGetTableAttr(lcfg, "targets") cfg.Targets = make(map[string]*target, len(cfg.Targets)) targets.ForEach(func(key, value lua.LValue) { t := target{} gluamapper.Map(value.(*lua.LTable), &t) cfg.Targets[key.String()] = &t t.Path = key.String() }) lnotifiers := luaMustGetTableAttr(lcfg, "notifiers") cfg.Notifiers.Default = lnotifiers.RawGetString("default").(*lua.LFunction) mapper.Map(luaMustGetTableAttr(lnotifiers, "code"), &cfg.Notifiers.Code) mapper.Map(luaMustGetTableAttr(lnotifiers, "level"), &cfg.Notifiers.Level) return &cfg, nil }
// This is a Lua module function. // run execute command on a remote host via SSH. func run(L *lua.LState) int { // communicator comm, err := commFromLTable(L.CheckTable(1)) if err != nil { panic(err) } defer comm.Close() // option and command option := NewOption() cmd := "" if L.GetTop() == 4 { if err := gluamapper.Map(L.CheckTable(2), option); err != nil { panic(err) } cmds, err := toStrings(L.Get(3)) if err != nil { panic(err) } cmd = concatCommandLines(cmds) fn := L.CheckFunction(4) option.OutputFunc = fn } else if L.GetTop() == 3 { if err := gluamapper.Map(L.CheckTable(2), option); err != nil { panic(err) } cmds, err := toStrings(L.Get(3)) if err != nil { panic(err) } cmd = concatCommandLines(cmds) } else if L.GetTop() == 2 { cmds, err := toStrings(L.Get(2)) if err != nil { panic(err) } cmd = concatCommandLines(cmds) } else { L.RaiseError("run method requires 2 arugments at least.") } // run ret, err := comm.Run(cmd, option, L) if err != nil { L.RaiseError("ssh error: %s", err) } tb := updateLTableByRunResult(L.NewTable(), ret) L.Push(tb) return 1 }
func commFromLTable(table *lua.LTable) (*Communicator, error) { // config cfg := NewConfig() // update config by passed table. if err := gluamapper.Map(table, cfg); err != nil { return nil, err } // communicator comm, err := NewComm(cfg) if err != nil { return nil, err } return comm, nil }
func registerMacro(L *lua.LState, name string, config *lua.LTable) { m := &Macro{ OnTags: map[string][]string{}, OnServers: []string{}, } if err := gluamapper.Map(config, m); err != nil { L.RaiseError("got a error when it is parsing the macro: %s", err) } m.Name = name on := config.RawGetString("on") if ontb, ok := on.(*lua.LTable); ok { m.RunLocally = false ontb.ForEach(func(k lua.LValue, v lua.LValue) { if ks, ok := toString(k); ok { // tags if vs, ok := toString(v); ok { m.OnTags[ks] = []string{vs} } else if vs, ok := toLTable(v); ok { var values = []string{} vs.ForEach(func(_ lua.LValue, vv lua.LValue) { if vvs, ok := toString(vv); ok { values = append(values, vvs) } else { L.RaiseError("unsupported format of tags.") } }) m.OnTags[ks] = values } else { L.RaiseError("unsupported format of tags.") } } else { // servers if vs, ok := toString(v); ok { m.OnServers = append(m.OnServers, vs) } } }) } else { m.RunLocally = true } confirm := config.RawGetString("confirm") switch confirmConverted := confirm.(type) { case lua.LBool: m.Confirm = bool(confirmConverted) case lua.LString: m.Confirm = true m.ConfirmText = string(confirmConverted) } command := config.RawGetString("command") if commandFn, ok := command.(*lua.LFunction); ok { m.CommandFunc = func(host *Host) (string, error) { lhost := L.NewUserData() lhost.Value = host L.SetMetatable(lhost, L.GetTypeMetatable(LHostClass)) err := L.CallByParam(lua.P{ Fn: commandFn, NRet: 1, Protect: true, }, lhost) if err != nil { return "", err } ret := L.Get(-1) // returned value L.Pop(1) if ret == lua.LNil { return "", nil } else if retStr, ok := ret.(lua.LString); ok { return string(retStr), nil } else { return "", errors.New("return value must be string") } } } else if commandStr, ok := command.(lua.LString); ok { m.Command = string(commandStr) } Macros = append(Macros, m) }
func (self *GLWeb) loadgl(p string) { fbody, err := ioutil.ReadFile(p) if err != nil { log.Errorln("GLWeb loadgl ReadFile "+p+" Error.", err) return } L := lua.NewState() defer func() { L.SetTop(0) L.Close() }() json.Preload(L) gllog.Preload(L) glstr.Preload(L) if err := L.DoString(string(fbody)); err != nil { log.Errorln("GLWeb loadgl DoFile Error.", err) return } ltask := L.GetGlobal("tasks") if ltask.Type() == lua.LTNil { log.Errorln("GLWeb loadgl Get Tasks Error.", p, " not tasks table.") return } var tasks *Tasks if err := gluamapper.Map(L.GetGlobal("tasks").(*lua.LTable), &tasks); err != nil { log.Errorln("GLWeb loadgl Get Tasks Error.", err) return } log.Infoln("GLWeb gls load ", p, tasks.Name) g := newglf(p, string(fbody)) if tasks.Name == "" { log.Errorln("GLWEB gls load Error tasks name is nil") return } if _, ok := self.gls[tasks.Name]; ok { log.Errorln("GLWeb gls load Error tasks name ", tasks.Name, " exist") return } g.name = tasks.Name for _, t := range tasks.Task { // log.WithFields(log.Fields{ // "name": t.Name, // "method": t.Method, // "action": t.Action, // "version": t.Version, // "function": t.Fn, // }).Infoln("load task") if t.Name == "nil" || t.Method == "nil" || t.Action == "nil" || t.Version == "nil" || t.Fn == "nil" { log.Errorln("GLWeb gls load Error name method action version fn is nil") continue } for n, r := range self.glsroute { if n == t.Name { log.Errorln("GLWeb gls load Error task name ", t.Name, " exist") continue } if r.pattern == t.Action { log.Errorln("GLWeb gls load Error action ", t.Action, " exist") continue } } self.glsroute[t.Name] = newRoute(g, t.Method, t.Action) g.addtask(t) } self.gls[p] = g self.glps[tasks.Name] = p }
func (c *Config) Map(st interface{}) error { return gluamapper.Map(c.tbl, st) }