diff --git a/.idea/learninggo.iml b/.idea/learninggo.iml new file mode 100644 index 0000000..c956989 --- /dev/null +++ b/.idea/learninggo.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..28a804d --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..2a89827 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..94a25f7 --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/workspace.xml b/.idea/workspace.xml new file mode 100644 index 0000000..b87b5bb --- /dev/null +++ b/.idea/workspace.xml @@ -0,0 +1,370 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + ta + string + + + + + + + + + + + + true + DEFINITION_ORDER + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + file://$PROJECT_DIR$/server/main.go + 71 + + + + file:///usr/local/go/src/net/net.go + 173 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/net/client/main.go b/net/client/main.go new file mode 100644 index 0000000..584d7f1 --- /dev/null +++ b/net/client/main.go @@ -0,0 +1,48 @@ +package main + +import ( + "bufio" + "fmt" + "io" + "net" + "os" + "time" +) + +func main() { + + c, err := net.Dial("unix", "/tmp/test.sock") + if err != nil { + panic(err) + } + defer c.Close() + + reader(c) + for { + r := bufio.NewReader(os.Stdin) + fmt.Println("text to send") + text, _ := r.ReadString('\n') + fmt.Println(text) + c.Write([]byte(text)) + + bufio.NewReader(c) + _, err = c.Write([]byte("hello")) + if err != nil { + panic(err) + } + time.Sleep(2 * time.Second) + } +} + +func reader(r io.Reader) { + buf := make([]byte, 1024) + for { + fmt.Println("read from conn") + n, err := r.Read(buf[:]) + if err != nil { + fmt.Println(err) + return + } + fmt.Println("got data", string(buf[0:n])) + } +} diff --git a/net/server/main.go b/net/server/main.go new file mode 100644 index 0000000..c8eb5c4 --- /dev/null +++ b/net/server/main.go @@ -0,0 +1,83 @@ +package main + +import ( + "fmt" + "log" + "net" + "os" + "os/signal" + "sync" + "syscall" +) + +func main() { + + var l net.Listener + _, err := os.Stat("/tmp/test.sock") + if os.IsNotExist(err) { + l, err = net.Listen("unix", "/tmp/test.sock") + } + f, _ := l.(*net.UnixListener).File() + l2, err := net.FileListener(f) + if err != nil { + panic(err) + } + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, os.Interrupt, syscall.SIGTERM, syscall.SIGPIPE) + var wg sync.WaitGroup + wg.Add(1) + go func(ln net.Listener, c chan os.Signal) { + sig := <-c + log.Printf("Caught signal %s: shutting down.", sig) + ln.Close() + os.Exit(0) + }(l, sigc) + go func() { + for { + fmt.Println("waiting for l2 to accept connection") + conn, err := l2.Accept() + if err != nil { + fmt.Printf("failed to accept connection %+v\n", err) + continue + } + fmt.Println("connection accepted from listener l2") + go handleConn(conn) + } + }() + go func() { + n := 0 + for { + if n = n + 1; n == 5 { + break + } + fmt.Println("waiting for l1 to accept connection") + conn, err := l.Accept() + if err != nil { + fmt.Printf("failed to accept connection %+v\n", err) + continue + } + fmt.Println("connection accepted from listener l1") + go handleConn(conn) + } + + }() + wg.Wait() +} + +func handleConn(c net.Conn) { + defer c.Close() + net.Pipe() + buf := make([]byte, 1024) + for { + n, err := c.Read(buf[0:]) + if err != nil { + return + } + data := buf[0:n] + fmt.Println(string(data)) + _, err = c.Write([]byte("write from server")) + if err != nil { + fmt.Println("write error: ", err) + } + } +} diff --git a/pipestdio/main.go b/pipestdio/main.go new file mode 100644 index 0000000..0d0a479 --- /dev/null +++ b/pipestdio/main.go @@ -0,0 +1,21 @@ +package main + +import ( + "bufio" + "fmt" + "os" +) + +func main() { + + r := bufio.NewReader(os.Stdin) + var b [1024]byte + for { + n, err := r.Read(b[:]) + if err != nil { + break + } + fmt.Print(string(b[0:n])) + } + +} diff --git a/pipestdio/namedpipe/Dockerfile b/pipestdio/namedpipe/Dockerfile new file mode 100644 index 0000000..3746dbd --- /dev/null +++ b/pipestdio/namedpipe/Dockerfile @@ -0,0 +1,21 @@ +FROM golang:1.10.3-alpine3.8 AS builder + +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories + +RUN apk update && \ + apk add git build-base && \ + rm -rf /var/cache/apk/* && \ + mkdir -p "$GOPATH/src/gitlab.alipay-inc.com/basement/cube/logcollector" + +ADD . "$GOPATH/src/gitlab.alipay-inc.com/basement/cube/logcollector" + +RUN cd "$GOPATH/src/gitlab.alipay-inc.com/basement/cube/logcollector" && \ + CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a --installsuffix cgo --ldflags="-s" -o /logcollector ./ + +FROM alpine:3.8 +RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/' /etc/apk/repositories +RUN apk add --update ca-certificates + +COPY --from=builder /logcollector /bin/logcollector + +ENTRYPOINT ["/bin/logcollector"] \ No newline at end of file diff --git a/pipestdio/namedpipe/main.go b/pipestdio/namedpipe/main.go new file mode 100644 index 0000000..5232887 --- /dev/null +++ b/pipestdio/namedpipe/main.go @@ -0,0 +1,90 @@ +package main + +import ( + "bytes" + "fmt" + "io/ioutil" + "log" + "net/http" + "os" + "os/signal" + "path/filepath" + "syscall" +) + +func main() { + // createLogEntry() + // appendLog() + namedPipe() +} + +func namedPipe() { + namedPipe := filepath.Join("/var/applogs", "stdout") + fmt.Println(namedPipe) + syscall.Mkfifo(namedPipe, 0600) + + stdout, _ := os.OpenFile(namedPipe, os.O_RDONLY, 0600) + defer stdout.Close() + fmt.Println("reading") + + sigc := make(chan os.Signal, 1) + signal.Notify(sigc, os.Interrupt, syscall.SIGTERM, syscall.SIGPIPE) + go func(c chan os.Signal) { + sig := <-c + log.Printf("Caught signal %s: shutting down.", sig) + os.Exit(0) + }(sigc) + + var b [512]byte + httpClient := http.DefaultClient + for { + fmt.Println("reading from namedpipe") + n, err := stdout.Read(b[:]) + if err != nil { + fmt.Println(err) + continue + } + req, _ := http.NewRequest("PUT", "https://tfapi.alipay.com/api/v1/logs/5be2f1890ab517886f7fff86", bytes.NewReader(b[0:n])) + resp, err := httpClient.Do(req) + if err != nil { + panic(err) + } + resp.Body.Close() + } +} + +func createLogEntry() { + httpClient := &http.Client{} + // b, _ := json.Marshal(struct { + // append bool + // }{ + // append: true, + // }) + + req, _ := http.NewRequest("POST", "https://tfapi.alipay.com/api/v1/logs?append", nil) + req.Header.Set("Content-Type", "application/json") + resp, err := httpClient.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + + body, err := ioutil.ReadAll(resp.Body) + fmt.Println(resp.StatusCode) + if err != nil { + panic(err) + } + fmt.Println(string(body)) +} + +func appendLog() { + httpClient := http.DefaultClient + req, _ := http.NewRequest("PUT", "https://tfapi.alipay.com/api/v1/logs/5be2ddfff8b5f7fa3ff36831", bytes.NewReader([]byte("hello world"))) + resp, err := httpClient.Do(req) + if err != nil { + panic(err) + } + defer resp.Body.Close() + fmt.Println(resp.StatusCode) + +} diff --git a/syscall/container/container b/syscall/container/container deleted file mode 100755 index c770028..0000000 Binary files a/syscall/container/container and /dev/null differ diff --git a/syscall/container/main_linux.go b/syscall/container/main_linux.go index dfa9e06..aec2ab3 100644 --- a/syscall/container/main_linux.go +++ b/syscall/container/main_linux.go @@ -4,8 +4,11 @@ package main import ( "fmt" + "io/ioutil" "os" "os/exec" + "path/filepath" + "strconv" "syscall" ) @@ -31,6 +34,16 @@ func run() { cmd.Stderr = os.Stderr cmd.SysProcAttr = &syscall.SysProcAttr{ Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS, + // use user ns enable you to do something with root privilege inside container + // notice that at this moment you can not use cgroup along with NEWUSER flag + // | syscall.CLONE_NEWUSER, + // Credential: &syscall.Credential{Uid: 0, Gid 0}, + // UidMappings: []syscall.SysProcIDMap { + // {ContainerID: 0, HostID: os.Getpid(), Size: 1} + // }, + // GidMappings: []syscall.SysProcIDMap { + // {ContainerID: 0, HostID: os.Getpid(), Size: 1} + // }, } cmd.Run() @@ -39,6 +52,7 @@ func run() { func child() { fmt.Printf("Running inside container %v\n", os.Args[2:]) + cgroup() cmd := exec.Command(os.Args[2], os.Args[3:]...) cmd.Stdin = os.Stdin cmd.Stdout = os.Stdout @@ -54,6 +68,22 @@ func child() { must(syscall.Unmount("mytemp", 0)) } +func cgroup() { + cgroups := "/sys/fs/cgroup" + + mem := filepath.Join(cgroups, "memory") + myCgroup := filepath.Join(filepath.Join(mem, "sean")) + os.Mkdir(myCgroup, 0755) + + must(ioutil.WriteFile(filepath.Join(myCgroup, "memory.limit_in_bytes"), []byte("999424"), 0700)) + must(ioutil.WriteFile(filepath.Join(myCgroup, "memory.memsw.limit_in_bytes"), []byte("999424"), 0700)) + must(ioutil.WriteFile(filepath.Join(myCgroup, "notify_on_release"), []byte("1"), 0700)) + + pid := strconv.Itoa(os.Getpid()) + must(ioutil.WriteFile(filepath.Join(myCgroup, "cgroup.procs"), []byte(pid), 0700)) + +} + func must(err error) { if err != nil { panic(err) diff --git a/syscall/container/memorykiller/main.go b/syscall/container/memorykiller/main.go new file mode 100644 index 0000000..8a9674c --- /dev/null +++ b/syscall/container/memorykiller/main.go @@ -0,0 +1,16 @@ +package main + +import "fmt" + +const kb = 1 << 20 + +func main() { + var b [][]byte + + for i := 0; i < 1000; i++ { + var k [kb]byte + b = append(b, k[:]) + fmt.Printf("allocate %d kb\n", i+1) + } + +}