diff --git a/etc/init.shy b/etc/init.shy index 76516731..c42427b7 100644 --- a/etc/init.shy +++ b/etc/init.shy @@ -10,4 +10,5 @@ source etc/local.shy alias import nfs alias send send alias dial dial + alias pwd pwd diff --git a/src/contexts/ctx.go b/src/contexts/ctx.go index c44bb821..140cb42c 100644 --- a/src/contexts/ctx.go +++ b/src/contexts/ctx.go @@ -1,6 +1,6 @@ -package ctx // {{{ -// }}} -import ( // {{{ +package ctx + +import ( "encoding/json" "errors" "fmt" @@ -16,18 +16,14 @@ import ( // {{{ "time" ) -// }}} - -func Right(str string) bool { // {{{ +func Right(str string) bool { switch str { case "", "0", "false", "off", "no", "error: ": return false } return true } - -// }}} -func Trans(arg ...interface{}) []string { // {{{ +func Trans(arg ...interface{}) []string { ls := []string{} for _, v := range arg { switch val := v.(type) { @@ -71,9 +67,7 @@ func Trans(arg ...interface{}) []string { // {{{ } return ls } - -// }}} -func Chain(m *Message, data interface{}, args ...interface{}) interface{} { // {{{ +func Chain(m *Message, data interface{}, args ...interface{}) interface{} { if len(args) == 1 { if arg, ok := args[0].([]string); ok { args = args[:0] @@ -223,22 +217,18 @@ func Chain(m *Message, data interface{}, args ...interface{}) interface{} { // { return root } -// }}} - type Cache struct { Name string Value string Help string Hand func(m *Message, x *Cache, arg ...string) string } - type Config struct { Name string Value interface{} Help string Hand func(m *Message, x *Config, arg ...string) string } - type Command struct { Name string Help string @@ -254,7 +244,6 @@ type Server interface { Start(m *Message, arg ...string) bool Close(m *Message, arg ...string) bool } - type Context struct { Name string Help string @@ -276,7 +265,7 @@ type Context struct { Server } -func (c *Context) Register(s *Context, x Server) { // {{{ +func (c *Context) Register(s *Context, x Server) { if c.contexts == nil { c.contexts = make(map[string]*Context) } @@ -288,9 +277,7 @@ func (c *Context) Register(s *Context, x Server) { // {{{ s.context = c s.Server = x } - -// }}} -func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{ +func (c *Context) Spawn(m *Message, name string, help string) *Context { s := &Context{Name: name, Help: help, root: c.root, context: c} if m.target = s; c.Server != nil { @@ -301,9 +288,7 @@ func (c *Context) Spawn(m *Message, name string, help string) *Context { // {{{ return s } - -// }}} -func (c *Context) Begin(m *Message, arg ...string) *Context { // {{{ +func (c *Context) Begin(m *Message, arg ...string) *Context { if len(arg) > 0 { m.Meta["detail"] = arg } @@ -336,9 +321,7 @@ func (c *Context) Begin(m *Message, arg ...string) *Context { // {{{ return c } - -// }}} -func (c *Context) Start(m *Message, arg ...string) bool { // {{{ +func (c *Context) Start(m *Message, arg ...string) bool { if len(arg) > 0 { m.Set("detail", arg...) } @@ -364,9 +347,7 @@ func (c *Context) Start(m *Message, arg ...string) bool { // {{{ }) return <-running } - -// }}} -func (c *Context) Close(m *Message, arg ...string) bool { // {{{ +func (c *Context) Close(m *Message, arg ...string) bool { if len(c.requests) == 0 { return true } @@ -406,20 +387,13 @@ func (c *Context) Close(m *Message, arg ...string) bool { // {{{ } return true } - -// }}} - -func (c *Context) Context() *Context { // {{{ +func (c *Context) Context() *Context { return c.context } - -// }}} -func (c *Context) Message() *Message { // {{{ +func (c *Context) Message() *Message { return c.message } - -// }}} -func (c *Context) Has(key ...string) bool { // {{{ +func (c *Context) Has(key ...string) bool { switch len(key) { case 1: if _, ok := c.Caches[key[0]]; ok { @@ -442,8 +416,6 @@ func (c *Context) Has(key ...string) bool { // {{{ return false } -// }}} - type Message struct { code int time time.Time @@ -465,37 +437,26 @@ type Message struct { Remote chan bool } -func (m *Message) Code() int { // {{{ +func (m *Message) Code() int { return m.code } - -// }}} -func (m *Message) Time() string { // {{{ +func (m *Message) Time() string { return m.time.Format("2006-01-02 15:04:05") } - -// }}} -func (m *Message) Message() *Message { // {{{ +func (m *Message) Message() *Message { return m.message } - -// }}} -func (m *Message) Source() *Context { // {{{ +func (m *Message) Source() *Context { return m.source } - -// }}} -func (m *Message) Target() *Context { // {{{ +func (m *Message) Target() *Context { return m.target } - -// }}} -func (m *Message) Format() string { // {{{ +func (m *Message) Format() string { return fmt.Sprintf("%d(%s->%s): %s %v %v", m.code, m.source.Name, m.target.Name, m.time.Format("15:04:05"), m.Meta["detail"], m.Meta["option"]) } -// }}} -func (m *Message) Tree(code int) *Message { // {{{ +func (m *Message) Tree(code int) *Message { ms := []*Message{m} for i := 0; i < len(ms); i++ { if ms[i].Code() == code { @@ -505,9 +466,7 @@ func (m *Message) Tree(code int) *Message { // {{{ } return nil } - -// }}} -func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // {{{ +func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { switch meta { case "target": m.target = msg.target @@ -544,10 +503,7 @@ func (m *Message) Copy(msg *Message, meta string, arg ...string) *Message { // { return m } - -// }}} - -func (m *Message) Log(action string, str string, arg ...interface{}) *Message { // {{{ +func (m *Message) Log(action string, str string, arg ...interface{}) *Message { l := m.Sess("log", !m.Confs("compact_log")) if l == nil || m.Detail(0) == "log" || m.Detail(0) == "write" || m.Options("silent") { return m @@ -558,8 +514,7 @@ func (m *Message) Log(action string, str string, arg ...interface{}) *Message { return m } -// }}} -func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ +func (m *Message) Assert(e interface{}, msg ...string) bool { switch v := e.(type) { case nil: return true @@ -592,9 +547,7 @@ func (m *Message) Assert(e interface{}, msg ...string) bool { // {{{ m.Log("error", "%s", fmt.Sprintln(e)) panic(m.Set("result", "error: ", fmt.Sprintln(e), "\n")) } - -// }}} -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 { defer func() { if e := recover(); e != nil && e != io.EOF { // switch v := e.(type) { @@ -625,9 +578,7 @@ func (m *Message) TryCatch(msg *Message, safe bool, hand ...func(msg *Message)) return m } -// }}} - -func (m *Message) Instance(msg *Message, source ...bool) bool { // {{{ +func (m *Message) Instance(msg *Message, source ...bool) bool { c := m.target if len(source) > 0 && source[0] == true { c = m.source @@ -640,9 +591,7 @@ func (m *Message) Instance(msg *Message, source ...bool) bool { // {{{ } return false } - -// }}} -func (m *Message) BackTrace(hand func(m *Message) bool, c ...*Context) *Message { // {{{ +func (m *Message) BackTrace(hand func(m *Message) bool, c ...*Context) *Message { target := m.target if len(c) > 0 { m.target = c[0] @@ -655,9 +604,7 @@ func (m *Message) BackTrace(hand func(m *Message) bool, c ...*Context) *Message m.target = target return m } - -// }}} -func (m *Message) Travel(hand func(m *Message, i int) bool, c ...*Context) { // {{{ +func (m *Message) Travel(hand func(m *Message, i int) bool, c ...*Context) { target := m.target if len(c) > 0 { m.target = c[0] @@ -682,9 +629,7 @@ func (m *Message) Travel(hand func(m *Message, i int) bool, c ...*Context) { // m.target = target } -// }}} - -func (m *Message) Spawn(arg ...interface{}) *Message { // {{{ +func (m *Message) Spawn(arg ...interface{}) *Message { c := m.target if len(arg) > 0 { switch v := arg[0].(type) { @@ -707,9 +652,7 @@ func (m *Message) Spawn(arg ...interface{}) *Message { // {{{ m.messages = append(m.messages, msg) return msg } - -// }}} -func (m *Message) Find(name string, root ...bool) *Message { // {{{ +func (m *Message) Find(name string, root ...bool) *Message { target := m.target.root if len(root) > 0 && !root[0] { target = m.target @@ -729,9 +672,7 @@ func (m *Message) Find(name string, root ...bool) *Message { // {{{ m.Log("find", "find %s", name) return m.Spawn(target) } - -// }}} -func (m *Message) Search(key string, root ...bool) []*Message { // {{{ +func (m *Message) Search(key string, root ...bool) []*Message { reg, e := regexp.Compile(key) m.Assert(e) @@ -759,9 +700,7 @@ func (m *Message) Search(key string, root ...bool) []*Message { // {{{ return ms } - -// }}} -func (m *Message) Sess(key string, arg ...interface{}) *Message { // {{{ +func (m *Message) Sess(key string, arg ...interface{}) *Message { spawn := true if _, ok := m.Sessions[key]; !ok && len(arg) > 0 { if m.Sessions == nil { @@ -822,17 +761,13 @@ func (m *Message) Sess(key string, arg ...interface{}) *Message { // {{{ return nil } - -// }}} -func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { // {{{ +func (m *Message) Call(cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { if m.callback = cb; len(arg) > 0 || len(m.Meta["detail"]) > 0 { m.Cmd(arg...) } return m } - -// }}} -func (m *Message) Back(msg *Message) *Message { // {{{ +func (m *Message) Back(msg *Message) *Message { if msg == nil || m.callback == nil { return m } @@ -849,9 +784,7 @@ func (m *Message) Back(msg *Message) *Message { // {{{ return m } - -// }}} -func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { // {{{ +func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg ...interface{}) *Message { if !sync { return m.Call(cb, arg...) } @@ -866,9 +799,7 @@ func (m *Message) CallBack(sync bool, cb func(msg *Message) (sub *Message), arg return <-wait } -// }}} - -func (m *Message) Add(meta string, key string, value ...interface{}) *Message { // {{{ +func (m *Message) Add(meta string, key string, value ...interface{}) *Message { if m.Meta == nil { m.Meta = make(map[string][]string) } @@ -901,9 +832,7 @@ func (m *Message) Add(meta string, key string, value ...interface{}) *Message { return m } - -// }}} -func (m *Message) Set(meta string, arg ...string) *Message { // {{{ +func (m *Message) Set(meta string, arg ...string) *Message { switch meta { case "detail", "result": delete(m.Meta, meta) @@ -927,9 +856,7 @@ func (m *Message) Set(meta string, arg ...string) *Message { // {{{ } return m } - -// }}} -func (m *Message) Put(meta string, key string, value interface{}) *Message { // {{{ +func (m *Message) Put(meta string, key string, value interface{}) *Message { switch meta { case "option", "append": if m.Set(meta, key); m.Data == nil { @@ -943,9 +870,7 @@ func (m *Message) Put(meta string, key string, value interface{}) *Message { // } return m } - -// }}} -func (m *Message) Has(key string) bool { // {{{ +func (m *Message) Has(key string) bool { if _, ok := m.Data[key]; ok { return true } @@ -954,38 +879,27 @@ func (m *Message) Has(key string) bool { // {{{ } return false } - -// }}} -func (m *Message) Get(key string) string { // {{{ +func (m *Message) Get(key string) string { if meta, ok := m.Meta[key]; ok && len(meta) > 0 { return meta[0] } return "" } - -// }}} -func (m *Message) Geti(key string) int { // {{{ +func (m *Message) Geti(key string) int { n, e := strconv.Atoi(m.Get(key)) m.Assert(e) return n } - -// }}} -func (m *Message) Gets(key string) bool { // {{{ +func (m *Message) Gets(key string) bool { return Right(m.Get(key)) } - -// }}} - -func (m *Message) Echo(str string, arg ...interface{}) *Message { // {{{ +func (m *Message) Echo(str string, arg ...interface{}) *Message { if len(arg) > 0 { return m.Add("result", fmt.Sprintf(str, arg...)) } return m.Add("result", str) } - -// }}} -func (m *Message) Color(color int, str string, arg ...interface{}) *Message { // {{{ +func (m *Message) Color(color int, str string, arg ...interface{}) *Message { if len(arg) > 0 { str = fmt.Sprintf(str, arg...) } @@ -994,9 +908,7 @@ func (m *Message) Color(color int, str string, arg ...interface{}) *Message { // } return m.Add("result", str) } - -// }}} -func (m *Message) Table(cbs ...func(maps map[string]string, list []string, line int) (goon bool)) *Message { // {{{ +func (m *Message) Table(cbs ...func(maps map[string]string, list []string, line int) (goon bool)) *Message { var cb func(maps map[string]string, list []string, line int) (goon bool) if len(cbs) > 0 { cb = cbs[0] @@ -1106,9 +1018,7 @@ func (m *Message) Table(cbs ...func(maps map[string]string, list []string, line return m } - -// }}} -func (m *Message) Matrix(index int, arg ...interface{}) string { // {{{ +func (m *Message) Matrix(index int, arg ...interface{}) string { if len(m.Meta["append"]) == 0 || index < 0 { return "" } @@ -1139,9 +1049,7 @@ func (m *Message) Matrix(index int, arg ...interface{}) string { // {{{ } return "" } - -// }}} -func (m *Message) Sort(key string, arg ...string) *Message { // {{{ +func (m *Message) Sort(key string, arg ...string) *Message { table := []map[string]string{} m.Table(func(line map[string]string, lists []string, index int) bool { if index != -1 { @@ -1219,9 +1127,7 @@ func (m *Message) Sort(key string, arg ...string) *Message { // {{{ return m } -// }}} - -func (m *Message) Insert(meta string, index int, arg ...interface{}) string { // {{{ +func (m *Message) Insert(meta string, index int, arg ...interface{}) string { if m.Meta == nil { m.Meta = make(map[string][]string) } @@ -1262,9 +1168,7 @@ func (m *Message) Insert(meta string, index int, arg ...interface{}) string { // } return "" } - -// }}} -func (m *Message) Detail(arg ...interface{}) string { // {{{ +func (m *Message) Detail(arg ...interface{}) string { noset, index := true, 0 if len(arg) > 0 { switch v := arg[0].(type) { @@ -1278,21 +1182,15 @@ func (m *Message) Detail(arg ...interface{}) string { // {{{ return m.Insert("detail", index, arg...) } - -// }}} -func (m *Message) Detaili(arg ...interface{}) int { // {{{ +func (m *Message) Detaili(arg ...interface{}) int { i, e := strconv.Atoi(m.Detail(arg...)) m.Assert(e) return i } - -// }}} -func (m *Message) Details(arg ...interface{}) bool { // {{{ +func (m *Message) Details(arg ...interface{}) bool { return Right(m.Detail(arg...)) } - -// }}} -func (m *Message) Result(arg ...interface{}) string { // {{{ +func (m *Message) Result(arg ...interface{}) string { noset, index := true, 0 if len(arg) > 0 { switch v := arg[0].(type) { @@ -1306,22 +1204,15 @@ func (m *Message) Result(arg ...interface{}) string { // {{{ return m.Insert("result", index, arg...) } - -// }}} -func (m *Message) Resulti(arg ...interface{}) int { // {{{ +func (m *Message) Resulti(arg ...interface{}) int { i, e := strconv.Atoi(m.Result(arg...)) m.Assert(e) return i } - -// }}} -func (m *Message) Results(arg ...interface{}) bool { // {{{ +func (m *Message) Results(arg ...interface{}) bool { return Right(m.Result(arg...)) } - -// }}} - -func (m *Message) Option(key string, arg ...interface{}) string { // {{{ +func (m *Message) Option(key string, arg ...interface{}) string { if len(arg) > 0 { m.Insert(key, 0, arg...) if _, ok := m.Meta[key]; ok { @@ -1341,21 +1232,15 @@ func (m *Message) Option(key string, arg ...interface{}) string { // {{{ } return "" } - -// }}} -func (m *Message) Optioni(key string, arg ...interface{}) int { // {{{ +func (m *Message) Optioni(key string, arg ...interface{}) int { i, e := strconv.Atoi(m.Option(key, arg...)) m.Assert(e) return i } - -// }}} -func (m *Message) Options(key string, arg ...interface{}) bool { // {{{ +func (m *Message) Options(key string, arg ...interface{}) bool { return Right(m.Option(key, arg...)) } - -// }}} -func (m *Message) Optionv(key string, arg ...interface{}) interface{} { // {{{ +func (m *Message) Optionv(key string, arg ...interface{}) interface{} { if len(arg) > 0 { m.Put("option", key, arg[0]) } @@ -1375,17 +1260,13 @@ func (m *Message) Optionv(key string, arg ...interface{}) interface{} { // {{{ } return nil } - -// }}} -func (m *Message) Optionx(key string, format string) interface{} { // {{{ +func (m *Message) Optionx(key string, format string) interface{} { if value := m.Option(key); value != "" { return fmt.Sprintf(format, value) } return "" } - -// }}} -func (m *Message) Append(key string, arg ...interface{}) string { // {{{ +func (m *Message) Append(key string, arg ...interface{}) string { if len(arg) > 0 { m.Insert(key, 0, arg...) if _, ok := m.Meta[key]; ok { @@ -1407,21 +1288,15 @@ func (m *Message) Append(key string, arg ...interface{}) string { // {{{ } return "" } - -// }}} -func (m *Message) Appendi(key string, arg ...interface{}) int { // {{{ +func (m *Message) Appendi(key string, arg ...interface{}) int { i, e := strconv.Atoi(m.Append(key, arg...)) m.Assert(e) return i } - -// }}} -func (m *Message) Appends(key string, arg ...interface{}) bool { // {{{ +func (m *Message) Appends(key string, arg ...interface{}) bool { return Right(m.Append(key, arg...)) } - -// }}} -func (m *Message) Appendv(key string, arg ...interface{}) interface{} { // {{{ +func (m *Message) Appendv(key string, arg ...interface{}) interface{} { if len(arg) > 0 { m.Put("append", key, arg[0]) } @@ -1444,22 +1319,16 @@ func (m *Message) Appendv(key string, arg ...interface{}) interface{} { // {{{ return nil } -// }}} - -func (m *Message) Wait() bool { // {{{ +func (m *Message) Wait() bool { if m.target.exit != nil { return <-m.target.exit } return true } - -// }}} -func (m *Message) Start(name string, help string, arg ...string) bool { // {{{ +func (m *Message) Start(name string, help string, arg ...string) bool { return m.Set("detail", arg...).target.Spawn(m, name, help).Begin(m).Start(m) } - -// }}} -func (m *Message) Cmd(args ...interface{}) *Message { // {{{ +func (m *Message) Cmd(args ...interface{}) *Message { if len(args) > 0 { m.Set("detail", Trans(args...)...) } @@ -1499,10 +1368,7 @@ func (m *Message) Cmd(args ...interface{}) *Message { // {{{ } return m } - -// }}} - -func (m *Message) Confx(key string, arg ...interface{}) string { // {{{ +func (m *Message) Confx(key string, arg ...interface{}) string { conf := m.Conf(key) if len(arg) == 0 { value := m.Option(key) @@ -1557,9 +1423,7 @@ func (m *Message) Confx(key string, arg ...interface{}) string { // {{{ } return value } - -// }}} -func (m *Message) Confs(key string, arg ...interface{}) bool { // {{{ +func (m *Message) Confs(key string, arg ...interface{}) bool { index, value := "", m.Conf(key) if len(arg) > 0 { switch v := arg[0].(type) { @@ -1586,9 +1450,7 @@ func (m *Message) Confs(key string, arg ...interface{}) bool { // {{{ return Right(value) } - -// }}} -func (m *Message) Confi(key string, arg ...interface{}) int { // {{{ +func (m *Message) Confi(key string, arg ...interface{}) int { index, value := "", m.Conf(key) if len(arg) > 0 { if i, ok := arg[0].(string); ok { @@ -1610,9 +1472,7 @@ func (m *Message) Confi(key string, arg ...interface{}) int { // {{{ return n } - -// }}} -func (m *Message) Confv(key string, args ...interface{}) interface{} { // {{{ +func (m *Message) Confv(key string, args ...interface{}) interface{} { var hand func(m *Message, x *Config, arg ...string) string arg := Trans(args...) @@ -1677,9 +1537,7 @@ func (m *Message) Confv(key string, args ...interface{}) interface{} { // {{{ m.target.Configs[key] = &Config{Name: key, Value: Chain(m, nil, args), Help: "auto make", Hand: hand} return Chain(m, key, args[len(args)-2+(len(args)%2)]) } - -// }}} -func (m *Message) Conf(key string, args ...interface{}) string { // {{{ +func (m *Message) Conf(key string, args ...interface{}) string { var hand func(m *Message, x *Config, arg ...string) string for _, c := range []*Context{m.target, m.source} { @@ -1770,9 +1628,7 @@ func (m *Message) Conf(key string, args ...interface{}) string { // {{{ return "" } - -// }}} -func (m *Message) Caps(key string, arg ...bool) bool { // {{{ +func (m *Message) Caps(key string, arg ...bool) bool { if len(arg) > 0 { if arg[0] { m.Cap(key, "1") @@ -1783,9 +1639,7 @@ func (m *Message) Caps(key string, arg ...bool) bool { // {{{ return Right(m.Cap(key)) } - -// }}} -func (m *Message) Capi(key string, arg ...int) int { // {{{ +func (m *Message) Capi(key string, arg ...int) int { n, e := strconv.Atoi(m.Cap(key)) m.Assert(e) @@ -1799,9 +1653,7 @@ func (m *Message) Capi(key string, arg ...int) int { // {{{ return n } - -// }}} -func (m *Message) Cap(key string, arg ...string) string { // {{{ +func (m *Message) Cap(key string, arg ...string) string { var hand func(m *Message, x *Cache, arg ...string) string for _, c := range []*Context{m.target, m.source} { @@ -1842,10 +1694,8 @@ func (m *Message) Cap(key string, arg ...string) string { // {{{ return "" } -// }}} - var CGI = template.FuncMap{ - "meta": func(arg ...interface{}) string { // {{{ + "meta": func(arg ...interface{}) string { //meta meta [key [index]] if len(arg) == 0 { return "" @@ -1894,8 +1744,8 @@ var CGI = template.FuncMap{ return "" } return list[index] - }, // }}} - "sess": func(arg ...interface{}) string { // {{{ + }, + "sess": func(arg ...interface{}) string { if len(arg) == 0 { return "" } @@ -1912,9 +1762,9 @@ var CGI = template.FuncMap{ } } return "" - }, // }}} + }, - "ctx": func(arg ...interface{}) string { // {{{ + "ctx": func(arg ...interface{}) string { if len(arg) == 0 { return "" } @@ -1958,8 +1808,8 @@ var CGI = template.FuncMap{ } } return "" - }, // }}} - "msg": func(arg ...interface{}) interface{} { // {{{ + }, + "msg": func(arg ...interface{}) interface{} { if len(arg) == 0 { return "" } @@ -2002,9 +1852,9 @@ var CGI = template.FuncMap{ } } return "" - }, // }}} + }, - "cap": func(arg ...interface{}) string { // {{{ + "cap": func(arg ...interface{}) string { if len(arg) == 0 { return "" } @@ -2033,8 +1883,8 @@ var CGI = template.FuncMap{ } } return "" - }, // }}} - "conf": func(arg ...interface{}) interface{} { // {{{ + }, + "conf": func(arg ...interface{}) interface{} { if len(arg) == 0 { return "" } @@ -2057,8 +1907,8 @@ var CGI = template.FuncMap{ } } return "" - }, // }}} - "cmd": func(arg ...interface{}) string { // {{{ + }, + "cmd": func(arg ...interface{}) string { if len(arg) == 0 { return "" } @@ -2072,9 +1922,9 @@ var CGI = template.FuncMap{ return strings.Join(msg.Meta["result"], "") } return "" - }, // }}} + }, - "detail": func(arg ...interface{}) interface{} { // {{{ + "detail": func(arg ...interface{}) interface{} { if len(arg) == 0 { return "" } @@ -2106,8 +1956,8 @@ var CGI = template.FuncMap{ return fmt.Sprintf("%v", arg[0]) } return "" - }, // }}} - "option": func(arg ...interface{}) interface{} { // {{{ + }, + "option": func(arg ...interface{}) interface{} { if len(arg) == 0 { return "" } @@ -2149,8 +1999,8 @@ var CGI = template.FuncMap{ return fmt.Sprintf("%v", arg[0]) } return "" - }, // }}} - "result": func(arg ...interface{}) interface{} { // {{{ + }, + "result": func(arg ...interface{}) interface{} { if len(arg) == 0 { return "" } @@ -2182,8 +2032,8 @@ var CGI = template.FuncMap{ return fmt.Sprintf("%v", arg[0]) } return "" - }, // }}} - "append": func(arg ...interface{}) interface{} { // {{{ + }, + "append": func(arg ...interface{}) interface{} { if len(arg) == 0 { return "" } @@ -2225,12 +2075,12 @@ var CGI = template.FuncMap{ return fmt.Sprintf("%v", arg[0]) } return "" - }, // }}} - "unscaped": func(str string) interface{} { // {{{ + }, + "unscaped": func(str string) interface{} { return template.HTML(str) - }, // }}} + }, - "list": func(arg interface{}) interface{} { // {{{ + "list": func(arg interface{}) interface{} { n := 0 switch v := arg.(type) { case string: @@ -2247,11 +2097,9 @@ var CGI = template.FuncMap{ list[i-1] = i } return list - }, // }}} + }, } - var Pulse = &Message{code: 0, time: time.Now(), source: Index, target: Index, Meta: map[string][]string{}} - var Index = &Context{Name: "ctx", Help: "模块中心", Caches: map[string]*Cache{ "nserver": &Cache{Name: "nserver", Value: "0", Help: "服务数量"}, @@ -2280,7 +2128,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", }, Commands: map[string]*Command{ "help": &Command{Name: "help topic", Help: "帮助", Hand: func(m *Message, c *Context, key string, arg ...string) { - if len(arg) == 0 { // {{{ + if len(arg) == 0 { m.Echo("usage: help context [module [command|config|cache name]]\n") m.Echo(" : 查看模块信息, module: 模块名, command: 模块命令, config: 模块配置, cache: 模块缓存, name: 模块参数\n") m.Echo("usage: help command [name]\n") @@ -2429,14 +2277,14 @@ var Index = &Context{Name: "ctx", Help: "模块中心", m.Echo("%s(%s): %s\n", k, values[k].Value, values[k].Name) } } - // }}} + }}, "message": &Command{Name: "message [code] [all]|[cmd...]", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { if len(arg) > 0 && arg[0] == "spawn" { m.Echo("%d", m.Spawn().code) return } - msg := m.Sess("cli", false) // {{{ + msg := m.Sess("cli", false) if len(arg) > 0 { if code, e := strconv.Atoi(arg[0]); e == nil { if msg = m.root.Tree(code); msg != nil { @@ -2538,10 +2386,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心", m.Copy(sub, "result").Copy(sub, "append") } - // }}} }}, "detail": &Command{Name: "detail [index] [value...]", Help: "查看或添加参数", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.message // {{{ + msg := m.message if len(arg) == 0 { m.Echo("%v\n", msg.Meta["detail"]) return @@ -2552,10 +2399,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心", index, arg = i, arg[1:] } m.Echo("%s", msg.Detail(index, arg)) - // }}} + }}, "option": &Command{Name: "option [key [value...]]", Help: "查看或添加选项", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.message // {{{ + msg := m.message if len(arg) == 0 { keys := []string{} values := map[string][]string{} @@ -2583,10 +2430,9 @@ var Index = &Context{Name: "ctx", Help: "模块中心", m.Echo("%s", msg.Option(arg[0])) } - // }}} }}, "result": &Command{Name: "result [value...]", Help: "查看或添加返回值", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.message // {{{ + msg := m.message if len(arg) == 0 { m.Echo("%v\n", msg.Meta["result"]) return @@ -2597,10 +2443,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心", index, arg = i, arg[1:] } m.Echo("%s", msg.Result(index, arg)) - // }}} + }}, "append": &Command{Name: "append [key [value...]]", Help: "查看或添加附加值", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.message // {{{ + msg := m.message if len(arg) == 0 { keys := []string{} values := map[string][]string{} @@ -2641,10 +2487,10 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } m.Echo("%s", msg.Append(arg[0], arg[1:])) - // }}} + }}, "session": &Command{Name: "session [key [cmd...]]", Help: "查看或添加会话", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.message // {{{ + msg := m.message if len(arg) == 0 { keys := []string{} values := map[string]*Message{} @@ -2694,22 +2540,22 @@ var Index = &Context{Name: "ctx", Help: "模块中心", if sub != nil { msg.Sessions[arg[0]] = sub } - // }}} + }}, "callback": &Command{Name: "callback", Help: "查看消息", Hand: func(m *Message, c *Context, key string, arg ...string) { - msg := m.message // {{{ + msg := m.message if len(arg) == 0 { for msg := msg; msg != nil; msg = msg.message { m.Echo("%d: %p\n", msg.code, msg.callback) } } - // }}} + }}, "context": &Command{ Name: "context [[find [root|home]|search [root|home] [name|help] [magic|rand|first|last]] name] [list|info|cache|config|command|switch] [args]", Help: "查找并操作模块,\n查找起点root:根模块、back:父模块、home:本模块,\n查找方法find:路径匹配、search:模糊匹配,\n查找对象name:支持点分和正则,\n操作类型show:显示信息、switch:切换为当前、start:启动模块、spawn:分裂子模块,args:启动参数", Hand: func(m *Message, c *Context, key string, arg ...string) { - action := m.Conf("search_action") // {{{ + action := m.Conf("search_action") if len(arg) == 0 { action = "list" } @@ -2862,13 +2708,13 @@ var Index = &Context{Name: "ctx", Help: "模块中心", // m.target = msg.target } } - // }}} + }}, "server": &Command{ Name: "server [spawn|begin|start|close][args]", Help: "查看、新建、初始化、启动、停止服务", Hand: func(m *Message, c *Context, key string, arg ...string) { - switch len(arg) { // {{{ + switch len(arg) { case 0: m.Travel(func(m *Message, i int) bool { if m.Cap("status") == "start" { @@ -2897,14 +2743,14 @@ var Index = &Context{Name: "ctx", Help: "模块中心", msg.target.Close(msg) } } - // }}} + }}, "command": &Command{ Name: "command [all|add cmd arg...|list [begin [end]]|test [begin [end]]|delete cmd]", Help: "查看或修改命令", Form: map[string]int{"list_name": 1, "list_help": 1, "list_cache": 2, "list_index": 1, "condition": -1}, Hand: func(m *Message, c *Context, key string, arg ...string) { - if len(arg) == 0 { // {{{ + if len(arg) == 0 { keys := []string{} for k, _ := range m.target.Commands { keys = append(keys, k) @@ -3084,13 +2930,13 @@ var Index = &Context{Name: "ctx", Help: "模块中心", delete(m.target.Commands, arg[1]) } } - // }}} + }}, "config": &Command{ Name: "config [all] [save|load file key...] [delete] [pop index] key [value...]|key name value help", Help: "查看、读写、添加配置变量", Hand: func(m *Message, c *Context, key string, arg ...string) { - all := false // {{{ + all := false if len(arg) > 0 && arg[0] == "all" { arg, all = arg[1:], true } @@ -3229,7 +3075,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", m.Assert(e) m.Echo("%s", string(buf)) } - // }}} + }}, "cache": &Command{ Name: "cache [all|key [value]|key = value|key name value help|delete key]", @@ -3276,14 +3122,14 @@ var Index = &Context{Name: "ctx", Help: "模块中心", m.Cap(arg[0], arg[1:]...) } m.Echo("%s", m.Cap(arg[0])) - // }}} + }}, "right": &Command{ Name: "right [share|add|del group [cache|config|command item]]", Help: "用户组管理,查看、添加、删除用户组或是接口", Form: map[string]int{"target": 1}, Hand: func(m *Message, c *Context, key string, arg ...string) { - owner := m.target // {{{ + owner := m.target if m.Has("target") { owner = m.Find(m.Option("target")).target } @@ -3493,7 +3339,7 @@ var Index = &Context{Name: "ctx", Help: "模块中心", } } } - } // }}} + } }}, "format": &Command{ Name: "format", diff --git a/src/contexts/nfs/nfs.go b/src/contexts/nfs/nfs.go index fa5d2b7e..f7723c47 100644 --- a/src/contexts/nfs/nfs.go +++ b/src/contexts/nfs/nfs.go @@ -1,15 +1,13 @@ -package nfs // {{{ -// }}} -import ( // {{{ +package nfs + +import ( + "bufio" "contexts" "encoding/json" - "github.com/nsf/termbox-go" - "github.com/skip2/go-qrcode" - "net" - - "bufio" "errors" "fmt" + "github.com/nsf/termbox-go" + "github.com/skip2/go-qrcode" "io" "io/ioutil" "net/url" @@ -22,10 +20,6 @@ import ( // {{{ "unicode" ) -// }}} - -var FileNotExist = errors.New("file not exist") - type NFS struct { in *os.File out *os.File @@ -35,7 +29,7 @@ type NFS struct { height int paths []string - io net.Conn + io io.ReadWriter send chan *ctx.Message recv chan *ctx.Message @@ -50,7 +44,7 @@ type NFS struct { *ctx.Context } -func (nfs *NFS) open(name string) (*os.File, error) { // {{{ +func (nfs *NFS) open(name string) (*os.File, error) { if path.IsAbs(name) { nfs.Message.Log("info", "open %s", name) return os.Open(name) @@ -64,9 +58,7 @@ func (nfs *NFS) open(name string) (*os.File, error) { // {{{ nfs.Log("info", "open %s", name) return os.Open(name) } - -// }}} -func dir(m *ctx.Message, name string, level int, deep bool, fields []string) { // {{{ +func dir(m *ctx.Message, name string, level int, deep bool, fields []string) { back, e := os.Getwd() m.Assert(e) os.Chdir(name) @@ -155,9 +147,7 @@ func dir(m *ctx.Message, name string, level int, deep bool, fields []string) { / } } } - -// }}} -func (nfs *NFS) insert(rest []rune, letters []rune) []rune { // {{{ +func (nfs *NFS) insert(rest []rune, letters []rune) []rune { n := len(rest) l := len(letters) rest = append(rest, letters...) @@ -169,18 +159,13 @@ func (nfs *NFS) insert(rest []rune, letters []rune) []rune { // {{{ } return rest } - -// }}} - -func (nfs *NFS) escape(form string, args ...interface{}) *NFS { // {{{ +func (nfs *NFS) escape(form string, args ...interface{}) *NFS { if !nfs.Caps("windows") { fmt.Fprintf(nfs.out, "\033[%s", fmt.Sprintf(form, args...)) } return nfs } - -// }}} -func (nfs *NFS) color(str string, attr ...int) *NFS { // {{{ +func (nfs *NFS) color(str string, attr ...int) *NFS { if !nfs.Confs("color") { fmt.Fprint(nfs.out, str) return nfs @@ -205,9 +190,7 @@ func (nfs *NFS) color(str string, attr ...int) *NFS { // {{{ nfs.escape("0m") return nfs } - -// }}} -func (nfs *NFS) print(str string) bool { // {{{ +func (nfs *NFS) print(str string) bool { ls := strings.Split(str, "\n") for i, l := range ls { rest := "" @@ -237,8 +220,7 @@ func (nfs *NFS) print(str string) bool { // {{{ return true } -// }}} -func (nfs *NFS) prompt(arg ...string) string { // {{{ +func (nfs *NFS) prompt(arg ...string) string { ps := nfs.Option("prompt") if nfs.Caps("windows") { nfs.color(ps) @@ -269,10 +251,7 @@ func (nfs *NFS) prompt(arg ...string) string { // {{{ } return ps } - -// }}} - -func (nfs *NFS) zone(buf []string, top, height int) (row, col int) { // {{{ +func (nfs *NFS) zone(buf []string, top, height int) (row, col int) { row, col = len(buf)-1, 0 for i := nfs.Capi("cursor_pos"); i > top-1; { if i -= len(buf[row]) / nfs.width; len(buf[row])%nfs.width > 0 { @@ -286,9 +265,7 @@ func (nfs *NFS) zone(buf []string, top, height int) (row, col int) { // {{{ } return } - -// }}} -func (nfs *NFS) page(buf []string, row, col, top, height int, status bool) { // {{{ +func (nfs *NFS) page(buf []string, row, col, top, height int, status bool) { nfs.escape("2J").escape("H") begin := row @@ -313,9 +290,7 @@ func (nfs *NFS) page(buf []string, row, col, top, height int, status bool) { // nfs.escape("E").color(fmt.Sprintf("pages: %d/%d", begin, len(nfs.pages)), nfs.Confi("statusfgcolor"), nfs.Confi("statusbgcolor")) } } - -// }}} -func (nfs *NFS) View(buf []string, top int, height int) { // {{{ +func (nfs *NFS) View(buf []string, top int, height int) { row, col := nfs.zone(buf, top, height) nfs.page(buf, row, col, top, height, true) @@ -368,9 +343,7 @@ func (nfs *NFS) View(buf []string, top int, height int) { // {{{ } } } - -// }}} -func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ +func (nfs *NFS) Read(p []byte) (n int, err error) { if nfs.Caps("windows") || !nfs.Caps("termbox") { return nfs.in.Read(p) } @@ -562,9 +535,7 @@ func (nfs *NFS) Read(p []byte) (n int, err error) { // {{{ return } -// }}} - -func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ +func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { if len(arg) > 0 && (arg[0] == "scan" || arg[0] == "open" || arg[0] == "append") { c.Caches = map[string]*ctx.Cache{ "pos": &ctx.Cache{Name: "pos", Value: "0", Help: "pos"}, @@ -589,16 +560,12 @@ func (nfs *NFS) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server return s } - -// }}} -func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (nfs *NFS) Begin(m *ctx.Message, arg ...string) ctx.Server { nfs.Message = m nfs.width, nfs.height = 1, 1 return nfs } - -// }}} -func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ +func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { nfs.Message = m if len(arg) > 0 && arg[0] == "scan" { nfs.Caches["windows"] = &ctx.Cache{Name: "windows", Value: "false", Help: "termbox"} @@ -702,7 +669,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ } m.Cap("stream", m.Option("stream")) - nfs.io = m.Optionv("io").(net.Conn) + nfs.io = m.Optionv("io").(io.ReadWriter) nfs.hand = map[int]*ctx.Message{} nfs.send = make(chan *ctx.Message, 10) nfs.recv = make(chan *ctx.Message, 10) @@ -744,10 +711,11 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ }() go func() { //接收消息队列 - bio := bufio.NewScanner(nfs.io) var e error var msg *ctx.Message - for head, body := "", ""; bio.Scan(); { + head, body := "", "" + + for bio := bufio.NewScanner(nfs.io); bio.Scan(); { if msg == nil { msg = m.Sess("target") } @@ -755,9 +723,9 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ msg.Meta = map[string][]string{} } line := bio.Text() + m.Log("recv", "(%s) %s", head, line) m.Capi("nread", len(line)+1) if len(line) == 0 { - if head == "detail" { m.Log("info", "%d recv: %v %v %v", m.Capi("nrecv", 1), msg.Meta[head], msg.Meta[body], msg.Meta) msg.Option("recv_code", m.Cap("nrecv")) @@ -768,7 +736,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ h.Copy(msg, "result").Copy(msg, "append") h.Remote <- true } - msg = nil + msg, head, body = nil, "", "append" continue } @@ -799,9 +767,7 @@ func (nfs *NFS) Start(m *ctx.Message, arg ...string) bool { // {{{ return true } - -// }}} -func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{ +func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { return false switch nfs.Context { case m.Target(): @@ -813,17 +779,12 @@ func (nfs *NFS) Close(m *ctx.Message, arg ...string) bool { // {{{ nfs.out.Close() nfs.out = nil } - if nfs.io != nil { - nfs.io.Close() - nfs.io = nil - } case m.Source(): } return true } -// }}} - +var FileNotExist = errors.New("file not exist") var Index = &ctx.Context{Name: "nfs", Help: "存储中心", Caches: map[string]*ctx.Cache{ "nfile": &ctx.Cache{Name: "nfile", Value: "-1", Help: "已经打开的文件数量"}, @@ -831,11 +792,11 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", Configs: map[string]*ctx.Config{ "pscolor": &ctx.Config{Name: "pscolor", Value: "2", Help: "pscolor"}, "nfs_name": &ctx.Config{Name: "nfs_name", Value: "file", Help: "默认模块命名", Hand: func(m *ctx.Message, x *ctx.Config, arg ...string) string { - if len(arg) > 0 { // {{{ + if len(arg) > 0 { return arg[0] } return fmt.Sprintf("%s%d", x.Value, m.Capi("nfile", 1)) - // }}} + }}, "nfs_help": &ctx.Config{Name: "nfs_help", Value: "file", Help: "默认模块帮助"}, @@ -865,7 +826,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", Name: "paths [add path]|[del index]|[set index path]|[index]", Help: "设置文件搜索路径, add: 添加目录, del: 删除目录, set: 修改目录,index: 目录序号, path: 目录名", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { if len(arg) == 0 { for i, v := range nfs.paths { m.Echo("%d: %s\n", i, v) @@ -892,13 +853,13 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", m.Echo("%d: %s\n", i, nfs.paths[i]) } } - } // }}} + } }}, "scan": &ctx.Command{ Name: "scan filename [nfs_name [nfs_help]]", Help: "扫描文件, filename: 文件名, nfs_name: 模块名, nfs_help: 模块帮助", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { if arg[0] == "stdio" { m.Optionv("in", os.Stdin) m.Optionv("out", os.Stdout) @@ -909,13 +870,13 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } m.Start(m.Confx("nfs_name", arg, 1), m.Confx("nfs_help", arg, 2), key, arg[0]) - } // }}} + } }}, "history": &ctx.Command{ Name: "history [save|load filename [lines [pos]]] [find|search key]", Help: "扫描记录, save: 保存记录, load: 加载记录, filename: 文件名, lines: 加载或保存记录数量, pos: 加载或保存的起始位置, find: 查找记录, search: 搜索记录, key: 查找或搜索的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { // {{{ + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) { if len(arg) == 0 { for i, v := range nfs.history { m.Echo("%d: %s\n", i, v) @@ -1000,34 +961,34 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", m.Echo(nfs.history[i]) } } - } // }}} + } }}, "open": &ctx.Command{ Name: "open filename [nfs_name [nfs_help]]", Help: "打开文件, filename: 文件名, nfs_name: 模块名, nfs_help: 模块帮助", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if m.Has("io") { // {{{ + if m.Has("io") { } else if f, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE, os.ModePerm); m.Assert(e) { m.Put("option", "in", f).Put("option", "out", f) } m.Start(m.Confx("nfs_name", arg, 1), m.Confx("nfs_help", arg, 2), "open", arg[0]) m.Echo(m.Target().Name) - // }}} + }}, "append": &ctx.Command{ Name: "append filename [nfs_name [nfs_help]]", Help: "打开文件, filename: 文件名, nfs_name: 模块名, nfs_help: 模块帮助", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if m.Has("io") { // {{{ + if m.Has("io") { } else if f, e := os.OpenFile(arg[0], os.O_RDWR|os.O_CREATE|os.O_APPEND, os.ModePerm); m.Assert(e) { m.Put("option", "in", f).Put("option", "out", f) } m.Start(m.Confx("nfs_name", arg, 1), m.Confx("nfs_help", arg, 2), "append", arg[0]) m.Echo(m.Target().Name) - // }}} + }}, "read": &ctx.Command{Name: "read [buf_size [pos]]", Help: "读取文件, buf_size: 读取大小, pos: 读取位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil { // {{{ + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.in != nil { n, e := strconv.Atoi(m.Confx("buf_size", arg, 0)) m.Assert(e) @@ -1045,10 +1006,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", if m.Capi("pos", n); n == 0 { m.Cap("pos", "0") } - } // }}} + } }}, "write": &ctx.Command{Name: "write string [pos]", Help: "写入文件, string: 写入内容, pos: 写入位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil { // {{{ + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.out != nil { if len(arg) > 1 { m.Cap("pos", arg[1]) } @@ -1066,10 +1027,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } m.Echo(m.Cap("pos")) - } // }}} + } }}, "load": &ctx.Command{Name: "load file [buf_size [pos]]", Help: "加载文件, buf_size: 加载大小, pos: 加载位置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if f, e := os.Open(arg[0]); m.Assert(e) { // {{{ + if f, e := os.Open(arg[0]); m.Assert(e) { defer f.Close() pos := 0 @@ -1087,34 +1048,34 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", m.Log("info", "read %d", l) m.Echo(string(buf[:l])) } - } // }}} + } }}, "save": &ctx.Command{Name: "save file string...", Help: "保存文件, file: 保存的文件, string: 保存的内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if f, e := os.Create(arg[0]); m.Assert(e) { // {{{ + if f, e := os.Create(arg[0]); m.Assert(e) { defer f.Close() for _, v := range arg[1:] { fmt.Fprint(f, v) } - } // }}} + } }}, "print": &ctx.Command{Name: "print file string...", Help: "输出文件, file: 输出的文件, string: 输出的内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if f, e := os.OpenFile(arg[0], os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666); m.Assert(e) { // {{{ + if f, e := os.OpenFile(arg[0], os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666); m.Assert(e) { defer f.Close() for _, v := range arg[1:] { fmt.Fprint(f, v) } fmt.Fprint(f, "\n") - } // }}} + } }}, "genqr": &ctx.Command{Name: "genqr [qr_size size] filename string...", Help: "生成二维码图片, qr_size: 图片大小, filename: 文件名, string: 输出内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if size, e := strconv.Atoi(m.Confx("qr_size")); m.Assert(e) { // {{{ + if size, e := strconv.Atoi(m.Confx("qr_size")); m.Assert(e) { qrcode.WriteFile(strings.Join(arg[1:], ""), qrcode.Medium, size, arg[0]) - } // }}} + } }}, "json": &ctx.Command{Name: "json [key value]...", Help: "生成格式化内容, key: 参数名, value: 参数值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if len(arg) == 1 { // {{{ + if len(arg) == 1 { var data interface{} e := json.Unmarshal([]byte(arg[0]), &data) m.Assert(e) @@ -1156,10 +1117,10 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", buf, e := json.Marshal(data) m.Assert(e) m.Echo(string(buf)) - // }}} + }}, "pwd": &ctx.Command{Name: "pwd", Help: "查看当前路径", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if m.Options("dir") { // {{{ + if m.Options("dir") { m.Echo(m.Option("dir")) m.Add("append", "hi", "hello") m.Add("append", "he", "hello") @@ -1172,7 +1133,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", } wd, e := os.Getwd() m.Assert(e) - m.Echo(wd) // }}} + m.Echo(wd) m.Append("hi", "hello") }}, "dir": &ctx.Command{ @@ -1180,7 +1141,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", Help: "查看目录, dir: 目录名, dir_info: 显示统计信息, dir_name: 文件名类型, dir_type: 文件类型, sort_field: 排序字段, sort_order: 排序类型", Form: map[string]int{"dir_field": 1, "dir_deep": 1, "dir_info": 1, "dir_name": 1, "dir_type": 1, "sort_field": 1, "sort_order": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - d := "./" + m.Option("dir") // {{{ + d := "./" + m.Option("dir") if len(arg) > 0 { d = arg[0] } @@ -1224,14 +1185,14 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", for _, v := range info { m.Echo("%s: %s\n", v, m.Option(v)) } - // }}} + }}, "git": &ctx.Command{ Name: "git branch|status|diff|log|info arg... [dir path]...", Help: "版本控制, branch: 分支管理, status: 查看状态, info: 查看分支与状态, dir: 指定路径", Form: map[string]int{"dir": 1, "git_info": 1, "git_log": 1, "git_log_form": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if len(arg) == 0 { // {{{ + if len(arg) == 0 { arg = []string{"info"} } cmds := []string{arg[0]} @@ -1354,7 +1315,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", m.Copy(msg, "result").Copy(msg, "append") m.Echo("\n") } - } // }}} + } }}, "listen": &ctx.Command{Name: "listen args...", Help: "启动文件服务, args: 参考tcp模块, listen命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -1370,7 +1331,7 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", }) }, m.Meta["detail"]) } - // }}} + }}, "dial": &ctx.Command{Name: "dial args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if _, ok := m.Target().Server.(*NFS); m.Assert(ok) { //{{{ @@ -1385,14 +1346,14 @@ var Index = &ctx.Context{Name: "nfs", Help: "存储中心", }) }, m.Meta["detail"]) } - // }}} + }}, "send": &ctx.Command{Name: "send [file] args...", Help: "连接文件服务, args: 参考tcp模块, dial命令的参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.io != nil { // {{{ + if nfs, ok := m.Target().Server.(*NFS); m.Assert(ok) && nfs.io != nil { m.Remote = make(chan bool, 1) nfs.send <- m <-m.Remote - } // }}} + } }}, }, } diff --git a/src/contexts/ssh/ssh.go b/src/contexts/ssh/ssh.go index 48fe25b1..a3b36970 100644 --- a/src/contexts/ssh/ssh.go +++ b/src/contexts/ssh/ssh.go @@ -1,15 +1,12 @@ -package ssh // {{{ -// }}} -import ( // {{{ - "contexts" +package ssh +import ( + "contexts" "fmt" "strings" "time" ) -// }}} - type SSH struct { nfs *ctx.Context peer map[string]*ctx.Message @@ -17,35 +14,27 @@ type SSH struct { *ctx.Context } -func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ - c.Caches = map[string]*ctx.Cache{ - "hostname": &ctx.Cache{Name: "hostname", Value: "com", Help: "主机数量"}, - } +func (ssh *SSH) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { + c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} s := new(SSH) s.Context = c return s } - -// }}} -func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (ssh *SSH) Begin(m *ctx.Message, arg ...string) ctx.Server { ssh.Caches["hostname"] = &ctx.Cache{Name: "hostname", Value: "", Help: "主机数量"} if ssh.Context == Index { Pulse = m } return ssh } - -// }}} -func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { // {{{ +func (ssh *SSH) Start(m *ctx.Message, arg ...string) bool { ssh.nfs = m.Source() m.Cap("stream", m.Source().Name) return false } - -// }}} -func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { // {{{ +func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { return false switch ssh.Context { case m.Target(): @@ -65,19 +54,14 @@ func (ssh *SSH) Close(m *ctx.Message, arg ...string) bool { // {{{ } return true } - -// }}} - -func Done(m *ctx.Message, lock chan bool) { // {{{ +func Done(m *ctx.Message, lock chan bool) { m.Log("lock", "done before %v", m.Meta["detail"]) if m.Options("stdio") { lock <- true } m.Log("lock", "done after %v", m.Meta["detail"]) } - -// }}} -func Wait(m *ctx.Message, lock chan bool) { // {{{ +func Wait(m *ctx.Message, lock chan bool) { m.Log("lock", "wait before %v", m.Meta["detail"]) if m.Options("stdio") { <-lock @@ -85,22 +69,21 @@ func Wait(m *ctx.Message, lock chan bool) { // {{{ m.Log("lock", "wait after %v", m.Meta["detail"]) } -// }}} - var Pulse *ctx.Message var Index = &ctx.Context{Name: "ssh", Help: "集群中心", Caches: map[string]*ctx.Cache{ - "nhost": &ctx.Cache{Name: "主机数量", Value: "0", Help: "主机数量"}, + "nhost": &ctx.Cache{Name: "主机数量", Value: "0", Help: "主机数量"}, + "domain": &ctx.Cache{Name: "domain", Value: "", Help: "主机域名"}, + "route": &ctx.Cache{Name: "route", Value: "com", Help: "主机数量"}, "count": &ctx.Cache{Name: "count", Value: "3", Help: "主机数量"}, "share": &ctx.Cache{Name: "share", Value: "root", Help: "主机数量"}, "level": &ctx.Cache{Name: "level", Value: "root", Help: "主机数量"}, - - "domain": &ctx.Cache{Name: "domain", Value: "com", Help: "主机数量"}, }, Configs: map[string]*ctx.Config{ + "hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机数量"}, + "interval": &ctx.Config{Name: "interval", Value: "3", Help: "主机数量"}, - "hostname": &ctx.Config{Name: "hostname", Value: "com", Help: "主机数量"}, "domain.json": &ctx.Config{Name: "domain.json", Value: "var/domain.json", Help: "主机数量"}, "domain.png": &ctx.Config{Name: "domain.png", Value: "var/domain.png", Help: "主机数量"}, @@ -113,35 +96,48 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", "mark": &ctx.Config{Name: "mark", Value: "com", Help: "主机数量"}, }, Commands: map[string]*ctx.Command{ - "listen": &ctx.Command{Name: "listen address protocol", Help: "监听连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{ + "listen": &ctx.Command{Name: "listen address [security [protocol]]", Help: "网络监听", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if _, ok := m.Target().Server.(*SSH); m.Assert(ok) { m.Sess("nfs").Call(func(sub *ctx.Message) *ctx.Message { sub.Start(fmt.Sprintf("host%d", Pulse.Capi("nhost", 1)), "远程主机") + // sub.Spawn().Cmd("pwd", "init") return sub }, m.Meta["detail"]) - m.Spawn(m.Target()).Cmd("save") + if !m.Caps("domain") { + m.Cap("domain", m.Cap("hostname", m.Conf("hostname"))) + } + // m.Spawn(m.Target()).Cmd("save") } - // }}} }}, - "dial": &ctx.Command{Name: "dial address protocol", Help: "建立连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{ + "dial": &ctx.Command{Name: "dial address [security [protocol]]", Help: "网络连接", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { + if _, ok := m.Target().Server.(*SSH); m.Assert(ok) { m.Sess("nfs").CallBack(true, func(sub *ctx.Message) *ctx.Message { sub.Target().Start(sub) - sub.Spawn().Cmd("pwd", m.Conf("hostname")) return sub }, m.Meta["detail"]) } - // }}} }}, "send": &ctx.Command{Name: "send [domain str] cmd arg...", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{ + if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { domain := "" if len(arg) > 1 && arg[0] == "domain" { domain, arg = arg[1], arg[2:] domain = strings.TrimPrefix(strings.TrimPrefix(domain, m.Cap("domain")), ".") } + if m.Has("send_code") { + msg := m.Spawn().Cmd(arg) + m.Copy(msg, "result").Copy(msg, "append") + } else { + msg := m.Spawn(ssh.Message().Source()) + msg.Cmd("send", arg) + m.Copy(msg, "result").Copy(msg, "append") + return + } + + return + if domain != "" { domain_miss := true host := strings.SplitN(domain, ".", 2) @@ -197,36 +193,45 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Copy(msg, "result").Copy(msg, "append") } return - } // }}} + } }}, "pwd": &ctx.Command{Name: "pwd", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if len(arg) == 0 { // {{{ - if m.Target() == c { - m.Echo(m.Cap("domain")) - } else { - m.Echo("%s.%s", m.Cap("domain"), m.Cap("hostname")) + if len(arg) > 0 { + if m.Options("send_code") { + if m.Target() == c { + msg := m.Spawn().Cmd("send", "pwd", m.Confx("hostname", arg, 0)) + m.Cap("hostname", msg.Result(0)) + m.Cap("domain", msg.Result(1)) + } else { + hostname := arg[0] + m.Travel(func(m *ctx.Message, line int) bool { + if hostname == m.Cap("hostname") { + hostname += m.Cap("nhost") + return false + } + return true + }, c) + m.Echo(m.Cap("hostname", hostname)) + m.Echo("%s.%s", m.Cap("domain"), m.Cap("hostname")) + } + return + } + + if m.Target() == c { + m.Conf("hostname", arg[0]) + msg := m.Spawn().Cmd("send", "pwd", arg[0]) + m.Cap("hostname", msg.Result(0)) + m.Cap("domain", msg.Result(1)) + } else { + m.Spawn().Cmd("send", "pwd", arg[0]) + return } - return } - if m.Target() == c { - msg := m.Spawn().Cmd("send", "pwd", arg[0]) - m.Copy(msg, "result").Copy(msg, "append") - m.Cap("domain", msg.Result(0)) - } else if m.Options("send_code") { - hostname := arg[0] - m.Travel(func(m *ctx.Message, line int) bool { - if hostname == m.Cap("hostname") { - hostname += m.Cap("nhost") - return false - } - return true - }, c) - m.Echo("%s.%s", m.Cap("domain"), m.Cap("hostname", hostname)) - } // }}} + m.Echo(m.Cap("domain")) }}, "hello": &ctx.Command{Name: "hello request", Help: "加密请求", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - aaa := m.Target().Message().Sess("aaa", false) // {{{ + aaa := m.Target().Message().Sess("aaa", false) for _, k := range m.Meta["seal"] { for i, v := range m.Meta[k] { m.Meta[k][i] = m.Spawn(aaa).Cmd("deal", v).Result(0) @@ -252,14 +257,14 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", msg := m.Spawn().Copy(m, "option").Cmd(arg) m.Copy(msg, "result").Copy(msg, "append") - // }}} + }}, "shake": &ctx.Command{ Name: "shake [domain host] cmd... [seal option...][encrypt option...]", Help: "加密通信", Form: map[string]int{"seal": -1, "encrypt": -1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { // {{{ + if ssh, ok := m.Target().Server.(*SSH); m.Assert(ok) { if len(arg) == 0 { for k, v := range ssh.peer { m.Echo("%s: %s\n", k, v.Cap("stream")) @@ -304,7 +309,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", msg.Detail("send", args, "hello", arg) ssh.Message().Back(msg) m.Copy(msg, "result").Copy(msg, "append") - } // }}} + } }}, "close": &ctx.Command{Name: "close", Help: "连接断开", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { m.Target().Close(m) @@ -319,21 +324,21 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", }, c) }}, "save": &ctx.Command{Name: "save", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - json := m.Sess("nfs") // {{{ + json := m.Sess("nfs") json.Put("option", "data", map[string]string{"domain": m.Cap("domain")}) json.Cmd("json", m.Conf("domain.json")) m.Sess("nfs").Cmd("genqr", m.Conf("domain.png"), json.Result(0)) - // }}} + }}, "who": &ctx.Command{Name: "who", Help: "远程执行", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - aaa := m.Sess("aaa") // {{{ + aaa := m.Sess("aaa") if aaa != nil { m.Echo(aaa.Cap("group")) } - // }}} + }}, "good": &ctx.Command{Name: "good context|command|config|cache args", Help: "设备注册", Hand: func(m *ctx.Message, c *ctx.Context, cmd string, arg ...string) { - if len(arg) == 0 { // {{{ + if len(arg) == 0 { m.Append("share", m.Cap("share")) m.Append("level", m.Cap("level")) m.Append("type", m.Conf("type")) @@ -399,7 +404,7 @@ var Index = &ctx.Context{Name: "ssh", Help: "集群中心", m.Add("append", "value", x.Value) m.Add("append", "help", x.Help) } - } // }}} + } }}, }, } diff --git a/src/contexts/tcp/tcp.go b/src/contexts/tcp/tcp.go index b398a255..bd703df5 100644 --- a/src/contexts/tcp/tcp.go +++ b/src/contexts/tcp/tcp.go @@ -1,8 +1,7 @@ -package tcp // {{{ -// }}} -import ( // {{{ - "contexts" +package tcp +import ( + "contexts" "crypto/tls" "fmt" "net" @@ -10,22 +9,36 @@ import ( // {{{ "strings" ) -// }}} - type TCP struct { net.Conn net.Listener *ctx.Context } -func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ +func (tcp *TCP) Read(b []byte) (n int, e error) { + m := tcp.Context.Message() + m.Assert(tcp.Conn != nil) + n, e = tcp.Conn.Read(b) + m.Capi("nrecv", n) + m.Assert(e) + return +} +func (tcp *TCP) Write(b []byte) (n int, e error) { + m := tcp.Context.Message() + m.Assert(tcp.Conn != nil) + n, e = tcp.Conn.Write(b) + m.Capi("nsend", n) + m.Assert(e) + return +} + +func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { c.Caches = map[string]*ctx.Cache{ - "protocol": &ctx.Cache{Name: "网络协议(tcp/tcp4/tcp6)", Value: m.Conf("protocol"), Help: "网络协议"}, - "certfile": &ctx.Cache{Name: "certfile", Value: "", Help: "加密通信"}, - "keyfile": &ctx.Cache{Name: "keyfile", Value: "", Help: "加密通信"}, - "address": &ctx.Cache{Name: "网络地址", Value: "", Help: "网络地址"}, - "nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "网络地址"}, - "nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "网络地址"}, + "protocol": &ctx.Cache{Name: "protocol(tcp/tcp4/tcp6)", Value: "", Help: "网络协议"}, + "security": &ctx.Cache{Name: "security(true/false)", Value: "", Help: "加密通信"}, + "address": &ctx.Cache{Name: "address", Value: "", Help: "网络地址"}, + "nrecv": &ctx.Cache{Name: "nrecv", Value: "0", Help: "接收字节数"}, + "nsend": &ctx.Cache{Name: "nsend", Value: "0", Help: "发送字节数"}, } c.Configs = map[string]*ctx.Config{} @@ -33,22 +46,17 @@ func (tcp *TCP) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server s.Context = c return s } - -// }}} -func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (tcp *TCP) Begin(m *ctx.Message, arg ...string) ctx.Server { return tcp } - -// }}} -func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ +func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { m.Cap("address", m.Confx("address", arg, 1)) - m.Cap("certfile", m.Confx("certfile", arg, 2)) - m.Cap("keyfile", m.Confx("keyfile", arg, 3)) - m.Cap("protocol", m.Confx("protocol", arg, 4)) + m.Cap("security", m.Confx("security", arg, 2)) + m.Cap("protocol", m.Confx("protocol", arg, 3)) switch arg[0] { case "dial": - if m.Caps("certfile") { + if m.Caps("security") { m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp")) cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile")) m.Assert(e) @@ -64,20 +72,22 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ } m.Log("info", "%s dial %s", m.Cap("nclient"), - m.Option("stream", m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr())))) - m.Put("option", "io", tcp.Conn).Back(m.Spawn(m.Source())) + m.Cap("stream", fmt.Sprintf("%s->%s", tcp.LocalAddr(), tcp.RemoteAddr()))) + + m.Put("option", "io", tcp).Back(m.Spawn(m.Source())) return false case "accept": - c, e := m.Data["io"].(net.Conn) + c, e := m.Optionv("io").(net.Conn) m.Assert(e) tcp.Conn = c m.Log("info", "%s accept %s", m.Cap("nclient"), - m.Option("stream", m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr())))) - m.Put("option", "io", tcp.Conn).Back(m.Spawn(m.Source())) + m.Cap("stream", fmt.Sprintf("%s<-%s", tcp.LocalAddr(), tcp.RemoteAddr()))) + + m.Put("option", "io", tcp).Back(m.Spawn(m.Source())) return false default: - if m.Caps("certfile") { + if m.Caps("security") { m.Sess("aaa", m.Sess("aaa").Cmd("login", "cert", m.Cap("certfile"), "key", m.Cap("keyfile"), "tcp")) cert, e := tls.LoadX509KeyPair(m.Cap("certfile"), m.Cap("keyfile")) m.Assert(e) @@ -92,23 +102,21 @@ func (tcp *TCP) Start(m *ctx.Message, arg ...string) bool { // {{{ tcp.Listener = l } - m.Log("info", "%d listen %v", m.Capi("nlisten"), m.Cap("stream", fmt.Sprintf("%s", tcp.Addr()))) + m.Log("info", "%d listen %v", m.Capi("nlisten"), + m.Cap("stream", fmt.Sprintf("%s", tcp.Addr()))) } for { c, e := tcp.Accept() m.Assert(e) - msg := m.Spawn(Index).Put("option", "io", c).Put("option", "source", m.Source()) - msg.Call(func(com *ctx.Message) *ctx.Message { + m.Spawn(Index).Put("option", "io", c).Call(func(com *ctx.Message) *ctx.Message { return com.Spawn(m.Source()) }, "accept", c.RemoteAddr().String(), m.Cap("security"), m.Cap("protocol")) } return true } - -// }}} -func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{ +func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { return false switch tcp.Context { case m.Target(): @@ -136,15 +144,13 @@ func (tcp *TCP) Close(m *ctx.Message, arg ...string) bool { // {{{ return true } -// }}} - var Index = &ctx.Context{Name: "tcp", Help: "网络中心", Caches: map[string]*ctx.Cache{ "nlisten": &ctx.Cache{Name: "nlisten", Value: "0", Help: "监听数量"}, "nclient": &ctx.Cache{Name: "nclient", Value: "0", Help: "连接数量"}, }, Configs: map[string]*ctx.Config{ - "address": &ctx.Config{Name: "address", Value: ":9090", Help: "加密通信"}, + "address": &ctx.Config{Name: "address", Value: ":9090", Help: "网络地址"}, "security": &ctx.Config{Name: "security(true/false)", Value: "false", Help: "加密通信"}, "protocol": &ctx.Config{Name: "protocol(tcp/tcp4/tcp6)", Value: "tcp4", Help: "网络协议"}, }, @@ -159,53 +165,39 @@ var Index = &ctx.Context{Name: "tcp", Help: "网络中心", m.Start(fmt.Sprintf("com%d", m.Capi("nclient", 1)), "网络连接", m.Meta["detail"]...) }}, "send": &ctx.Command{Name: "send message", Help: "发送消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) && tcp.Conn != nil { // {{{ - tcp.Conn.Write([]byte(arg[0])) - m.Capi("nsend", len(arg[0])) - } // }}} + if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) { + tcp.Write([]byte(arg[0])) + } }}, "recv": &ctx.Command{Name: "recv size", Help: "接收消息", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) && tcp.Conn != nil { // {{{ - size, e := strconv.Atoi(arg[0]) + if tcp, ok := m.Target().Server.(*TCP); m.Assert(ok) { + n, e := strconv.Atoi(arg[0]) m.Assert(e) + buf := make([]byte, n) - buf := make([]byte, size) - n, e := tcp.Conn.Read(buf) - m.Assert(e) - buf = buf[:n] - - m.Echo(string(buf)) - m.Capi("nrecv", n) - } // }}} + n, _ = tcp.Read(buf) + m.Echo(string(buf[:n])) + } }}, "ifconfig": &ctx.Command{Name: "ifconfig", Help: "网络配置", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - ifs, e := net.Interfaces() // {{{ - m.Assert(e) - for _, v := range ifs { - ips, e := v.Addrs() - m.Assert(e) - for _, x := range ips { - ip := x.String() - if !strings.Contains(ip, ":") && len(ip) > 0 && len(v.HardwareAddr) > 0 { - m.Add("append", "index", v.Index) - m.Add("append", "name", v.Name) - m.Add("append", "hard", v.HardwareAddr) - m.Add("append", "ip", ip) + if ifs, e := net.Interfaces(); m.Assert(e) { + for _, v := range ifs { + if ips, e := v.Addrs(); m.Assert(e) { + for _, x := range ips { + ip := x.String() + if !strings.Contains(ip, ":") && len(ip) > 0 && len(v.HardwareAddr) > 0 { + m.Add("append", "index", v.Index) + m.Add("append", "name", v.Name) + m.Add("append", "hard", v.HardwareAddr) + m.Add("append", "ip", ip) + } + } } } + m.Table() } - m.Table() - // }}} }}, }, - Index: map[string]*ctx.Context{ - "void": &ctx.Context{ - Commands: map[string]*ctx.Command{ - "listen": &ctx.Command{}, - "dial": &ctx.Command{}, - }, - }, - }, } func init() { diff --git a/src/contexts/web/web.go b/src/contexts/web/web.go index 24549659..8f570ea3 100644 --- a/src/contexts/web/web.go +++ b/src/contexts/web/web.go @@ -1,6 +1,6 @@ -package web // {{{ -// }}} -import ( // {{{ +package web + +import ( "bufio" "contexts" "github.com/gomarkdown/markdown" @@ -26,14 +26,11 @@ import ( // {{{ "time" ) -// }}} - type MUX interface { Handle(string, http.Handler) HandleFunc(string, func(http.ResponseWriter, *http.Request)) Trans(*ctx.Message, string, func(*ctx.Message, *ctx.Context, string, ...string)) } - type WEB struct { *http.ServeMux *http.Server @@ -44,7 +41,7 @@ type WEB struct { *ctx.Context } -func (web *WEB) Merge(m *ctx.Message, uri string, arg ...string) string { // {{{ +func (web *WEB) Merge(m *ctx.Message, uri string, arg ...string) string { add, e := url.Parse(uri) m.Assert(e) adds := []string{m.Confx("protocol", add.Scheme, "%s://"), m.Confx("hostname", add.Host)} @@ -86,9 +83,7 @@ func (web *WEB) Merge(m *ctx.Message, uri string, arg ...string) string { // {{{ return strings.Join(adds, "") } - -// }}} -func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.Context, string, ...string)) { // {{{ +func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.Context, string, ...string)) { web.HandleFunc(key, func(w http.ResponseWriter, r *http.Request) { msg := m.Spawn() msg.TryCatch(msg, true, func(msg *ctx.Message) { @@ -154,9 +149,7 @@ func (web *WEB) Trans(m *ctx.Message, key string, hand func(*ctx.Message, *ctx.C }) }) } - -// }}} -func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{ +func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { m := web.Message().Log("info", "").Log("info", "%v %s %s", r.RemoteAddr, r.Method, r.URL) if m.Confs("logheaders") { @@ -186,10 +179,7 @@ func (web *WEB) ServeHTTP(w http.ResponseWriter, r *http.Request) { // {{{ m.Log("info", "") } } - -// }}} - -func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { // {{{ +func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server { c.Caches = map[string]*ctx.Cache{} c.Configs = map[string]*ctx.Config{} @@ -198,9 +188,7 @@ func (web *WEB) Spawn(m *ctx.Message, c *ctx.Context, arg ...string) ctx.Server s.cookie = web.cookie return s } - -// }}} -func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ +func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { web.Caches["route"] = &ctx.Cache{Name: "请求路径", Value: "/" + web.Context.Name + "/", Help: "请求路径"} web.Caches["register"] = &ctx.Cache{Name: "已初始化(yes/no)", Value: "no", Help: "模块是否已初始化"} web.Caches["master"] = &ctx.Cache{Name: "服务入口(yes/no)", Value: "no", Help: "服务入口"} @@ -219,9 +207,7 @@ func (web *WEB) Begin(m *ctx.Message, arg ...string) ctx.Server { // {{{ } return web } - -// }}} -func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{ +func (web *WEB) Start(m *ctx.Message, arg ...string) bool { if len(arg) > 0 { m.Cap("directory", arg[0]) } @@ -307,9 +293,7 @@ func (web *WEB) Start(m *ctx.Message, arg ...string) bool { // {{{ return true } - -// }}} -func (web *WEB) Close(m *ctx.Message, arg ...string) bool { // {{{ +func (web *WEB) Close(m *ctx.Message, arg ...string) bool { switch web.Context { case m.Target(): case m.Source(): @@ -317,8 +301,6 @@ func (web *WEB) Close(m *ctx.Message, arg ...string) bool { // {{{ return true } -// }}} - var Index = &ctx.Context{Name: "web", Help: "应用中心", Caches: map[string]*ctx.Cache{ "nserve": &ctx.Cache{Name: "nserve", Value: "0", Help: "主机数量"}, @@ -531,7 +513,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", Name: "client address [output [editor]]", Help: "添加请求配置, address: 默认地址, output: 输出路径, editor: 编辑器", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if _, e := m.Target().Server.(*WEB); m.Assert(e) { // {{{ + if _, e := m.Target().Server.(*WEB); m.Assert(e) { if len(arg) == 0 { return } @@ -553,13 +535,13 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", if m.Conf("editor", "editor", "vim", "文件编辑器"); len(arg) > 2 { m.Conf("editor", arg[2]) } - } // }}} + } }}, "cookie": &ctx.Command{ Name: "cookie [create]|[name [value]]", Help: "读写请求的Cookie, name: 变量名, value: 变量值", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if web, ok := m.Target().Server.(*WEB); m.Assert(ok) { // {{{ + if web, ok := m.Target().Server.(*WEB); m.Assert(ok) { switch len(arg) { case 0: for k, v := range web.cookie { @@ -583,14 +565,14 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", web.cookie[arg[0]] = &http.Cookie{Name: arg[0], Value: arg[1]} } } - } // }}} + } }}, "get": &ctx.Command{ Name: "get [method GET|POST] [file name filename] url arg...", Help: "访问服务, method: 请求方法, file: 发送文件, url: 请求地址, arg: 请求参数", Form: map[string]int{"method": 1, "headers": 2, "file": 2, "body_type": 1, "body": 1, "fields": 1, "value": 1, "json_route": 1, "json_key": 1}, Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if web, ok := m.Target().Server.(*WEB); m.Assert(ok) { // {{{ + if web, ok := m.Target().Server.(*WEB); m.Assert(ok) { if web.client == nil { web.client = &http.Client{} } @@ -844,7 +826,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", if m.Table(); len(m.Meta["append"]) == 0 { m.Echo("%s", string(buf)) } - } // }}} + } }}, "post": &ctx.Command{Name: "post", Help: "访问服务", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { @@ -864,7 +846,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", case "linux": m.Spawn().Cmd("open", url) } - // }}} + }}, "serve": &ctx.Command{ Name: "serve [directory [address [protocol]]]", @@ -876,7 +858,7 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", Name: "route script|template|directory route content", Help: "添加响应, script: 脚本响应, template: 模板响应, directory: 目录响应, route: 请求路由, content: 响应内容", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if mux, ok := m.Target().Server.(MUX); m.Assert(ok) { // {{{ + if mux, ok := m.Target().Server.(MUX); m.Assert(ok) { switch len(arg) { case 0: for k, v := range m.Target().Commands { @@ -910,26 +892,26 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", mux.Handle(arg[1]+"/", http.StripPrefix(arg[1], http.FileServer(http.Dir(arg[2])))) } } - } // }}} + } }}, "upload": &ctx.Command{Name: "upload file", Help: "上传文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - msg := m.Spawn(m.Target()) // {{{ + msg := m.Spawn(m.Target()) msg.Cmd("get", "/upload", "method", "POST", "file", "file", arg[0]) m.Copy(msg, "result") - // }}} + }}, "/library/": &ctx.Command{Name: "/library", Help: "网页门户", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - r := m.Optionv("request").(*http.Request) // {{{ + r := m.Optionv("request").(*http.Request) w := m.Optionv("response").(http.ResponseWriter) dir := path.Join(m.Conf("library_dir"), m.Option("path")) if s, e := os.Stat(dir); e == nil && !s.IsDir() { http.ServeFile(w, r, dir) return } - // }}} + }}, "/travel": &ctx.Command{Name: "/travel", Help: "文件上传", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - // r := m.Optionv("request").(*http.Request) // {{{ + // r := m.Optionv("request").(*http.Request) // w := m.Optionv("response").(http.ResponseWriter) if !m.Options("dir") { @@ -1020,10 +1002,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } m.Append("template", m.Conf("travel_main"), m.Conf("travel_tmpl")) - // }}} + }}, "/index/": &ctx.Command{Name: "/index", Help: "网页门户", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - r := m.Optionv("request").(*http.Request) // {{{ + r := m.Optionv("request").(*http.Request) w := m.Optionv("response").(http.ResponseWriter) if login := m.Spawn().Cmd("/login"); login.Has("template") { @@ -1065,10 +1047,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", //浏览目录 m.Append("template", m.Append("username")) m.Option("page_title", "index") - // }}} + }}, "/create": &ctx.Command{Name: "/create", Help: "创建目录或文件", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - // if check := m.Spawn().Cmd("/share", "/upload", "dir", m.Option("dir")); !check.Results(0) { // {{{ + // if check := m.Spawn().Cmd("/share", "/upload", "dir", m.Option("dir")); !check.Results(0) { // m.Copy(check, "append") // return // } @@ -1113,10 +1095,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } m.Append("redirect", m.Option("referer")) - // }}} + }}, "/share": &ctx.Command{Name: "/share arg...", Help: "资源共享", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if check := m.Spawn().Cmd("/check", "target", m.Option("module"), m.Optionv("share")); !check.Results(0) { // {{{ + if check := m.Spawn().Cmd("/check", "target", m.Option("module"), m.Optionv("share")); !check.Results(0) { m.Copy(check, "append") return } @@ -1205,10 +1187,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Add("append", "to", u) } } - // }}} + }}, "/check": &ctx.Command{Name: "/check arg...", Help: "权限检查, cache|config|command: 接口类型, name: 接口名称, args: 其它参数", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if login := m.Spawn().Cmd("/login"); login.Has("template") { // {{{ + if login := m.Spawn().Cmd("/login"); login.Has("template") { m.Echo("no").Copy(login, "append") return } @@ -1219,10 +1201,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } m.Echo("ok") - // }}} + }}, "/login": &ctx.Command{Name: "/login", Help: "用户登录", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - if m.Options("sessid") { // {{{ + if m.Options("sessid") { if aaa := m.Sess("aaa").Cmd("login", m.Option("sessid")); aaa.Results(0) { m.Append("redirect", m.Option("referer")) m.Append("username", aaa.Cap("username")) @@ -1242,10 +1224,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", w.WriteHeader(http.StatusUnauthorized) m.Append("template", "login") - // }}} + }}, "/render": &ctx.Command{Name: "/render index", Help: "模板响应, main: 模板入口, tmpl: 附加模板", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - w := m.Optionv("response").(http.ResponseWriter) // {{{ + w := m.Optionv("response").(http.ResponseWriter) w.Header().Add("Content-Type", "text/html") m.Optioni("ninput", 0) @@ -1307,10 +1289,10 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", } } m.Assert(tpl.ExecuteTemplate(w, "tail", m)) - // }}} + }}, "/json": &ctx.Command{Name: "/json", Help: "json响应", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { - w := m.Optionv("response").(http.ResponseWriter) // {{{ + w := m.Optionv("response").(http.ResponseWriter) meta := map[string]interface{}{} if len(m.Meta["result"]) > 0 { @@ -1337,18 +1319,20 @@ var Index = &ctx.Context{Name: "web", Help: "应用中心", m.Log("json", "won %v", string(b)) w.Write(b) } - // }}} + }}, "/paste": &ctx.Command{Name: "/paste", Help: "应用示例", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if login := m.Spawn().Cmd("/login"); login.Has("redirect") { m.Sess("cli").Cmd("system", "tmux", "set-buffer", "-b", "0", m.Option("content")) } + }}, "/blog": &ctx.Command{Name: "/blog", Help: "博客", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if m.Has("title") && m.Has("content") { } m.Echo("blog service") + }}, "/wiki_tags": &ctx.Command{Name: "/wiki_tags ", Help: "博客", Hand: func(m *ctx.Message, c *ctx.Context, key string, arg ...string) { if len(arg) > 0 { diff --git a/usr/wiki/lamp.md b/usr/wiki/lamp.md index f5be41c8..e5fb5318 100644 --- a/usr/wiki/lamp.md +++ b/usr/wiki/lamp.md @@ -134,6 +134,24 @@ $ sftp shy@10.0.0.10 - 公钥文件 ~/.ssh/id_rsa.pub - 授权公钥 ~/.ssh/authorized_keys +#### 编译代码 +计算机由硬件与软件组成,软件又分为操作系统与应用程序。 + +无论是Linux,还是MacOSX,还是Windows,操作系统给应用程序提供了API接口。 +应用程序通过调用这些API接口,实现各种各样的功能。 + +如果现有的工具不能满足需求时,就需要下载工具的源码进行定制编译,或是开发一些模块。 + +API + + + +##### Makefile +make命令根据Makefile文件中定义的规则,调用各种命令,来生成目标文件。 +可以用来调用编译器,将项目的源码文件,编译成可执行文件。 +将源码文件编译成可执行文件。 +[Makefile官方文档](https://www.gnu.org/software/make/manual/make.html) +<> #### 本地化 diff --git a/usr/wiki/zsh_tmux_vim.md b/usr/wiki/zsh_tmux_vim.md index 37d53da1..12d7195b 100644 --- a/usr/wiki/zsh_tmux_vim.md +++ b/usr/wiki/zsh_tmux_vim.md @@ -838,12 +838,12 @@ docker以容器的形式,将程序运行的所有环境,打包成一个独 与VMware或是VirtualBox之类的虚拟机相比,docker更加轻量,docker中的进程和本机进程一样,docker中的文件和本机文件一样,docker只是将它们组织在一起。 而不像虚拟机一样,需要虚拟出一个完整的操作系统,并提供一堆设备驱动程序,一台普通的电脑开几个虚拟机资源就不足了,但docker却像进程一样占有很少的资源,可以运行很多容器。 -docker分为企业版EE,社区版CE,对于个人使用社会版即可。更多信息参考:[docker官网](https://docs.docker.com/) +docker分为企业版EE,社区版CE,对于个人使用社区版即可。更多信息参考:[docker官网](https://docs.docker.com/) - [Windows版docker下载](https://store.docker.com/editions/community/docker-ce-desktop-windows) - [Mac版docker下载](https://store.docker.com/editions/community/docker-ce-desktop-mac) -Ubuntu上安装docker +Ubuntu上安装docker,还需要将docker官网加到软件源中 ``` $ curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add - $ sudo add-apt-repository \ @@ -854,256 +854,310 @@ $ sudo apt-get update $ sudo apt-get install docker-ce ``` - - +#### 入门体验 +如下示例,run命令用busybox镜像,启动了docker的一个容器。 ``` -$ docker -Usage: docker [OPTIONS] COMMAND - -A self-sufficient runtime for containers - -Options: - --config string Location of client config files (default "/Users/shaoying/.docker") - -D, --debug Enable debug mode - -H, --host list Daemon socket(s) to connect to - -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") - --tls Use TLS; implied by --tlsverify - --tlscacert string Trust certs signed only by this CA (default "/Users/shaoying/.docker/ca.pem") - --tlscert string Path to TLS certificate file (default "/Users/shaoying/.docker/cert.pem") - --tlskey string Path to TLS key file (default "/Users/shaoying/.docker/key.pem") - --tlsverify Use TLS and verify the remote - -v, --version Print version information and quit - -Management Commands: - checkpoint Manage checkpoints - config Manage Docker configs - container Manage containers - image Manage images - network Manage networks - node Manage Swarm nodes - plugin Manage plugins - secret Manage Docker secrets - service Manage services - stack Manage Docker stacks - swarm Manage Swarm - system Manage Docker - trust Manage trust on Docker images - volume Manage volumes - -Commands: - attach Attach local standard input, output, and error streams to a running container - build Build an image from a Dockerfile - commit Create a new image from a container's changes - cp Copy files/folders between a container and the local filesystem - create Create a new container - deploy Deploy a new stack or update an existing stack - diff Inspect changes to files or directories on a container's filesystem - events Get real time events from the server - exec Run a command in a running container - export Export a container's filesystem as a tar archive - history Show the history of an image - images List images - import Import the contents from a tarball to create a filesystem image - info Display system-wide information - inspect Return low-level information on Docker objects - kill Kill one or more running containers - load Load an image from a tar archive or STDIN - login Log in to a Docker registry - logout Log out from a Docker registry - logs Fetch the logs of a container - pause Pause all processes within one or more containers - port List port mappings or a specific mapping for the container - ps List containers - pull Pull an image or a repository from a registry - push Push an image or a repository to a registry - rename Rename a container - restart Restart one or more containers - rm Remove one or more containers - rmi Remove one or more images - run Run a command in a new container - save Save one or more images to a tar archive (streamed to STDOUT by default) - search Search the Docker Hub for images - start Start one or more stopped containers - stats Display a live stream of container(s) resource usage statistics - stop Stop one or more running containers - tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE - top Display the running processes of a container - unpause Unpause all processes within one or more containers - update Update configuration of one or more containers - version Show the Docker version information - wait Block until one or more containers stop, then print their exit codes - -Run 'docker COMMAND --help' for more information on a command. +$ docker run -it busybox +Unable to find image 'busybox:latest' locally +latest: Pulling from library/busybox +8c5a7da1afbc: Pull complete +Digest: sha256:cb63aa0641a885f54de20f61d152187419e8f6b159ed11a251a09d115f_f9bd +Status: Downloaded newer image for busybox:latest +/ # ``` +这里本机并没有busybox的镜像,所以docker自动从dockhub上,下载了busybox的镜像,并用这个镜像启动了一个容器。 +像github共享代码一样,dockhub上也共享了各种系统镜像,用户可以自由的下载与上传。 +run命令需要一个参数,指定镜像的名称与版本,这里镜像的名字为busybox,默认的版本为latest,即最新版。 +busybox是将Unix下的常用命令经过挑选裁剪集成到一个程序中,搭配Linux内核就可以做出一个小型的操作系统,在嵌入式领域应用广泛。 +体积小到只有1M左右,下载很快,所以这里用做示例。更多信息参考[busybox官网](https://busybox.net/) + +"/ #",看到最后一行的的命令提示符,就知道容器已经启动了,就可以在这个容器的shell中,执行各种命令与操作了。最后用Ctrl+D或关闭终端窗口,就可以结束容器。 +再次运行run,又可以重新启动容器。 + + + +如下示例,除了交互式启动容器,还可以用守护的方式启动容器。 ``` -$ docker -Usage: docker [OPTIONS] COMMAND - -A self-sufficient runtime for containers - -Options: - --config string Location of client config files (default "/Users/shaoying/.docker") - -D, --debug Enable debug mode - -H, --host list Daemon socket(s) to connect to - -l, --log-level string Set the logging level ("debug"|"info"|"warn"|"error"|"fatal") (default "info") - --tls Use TLS; implied by --tlsverify - --tlscacert string Trust certs signed only by this CA (default "/Users/shaoying/.docker/ca.pem") - --tlscert string Path to TLS certificate file (default "/Users/shaoying/.docker/cert.pem") - --tlskey string Path to TLS key file (default "/Users/shaoying/.docker/key.pem") - --tlsverify Use TLS and verify the remote - -v, --version Print version information and quit - -Management Commands: - checkpoint Manage checkpoints - node Manage Swarm nodes - plugin Manage plugins - secret Manage Docker secrets - service Manage services - stack Manage Docker stacks - swarm Manage Swarm - trust Manage trust on Docker images - -Commands: - attach Attach local standard input, output, and error streams to a running container - build Build an image from a Dockerfile - commit Create a new image from a container's changes - cp Copy files/folders between a container and the local filesystem - create Create a new container - deploy Deploy a new stack or update an existing stack - diff Inspect changes to files or directories on a container's filesystem - events Get real time events from the server - exec Run a command in a running container - export Export a container's filesystem as a tar archive - history Show the history of an image - images List images - import Import the contents from a tarball to create a filesystem image - info Display system-wide information - inspect Return low-level information on Docker objects - kill Kill one or more running containers - load Load an image from a tar archive or STDIN - login Log in to a Docker registry - logout Log out from a Docker registry - logs Fetch the logs of a container - pause Pause all processes within one or more containers - port List port mappings or a specific mapping for the container - ps List containers - pull Pull an image or a repository from a registry - push Push an image or a repository to a registry - rename Rename a container - restart Restart one or more containers - rm Remove one or more containers - rmi Remove one or more images - run Run a command in a new container - save Save one or more images to a tar archive (streamed to STDOUT by default) - search Search the Docker Hub for images - start Start one or more stopped containers - stats Display a live stream of container(s) resource usage statistics - stop Stop one or more running containers - tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE - top Display the running processes of a container - unpause Unpause all processes within one or more containers - update Update configuration of one or more containers - version Show the Docker version information - wait Block until one or more containers stop, then print their exit codes - -Run 'docker COMMAND --help' for more information on a command. +$ docker run -dt --name demo busybox +d71c8e37bcc153db239f8b1eccb5fa53d202df84d3ffa7ae4e7f8c051d0d481a ``` +- "-dt",指定容器守护的方式运行,即使终端窗口关闭了,守护式的容器会在后台一直运行,可以被反复连接使用。 +- "--name demo",指定了容器的名字为demo,每个容器启动后docker会生成一个sha256的哈希值,如这里的"d71c8e37bcc153db239f8b1eccb5fa53d202df84d3ffa7ae4e7f8c051d0d481a" +在之后的命令中,参数中需要指定容器的地方,都可以这个sha256的哈希值,也可以只写出前几位。但为了方便记忆,可以给容器指定名字。 +- "busybox",指定镜像名字与版本 -镜像管理 -image Manage images - -容器管理 -container Manage containers - -配置管理 -config Manage Docker configs - -系统管理 -system Manage Docker - -网络管理 -network Manage networks - -磁盘管理 -volume Manage volumes - -#### docker镜像管理 - -- 查看镜像 docker image ls -- 下载镜像 docker image pull - -刚安装docker后,查看镜像列表,如下为空。 -``` -$ docker image ls -REPOSITORY TAG IMAGE ID CREATED SIZE -``` -像github管理代码仓库一样,docker hub上也存放了很多镜像,用户可以自由的下载与上传各种镜像。 -如下示例,下载一个busybox镜像。busybox是将Unix下的常用命令经过挑选裁剪集成一个程序中,搭配Linux内核就可以做出一个小型的操作系统,在嵌入式领域应用广泛。 -体积很小不到1M,下载很快,所以这里用做示例。更多信息参考[busybox官网](https://busybox.net/) -``` -$ docker image pull busybox -``` -下载完成后,再查看镜像列表,就会看到busybox镜像相关的信息。 -``` -$ docker image ls -REPOSITORY TAG IMAGE ID CREATED SIZE -busybox latest e1ddd7948a1c 6 weeks ago 1.16MB -``` -#### docker容器管理 - -- 查看容器 docker ps -- 启动容器 docker run -- 停止容器 docker exec -- 停止容器 docker stop - -如下示例,查看容器列表,因为还没启动任何容器,所以这里为空。 +如下示例,ps命令可以查看正在运行的容器。 ``` $ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +d71c8e37bcc1 busybox "sh" 14 seconds ago Up 13 seconds demo ``` -如下示例,用busybox:latest镜像,启动一个容器,并调用sh命令。 +如下示例,top命令可以查看某容器中运行的进程 ``` -$ docker run --name demo -dt busybox:latest sh -29ff6b8343c4a2c57eab297e74e62422ab9bbd481d69f5ebf108f4aa23ae835c -``` -其中,-d 指用守护的方式启动,与交互式 -i 不同,守护式启动,容器可以一直运行,不会因为终端容器关闭而停止。 ---name参数,指定容器的名字为demo,docker中标识容器有两种方式,一是通过ID查找容器,二是通过NAMES查找容器,为了方便记忆与查找,建议启动容器时加上名字参数。 - -如下示例,再次查看容器列表,看到容器已经启动。 -``` -$ docker ps -CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES -29ff6b8343c4 busybox:latest "sh" 4 minutes ago Up 4 minutes demo +$ docker top demo +PID USER TIME COMMAND +4163 root 0:00 sh ``` -连接容器demo,调用命令解析器sh。这样就连接上了容器的命令行,可以执行各种命令。 +如下示例,exec可以在容器中运行各种命令,并将命令输出到当前终端。 +``` +$ docker exec demo uname +Linux +$ docker exec demo hostname +d71c8e37bcc1 +``` +如下示例,还可以连接容器,启动一个交互shell。Ctrl+D或是关闭终端窗口,只会结束当前shell,容器依然还在后台继续运行。还可以被反复连接。 ``` $ docker exec -it demo sh -# +/ # +``` +如下示例,还可以对容器进行重命名。可以用ps命令查看,新名字已经生效。 +``` +$ docker rename demo demo1 ``` -容器的停止,退出连接后,容器依然在后台运行,可以反复被连接。如果想停止容器的运行就用stop命令。 +容器中的根文件系统与本机的文件系统是完全隔离的,所以才能提供给容器中应用一个独立的运行环境。 + +如下示例,可以将本机文件复制到容器中。 ``` -$ docker stop demo +$ docker cp ~/.vimrc demo1:/root +$ docker exec demo1 ls -a /root +. +.. +.vimrc +``` +如下示例,可以将容器中文件复制到本机。 +``` +$ docker cp demo1:/root vimrc +$ ls +vimrc ``` -#### 挂载文件 -之前启动的容器都是与本机之间没有什么交互,是一个完全独立的运行环境。 -如果需要容器与本机交互一些文件,就可以在启动容器时指定文件参数。 +如下示例,停止容器 ``` -$ docker run --name demo1 -v/Users/shaoying:/home/shaoying -dt busybox:latest sh +$ docker stop demo1 ``` -#### 端口映射 +ps命令默认只查看正在运行的容器,如果要查看已经停止的容器可以加参数-a +``` +$ docker ps -a +CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES +513a5e1fc6f4 busybox "sh" 4 minutes ago Exited (137) 3 seconds ago demo1 +``` + +如下示例,已经停止的容器,还可以再启动,继续运行。 +``` +$ docker start demo1 +``` + +如下示例,如果确定已经停止的容器,不会再次启动使用,可以删除掉。 +``` +$ docker rm demo1 +``` + +#### 镜像管理 +``` +docker images +image Manage images + +images List images +search Search the Docker Hub for images +pull Pull an image or a repository from a registry +push Push an image or a repository to a registry +save Save one or more images to a tar archive (streamed to STDOUT by default) +load Load an image from a tar archive or STDIN +rmi Remove one or more images + +history Show the history of an image +build Build an image from a Dockerfile +tag Create a tag TARGET_IMAGE that refers to SOURCE_IMAGE +``` + +#### 容器管理 +``` +stats Display a live stream of container(s) resource usage statistics +attach Attach local standard input, output, and error streams to a running container +container Manage containers +commit Create a new image from a container's changes +diff Inspect changes to files or directories on a container's filesystem +kill Kill one or more running containers +wait Block until one or more containers stop, then print their exit codes +create Create a new container +pause Pause all processes within one or more containers +unpause Unpause all processes within one or more containers +export Export a container's filesystem as a tar archive +import Import the contents from a tarball to create a filesystem image +logs Fetch the logs of a container +restart Restart one or more containers +update Update configuration of one or more containers +volume Manage volumes +network Manage networks +``` + +#### 系统管理 +``` +deploy Deploy a new stack or update an existing stack +version Show the Docker version information +system Manage Docker +info Display system-wide information +login Log in to a Docker registry +logout Log out from a Docker registry +inspect Return low-level information on Docker objects +secret Manage Docker secrets +trust Manage trust on Docker images +``` + +#### 集群管理 +``` +config Manage Docker configs +checkpoint Manage checkpoints +plugin Manage plugins +service Manage services +swarm Manage Swarm +node Manage Swarm nodes +stack Manage Docker stacks +``` + +### git使用 +软件的开发是不断的迭代,不断的优化,不断的升级,是一个循序渐进的过程。 +所以需要对代码进行版本管理,记录每次提交的代码,可以随时查看变化与切换版本。 + +软件开发有时需要同时进行多个任务,如在开发新功能时,需要修复线上bug,所以需要分支管理。 +一般一个项目中至少会有三种分支:master、feature、bugfix。 + +此外软件开发的项目都一般是由团队完成,要多人协作共同完成功能开发,所以需要仓库管理,管理多人的代码。 + +git就是这样一种开源的代码管理工具,可以用来管理代码的版本、分支、仓库等。 -### git入门 Mac上自带git,不需要安装。 Windows上安装了的git-scm,也集成了git,也不需要单独安装。 但Ubuntu需要自己安装一下。 ``` $ sudo apt-get install git ``` +#### git 基础入门 +git help tutorial +git help everyday +git help workflows +git help glossary + +git是一个命令集合,有很多子命令,可以通过help命令来查看。 +``` +$ git help +``` + +git init +git status +git diff +git add +git mv +git rm +git reset +git commit +git checkout +git blame +git log +git tag + +git branch +git merge +git rebase + +git config +git clone +git remote +git revert +git fetch +git pull +git push + +git bisect +git grep +git show + + +add merge-octopus +add--interactive merge-one-file +am merge-ours +annotate merge-recursive +apply merge-resolve +archimport merge-subtree +archive merge-tree +bisect mergetool +bisect--helper mktag +blame mktree +branch mv +bundle name-rev +cat-file notes +check-attr p4 +check-ignore pack-objects +check-mailmap pack-redundant +check-ref-format pack-refs +checkout patch-id +checkout-index prune +cherry prune-packed +cherry-pick pull +citool push +clean quiltimport +clone read-tree +column rebase +commit receive-pack +commit-tree reflog +config relink +count-objects remote +credential remote-ext +credential-cache remote-fd +credential-cache--daemon remote-ftp +credential-osxkeychain remote-ftps +credential-store remote-http +cvsexportcommit remote-https +cvsimport remote-testsvn +cvsserver repack +daemon replace +describe request-pull +diff rerere +diff-files reset +diff-index rev-list +diff-tree rev-parse +difftool revert +difftool--helper rm +fast-export send-email +fast-import send-pack +fetch sh-i18n--envsubst +fetch-pack shell +filter-branch shortlog +fmt-merge-msg show +for-each-ref show-branch +format-patch show-index +fsck show-ref +fsck-objects stage +gc stash +get-tar-commit-id status +grep stripspace +gui--askpass submodule +hash-object submodule--helper +help subtree +http-backend svn +http-fetch symbolic-ref +http-push tag +imap-send unpack-file +index-pack unpack-objects +init update-index +init-db update-ref +instaweb update-server-info +interpret-trailers upload-archive +log upload-pack +ls-files var +ls-remote verify-commit +ls-tree verify-pack +mailinfo verify-tag +mailsplit web--browse +merge whatchanged +merge-base worktree +merge-file write-tree +merge-index + ### vim入门 Mac上自带vim,不需要安装。 Windows上安装了的git-scm,也集成了vim,也不需要单独安装。