-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathupdate_ssh_config.sh
More file actions
executable file
·137 lines (123 loc) · 3.78 KB
/
Copy pathupdate_ssh_config.sh
File metadata and controls
executable file
·137 lines (123 loc) · 3.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
#!/bin/bash
current_path="$(dirname "$0")"
source "$current_path/cluster_helpers.sh"
# Default values
CLUSTER="bluehive3"
NODE=""
PARTITION="doppelbock"
PORT="22" # 默认SSH端口
# Parse command line arguments
while getopts "a:w:p:o:" opt; do
case $opt in
a) CLUSTER="$OPTARG" ;;
w) NODE="$OPTARG" ;;
p) PARTITION="$OPTARG" ;;
o) PORT="$OPTARG" ;;
?) echo "Invalid option: -$OPTARG" >&2; exit 1 ;;
esac
done
# SSH config file path
SSH_CONFIG="$HOME/.ssh/config"
COMPUTE_HOST="$(cluster_compute_host "$CLUSTER")" || exit 1
if ! awk -v target="$COMPUTE_HOST" '
/^Host[[:space:]]/ {
n = split($0, parts, /[[:space:]]+/)
for (i = 2; i <= n; i++) {
if (parts[i] == target) {
found = 1
}
}
}
END { exit(found ? 0 : 1) }
' "$SSH_CONFIG"; then
echo "Error: Host $COMPUTE_HOST not found in $SSH_CONFIG" >&2
exit 1
fi
update_host_value() {
local host_alias="$1"
local key="$2"
local value="$3"
local tmp_file
tmp_file="$(mktemp "${SSH_CONFIG}.XXXXXX")"
awk -v target="$host_alias" -v key="$key" -v value="$value" '
function host_line_matches( i, n, parts) {
n = split($0, parts, /[[:space:]]+/)
for (i = 2; i <= n; i++) {
if (parts[i] == target) {
return 1
}
}
return 0
}
function add_key_if_missing() {
if (in_block && !updated) {
print "\t" key " " value
updated = 1
}
}
/^Host[[:space:]]/ {
add_key_if_missing()
in_block = host_line_matches()
updated = 0
print
next
}
in_block && $1 == key {
print "\t" key " " value
updated = 1
next
}
{ print }
END {
add_key_if_missing()
}
' "$SSH_CONFIG" > "$tmp_file" && mv "$tmp_file" "$SSH_CONFIG"
}
# If node is specified, use it directly
if [ -n "$NODE" ]; then
TARGET_NODE="$NODE"
# Otherwise use default logic based on partition
else
if [ "$PARTITION" = "doppelbock" ]; then
TARGET_NODE="bhg0061"
elif [ "$PARTITION" = "dmi" ]; then
TARGET_NODE="bhc0208"
elif [ "$PARTITION" = "preempt" ]; then
echo "Error: preempt partition requires a specific allocated node" >&2
exit 1
else
echo "Error: Unknown partition $PARTITION" >&2
exit 1
fi
fi
read_effective_ssh_value() {
local key="$1"
ssh -G "$COMPUTE_HOST" 2>/dev/null |
awk -v key="$key" '$1 == key { print $2; exit }'
}
current_hostname="$(read_effective_ssh_value hostname)"
current_port="$(read_effective_ssh_value port)"
control_path="$(read_effective_ssh_value controlpath)"
if { [ "$current_hostname" != "$TARGET_NODE" ] || [ "$current_port" != "$PORT" ]; } &&
[[ "$control_path" == /* && "$control_path" != *%* && -S "$control_path" ]]; then
control_status="$(
ssh -S "$control_path" -O check "$COMPUTE_HOST" 2>&1 || true
)"
if [[ "$control_status" == *"Master running"* ]]; then
echo "Closing the previous SSH master for $COMPUTE_HOST."
ssh -S "$control_path" -O exit "$COMPUTE_HOST" >/dev/null 2>&1 || true
for _ in 1 2 3 4 5; do
[[ ! -S "$control_path" ]] && break
sleep 1
done
if [[ -S "$control_path" ]]; then
echo "Error: SSH master did not close: $control_path" >&2
exit 1
fi
else
unlink "$control_path"
fi
fi
update_host_value "$COMPUTE_HOST" "Hostname" "$TARGET_NODE"
update_host_value "$COMPUTE_HOST" "Port" "$PORT"
echo "Updated SSH config for $COMPUTE_HOST ($CLUSTER) with node: $TARGET_NODE and port: $PORT"