Skip to content

Commit 4dd0fbd

Browse files
Add prepare_client_pod stage for warm client-pod bootstrap
When cifmw recreates shiftstackclient and jobs omit prepare (Pipeline B run-tests), the empty pod lacks oc, clouds.shiftstack, /etc/hosts, and resources.yml. Add a lightweight stage that restores only that subset from the PVC / install-config without re-running full prepare. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent f01bb8a commit 4dd0fbd

5 files changed

Lines changed: 214 additions & 0 deletions

File tree

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
# Lightweight client bootstrap when full "prepare" is skipped (e.g. Pipeline B
3+
# run-tests after a warm guest install). Mirrors the subset of prepare that is
4+
# lost when the shiftstackclient pod is recreated: oc, clouds.shiftstack,
5+
# /etc/hosts, and resources.yml.
6+
#
7+
# Do NOT recreate OpenStack projects, FIPs, or installer hosts here.
8+
prepare_client_pod_bootstrap_oc_dir: "{{ home_dir }}/bootstrap-oc"
9+
prepare_client_pod_bootstrap_oc_url: >-
10+
{{ openshift_mirror_url | default('https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp') }}/stable/openshift-client-linux.tar.gz
11+
prepare_client_pod_install_config: "{{ user_cloud_installation_dir }}/install-config.yaml"
12+
prepare_client_pod_metadata: "{{ ocp_installation_dir }}/metadata.json"
13+
# Same host rows as prepare/defaults etc_hosts_entries (api_ip / apps_ip at runtime).
14+
prepare_client_pod_etc_hosts_entries:
15+
- {regex: 'api\..*\.{{ ocp_base_domain }}', row: '{{ api_ip }} api.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
16+
- {regex: 'oauth-openshift.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} oauth-openshift.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
17+
- {regex: 'console-openshift-console.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} console-openshift-console.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
18+
- {regex: 'downloads-openshift-console.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} downloads-openshift-console.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
19+
- {regex: 'canary-openshift-ingress-canary.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} canary-openshift-ingress-canary.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
20+
- {regex: 'alertmanager-main-openshift-monitoring.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} alertmanager-main-openshift-monitoring.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
21+
- {regex: 'grafana-openshift-monitoring.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} grafana-openshift-monitoring.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
22+
- {regex: 'prometheus-k8s-openshift-monitoring.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} prometheus-k8s-openshift-monitoring.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
23+
- {regex: 'prometheus-k8s-federate-openshift-monitoring.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} prometheus-k8s-federate-openshift-monitoring.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
24+
- {regex: 'thanos-querier-openshift-monitoring.apps\..*\.{{ ocp_base_domain }}', row: '{{ apps_ip }} thanos-querier-openshift-monitoring.apps.{{ ocp_cluster_name }}.{{ ocp_base_domain }}'}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
collections:
3+
- shiftstack.tools
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
# Prepare the recreated shiftstackclient / installer inventory host for warm
3+
# testing when the full prepare stage was skipped.
4+
5+
- name: Check for PVC OpenStack clouds.yaml
6+
ansible.builtin.stat:
7+
path: "{{ osp_config_dir }}/clouds.yaml"
8+
register: prepare_client_pod_pvc_clouds
9+
10+
- name: Check for original-config OpenStack clouds.yaml
11+
ansible.builtin.stat:
12+
path: "{{ home_dir }}/.original-config/openstack/clouds.yaml"
13+
register: prepare_client_pod_orig_clouds
14+
15+
- name: Ensure OpenStack client config directory exists
16+
ansible.builtin.file:
17+
path: "{{ home_dir }}/.config/openstack"
18+
state: directory
19+
mode: u=rwx,g=rx,o=rx
20+
21+
- name: Restore OpenStack clouds config from PVC osp_config_dir
22+
when: prepare_client_pod_pvc_clouds.stat.exists | default(false)
23+
ansible.builtin.copy:
24+
src: "{{ osp_config_dir }}/"
25+
dest: "{{ home_dir }}/.config/openstack/"
26+
remote_src: true
27+
mode: preserve
28+
29+
- name: Fall back to original-config OpenStack clouds when PVC copy is absent
30+
when:
31+
- not (prepare_client_pod_pvc_clouds.stat.exists | default(false))
32+
- prepare_client_pod_orig_clouds.stat.exists | default(false)
33+
ansible.builtin.copy:
34+
src: "{{ home_dir }}/.original-config/openstack/"
35+
dest: "{{ home_dir }}/.config/openstack/"
36+
remote_src: true
37+
mode: preserve
38+
39+
- name: Check for secure.yaml on destination and original-config
40+
ansible.builtin.stat:
41+
path: "{{ item }}"
42+
loop:
43+
- "{{ home_dir }}/.config/openstack/secure.yaml"
44+
- "{{ home_dir }}/.original-config/openstack/secure.yaml"
45+
register: prepare_client_pod_secure_stats
46+
47+
- name: Ensure secure.yaml is present when only available on original-config
48+
when:
49+
- not (prepare_client_pod_secure_stats.results[0].stat.exists | default(false))
50+
- prepare_client_pod_secure_stats.results[1].stat.exists | default(false)
51+
ansible.builtin.copy:
52+
src: "{{ home_dir }}/.original-config/openstack/secure.yaml"
53+
dest: "{{ home_dir }}/.config/openstack/secure.yaml"
54+
remote_src: true
55+
mode: preserve
56+
57+
- name: Check whether oc is already available
58+
ansible.builtin.command:
59+
cmd: which oc
60+
register: prepare_client_pod_oc_which
61+
changed_when: false
62+
failed_when: false
63+
64+
- name: Bootstrap oc and kubectl from the OpenShift mirror
65+
when: prepare_client_pod_oc_which.rc != 0
66+
block:
67+
- name: Create bootstrap oc directory
68+
ansible.builtin.file:
69+
path: "{{ prepare_client_pod_bootstrap_oc_dir }}"
70+
state: directory
71+
mode: u=rwx,g=rw,o=r
72+
73+
- name: Download and extract stable oc client
74+
ansible.builtin.unarchive:
75+
src: "{{ prepare_client_pod_bootstrap_oc_url }}"
76+
dest: "{{ prepare_client_pod_bootstrap_oc_dir }}"
77+
remote_src: true
78+
include:
79+
- oc
80+
- kubectl
81+
register: prepare_client_pod_oc_download
82+
until: prepare_client_pod_oc_download is not failed
83+
retries: 3
84+
delay: 10
85+
86+
- name: Symlink oc into /usr/local/bin
87+
ansible.builtin.file:
88+
src: "{{ prepare_client_pod_bootstrap_oc_dir }}/oc"
89+
dest: /usr/local/bin/oc
90+
state: link
91+
become: true
92+
93+
- name: Symlink kubectl into /usr/bin
94+
ansible.builtin.file:
95+
src: "{{ prepare_client_pod_bootstrap_oc_dir }}/kubectl"
96+
dest: /usr/bin/kubectl
97+
state: link
98+
become: true
99+
100+
- name: Check install-config.yaml on the PVC
101+
ansible.builtin.stat:
102+
path: "{{ prepare_client_pod_install_config }}"
103+
register: prepare_client_pod_ic_stat
104+
105+
- name: Fail when install-config.yaml is missing
106+
ansible.builtin.assert:
107+
that:
108+
- prepare_client_pod_ic_stat.stat.exists | default(false)
109+
fail_msg: >-
110+
prepare_client_pod requires {{ prepare_client_pod_install_config }} on the
111+
PVC to restore guest API/apps FIPs into /etc/hosts and resources.yml.
112+
113+
- name: Load install-config.yaml
114+
ansible.builtin.slurp:
115+
src: "{{ prepare_client_pod_install_config }}"
116+
register: prepare_client_pod_install_config_slurp
117+
118+
- name: Parse install-config FIPs and base domain
119+
vars:
120+
_ic: "{{ prepare_client_pod_install_config_slurp.content | b64decode | from_yaml }}"
121+
ansible.builtin.set_fact:
122+
api_accessible_ip: "{{ _ic.platform.openstack.apiFloatingIP }}"
123+
apps_accessible_ip: "{{ _ic.platform.openstack.ingressFloatingIP }}"
124+
api_ip: "{{ _ic.platform.openstack.apiFloatingIP }}"
125+
apps_ip: "{{ _ic.platform.openstack.ingressFloatingIP }}"
126+
prepare_client_pod_base_domain: "{{ _ic.baseDomain }}"
127+
prepare_client_pod_cluster_name: "{{ ocp_cluster_name }}"
128+
129+
- name: Check for metadata.json
130+
ansible.builtin.stat:
131+
path: "{{ prepare_client_pod_metadata }}"
132+
register: prepare_client_pod_meta_stat
133+
134+
- name: Override cluster name from metadata.json when present
135+
when: prepare_client_pod_meta_stat.stat.exists | default(false)
136+
block:
137+
- name: Load metadata.json
138+
ansible.builtin.slurp:
139+
src: "{{ prepare_client_pod_metadata }}"
140+
register: prepare_client_pod_metadata_slurp
141+
142+
- name: Set cluster name from metadata
143+
vars:
144+
_meta: "{{ prepare_client_pod_metadata_slurp.content | b64decode | from_json }}"
145+
ansible.builtin.set_fact:
146+
prepare_client_pod_cluster_name: >-
147+
{{ _meta.clusterName | default(ocp_cluster_name) }}
148+
149+
- name: Check whether resources.yml already exists
150+
ansible.builtin.stat:
151+
path: "{{ resources_file }}"
152+
register: prepare_client_pod_resources_stat
153+
154+
- name: Write resources.yml when absent
155+
when: not (prepare_client_pod_resources_stat.stat.exists | default(false))
156+
ansible.builtin.include_role:
157+
name: shiftstack.tools.tools_register_resources_file
158+
vars:
159+
input:
160+
api_accessible_ip: "{{ api_accessible_ip }}"
161+
apps_accessible_ip: "{{ apps_accessible_ip }}"
162+
163+
- name: Restore guest API and apps entries in /etc/hosts
164+
become: true
165+
ansible.builtin.lineinfile:
166+
path: /etc/hosts
167+
regexp: "{{ item.regex }}"
168+
line: "{{ item.row }}"
169+
unsafe_writes: true
170+
vars:
171+
ocp_cluster_name: "{{ prepare_client_pod_cluster_name }}"
172+
ocp_base_domain: "{{ prepare_client_pod_base_domain }}"
173+
loop: "{{ prepare_client_pod_etc_hosts_entries }}"

‎playbooks/ocp_testing.yaml‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@
5959
tasks_from: create_installer_group.yml
6060
when: "not deploy_installer_host"
6161

62+
- name: Prepare the shiftstackclient pod when full prepare was skipped
63+
ansible.builtin.import_playbook: plays/prepare_client_pod.yaml
64+
when: "'prepare_client_pod' in stages"
65+
6266
- name: Prepare the OpenShift installer
6367
ansible.builtin.import_playbook: plays/prepare.yaml
6468
when: "'prepare' in stages"
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
- name: Prepare the shiftstackclient pod for warm testing
3+
hosts: localhost
4+
gather_facts: true
5+
vars_files:
6+
- "../../configs/global.yml"
7+
tasks:
8+
- name: Bootstrap oc, clouds, hosts, and resources.yml on the client pod
9+
ansible.builtin.include_role:
10+
name: shiftstack.stages.prepare_client_pod

0 commit comments

Comments
 (0)