Setting the file. One moment.
Run Ig · Azure Diagnostics · microsoft/azure-skills · Skills Docs
ContentsBack to the top of the page ·
scripts/run-ig.sh
scripts/ run-ig.sh
Shell · 186 lines · 7 KB
15
# Usage:
16 # ./run-ig.sh --gadget <name> (--pod <pod> --ns <namespace> | --node <node>) [options]
17 #
18 # Options:
19 # --gadget <name> Gadget to run, e.g. trace_dns, snapshot_socket, tcpdump (required)
20 # --pod <pod> Pod name; the node is resolved automatically
21 # --ns <namespace> Namespace of the pod (required with --pod)
22 # --node <node> Run directly against a node (node-wide scope)
23 # --container <name> Scope to a specific container
24 # --timeout <seconds> Override the gadget-type default timeout
25 # --filter <arg> Extra IG flag, repeatable (e.g. --filter --max-entries --filter 20)
26 # --pf "<expr>" tcpdump packet filter (tcpdump gadget only, e.g. "port 80")
27 # --ig-version <tag> Override the pinned IG image tag (default below)
28 # --dry-run Print the assembled command; do not execute
29 #
30 # Examples:
31 # ./run-ig.sh --gadget trace_dns --pod web-0 --ns default
32 # ./run-ig.sh --gadget snapshot_process --node aks-nodepool1-1234
33 # ./run-ig.sh --gadget tcpdump --pod web-0 --ns default --pf "port 80"
34 # ./run-ig.sh --gadget traceloop --pod web-0 --ns default --filter --syscall-filters --filter open,connect
35 # ./run-ig.sh --gadget trace_dns --pod web-0 --ns default --dry-run
36
37 set -euo pipefail
38
39 # Pinned IG image tag. Bump this line (and run-ig.ps1) to update the IG version.
40 IG_VERSION = "v0.51.0"
41 IG_IMAGE_REPO = "mcr.microsoft.com/oss/v2/inspektor-gadget/ig"
42
43 GADGET = ""
44 POD = ""
45 NS = ""
46 NODE = ""
47 CONTAINER = ""
48 TIMEOUT = ""
49 PF = ""
50 DRY_RUN = "false"
51 EXTRA_FILTERS = ()
52
53 usage () {
54 # Print the leading comment block (from line 2) as help, stopping at the
55 # first non-comment line so script code is never echoed.
56 awk 'NR>1 && /^#/ { sub(/^# ?/, ""); print; next } NR>1 { exit }' " $0 "
57 }
58
59 while [[ $# -gt 0 ]]; do
60 case " $1 " in
61 --gadget ) GADGET = " ${2 :? --gadget requires a value } " ; shift 2 ;;
62 --pod ) POD = " ${2 :? --pod requires a value } " ; shift 2 ;;
63 --ns | --namespace ) NS = " ${2 :? --ns requires a value } " ; shift 2 ;;
64 --node ) NODE = " ${2 :? --node requires a value } " ; shift 2 ;;
65 --container ) CONTAINER = " ${2 :? --container requires a value } " ; shift 2 ;;
66 --timeout ) TIMEOUT = " ${2 :? --timeout requires a value } " ; shift 2 ;;
67 --filter ) EXTRA_FILTERS += ( " ${2 :? --filter requires a value } " ); shift 2 ;;
68 --pf ) PF = " ${2 :? --pf requires a value } " ; shift 2 ;;
69 --ig-version ) IG_VERSION = " ${2 :? --ig-version requires a value } " ; shift 2 ;;
70 --dry-run ) DRY_RUN = "true" ; shift ;;
71 -h | --help ) usage ; exit 0 ;;
72 *) echo "Unknown argument: $1 " >&2 ; usage >&2 ; exit 2 ;;
73 esac
74 done
75
76 if [[ -z " $GADGET " ]]; then
77 echo "Error: --gadget is required." >&2
78 exit 2
79 fi
80
81 if [[ -z " $NODE " && -z " $POD " ]]; then
82 echo "Error: provide either --node <node> or --pod <pod> --ns <namespace>." >&2
83 exit 2
84 fi
85
86 if [[ -n " $POD " && -z " $NS " ]]; then
87 echo "Error: --pod requires --ns <namespace>." >&2
88 exit 2
89 fi
90
91 # Default timeout by gadget type, inferred from the gadget name prefix.
92 # snapshot_* / top_* -> 5s (point-in-time / quick aggregate)
93 # trace_* / profile_* / tcpdump -> 30s (streaming / sampling)
94 default_timeout () {
95 case " $1 " in
96 snapshot_ *| top_ * ) echo 5 ;;
97 trace_ *| profile_ *| tcpdump ) echo 30 ;;
98 *) echo 30 ;; # unknown gadget: use the safer streaming default
99 esac
100 }
101
102 if [[ -z " $TIMEOUT " ]]; then
103 TIMEOUT = "$( default_timeout " $GADGET ")"
104 fi
105
106 # Resolve the node name from the pod when not given directly.
107 if [[ -z " $NODE " ]]; then
108 NODE = "$( kubectl get pod " $POD " -n " $NS " -o jsonpath='{.spec.nodeName}')"
109 if [[ -z " $NODE " ]]; then
110 echo "Error: could not resolve node for pod ' $POD ' in namespace ' $NS '." >&2
111 exit 1
112 fi
113 fi
114
115 IG_IMAGE = "${ IG_IMAGE_REPO }:${ IG_VERSION }"
116
117 # Assemble the k8s scoping filters.
118 FILTERS = ()
119 [[ -n " $NS " ]] && FILTERS += ( --k8s-namespace " $NS " )
120 [[ -n " $POD " ]] && FILTERS += ( --k8s-podname " $POD " )
121 [[ -n " $CONTAINER " ]] && FILTERS += ( --k8s-containername " $CONTAINER " )
122
123 # Base kubectl debug invocation.
124 DEBUG = ( kubectl debug --profile = sysadmin "node/${ NODE }" --attach --quiet --image = " $IG_IMAGE " -- )
125
126 if [[ " $GADGET " == "tcpdump" ]]; then
127 # tcpdump emits raw pcap-ng; pipe through tcpdump for readable output when available.
128 IG_CMD = ( ig run "tcpdump:${ IG_VERSION }" -o pcap-ng "${ FILTERS [ @ ]}" --timeout " $TIMEOUT " )
129 [[ -n " $PF " ]] && IG_CMD += ( --pf " $PF " )
130 [[ ${ # EXTRA_FILTERS[ @ ]} -gt 0 ]] && IG_CMD += ( "${ EXTRA_FILTERS [ @ ]}" )
131 else
132 if [[ -n " $PF " ]]; then
133 echo "Error: --pf is only valid for the tcpdump gadget." >&2
134 exit 2
135 fi
136 IG_CMD = ( ig run "${ GADGET }:${ IG_VERSION }" -o json "${ FILTERS [ @ ]}" --timeout " $TIMEOUT " )
137 [[ ${ # EXTRA_FILTERS[ @ ]} -gt 0 ]] && IG_CMD += ( "${ EXTRA_FILTERS [ @ ]}" )
138 fi
139
140 FULL_CMD = ( "${ DEBUG [ @ ]}" "${ IG_CMD [ @ ]}" )
141
142 # Pretty-print a shell-quoted version of the command for display.
143 quote_cmd () {
144 local out = ""
145 local a
146 for a in " $@ " ; do
147 if [[ " $a " =~ [[:space:]] ]]; then
148 out += " \" $a \" "
149 else
150 out += " $a "
151 fi
152 done
153 echo "${ out % }"
154 }
155
156 DISPLAY_CMD = "$( quote_cmd "${ FULL_CMD [ @ ]}")"
157
158 # The tcpdump gadget is only piped through `tcpdump` when that binary is present.
159 # Reflect the real behavior in the displayed command so --dry-run does not mislead.
160 TCPDUMP_AVAIL = "false"
161 if [[ " $GADGET " == "tcpdump" ]] && command -v tcpdump > /dev/null 2>&1 ; then
162 TCPDUMP_AVAIL = "true"
163 DISPLAY_CMD = " $DISPLAY_CMD | tcpdump -nvr -"
164 fi
165
166 echo "Gadget: $GADGET " >&2
167 echo "Node: $NODE " >&2
168 echo "Timeout: ${ TIMEOUT }s" >&2
169 echo "Image: $IG_IMAGE " >&2
170 echo "Command: $DISPLAY_CMD " >&2
171 if [[ " $GADGET " == "tcpdump" && " $TCPDUMP_AVAIL " == "false" ]]; then
172 echo "Note: tcpdump not found; emitting raw pcap-ng to stdout." >&2
173 fi
174
175 if [[ " $DRY_RUN " == "true" ]]; then
176 echo "(dry-run: command not executed)" >&2
177 exit 0
178 fi
179
180 echo "Ran gadget $GADGET on node $NODE (timeout ${ TIMEOUT }s)" >&2
181
182 if [[ " $TCPDUMP_AVAIL " == "true" ]]; then
183 "${ FULL_CMD [ @ ]}" | tcpdump -nvr -
184 else
185 "${ FULL_CMD [ @ ]}"
186 fi