provision.j2.sh 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  1. #!/bin/bash
  2. set -euo pipefail
  3. if [[ -n "{{ openshift_gcp_ssh_private_key }}" ]]; then
  4. # Create SSH key for GCE
  5. if [ ! -f "{{ openshift_gcp_ssh_private_key }}" ]; then
  6. ssh-keygen -t rsa -f "{{ openshift_gcp_ssh_private_key }}" -C gce-provision-cloud-user -N ''
  7. ssh-add "{{ openshift_gcp_ssh_private_key }}" || true
  8. fi
  9. # Check if the public key is in the project metadata, and if not, add it there
  10. if [ -f "{{ openshift_gcp_ssh_private_key }}.pub" ]; then
  11. pub_file="{{ openshift_gcp_ssh_private_key }}.pub"
  12. pub_key=$(cut -d ' ' -f 2 < "{{ openshift_gcp_ssh_private_key }}.pub")
  13. else
  14. keyfile="${HOME}/.ssh/google_compute_engine"
  15. pub_file="${keyfile}.pub"
  16. mkdir -p "${HOME}/.ssh"
  17. cp "{{ openshift_gcp_ssh_private_key }}" "${keyfile}"
  18. chmod 0600 "${keyfile}"
  19. ssh-keygen -y -f "${keyfile}" > "${pub_file}"
  20. pub_key=$(cut -d ' ' -f 2 < "${pub_file}")
  21. fi
  22. key_tmp_file='/tmp/ocp-gce-keys'
  23. if ! gcloud --project "{{ openshift_gcp_project }}" compute project-info describe | grep -q "$pub_key"; then
  24. if gcloud --project "{{ openshift_gcp_project }}" compute project-info describe | grep -q ssh-rsa; then
  25. gcloud --project "{{ openshift_gcp_project }}" compute project-info describe | grep ssh-rsa | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//' -e 's/value: //' > "$key_tmp_file"
  26. fi
  27. echo -n 'cloud-user:' >> "$key_tmp_file"
  28. cat "${pub_file}" >> "$key_tmp_file"
  29. gcloud --project "{{ openshift_gcp_project }}" compute project-info add-metadata --metadata-from-file "sshKeys=${key_tmp_file}"
  30. rm -f "$key_tmp_file"
  31. fi
  32. fi
  33. metadata=""
  34. if [[ -n "{{ openshift_gcp_startup_script_file }}" ]]; then
  35. if [[ ! -f "{{ openshift_gcp_startup_script_file }}" ]]; then
  36. echo "Startup script file missing at {{ openshift_gcp_startup_script_file }} from=$(pwd)"
  37. exit 1
  38. fi
  39. metadata+="--metadata-from-file=startup-script={{ openshift_gcp_startup_script_file }}"
  40. fi
  41. if [[ -n "{{ openshift_gcp_user_data_file }}" ]]; then
  42. if [[ ! -f "{{ openshift_gcp_user_data_file }}" ]]; then
  43. echo "User data file missing at {{ openshift_gcp_user_data_file }}"
  44. exit 1
  45. fi
  46. if [[ -n "${metadata}" ]]; then
  47. metadata+=","
  48. else
  49. metadata="--metadata-from-file="
  50. fi
  51. metadata+="user-data={{ openshift_gcp_user_data_file }}"
  52. fi
  53. # Select image or image family
  54. image="{{ openshift_gcp_image }}"
  55. if ! gcloud --project "{{ openshift_gcp_project }}" compute images describe "${image}" &>/dev/null; then
  56. if ! gcloud --project "{{ openshift_gcp_project }}" compute images describe-from-family "${image}" &>/dev/null; then
  57. echo "No compute image or image-family found, create an image named '{{ openshift_gcp_image }}' to continue'"
  58. exit 1
  59. fi
  60. image="family/${image}"
  61. fi
  62. ### PROVISION THE INFRASTRUCTURE ###
  63. dns_zone="{{ dns_managed_zone | default(openshift_gcp_prefix + 'managed-zone') }}"
  64. # Check the DNS managed zone in Google Cloud DNS, create it if it doesn't exist and exit after printing NS servers
  65. if ! gcloud --project "{{ openshift_gcp_project }}" dns managed-zones describe "${dns_zone}" &>/dev/null; then
  66. echo "DNS zone '${dns_zone}' doesn't exist. Must be configured prior to running this script"
  67. exit 1
  68. fi
  69. # Create network
  70. if ! gcloud --project "{{ openshift_gcp_project }}" compute networks describe "{{ openshift_gcp_network_name }}" &>/dev/null; then
  71. gcloud --project "{{ openshift_gcp_project }}" compute networks create "{{ openshift_gcp_network_name }}" --mode "auto"
  72. else
  73. echo "Network '{{ openshift_gcp_network_name }}' already exists"
  74. fi
  75. # Firewall rules in a form:
  76. # ['name']='parameters for "gcloud compute firewall-rules create"'
  77. # For all possible parameters see: gcloud compute firewall-rules create --help
  78. range=""
  79. if [[ -n "{{ openshift_node_port_range }}" ]]; then
  80. range=",tcp:{{ openshift_node_port_range }},udp:{{ openshift_node_port_range }}"
  81. fi
  82. declare -A FW_RULES=(
  83. ['icmp']='--allow icmp'
  84. ['ssh-external']='--allow tcp:22'
  85. ['ssh-internal']='--allow tcp:22 --source-tags bastion'
  86. ['master-internal']="--allow tcp:2224,tcp:2379,tcp:2380,tcp:4001,udp:4789,udp:5404,udp:5405,tcp:8053,udp:8053,tcp:8444,tcp:10250,tcp:10255,udp:10255,tcp:24224,udp:24224 --source-tags ocp --target-tags ocp-master"
  87. ['master-external']="--allow tcp:80,tcp:443,tcp:1936,tcp:8080,tcp:8443${range} --target-tags ocp-master"
  88. ['node-internal']="--allow udp:4789,tcp:10250,tcp:10255,udp:10255 --source-tags ocp --target-tags ocp-node,ocp-infra-node"
  89. ['infra-node-internal']="--allow tcp:5000 --source-tags ocp --target-tags ocp-infra-node"
  90. ['infra-node-external']="--allow tcp:80,tcp:443,tcp:1936${range} --target-tags ocp-infra-node"
  91. )
  92. for rule in "${!FW_RULES[@]}"; do
  93. ( if ! gcloud --project "{{ openshift_gcp_project }}" compute firewall-rules describe "{{ openshift_gcp_prefix }}$rule" &>/dev/null; then
  94. gcloud --project "{{ openshift_gcp_project }}" compute firewall-rules create "{{ openshift_gcp_prefix }}$rule" --network "{{ openshift_gcp_network_name }}" ${FW_RULES[$rule]}
  95. else
  96. echo "Firewall rule '{{ openshift_gcp_prefix }}${rule}' already exists"
  97. fi ) &
  98. done
  99. # Master IP
  100. ( if ! gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}master-ssl-lb-ip" --global &>/dev/null; then
  101. gcloud --project "{{ openshift_gcp_project }}" compute addresses create "{{ openshift_gcp_prefix }}master-ssl-lb-ip" --global
  102. else
  103. echo "IP '{{ openshift_gcp_prefix }}master-ssl-lb-ip' already exists"
  104. fi ) &
  105. # Internal master IP
  106. ( if ! gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}master-network-lb-ip" --region "{{ openshift_gcp_region }}" &>/dev/null; then
  107. gcloud --project "{{ openshift_gcp_project }}" compute addresses create "{{ openshift_gcp_prefix }}master-network-lb-ip" --region "{{ openshift_gcp_region }}"
  108. else
  109. echo "IP '{{ openshift_gcp_prefix }}master-network-lb-ip' already exists"
  110. fi ) &
  111. # Router IP
  112. ( if ! gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}router-network-lb-ip" --region "{{ openshift_gcp_region }}" &>/dev/null; then
  113. gcloud --project "{{ openshift_gcp_project }}" compute addresses create "{{ openshift_gcp_prefix }}router-network-lb-ip" --region "{{ openshift_gcp_region }}"
  114. else
  115. echo "IP '{{ openshift_gcp_prefix }}router-network-lb-ip' already exists"
  116. fi ) &
  117. {% for node_group in openshift_gcp_node_group_config %}
  118. # configure {{ node_group.name }}
  119. (
  120. if ! gcloud --project "{{ openshift_gcp_project }}" compute instance-templates describe "{{ openshift_gcp_prefix }}instance-template-{{ node_group.name }}" &>/dev/null; then
  121. gcloud --project "{{ openshift_gcp_project }}" compute instance-templates create "{{ openshift_gcp_prefix }}instance-template-{{ node_group.name }}" \
  122. --machine-type "{{ node_group.machine_type }}" --network "{{ openshift_gcp_network_name }}" \
  123. --tags "{{ openshift_gcp_prefix }}ocp,ocp,{{ 'ocp-bootstrap,' if (node_group.bootstrap | default(False)) else '' }}{{ node_group.tags }}" \
  124. --boot-disk-size "{{ node_group.boot_disk_size }}" --boot-disk-type "pd-ssd" \
  125. --scopes "logging-write,monitoring-write,useraccounts-ro,service-control,service-management,storage-ro,compute-rw" \
  126. --image "{{ node_group.image | default('${image}') }}" ${metadata} \
  127. --metadata "bootstrap={{ node_group.bootstrap | default(False) | bool | to_json }},cluster-id={{ openshift_gcp_prefix + openshift_gcp_clusterid }},node-group={{ node_group.name }}"
  128. else
  129. echo "Instance template '{{ openshift_gcp_prefix }}instance-template-{{ node_group.name }}' already exists"
  130. fi
  131. # Create instance group
  132. if ! gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed describe "{{ openshift_gcp_prefix }}ig-{{ node_group.suffix }}" --zone "{{ openshift_gcp_zone }}" &>/dev/null; then
  133. gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed create "{{ openshift_gcp_prefix }}ig-{{ node_group.suffix }}" \
  134. --zone "{{ openshift_gcp_zone }}" --template "{{ openshift_gcp_prefix }}instance-template-{{ node_group.name }}" --size "{{ node_group.scale }}"
  135. else
  136. echo "Instance group '{{ openshift_gcp_prefix }}ig-{{ node_group.suffix }}' already exists"
  137. fi
  138. ) &
  139. {% endfor %}
  140. for i in `jobs -p`; do wait $i; done
  141. # Configure the master external LB rules
  142. (
  143. # Master health check
  144. if ! gcloud --project "{{ openshift_gcp_project }}" compute health-checks describe "{{ openshift_gcp_prefix }}master-ssl-lb-health-check" &>/dev/null; then
  145. gcloud --project "{{ openshift_gcp_project }}" compute health-checks create https "{{ openshift_gcp_prefix }}master-ssl-lb-health-check" --port "{{ internal_console_port }}" --request-path "/healthz"
  146. else
  147. echo "Health check '{{ openshift_gcp_prefix }}master-ssl-lb-health-check' already exists"
  148. fi
  149. gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed set-named-ports "{{ openshift_gcp_prefix }}ig-m" \
  150. --zone "{{ openshift_gcp_zone }}" --named-ports "{{ openshift_gcp_prefix }}port-name-master:{{ internal_console_port }}"
  151. # Master backend service
  152. if ! gcloud --project "{{ openshift_gcp_project }}" compute backend-services describe "{{ openshift_gcp_prefix }}master-ssl-lb-backend" --global &>/dev/null; then
  153. gcloud --project "{{ openshift_gcp_project }}" compute backend-services create "{{ openshift_gcp_prefix }}master-ssl-lb-backend" --health-checks "{{ openshift_gcp_prefix }}master-ssl-lb-health-check" --port-name "{{ openshift_gcp_prefix }}port-name-master" --protocol "TCP" --global --timeout="{{ openshift_gcp_master_lb_timeout }}"
  154. gcloud --project "{{ openshift_gcp_project }}" compute backend-services add-backend "{{ openshift_gcp_prefix }}master-ssl-lb-backend" --instance-group "{{ openshift_gcp_prefix }}ig-m" --global --instance-group-zone "{{ openshift_gcp_zone }}"
  155. else
  156. echo "Backend service '{{ openshift_gcp_prefix }}master-ssl-lb-backend' already exists"
  157. fi
  158. # Master tcp proxy target
  159. if ! gcloud --project "{{ openshift_gcp_project }}" compute target-tcp-proxies describe "{{ openshift_gcp_prefix }}master-ssl-lb-target" &>/dev/null; then
  160. gcloud --project "{{ openshift_gcp_project }}" compute target-tcp-proxies create "{{ openshift_gcp_prefix }}master-ssl-lb-target" --backend-service "{{ openshift_gcp_prefix }}master-ssl-lb-backend"
  161. else
  162. echo "Proxy target '{{ openshift_gcp_prefix }}master-ssl-lb-target' already exists"
  163. fi
  164. # Master forwarding rule
  165. if ! gcloud --project "{{ openshift_gcp_project }}" compute forwarding-rules describe "{{ openshift_gcp_prefix }}master-ssl-lb-rule" --global &>/dev/null; then
  166. IP=$(gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}master-ssl-lb-ip" --global --format='value(address)')
  167. gcloud --project "{{ openshift_gcp_project }}" compute forwarding-rules create "{{ openshift_gcp_prefix }}master-ssl-lb-rule" --address "$IP" --global --ports "{{ console_port }}" --target-tcp-proxy "{{ openshift_gcp_prefix }}master-ssl-lb-target"
  168. else
  169. echo "Forwarding rule '{{ openshift_gcp_prefix }}master-ssl-lb-rule' already exists"
  170. fi
  171. ) &
  172. # Configure the master internal LB rules
  173. (
  174. # Internal master health check
  175. if ! gcloud --project "{{ openshift_gcp_project }}" compute http-health-checks describe "{{ openshift_gcp_prefix }}master-network-lb-health-check" &>/dev/null; then
  176. gcloud --project "{{ openshift_gcp_project }}" compute http-health-checks create "{{ openshift_gcp_prefix }}master-network-lb-health-check" --port "8080" --request-path "/healthz"
  177. else
  178. echo "Health check '{{ openshift_gcp_prefix }}master-network-lb-health-check' already exists"
  179. fi
  180. # Internal master target pool
  181. if ! gcloud --project "{{ openshift_gcp_project }}" compute target-pools describe "{{ openshift_gcp_prefix }}master-network-lb-pool" --region "{{ openshift_gcp_region }}" &>/dev/null; then
  182. gcloud --project "{{ openshift_gcp_project }}" compute target-pools create "{{ openshift_gcp_prefix }}master-network-lb-pool" --http-health-check "{{ openshift_gcp_prefix }}master-network-lb-health-check" --region "{{ openshift_gcp_region }}"
  183. else
  184. echo "Target pool '{{ openshift_gcp_prefix }}master-network-lb-pool' already exists"
  185. fi
  186. # Internal master forwarding rule
  187. if ! gcloud --project "{{ openshift_gcp_project }}" compute forwarding-rules describe "{{ openshift_gcp_prefix }}master-network-lb-rule" --region "{{ openshift_gcp_region }}" &>/dev/null; then
  188. IP=$(gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}master-network-lb-ip" --region "{{ openshift_gcp_region }}" --format='value(address)')
  189. gcloud --project "{{ openshift_gcp_project }}" compute forwarding-rules create "{{ openshift_gcp_prefix }}master-network-lb-rule" --address "$IP" --region "{{ openshift_gcp_region }}" --target-pool "{{ openshift_gcp_prefix }}master-network-lb-pool"
  190. else
  191. echo "Forwarding rule '{{ openshift_gcp_prefix }}master-network-lb-rule' already exists"
  192. fi
  193. ) &
  194. # Configure the infra node rules
  195. (
  196. # Router health check
  197. if ! gcloud --project "{{ openshift_gcp_project }}" compute http-health-checks describe "{{ openshift_gcp_prefix }}router-network-lb-health-check" &>/dev/null; then
  198. gcloud --project "{{ openshift_gcp_project }}" compute http-health-checks create "{{ openshift_gcp_prefix }}router-network-lb-health-check" --port "1936" --request-path "/healthz"
  199. else
  200. echo "Health check '{{ openshift_gcp_prefix }}router-network-lb-health-check' already exists"
  201. fi
  202. # Router target pool
  203. if ! gcloud --project "{{ openshift_gcp_project }}" compute target-pools describe "{{ openshift_gcp_prefix }}router-network-lb-pool" --region "{{ openshift_gcp_region }}" &>/dev/null; then
  204. gcloud --project "{{ openshift_gcp_project }}" compute target-pools create "{{ openshift_gcp_prefix }}router-network-lb-pool" --http-health-check "{{ openshift_gcp_prefix }}router-network-lb-health-check" --region "{{ openshift_gcp_region }}"
  205. else
  206. echo "Target pool '{{ openshift_gcp_prefix }}router-network-lb-pool' already exists"
  207. fi
  208. # Router forwarding rule
  209. if ! gcloud --project "{{ openshift_gcp_project }}" compute forwarding-rules describe "{{ openshift_gcp_prefix }}router-network-lb-rule" --region "{{ openshift_gcp_region }}" &>/dev/null; then
  210. IP=$(gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}router-network-lb-ip" --region "{{ openshift_gcp_region }}" --format='value(address)')
  211. gcloud --project "{{ openshift_gcp_project }}" compute forwarding-rules create "{{ openshift_gcp_prefix }}router-network-lb-rule" --address "$IP" --region "{{ openshift_gcp_region }}" --target-pool "{{ openshift_gcp_prefix }}router-network-lb-pool"
  212. else
  213. echo "Forwarding rule '{{ openshift_gcp_prefix }}router-network-lb-rule' already exists"
  214. fi
  215. ) &
  216. for i in `jobs -p`; do wait $i; done
  217. # set the target pools
  218. (
  219. if [[ "ig-m" == "{{ openshift_gcp_infra_network_instance_group }}" ]]; then
  220. gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed set-target-pools "{{ openshift_gcp_prefix }}ig-m" --target-pools "{{ openshift_gcp_prefix }}master-network-lb-pool,{{ openshift_gcp_prefix }}router-network-lb-pool" --zone "{{ openshift_gcp_zone }}"
  221. else
  222. gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed set-target-pools "{{ openshift_gcp_prefix }}ig-m" --target-pools "{{ openshift_gcp_prefix }}master-network-lb-pool" --zone "{{ openshift_gcp_zone }}"
  223. gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed set-target-pools "{{ openshift_gcp_prefix }}{{ openshift_gcp_infra_network_instance_group }}" --target-pools "{{ openshift_gcp_prefix }}router-network-lb-pool" --zone "{{ openshift_gcp_zone }}"
  224. fi
  225. ) &
  226. # configure DNS
  227. (
  228. # Retry DNS changes until they succeed since this may be a shared resource
  229. while true; do
  230. dns="${TMPDIR:-/tmp}/dns.yaml"
  231. rm -f $dns
  232. # DNS record for master lb
  233. if ! gcloud --project "{{ openshift_gcp_project }}" dns record-sets list -z "${dns_zone}" --name "{{ openshift_master_cluster_public_hostname }}" 2>/dev/null | grep -q "{{ openshift_master_cluster_public_hostname }}"; then
  234. IP=$(gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}master-ssl-lb-ip" --global --format='value(address)')
  235. if [[ ! -f $dns ]]; then
  236. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns start -z "${dns_zone}"
  237. fi
  238. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns add -z "${dns_zone}" --ttl 3600 --name "{{ openshift_master_cluster_public_hostname }}." --type A "$IP"
  239. else
  240. echo "DNS record for '{{ openshift_master_cluster_public_hostname }}' already exists"
  241. fi
  242. # DNS record for internal master lb
  243. if ! gcloud --project "{{ openshift_gcp_project }}" dns record-sets list -z "${dns_zone}" --name "{{ openshift_master_cluster_hostname }}" 2>/dev/null | grep -q "{{ openshift_master_cluster_hostname }}"; then
  244. IP=$(gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}master-network-lb-ip" --region "{{ openshift_gcp_region }}" --format='value(address)')
  245. if [[ ! -f $dns ]]; then
  246. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns start -z "${dns_zone}"
  247. fi
  248. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns add -z "${dns_zone}" --ttl 3600 --name "{{ openshift_master_cluster_hostname }}." --type A "$IP"
  249. else
  250. echo "DNS record for '{{ openshift_master_cluster_hostname }}' already exists"
  251. fi
  252. # DNS record for router lb
  253. if ! gcloud --project "{{ openshift_gcp_project }}" dns record-sets list -z "${dns_zone}" --name "{{ wildcard_zone }}" 2>/dev/null | grep -q "{{ wildcard_zone }}"; then
  254. IP=$(gcloud --project "{{ openshift_gcp_project }}" compute addresses describe "{{ openshift_gcp_prefix }}router-network-lb-ip" --region "{{ openshift_gcp_region }}" --format='value(address)')
  255. if [[ ! -f $dns ]]; then
  256. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns start -z "${dns_zone}"
  257. fi
  258. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns add -z "${dns_zone}" --ttl 3600 --name "{{ wildcard_zone }}." --type A "$IP"
  259. gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns add -z "${dns_zone}" --ttl 3600 --name "*.{{ wildcard_zone }}." --type CNAME "{{ wildcard_zone }}."
  260. else
  261. echo "DNS record for '{{ wildcard_zone }}' already exists"
  262. fi
  263. # Commit all DNS changes, retrying if preconditions are not met
  264. if [[ -f $dns ]]; then
  265. if ! out="$( gcloud --project "{{ openshift_gcp_project }}" dns record-sets transaction --transaction-file=$dns execute -z "${dns_zone}" 2>&1 )"; then
  266. rc=$?
  267. if [[ "${out}" == *"HTTPError 412: Precondition not met"* ]]; then
  268. continue
  269. fi
  270. exit $rc
  271. fi
  272. fi
  273. break
  274. done
  275. ) &
  276. # Create bucket for registry
  277. (
  278. if ! gsutil ls -p "{{ openshift_gcp_project }}" "gs://{{ openshift_gcp_registry_bucket_name }}" &>/dev/null; then
  279. gsutil mb -p "{{ openshift_gcp_project }}" -l "{{ openshift_gcp_region }}" "gs://{{ openshift_gcp_registry_bucket_name }}"
  280. else
  281. echo "Bucket '{{ openshift_gcp_registry_bucket_name }}' already exists"
  282. fi
  283. ) &
  284. # wait until all node groups are stable
  285. {% for node_group in openshift_gcp_node_group_config %}
  286. {% if node_group.wait_for_stable | default(False) or not (node_group.bootstrap | default(False)) %}
  287. # wait for stable {{ node_group.name }}
  288. ( gcloud --project "{{ openshift_gcp_project }}" compute instance-groups managed wait-until-stable "{{ openshift_gcp_prefix }}ig-{{ node_group.suffix }}" --zone "{{ openshift_gcp_zone }}" --timeout=600 ) &
  289. {% else %}
  290. # not waiting for {{ node_group.name }} due to bootstrapping
  291. {% endif %}
  292. {% endfor %}
  293. for i in `jobs -p`; do wait $i; done