@@ -11,14 +11,15 @@ import (
11
11
"syscall"
12
12
13
13
"github.com/containerd/nerdctl/pkg/rootlessutil"
14
- log "github.com/sirupsen/logrus"
14
+ "github.com/pkg/errors"
15
+ "github.com/sirupsen/logrus"
15
16
"github.com/spf13/pflag"
16
17
"github.com/vishvananda/netlink"
17
18
"github.com/vishvananda/netns"
18
19
19
- "github.com/t1anz0ng/iftree/pkg"
20
20
"github.com/t1anz0ng/iftree/pkg/formatter"
21
21
"github.com/t1anz0ng/iftree/pkg/netutil"
22
+ "github.com/t1anz0ng/iftree/pkg/types"
22
23
)
23
24
24
25
var (
@@ -63,6 +64,7 @@ Help Options:
63
64
version: %s
64
65
` , version )
65
66
}
67
+
66
68
}
67
69
68
70
func helper () error {
@@ -75,77 +77,82 @@ func helper() error {
75
77
}
76
78
return nil
77
79
}
80
+
78
81
func main () {
79
82
pflag .Parse ()
80
83
if err := helper (); err != nil {
81
- log .Fatal (err )
84
+ logrus .Fatal (err )
82
85
}
83
86
if rootlessutil .IsRootless () {
84
- log .Error ("iftree must be run as root to enter ns" )
87
+ logrus .Error ("iftree must be run as root to enter ns" )
85
88
os .Exit (1 )
86
89
}
87
- log .SetLevel (log .InfoLevel )
90
+ logrus .SetLevel (logrus .InfoLevel )
88
91
if * debug {
89
- log .SetReportCaller (true )
90
- log .SetLevel (log .DebugLevel )
92
+ logrus .SetReportCaller (true )
93
+ logrus .SetLevel (logrus .DebugLevel )
94
+ } else {
95
+ logrus .SetLevel (logrus .ErrorLevel )
91
96
}
97
+
98
+ // Lock the OS Thread so we don't accidentally switch namespaces
92
99
runtime .LockOSThread ()
93
100
defer runtime .UnlockOSThread ()
94
101
95
102
netNsMap , err := netutil .NetNsMap ()
96
103
if err != nil {
97
- log .Fatal (err )
104
+ logrus .Fatal (err )
98
105
}
99
106
if len (netNsMap ) == 0 {
100
- log .Warn ("no netns found" )
107
+ logrus .Warn ("no netns found" )
101
108
os .Exit (0 )
102
109
}
103
- log .Debugf ("net namespace id <-> name map:\n %+v\n " , netNsMap )
110
+ logrus .Debugf ("net namespace id <-> name map:\n %+v\n " , netNsMap )
104
111
105
112
ll , err := netlink .LinkList ()
106
113
if err != nil {
107
- log .Fatal (err )
114
+ logrus .Fatal (errors . Unwrap ( err ) )
108
115
}
109
- log .Debugf ("net link list:\n %+v\n " , ll )
116
+ logrus .Debugf ("net link list:\n %+v\n " , ll )
110
117
111
- bridgeVethM := make (map [string ][]pkg .Node ) // map bridge <-> veth paris
112
- unBridgedVpairs := []pkg .Node {}
118
+ bridgeVethM := make (map [string ][]types .Node ) // map bridge <-> veth paris
119
+ unBridgedVpairs := []types .Node {}
113
120
bridgeIps := make (map [string ]* net.IP ) // bridge ip
114
- loS := []pkg .Node {} // loopback
121
+ loS := []types .Node {} // loopback
115
122
116
123
origin , err := netns .Get ()
117
124
if err != nil {
118
- log .Fatalf ("failed get current netne, %v" , err )
125
+ logrus .Fatalf ("failed get current netne, %v" , err )
119
126
}
120
- // FIXME: use undirected graph insted of array/map to store relations
127
+
121
128
for _ , link := range ll {
122
129
veth , ok := link .(* netlink.Veth )
123
130
if ! ok {
124
131
// skip device not enslaved to any bridge
125
- log .Debugf ("skip %s, type: %s" , link .Attrs ().Name , link .Type ())
132
+ logrus .Debugf ("skip %s, type: %s" , link .Attrs ().Name , link .Type ())
126
133
continue
127
134
}
128
- log .Debugf ("found veth device: %s " , veth . Name )
135
+ logrus .Debugf ("veth device: %+v " , veth )
129
136
130
137
peerIdx , err := netlink .VethPeerIndex (veth )
131
138
if err != nil {
132
- log .Fatal (err )
139
+ logrus .Fatal (err )
133
140
}
134
141
if link .Attrs ().MasterIndex == - 1 || veth .MasterIndex == 0 {
135
- log .Debugf ("%s not has a bridge as master, MasterIndex: %d" , veth .Name , link .Attrs ().MasterIndex )
142
+ logrus .Debugf ("%s not has a bridge as master, MasterIndex: %d" , veth .Name , link .Attrs ().MasterIndex )
136
143
if veth .PeerName == "" {
137
144
p , err := netlink .LinkByIndex (peerIdx )
138
145
if err != nil {
139
- log .Fatal (err )
146
+ logrus .Fatal (err )
140
147
}
141
148
veth .PeerName = p .Attrs ().Name
142
149
}
143
150
routes , err := netlink .RouteList (link , 4 )
144
151
if err != nil {
145
- log .Fatal (err )
152
+ logrus .Fatal (err )
146
153
}
147
- node := pkg .Node {
148
- Type : pkg .VethType ,
154
+ node := types .Node {
155
+ Type : types .VethType ,
149
156
Veth : veth .Name ,
150
157
Peer : veth .PeerName ,
151
158
PeerId : peerIdx ,
@@ -161,7 +168,7 @@ func main() {
161
168
162
169
master , err := netlink .LinkByIndex (veth .Attrs ().MasterIndex )
163
170
if err != nil {
164
- log .Fatal (err )
171
+ logrus .Fatal (err )
165
172
}
166
173
167
174
// if master is not bridge
@@ -172,27 +179,27 @@ func main() {
172
179
bridge := master .Attrs ().Name
173
180
v , ok := bridgeVethM [bridge ]
174
181
if ! ok {
175
- bridgeVethM [bridge ] = []pkg .Node {}
182
+ bridgeVethM [bridge ] = []types .Node {}
176
183
}
177
- pair := pkg .Node {
178
- Type : pkg .VethType ,
184
+ pair := types .Node {
185
+ Type : types .VethType ,
179
186
Veth : veth .Name ,
180
187
PeerId : peerIdx ,
181
188
NetNsID : veth .NetNsID ,
182
189
}
183
190
if peerNetNs , ok := netNsMap [veth .NetNsID ]; ok {
184
191
peerInNs , err := netutil .GetPeerInNs (peerNetNs , origin , peerIdx )
185
192
if err != nil {
186
- log .Fatal (err )
193
+ logrus .Fatal (err )
187
194
}
188
195
pair .NetNsName = peerNetNs
189
196
pair .PeerNameInNetns = peerInNs .Attrs ().Name
190
197
pair .Status = peerInNs .Attrs ().OperState .String ()
191
198
192
199
lo , err := netutil .GetLoInNs (peerNetNs , origin )
193
200
if err == nil && lo != nil {
194
- loS = append (loS , pkg .Node {
195
- Type : pkg .LoType ,
201
+ loS = append (loS , types .Node {
202
+ Type : types .LoType ,
196
203
NetNsName : peerNetNs ,
197
204
Status : lo .Attrs ().OperState .String (),
198
205
})
@@ -203,25 +210,25 @@ func main() {
203
210
204
211
addrs , err := netlink .AddrList (master , syscall .AF_INET )
205
212
if err != nil {
206
- log .Fatal (err )
213
+ logrus .Fatal (err )
207
214
}
208
215
if len (addrs ) > 0 {
209
- pair .Master = & pkg .Bridge {
216
+ pair .Master = & types .Bridge {
210
217
Name : bridge ,
211
218
IP : & addrs [0 ].IP ,
212
219
}
213
220
bridgeIps [bridge ] = & addrs [0 ].IP
214
221
}
215
222
bridgeVethM [bridge ] = append (v , pair )
216
223
}
217
- log .Debugf ("bridgeVethMap: %+v" , bridgeVethM )
224
+ logrus .Debugf ("bridgeVethMap: %+v" , bridgeVethM )
218
225
219
226
switch {
220
227
case * oGraph :
221
228
buf := bytes.Buffer {}
222
229
output , err := formatter .GraphInDOT (bridgeVethM , unBridgedVpairs , loS , bridgeIps )
223
230
if err != nil {
224
- log .Fatal (err )
231
+ logrus .Fatal (errors . Unwrap ( err ) )
225
232
}
226
233
fmt .Fprintln (& buf , output )
227
234
gType := strings .ToLower (* oGraphType )
@@ -231,21 +238,25 @@ func main() {
231
238
_ , err = io .Copy (defaultOutput , & buf )
232
239
case "jpg" , "png" , "svg" :
233
240
if ! pflag .CommandLine .Changed ("output" ) && ! pflag .CommandLine .Changed ("gtype" ) {
234
- log .Warn (`default output dst file: "output.png"` )
241
+ logrus .Warn (`default output dst file: "output.png"` )
242
+ }
243
+ if fn , err := formatter .GenImage (buf .Bytes (), oGraphName , gType ); err != nil {
244
+ os .Remove (fn )
245
+ logrus .Fatal (errors .Unwrap (err ))
235
246
}
236
- err = formatter .GenImage (buf .Bytes (), oGraphName , gType )
237
247
default :
238
- log .Fatal ("invalid graph type" )
248
+ logrus .Error ("unknown image type" )
249
+ os .Exit (1 )
239
250
}
240
251
if err != nil {
241
- log .Fatal (err )
252
+ logrus .Fatal (err )
242
253
}
243
254
return
244
255
case * oTable :
245
256
if len (bridgeVethM ) > 0 {
246
257
err := formatter .Table (defaultOutput , bridgeVethM )
247
258
if err != nil {
248
- log .Fatal (err )
259
+ logrus .Fatal (errors . Unwrap ( err ) )
249
260
}
250
261
}
251
262
if * oNotBridgedVeths && len (unBridgedVpairs ) > 0 {
0 commit comments