Skip to content

Commit 5f51461

Browse files
🐛 wip nic-info.sh (#1524)
Better GetHardwareDetailsNics. Fixes #1523
1 parent 61ce827 commit 5f51461

File tree

3 files changed

+73
-30
lines changed

3 files changed

+73
-30
lines changed
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
#!/bin/bash
2+
# Copyright 2025 The Kubernetes Authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
trap 'echo "ERROR: A command has failed. Exiting the script. Line was ($0:$LINENO): $(sed -n "${LINENO}p" "$0")"; exit 3' ERR
17+
set -Eeuo pipefail
18+
19+
for idir in $(echo /sys/class/net/* | sort); do
20+
iname=$(basename "$idir")
21+
22+
# Skip loopback
23+
if [ "$iname" = "lo" ]; then
24+
continue
25+
fi
26+
27+
# Skip interfaces that are not up
28+
if [ "$(cat "$idir/operstate")" != "up" ]; then
29+
continue
30+
fi
31+
32+
MAC=$(cat "$idir/address")
33+
34+
SPEED=$(ethtool "$iname" 2>/dev/null | awk '/Speed:/{print $2}' | sed 's/[^0-9]//g')
35+
36+
# Grab the PCI bus info via ethtool, then get the model from lspci
37+
BUSINFO=$(ethtool -i "$iname" 2>/dev/null | awk '/bus-info:/{print $2}')
38+
39+
if [ -z "$BUSINFO" ] || [ "$BUSINFO" = "N/A" ]; then
40+
MODEL="Unknown model"
41+
else
42+
MODEL=$(lspci -s "$BUSINFO" | cut -d ' ' -f3- | tr '"' "'")
43+
fi
44+
45+
for ipv4 in $(ip -4 addr show dev "$iname" | awk '/inet /{print $2}'); do
46+
echo "name=\"$iname\" model=\"$MODEL\" mac=\"$MAC\" ip=\"$ipv4\" speedMbps=\"$SPEED\""
47+
done
48+
for ipv6 in $(ip -6 addr show dev "$iname" | awk '/inet6 /{print $2}'); do
49+
if [[ "$ipv6" == fe80:* ]]; then
50+
continue
51+
fi
52+
echo "name=\"$iname\" model=\"$MODEL\" mac=\"$MAC\" ip=\"$ipv6\" speedMbps=\"$SPEED\""
53+
done
54+
done

pkg/services/baremetal/client/ssh/ssh_client.go

Lines changed: 9 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ var wipeDiskShellScript string
4848
//go:embed check-disk.sh
4949
var checkDiskShellScript string
5050

51+
//go:embed nic-info.sh
52+
var nicInfoShellScript string
53+
5154
var downloadFromOciShellScript = `#!/bin/bash
5255
5356
# Copyright 2023 The Kubernetes Authors.
@@ -316,32 +319,12 @@ func (c *sshClient) GetHardwareDetailsRAM() Output {
316319

317320
// GetHardwareDetailsNics implements the GetHardwareDetailsNics method of the SSHClient interface.
318321
func (c *sshClient) GetHardwareDetailsNics() Output {
319-
out := c.runSSH(`cat << 'EOF_VIA_SSH' > nic-info.sh
320-
#!/bin/sh
321-
for iname in $(ip a |awk '/state UP/{print $2}' | sed 's/://')
322-
do
323-
324-
MAC=\""$(ip a | grep -A2 $iname | awk '/link/{print $2}')\""
325-
SPEED=\""$(ethtool eth0 |grep "Speed:" | awk '{print $2}' | sed 's/[^0-9]//g')\""
326-
MODEL=\""$( lspci | grep net | head -1 | awk '{$1=$2=$3=""; print $0}' | sed "s/^[ \t]*//")\""
327-
IP_V4=\""$(ip a | grep -A2 eth0 | sed -n '/\binet\b/p' | awk '{print $2}')\""
328-
IP_V6=\""$(ip a | grep -A2 eth0 | sed -n '/\binet6\b/p' | awk '{print $2}')\""
329-
330-
if test -n $IP_V4; then
331-
echo "name=\""$iname\""" "model=$MODEL" "mac=$MAC" "ip=$IP_V4" "speedMbps=$SPEED"
332-
fi
333-
334-
if test -n $IP_V6; then
335-
echo "name=\""$iname\""" "model=$MODEL" "mac=$MAC" "ip=$IP_V6" "speedMbps=$SPEED"
336-
fi
337-
338-
done
339-
EOF_VIA_SSH`)
340-
if out.Err != nil || out.StdErr != "" {
341-
return out
342-
}
343-
344-
return c.runSSH("sh nic-info.sh")
322+
return c.runSSH(fmt.Sprintf(`cat >/root/nic-info.sh <<'EOF_VIA_SSH'
323+
%s
324+
EOF_VIA_SSH
325+
chmod a+rx /root/nic-info.sh
326+
/root/nic-info.sh
327+
`, nicInfoShellScript))
345328
}
346329

347330
// GetHardwareDetailsStorage implements the GetHardwareDetailsStorage method of the SSHClient interface.

pkg/services/baremetal/host/host.go

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -849,26 +849,32 @@ func obtainHardwareDetailsNics(sshClient sshclient.Client) ([]infrav1.NIC, error
849849
}
850850

851851
stringArray := strings.Split(stdOut, "\n")
852-
nicsArray := make([]infrav1.NIC, len(stringArray))
852+
nicsArray := make([]infrav1.NIC, 0, len(stringArray))
853853

854-
for i, str := range stringArray {
854+
for _, str := range stringArray {
855855
validJSONString := validJSONFromSSHOutput(str)
856856

857857
var nic originalNic
858858
if err := json.Unmarshal([]byte(validJSONString), &nic); err != nil {
859859
return nil, fmt.Errorf("failed to unmarshal %v. Original ssh output %s: %w", validJSONString, stdOut, err)
860860
}
861+
862+
// speedMbps can be empty
863+
if nic.SpeedMbps == "" {
864+
nic.SpeedMbps = "0"
865+
}
861866
speedMbps, err := strconv.Atoi(nic.SpeedMbps)
862867
if err != nil {
863868
return nil, fmt.Errorf("failed to parse int from string %s: %w", nic.SpeedMbps, err)
864869
}
865-
nicsArray[i] = infrav1.NIC{
870+
871+
nicsArray = append(nicsArray, infrav1.NIC{
866872
Name: nic.Name,
867873
Model: nic.Model,
868874
MAC: nic.MAC,
869875
IP: nic.IP,
870876
SpeedMbps: speedMbps,
871-
}
877+
})
872878
}
873879

874880
return nicsArray, nil

0 commit comments

Comments
 (0)