xref: /unit/test/go/ns_inspect/app.go (revision 2592:e079c44a8340)
1package main
2
3import (
4	"encoding/json"
5	"fmt"
6	"net/http"
7	"unit.nginx.org/go"
8	"os"
9	"strconv"
10	"io/ioutil"
11)
12
13type (
14	NS struct {
15		USER   uint64
16		PID    uint64
17		IPC    uint64
18		CGROUP uint64
19		UTS    uint64
20		MNT    uint64
21		NET    uint64
22	}
23
24	Output struct {
25		PID        int
26		UID        int
27		GID        int
28		NS         NS
29		FileExists bool
30		Mounts     string
31	}
32)
33
34func abortonerr(err error) {
35	if err != nil {
36		panic(err)
37	}
38}
39
40// returns: [nstype]:[4026531835]
41func getns(nstype string) uint64 {
42	str, err := os.Readlink(fmt.Sprintf("/proc/self/ns/%s", nstype))
43	if err != nil {
44		return 0
45	}
46
47	str = str[len(nstype)+2:]
48	str = str[:len(str)-1]
49	val, err := strconv.ParseUint(str, 10, 64)
50	abortonerr(err)
51	return val
52}
53
54func handler(w http.ResponseWriter, r *http.Request) {
55	pid := os.Getpid()
56	out := &Output{
57		PID: pid,
58		UID: os.Getuid(),
59		GID: os.Getgid(),
60		NS: NS{
61			PID:    getns("pid"),
62			USER:   getns("user"),
63			MNT:    getns("mnt"),
64			IPC:    getns("ipc"),
65			UTS:    getns("uts"),
66			NET:    getns("net"),
67			CGROUP: getns("cgroup"),
68		},
69	}
70
71	err := r.ParseForm()
72	if err != nil {
73		w.WriteHeader(http.StatusInternalServerError)
74		return
75	}
76
77	if fname := r.Form.Get("file"); fname != "" {
78		_, err = os.Stat(fname);
79		out.FileExists = err == nil
80	}
81
82	if mounts := r.Form.Get("mounts"); mounts != "" {
83		data, _ := ioutil.ReadFile("/proc/self/mountinfo")
84		out.Mounts = string(data)
85	}
86
87	data, err := json.Marshal(out)
88	if err != nil {
89		w.WriteHeader(http.StatusInternalServerError)
90		return
91	}
92
93	w.Header().Add("Content-Type", "application/json")
94
95	w.Write(data)
96}
97
98func main() {
99	http.HandleFunc("/", handler)
100	unit.ListenAndServe(":8080", nil)
101}
102