Skip to content

Commit 0176d3f

Browse files
authored
test(slurm): support integration testing on private IP VMs via IAP tunnel (#5950)
1 parent f10b144 commit 0176d3f

4 files changed

Lines changed: 119 additions & 42 deletions

File tree

examples/hpc-enterprise-slurm.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ deployment_groups:
288288
# we recommend disabling public IPs if possible
289289
# but that requires your network to have a NAT or
290290
# private access configured
291-
enable_login_public_ips: true
291+
enable_login_public_ips: false
292292

293293
- id: slurm_controller
294294
source: community/modules/scheduler/schedmd-slurm-gcp-v6-controller
@@ -307,7 +307,7 @@ deployment_groups:
307307
# we recommend disabling public IPs if possible
308308
# but that requires your network to have a NAT or
309309
# private access configured
310-
enable_controller_public_ips: true
310+
enable_controller_public_ips: false
311311

312312
- id: hpc_dashboard
313313
source: modules/monitoring/dashboard

examples/pfs-managed-lustre-slurm.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ deployment_groups:
8989
use: [network]
9090
settings:
9191
machine_type: n2-standard-4
92-
enable_login_public_ips: true
92+
enable_login_public_ips: false
9393
instance_image: $(vars.slurm_image)
9494

9595
- id: slurm_controller
@@ -101,5 +101,5 @@ deployment_groups:
101101
- slurm_login
102102
settings:
103103
machine_type: n2-standard-4
104-
enable_controller_public_ips: true
104+
enable_controller_public_ips: false
105105
instance_image: $(vars.slurm_image)

tools/cloud-build/daily-tests/ansible_playbooks/slurm-integration-test.yml

Lines changed: 104 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -79,53 +79,109 @@
7979
ansible.builtin.include_tasks:
8080
file: tasks/get_instance_ids.yml
8181

82-
- name: Get IP of a login node - Exact name provided
83-
changed_when: false
84-
register: get_login_ip
85-
ansible.builtin.command: >-
86-
gcloud compute instances describe --zone={{ zone }} {{ login_node }}
87-
--format='get(networkInterfaces[0].accessConfigs[0].natIP)'
88-
when: '"*" not in login_node'
89-
90-
- name: Set login_ip variable - Exact name provided
82+
- name: Set login node name fact - Exact name provided
9183
ansible.builtin.set_fact:
92-
login_ip: "{{ get_login_ip.stdout }}"
84+
login_node_name: "{{ login_node }}"
9385
when: '"*" not in login_node'
9486

95-
- name: Get IP of a login node - Name pattern provided
87+
- name: Get login node name - Name pattern provided
9688
changed_when: false
97-
register: get_login_ip
89+
register: get_login_name
9890
ansible.builtin.command: >-
99-
gcloud compute instances list \
100-
--format='get(networkInterfaces[0].accessConfigs[0].natIP)' --limit=1 \
101-
--filter=NAME:{{ login_node }}
91+
gcloud compute instances list
92+
--format='value(name)' --limit=1
93+
--filter=NAME:{{ login_node }}
10294
when: '"*" in login_node'
10395

104-
- name: Set login_ip variable - Name pattern provided
96+
- name: Set login node name fact - Name pattern provided
10597
ansible.builtin.set_fact:
106-
login_ip: "{{ get_login_ip.stdout }}"
98+
login_node_name: "{{ get_login_name.stdout }}"
10799
when: '"*" in login_node'
108100

101+
- name: Check that login node name is resolved
102+
ansible.builtin.assert:
103+
that:
104+
- login_node_name is defined
105+
- login_node_name != ""
106+
107+
- name: Get Login Nat IP
108+
changed_when: false
109+
register: get_login_nat_ip
110+
ansible.builtin.command: >-
111+
gcloud compute instances describe --zone={{ zone }} {{ login_node_name }}
112+
--format='value(networkInterfaces[0].accessConfigs[0].natIP)'
113+
failed_when: false
114+
115+
- name: Get Login Network IP
116+
changed_when: false
117+
register: get_login_network_ip
118+
ansible.builtin.command: >-
119+
gcloud compute instances describe --zone={{ zone }} {{ login_node_name }}
120+
--format='value(networkInterfaces[0].networkIP)'
121+
122+
- name: Set Login IP facts
123+
ansible.builtin.set_fact:
124+
login_ip: "{{ get_login_nat_ip.stdout | default(get_login_network_ip.stdout, true) }}"
125+
login_is_private: "{{ get_login_nat_ip.stdout == '' }}"
126+
109127
- name: Check that login IP is set
110128
ansible.builtin.assert:
111129
that:
112130
- login_ip is defined
113131
- login_ip != ""
114132

115-
- name: Print login public IP
133+
- name: Print login IP info
116134
ansible.builtin.debug:
117-
var: login_ip
135+
msg: "Login IP: {{ login_ip }}, Private: {{ login_is_private }}"
136+
137+
- name: Set controller node name fact - Exact name provided
138+
ansible.builtin.set_fact:
139+
controller_node_name: "{{ controller_node }}"
140+
when: '"*" not in controller_node'
118141

119-
- name: Get Controller IP
142+
- name: Get controller node name - Name pattern provided
120143
changed_when: false
121-
register: controller_ip
144+
register: get_controller_name
122145
ansible.builtin.command: >-
123-
gcloud compute instances describe --zone={{ zone }} {{ controller_node }}
124-
--format='get(networkInterfaces[0].accessConfigs[0].natIP)'
146+
gcloud compute instances list
147+
--format='value(name)' --limit=1
148+
--filter=NAME:{{ controller_node }}
149+
when: '"*" in controller_node'
125150

126-
- name: Print controller public IP
151+
- name: Set controller node name fact - Name pattern provided
152+
ansible.builtin.set_fact:
153+
controller_node_name: "{{ get_controller_name.stdout }}"
154+
when: '"*" in controller_node'
155+
156+
- name: Check that controller node name is resolved
157+
ansible.builtin.assert:
158+
that:
159+
- controller_node_name is defined
160+
- controller_node_name != ""
161+
162+
- name: Get Controller Nat IP
163+
changed_when: false
164+
register: get_controller_nat_ip
165+
ansible.builtin.command: >-
166+
gcloud compute instances describe --zone={{ zone }} {{ controller_node_name }}
167+
--format='value(networkInterfaces[0].accessConfigs[0].natIP)'
168+
failed_when: false
169+
170+
- name: Get Controller Network IP
171+
changed_when: false
172+
register: get_controller_network_ip
173+
ansible.builtin.command: >-
174+
gcloud compute instances describe --zone={{ zone }} {{ controller_node_name }}
175+
--format='value(networkInterfaces[0].networkIP)'
176+
177+
- name: Set Controller IP facts
178+
ansible.builtin.set_fact:
179+
controller_ip: "{{ get_controller_nat_ip.stdout | default(get_controller_network_ip.stdout, true) }}"
180+
controller_is_private: "{{ get_controller_nat_ip.stdout == '' }}"
181+
182+
- name: Print controller IP info
127183
ansible.builtin.debug:
128-
var: controller_ip.stdout_lines
184+
msg: "Controller IP: {{ controller_ip }}, Private: {{ controller_is_private }}"
129185

130186
## Setup firewall for cloud build
131187
- name: Create firewall rule
@@ -171,14 +227,29 @@
171227

172228
- name: Add Login node as host
173229
ansible.builtin.add_host:
174-
hostname: "{{ login_ip }}"
230+
name: login_node_host
231+
ansible_host: "{{ login_node_name if login_is_private else login_ip }}"
232+
ansible_ssh_common_args: >-
233+
{% if login_is_private %}
234+
-o ProxyCommand="gcloud compute start-iap-tunnel %h %p --listen-on-stdin --project={{ project }} --zone={{ zone }} --verbosity=warning"
235+
{% endif %}
175236
groups: [remote_host]
176-
when: (login_ip | default('')) | ansible.utils.ipaddr != false
237+
238+
- name: Add Controller node as host
239+
ansible.builtin.add_host:
240+
name: controller_node_host
241+
ansible_host: "{{ controller_ip if not controller_is_private else controller_node_name }}"
242+
ansible_ssh_common_args: >-
243+
{% if controller_is_private %}
244+
-o ProxyCommand="gcloud compute start-iap-tunnel %h %p --listen-on-stdin --project={{ project }} --zone={{ zone }} --verbosity=warning"
245+
{% endif %}
246+
177247
178248
- name: Wait for host tasks
179249
ansible.builtin.include_tasks: tasks/wait-for-host.yml
180250
vars:
181-
host_ip: "{{ login_ip }}"
251+
host_to_wait: login_node_host
252+
is_private: "{{ login_is_private }}"
182253
ansible_ssh_private_key_file: "/builder/home/.ssh/id_rsa"
183254

184255
## Cleanup and fail gracefully
@@ -297,7 +368,7 @@
297368
become: true
298369
changed_when: false
299370
failed_when: false
300-
delegate_to: "{{ hostvars['localhost']['controller_ip']['stdout'] }}"
371+
delegate_to: controller_node_host
301372
ansible.builtin.command: cat /slurm/scripts/setup.log
302373
register: setup_output
303374

@@ -309,7 +380,7 @@
309380
become: true
310381
changed_when: false
311382
failed_when: false
312-
delegate_to: "{{ hostvars['localhost']['controller_ip']['stdout'] }}"
383+
delegate_to: controller_node_host
313384
ansible.builtin.command: cat /var/log/slurm/resume.log
314385
register: resume_output
315386

@@ -321,7 +392,7 @@
321392
become: true
322393
changed_when: false
323394
failed_when: false
324-
delegate_to: "{{ hostvars['localhost']['controller_ip']['stdout'] }}"
395+
delegate_to: controller_node_host
325396
ansible.builtin.command: cat /var/log/slurm/suspend.log
326397
register: suspend_output
327398

@@ -333,7 +404,7 @@
333404
become: true
334405
changed_when: false
335406
failed_when: false
336-
delegate_to: "{{ hostvars['localhost']['controller_ip']['stdout'] }}"
407+
delegate_to: controller_node_host
337408
ansible.builtin.command: cat /var/log/slurm/slurmctld.log
338409
register: slurmctld_output
339410

@@ -345,7 +416,7 @@
345416
become: true
346417
changed_when: false
347418
failed_when: false
348-
delegate_to: "{{ hostvars['localhost']['controller_ip']['stdout'] }}"
419+
delegate_to: controller_node_host
349420
ansible.builtin.command: cat /var/log/slurm/slurmsync.log
350421
register: slurmsync_output
351422

tools/cloud-build/daily-tests/ansible_playbooks/tasks/wait-for-host.yml

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,35 @@
1313
# limitations under the License.
1414
---
1515

16+
- name: Set backward compatibility facts
17+
ansible.builtin.set_fact:
18+
_host_to_wait: "{{ host_to_wait | default(host_ip | default('')) }}"
19+
_is_private: "{{ is_private | default(false) | bool }}"
20+
1621
- name: Assert variables are defined
1722
ansible.builtin.assert:
1823
that:
19-
- host_ip is defined
24+
- _host_to_wait != ""
2025

2126
- name: Wait for firewall to allow port 22 connection
2227
ansible.builtin.wait_for:
23-
host: "{{ host_ip }}"
28+
host: "{{ hostvars[_host_to_wait]['ansible_host'] | default(_host_to_wait) if _host_to_wait in hostvars else _host_to_wait }}"
2429
port: 22
2530
delay: 60
2631
timeout: 300
2732
delegate_to: localhost
2833
ignore_errors: true
2934
register: port_out
35+
when: not _is_private
3036

3137
- name: Check connection to remote host
3238
ansible.builtin.wait_for_connection:
3339
delay: 10
34-
delegate_to: "{{ host_ip }}"
40+
delegate_to: "{{ _host_to_wait }}"
3541
ignore_unreachable: true
3642
register: connect_out
3743

3844
- name: Fail on bad connections
3945
ansible.builtin.fail:
40-
msg: "Failed to connect to remote host {{ host_ip }}"
41-
when: port_out is failed or connect_out is failed
46+
msg: "Failed to connect to remote host {{ _host_to_wait }}"
47+
when: (not _is_private and port_out is failed) or connect_out is failed

0 commit comments

Comments
 (0)