kcli 99.0.202507120954__py3-none-any.whl → 99.0.202601080644__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (69) hide show
  1. {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/METADATA +1 -1
  2. {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/RECORD +68 -64
  3. {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/entry_points.txt +2 -1
  4. kvirt/baseconfig.py +4 -9
  5. kvirt/cli.py +65 -19
  6. kvirt/cluster/hypershift/__init__.py +15 -23
  7. kvirt/cluster/kubeadm/__init__.py +1 -1
  8. kvirt/cluster/kubeadm/crio-d.sh +4 -4
  9. kvirt/cluster/kubeadm/keepalived.sh +1 -1
  10. kvirt/cluster/microshift/kcli_default.yml +1 -1
  11. kvirt/cluster/microshift/scripts/01_clients.sh +1 -1
  12. kvirt/cluster/openshift/99-kcli-forcedns +8 -11
  13. kvirt/cluster/openshift/__init__.py +80 -42
  14. kvirt/cluster/openshift/apps/advanced-cluster-management/assisted-service.sh +1 -1
  15. kvirt/cluster/openshift/apps/advanced-cluster-management/kcli_default.yml +1 -0
  16. kvirt/cluster/openshift/apps/advanced-cluster-management/post.sh +4 -0
  17. kvirt/cluster/openshift/apps/multicluster-engine/assisted-service.sh +1 -1
  18. kvirt/cluster/openshift/apps/odf-operator/cr.yml +5 -0
  19. kvirt/cluster/openshift/apps/odf-operator/kcli_default.yml +1 -0
  20. kvirt/cluster/openshift/apps/odf-operator/pre.sh +1 -0
  21. kvirt/cluster/openshift/bgp-vip.sh +16 -0
  22. kvirt/cluster/openshift/bootstrap.yml +31 -1
  23. kvirt/cluster/openshift/ctlplanes.yml +31 -1
  24. kvirt/cluster/openshift/disconnected/mirror-config.yaml +6 -6
  25. kvirt/cluster/openshift/disconnected/scripts/01_packages.sh +2 -2
  26. kvirt/cluster/openshift/disconnected/scripts/02_registry.sh +5 -1
  27. kvirt/cluster/openshift/disconnected/scripts/03_mirror.sh +5 -1
  28. kvirt/cluster/openshift/frr.conf +29 -0
  29. kvirt/cluster/openshift/frr_daemons +38 -0
  30. kvirt/cluster/openshift/install-config.yaml +1 -1
  31. kvirt/cluster/openshift/kcli_default.yml +15 -10
  32. kvirt/cluster/openshift/sno_default.yml +1 -0
  33. kvirt/cluster/openshift/staticpods/bgp.yml +34 -0
  34. kvirt/cluster/openshift/telco_manifests.yml +790 -0
  35. kvirt/cluster/openshift/workers.yml +9 -0
  36. kvirt/common/__init__.py +63 -14
  37. kvirt/config.py +15 -9
  38. kvirt/containerconfig.py +2 -2
  39. kvirt/defaults.py +13 -7
  40. kvirt/examples.py +28 -15
  41. kvirt/expose/__init__.py +1 -1
  42. kvirt/extra_keywords/kvm.yaml +1 -0
  43. kvirt/internalplans/__init__.py +3 -10
  44. kvirt/jinjafilters/jinjafilters.py +9 -4
  45. kvirt/keywords.yaml +3 -0
  46. kvirt/kfish/__init__.py +1 -1
  47. kvirt/kmcp.py +55 -11
  48. kvirt/ksushy/__init__.py +19 -21
  49. kvirt/kubecommon/__init__.py +8 -6
  50. kvirt/providers/aws/__init__.py +2 -2
  51. kvirt/providers/azure/__init__.py +2 -2
  52. kvirt/providers/fake/__init__.py +1 -1
  53. kvirt/providers/gcp/__init__.py +2 -2
  54. kvirt/providers/hcloud/__init__.py +64 -50
  55. kvirt/providers/ibm/__init__.py +2 -2
  56. kvirt/providers/kubevirt/__init__.py +110 -43
  57. kvirt/providers/kvm/__init__.py +56 -38
  58. kvirt/providers/openstack/__init__.py +19 -5
  59. kvirt/providers/ovirt/__init__.py +1 -1
  60. kvirt/providers/proxmox/__init__.py +1 -1
  61. kvirt/providers/sampleprovider.py +1 -1
  62. kvirt/providers/vsphere/__init__.py +1 -1
  63. kvirt/providers/web/__init__.py +1 -1
  64. kvirt/version/git +1 -1
  65. kvirt/web/__init__.py +1 -3
  66. kvirt/cluster/hypershift/ignition.sh +0 -12
  67. {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/WHEEL +0 -0
  68. {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/licenses/LICENSE +0 -0
  69. {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/top_level.txt +0 -0
@@ -68,7 +68,7 @@ def get_info(url, user, password):
68
68
  model = 'virtual'
69
69
  user = user or 'fake'
70
70
  password = password or 'fake'
71
- url = url.replace('http', 'redfish-virtualmedia+http')
71
+ url = url.replace('https', 'redfish-virtualmedia')
72
72
  return url, user, password
73
73
  oem_url = f"https://{url}" if '://' not in url else url
74
74
  p = urlparse(oem_url)
@@ -190,26 +190,18 @@ def process_nodepools(config, plandir, namespace, cluster, platform, nodepools,
190
190
  return
191
191
  for entry in nodepools:
192
192
  nodepool = entry['name']
193
+ note = r"{.metadata.annotations.hypershift\.openshift\.io/nodePoolCurrentConfigVersion}"
194
+ cmd = f"until oc get nodepool ci-hypershift -n clusters -o jsonpath='{note}' | grep -q . ; do sleep 2; done"
195
+ call(cmd, shell=True)
196
+ cmd = f"oc get nodepool ci-hypershift -n clusters -o jsonpath='{note}'"
197
+ version = os.popen(cmd).read()
193
198
  pprint(f"Waiting before ignition data for nodepool {nodepool} is available")
194
- user_data = f"user-data-{cluster}"
195
- cmd = f"until oc -n {namespace}-{cluster} get secret | grep {user_data} >/dev/null 2>&1 ; do sleep 1 ; done"
199
+ cmd = f"until oc -n {namespace}-{cluster} get secret user-data-{cluster}-{version} ; do sleep 2 ; done"
196
200
  call(cmd, shell=True)
197
- ignition_data = {'namespace': namespace, 'cluster': cluster, 'nodepool': nodepool}
198
- ignitionscript = config.process_inputfile(cluster, f"{plandir}/ignition.sh", overrides=ignition_data)
199
- with open(f"{clusterdir}/ignition_{nodepool}.sh", 'w') as f:
200
- f.write(ignitionscript)
201
- ignition_worker = f"{clusterdir}/nodepool_{nodepool}.ign"
202
- timeout = 0
203
- while True:
204
- if os.path.exists(ignition_worker):
205
- break
206
- else:
207
- sleep(30)
208
- timeout += 30
209
- if timeout > 300:
210
- msg = "Timeout trying to retrieve worker ignition"
211
- return {'result': 'failure', 'reason': msg}
212
- call(f'bash {clusterdir}/ignition_{nodepool}.sh', shell=True)
201
+ cmd = f"oc extract -n {namespace}-{cluster} secret/user-data-{cluster}-{version} --keys=value --to=-"
202
+ ignition = os.popen(cmd).read()
203
+ with open(f"{clusterdir}/nodepool_{nodepool}.ign", 'w') as f:
204
+ f.write(ignition)
213
205
 
214
206
 
215
207
  def scale(config, plandir, cluster, overrides):
@@ -286,7 +278,7 @@ def scale(config, plandir, cluster, overrides):
286
278
  new_baremetal_hosts = overrides.get('baremetal_hosts', [])
287
279
  if assisted:
288
280
  ksushy_ip = data['assisted_vms_ksushy_ip']
289
- ksushy_url = f'http://{ksushy_ip}:9000/redfish/v1/Systems/{config.client}'
281
+ ksushy_url = f'https://{ksushy_ip}:9000/redfish/v1/Systems/{config.client}'
290
282
  old_physical_baremetal_hosts = [h for h in old_baremetal_hosts if ksushy_ip not in h['url']]
291
283
  assisted_vms_number = workers - len(old_physical_baremetal_hosts + new_baremetal_hosts)
292
284
  if assisted_vms_number > 0:
@@ -388,8 +380,8 @@ def create(config, plandir, cluster, overrides):
388
380
  version = 'stable'
389
381
  coredns = data.get('coredns')
390
382
  tag = data.get('tag')
391
- if str(tag) == '4.1':
392
- tag = '4.10'
383
+ if isinstance(tag, float) and str(tag).count('.') == 1 and len(str(tag).split('.')[1]) == 1:
384
+ tag = f'{tag}0'
393
385
  data['tag'] = tag
394
386
  pull_secret = os.path.expanduser(pwd_path(data.get('pull_secret')))
395
387
  if not os.path.exists(pull_secret):
@@ -787,7 +779,7 @@ def create(config, plandir, cluster, overrides):
787
779
  return result
788
780
  vms = result['newvms']
789
781
  ksushy_ip = data['assisted_vms_ksushy_ip']
790
- ksushy_url = f'http://{ksushy_ip}:9000/redfish/v1/Systems/{config.client}'
782
+ ksushy_url = f'https://{ksushy_ip}:9000/redfish/v1/Systems/{config.client}'
791
783
  virtual_hosts = []
792
784
  for vm in vms:
793
785
  new_mac = config.k.info(vm)['nets'][0]['mac']
@@ -204,7 +204,7 @@ def create(config, plandir, cluster, overrides):
204
204
  engine_version = data['engine_version'] or kube_version
205
205
  if not engine_version.startswith('v'):
206
206
  engine_version = f'v{engine_version}'
207
- engine_url = f"https://pkgs.k8s.io/addons:/cri-o:/stable:/{engine_version}/rpm/repodata/repomd.xml"
207
+ engine_url = f"https://download.opensuse.org/repositories/isv:/cri-o:/stable:/{engine_version}/rpm/repodata/repomd.xml"
208
208
  try:
209
209
  urlopen(engine_url)
210
210
  except:
@@ -4,18 +4,18 @@ VERSION=$(echo "v${VERSION#v}" | cut -d. -f1,2)
4
4
 
5
5
  {% if ubuntu|default(False) %}
6
6
  PROJECT_PATH={{ engine_version or 'stable:/$VERSION' }}
7
- curl -fsSL https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg
8
- echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/deb/ /" > /etc/apt/sources.list.d/cri-o.list
7
+ curl -fsSL https://download.opensuse.org/repositories/isv:/cri-o:/$PROJECT_PATH/deb/Release.key | gpg --dearmor -o /etc/apt/keyrings/cri-o-apt-keyring.gpg
8
+ echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://download.opensuse.org/repositories/isv:/cri-o:/$PROJECT_PATH/deb/ /" > /etc/apt/sources.list.d/cri-o.list
9
9
  apt-get update
10
10
  apt-get -y install cri-o runc software-properties-common
11
11
  {% else %}
12
12
  PROJECT_PATH={{ engine_version or 'stable:/$VERSION' }}
13
13
  echo """[cri-o]
14
14
  name=CRI-O
15
- baseurl=https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/rpm
15
+ baseurl=https://download.opensuse.org/repositories/isv:/cri-o:/$PROJECT_PATH/rpm
16
16
  enabled=1
17
17
  gpgcheck=1
18
- gpgkey=https://pkgs.k8s.io/addons:/cri-o:/$PROJECT_PATH/rpm/repodata/repomd.xml.key""" >/etc/yum.repos.d/cri-o.repo
18
+ gpgkey=https://download.opensuse.org/repositories/isv:/cri-o:/$PROJECT_PATH/rpm/repodata/repomd.xml.key""" >/etc/yum.repos.d/cri-o.repo
19
19
  dnf -y install container-selinux cri-o conntrack
20
20
  {% endif %}
21
21
 
@@ -2,7 +2,7 @@ PKGMGR="{{ 'apt-get' if ubuntu else 'dnf' }}"
2
2
  $PKGMGR -y install keepalived
3
3
  NETMASK=$(ip -o -f inet addr show | awk '/scope global/ {print $4}' | head -1 | cut -d'/' -f2)
4
4
  sed -i "s/NETMASK/$NETMASK/" /root/keepalived.conf
5
- NIC=$(find /sys/class/net -type l -not -lname '*virtual*' -printf '%f\n' | head -1)
5
+ NIC=$(awk '/default/ {for(i=1;i<=NF;i++) if($i=="dev") {print $(i+1); exit}}' <(ip route show default; ip -6 route show default))
6
6
  sed -i "s/NIC/$NIC/" /root/keepalived.conf
7
7
  cp /root/keepalived.conf /etc/keepalived
8
8
  systemctl enable --now keepalived
@@ -5,7 +5,7 @@ info: |
5
5
  cluster: mymicroshift
6
6
  domain: karmalabs.corp
7
7
  version: stable
8
- tag: '4.16'
8
+ tag: '4.20'
9
9
  image: rhel9
10
10
  network: default
11
11
  memory: 4096
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env bash
2
2
 
3
- MAJOR={{ 8 if 'rhel8' in image else 9 }}
3
+ MAJOR=$(awk '{print $6}' /etc/redhat-release | cut -d'.' -f1)
4
4
  {% set tag_str = tag|string %}
5
5
 
6
6
  {% if version in ['candidate', 'nightly'] %}
@@ -1,21 +1,18 @@
1
1
  #!/bin/bash
2
2
 
3
- which crictl >/dev/null 2>&1
3
+ CLUSTER={{ cluster }}
4
+ DOMAIN={{ domain }}
5
+
6
+ [ "$(hostname -s)" == "{{ cluster }}-bootstrap" ] || which crictl >/dev/null 2>&1
4
7
  if [ "$?" != "0" ] ; then
5
8
  exit 0
6
9
  fi
7
10
 
8
- if [ "$2" = "dhcp4-change" ] || [ "$2" = "dhcp6-change" ] || [ "$2" = "up" ] || [ "$2" = "connectivity-change" ]; then
11
+ if [ "$(grep '# kcli' /etc/resolv.conf)" == "" ] ; then
9
12
  sleep 2
10
13
  NIC={{ "$(ip -6 r | grep -v lo | head -1 | grep -oP '(?<=dev )[^ ]*')" if ipv6 else "$(ip r | grep default | head -1 | grep -oP '(?<=dev )[^ ]*')" }}
11
14
  IP={{ "$(ip -o -f inet6 addr show $NIC | head -1 | grep -oP '(?<=inet6 )[^ ]*' | cut -d '/' -f 1)" if ipv6 else "$(ip -o -f inet addr show $NIC | head -1 | grep -oP '(?<=inet )[^ ]*' | cut -d '/' -f 1)" }}
12
- if [ "$IP" != "" ] ; then
13
- grep -q $IP /etc/resolv.conf
14
- if [ "$?" != "0" ] ; then
15
- sed -i 's/{{ cluster }}.{{ domain }}//' /etc/resolv.conf
16
- sed -i 's/search /search {{ cluster }}.{{ domain }} /' /etc/resolv.conf
17
- sed -i "/nameserver.* #coredns/d" /etc/resolv.conf
18
- sed -i "0,/nameserver/s/nameserver/nameserver $IP #coredns\n&/" /etc/resolv.conf
19
- fi
20
- fi
15
+ sed -i "s/$CLUSTER.$DOMAIN//" /etc/resolv.conf
16
+ sed -i "s/search /search $CLUSTER.$DOMAIN /" /etc/resolv.conf
17
+ sed -i "0,/nameserver/s/nameserver/nameserver $IP # kcli\n&/" /etc/resolv.conf
21
18
  fi
@@ -11,6 +11,7 @@ from kvirt.common import ssh, scp, _ssh_credentials, get_ssh_pub_key
11
11
  from kvirt.common import start_baremetal_hosts_with_iso, update_baremetal_hosts, get_new_vip, process_postscripts
12
12
  from kvirt.defaults import LOCAL_OPENSHIFT_APPS, OPENSHIFT_TAG
13
13
  import os
14
+ import platform
14
15
  import re
15
16
  from random import choice
16
17
  from shutil import copy2, move, rmtree, which
@@ -336,16 +337,18 @@ def get_downstream_installer(version='stable', macosx=False, tag=None, debug=Fal
336
337
 
337
338
 
338
339
  def get_okd_installer(tag, version='stable', debug=False):
339
- if version == 'stable' and str(tag).count('.') == 1:
340
- tag = f'quay.io/okd/scos-release:{tag}.0-okd-scos.1'
341
- elif 'quay.io' not in str(tag) and 'registry.ci.openshift.org' not in str(tag):
342
- if version == 'candidate':
343
- url = "https://amd64.origin.releases.ci.openshift.org/api/v1/releasestream/4-scos-next/latest"
344
- elif version in ['ci', 'nightly']:
345
- url = f"https://amd64.origin.releases.ci.openshift.org/api/v1/releasestream/{tag}.0-0.okd-scos/latest"
346
- else:
347
- url = "https://amd64.origin.releases.ci.openshift.org/api/v1/releasestream/4-scos-stable/latest"
340
+ if version == 'candidate':
341
+ url = "https://amd64.origin.releases.ci.openshift.org/api/v1/releasestream/4-scos-next/latest"
342
+ tag = json.loads(urlopen(url).read())['pullSpec']
343
+ elif version in ['ci', 'nightly']:
344
+ url = f"https://amd64.origin.releases.ci.openshift.org/api/v1/releasestream/{tag}.0-0.okd-scos/latest"
348
345
  tag = json.loads(urlopen(url).read())['pullSpec']
346
+ else:
347
+ url = 'https://quay.io/api/v1/repository/okd/scos-release/tag'
348
+ for t in json.loads(urlopen(url).read())["tags"]:
349
+ if tag in t["name"] and ".ec." not in t["name"]:
350
+ tag = f'quay.io/okd/scos-release:{t["name"]}'
351
+ break
349
352
  cmd = f"oc adm release extract --command=openshift-install --to . {tag}"
350
353
  cmd += "; chmod 700 openshift-install"
351
354
  pprint(f'Downloading openshift-install {tag} in current directory')
@@ -663,14 +666,14 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
663
666
  warning("Forcing dualstack")
664
667
  data['dualstack'] = True
665
668
  http_proxy = os.environ.get('HTTP_PROXY') or os.environ.get('http_proxy')
666
- if 'http_proxy' not in data and http_proxy is not None:
669
+ if data['http_proxy'] is None and http_proxy is not None:
667
670
  pprint("Using proxy settings from environment")
668
671
  data['http_proxy'] = http_proxy
669
672
  https_proxy = os.environ.get('HTTPS_PROXY') or os.environ.get('https_proxy')
670
- if 'https_proxy' not in data and https_proxy is not None:
673
+ if data['https_proxy'] is None and https_proxy is not None:
671
674
  data['https_proxy'] = https_proxy
672
675
  no_proxy = os.environ.get('NO_PROXY') or os.environ.get('no_proxy')
673
- if 'no_proxy' not in data and no_proxy is not None:
676
+ if data['no_proxy'] is None and no_proxy is not None:
674
677
  data['no_proxy'] = no_proxy
675
678
  if data['ctlplanes'] == 1 and data['workers'] == 0\
676
679
  and 'ctlplane_memory' not in overrides and 'memory' not in overrides:
@@ -710,8 +713,11 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
710
713
  data['sno'] = sno
711
714
  sno_wait = overrides.get('sno_wait') or baremetal_sno or data['api_ip'] is not None or sno_vm
712
715
  sno_disk = data['sno_disk']
716
+ if sno_disk is not None and not sno_disk.startswith('/dev/'):
717
+ sno_disk = f'/dev/{sno_disk}'
713
718
  sno_ctlplanes = data['sno_ctlplanes'] or baremetal_ctlplane
714
719
  sno_workers = data['sno_workers']
720
+ sno_telco = data['sno_telco']
715
721
  ignore_hosts = data['ignore_hosts'] or sslip
716
722
  if sno:
717
723
  if sno_disk is None:
@@ -756,7 +762,13 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
756
762
  if not data['coredns']:
757
763
  warning("You will need to provide DNS records for api and ingress on your own")
758
764
  keepalived = data['keepalived']
759
- if not keepalived:
765
+ bgp = data['bgp']
766
+ if bgp:
767
+ data['keepalived'] = False
768
+ keepalived = False
769
+ if not data['bgp_peers']:
770
+ return {'result': 'failure', 'reason': 'bgp_peers needs to be set'}
771
+ elif not keepalived:
760
772
  warning("You will need to provide LB for api and ingress on your own")
761
773
  mdns = data['mdns']
762
774
  localhost_fix = data['localhost_fix']
@@ -769,12 +781,15 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
769
781
  virtualization_nightly = data['virtualization_nightly']
770
782
  version = data['version']
771
783
  tag = data['tag']
784
+ if isinstance(tag, float) and str(tag).count('.') == 1 and len(str(tag).split('.')[1]) == 1:
785
+ tag = f'{tag}0'
786
+ data['tag'] = tag
772
787
  version = overrides.get('version') or detect_openshift_version(tag, OPENSHIFT_TAG)
773
788
  data['version'] = version
774
789
  if os.path.exists('coreos-installer'):
775
790
  pprint("Removing old coreos-installer")
776
791
  os.remove('coreos-installer')
777
- if version not in ['ci', 'candidate', 'nightly', 'stable']:
792
+ if version not in ['ci', 'candidate', 'latest', 'nightly', 'stable']:
778
793
  return {'result': 'failure', 'reason': f"Incorrect version {version}"}
779
794
  else:
780
795
  pprint(f"Using {version} version")
@@ -782,7 +797,7 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
782
797
  image = data['image']
783
798
  api_ip = data['api_ip']
784
799
  cidr = None
785
- if provider in virt_providers and keepalived and not sno and api_ip is None:
800
+ if provider in virt_providers and (keepalived or bgp) and not sno and api_ip is None:
786
801
  network = data['network']
787
802
  networkinfo = k.info_network(network)
788
803
  if not networkinfo:
@@ -838,7 +853,7 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
838
853
  data['ipv6'] = True
839
854
  overrides['ipv6'] = True
840
855
  data['disconnected_ipv6_network'] = True
841
- if not disconnected_vm and disconnected_url is None:
856
+ if not disconnected_vm and disconnected_url is None and data['http_proxy'] is None:
842
857
  warning("Forcing disconnected_vm to True as no disconnected_url was provided")
843
858
  data['disconnected_vm'] = True
844
859
  disconnected_vm = True
@@ -926,13 +941,19 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
926
941
  tag = f'registry.ci.openshift.org/{basetag}/release:{tag}'
927
942
  which_openshift = which('openshift-install')
928
943
  openshift_dir = os.path.dirname(which_openshift) if which_openshift is not None else '.'
929
- if which_openshift is not None and not has_internet():
930
- pprint("Using existing openshift-install found in your PATH")
931
- warning("Not checking version")
932
- elif okd:
933
- run = get_okd_installer(tag, version=version)
934
- elif not same_release_images(version=version, tag=tag, pull_secret=pull_secret, path=openshift_dir):
935
- if version in ['ci', 'nightly'] or '/' in str(tag):
944
+ if which_openshift is None:
945
+ download = True
946
+ elif not has_internet:
947
+ pprint("Using existing openshift-install found in your PATH and skipping version check")
948
+ download = False
949
+ else:
950
+ download = not same_release_images(version=version, tag=tag, pull_secret=pull_secret, path=openshift_dir)
951
+ if download:
952
+ pprint("Redownloading openshift-install as found version doesn't match requirements")
953
+ if download:
954
+ if okd:
955
+ run = get_okd_installer(tag, version=version)
956
+ elif version in ['ci', 'nightly'] or '/' in str(tag):
936
957
  nightly = version == 'nightly'
937
958
  run = get_ci_installer(pull_secret, tag=tag, nightly=nightly)
938
959
  elif version in ['candidate', 'stable', 'latest']:
@@ -942,10 +963,6 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
942
963
  if run != 0:
943
964
  return {'result': 'failure', 'reason': "Couldn't download openshift-install"}
944
965
  pprint("Move downloaded openshift-install somewhere in your PATH if you want to reuse it")
945
- elif which_openshift is not None:
946
- pprint("Using existing openshift-install found in your PATH")
947
- else:
948
- pprint("Reusing matching openshift-install")
949
966
  os.environ["PATH"] = f'{os.getcwd()}:{os.environ["PATH"]}'
950
967
  INSTALLER_VERSION = get_installer_version()
951
968
  pprint(f"Using installer version {INSTALLER_VERSION}")
@@ -968,6 +985,10 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
968
985
  cacmd = f"openssl s_client -showcerts -connect {disconnected_url} </dev/null 2>/dev/null|"
969
986
  cacmd += "openssl x509 -outform PEM"
970
987
  data['ca'] = os.popen(cacmd).read()
988
+ kcli_images = ["curl:multi", "origin-coredns:multi", "haproxy:multi", "origin-keepalived-ipfailover:multi",
989
+ "mdns-publisher:multi", "kubectl:multi"]
990
+ kcli_images = '\n'.join([f'quay.io/karmab/{image}' for image in kcli_images])
991
+ warning(f"Make sure to push the following images in your registry: {kcli_images}")
971
992
  if sno:
972
993
  pass
973
994
  elif image is None:
@@ -1008,6 +1029,10 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1008
1029
  if not images:
1009
1030
  msg = f"Missing {image}. Indicate correct image in your parameters file..."
1010
1031
  return {'result': 'failure', 'reason': msg}
1032
+ if provider in virt_providers and platform.machine() != arch:
1033
+ pprint(f"Forcing release image to {arch}")
1034
+ base_url = 'quay.io/okd/scos-release' if okd else 'quay.io/openshift-release-dev'
1035
+ os.environ['OPENSHIFT_INSTALL_RELEASE_IMAGE_OVERRIDE'] = f'{base_url}:{INSTALLER_VERSION}-{arch}'
1011
1036
  overrides['image'] = image
1012
1037
  static_networking_ctlplane, static_networking_worker = False, False
1013
1038
  macentries = []
@@ -1046,7 +1071,7 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1046
1071
  disconnected_overrides['OPENSHIFT_TAG'] = OPENSHIFT_TAG
1047
1072
  disconnected_overrides['kube'] = f"{cluster}-reuse" if disconnected_reuse else cluster
1048
1073
  disconnected_overrides['openshift_version'] = INSTALLER_VERSION
1049
- disconnected_overrides['disconnected_operators_version'] = f"4.{INSTALLER_VERSION.split('.')[1]}"
1074
+ disconnected_overrides['disconnected_operators_version'] = f"v4.{INSTALLER_VERSION.split('.')[1]}"
1050
1075
  x_apps = ['users', 'autolabeller', 'metal3', 'nfs']
1051
1076
  disconnected_operators_2 = [o['name'] for o in disconnected_operators if isinstance(o, dict) and 'name' in o]
1052
1077
  for app in apps:
@@ -1150,21 +1175,31 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1150
1175
  overrides={'role': role, 'node_ip_hint': node_ip_hint})
1151
1176
  with open(f"{clusterdir}/manifests/99-chrony-{role}.yaml", 'w') as f:
1152
1177
  f.write(hint)
1153
- manifestsdir = data.get('manifests')
1154
- manifestsdir = pwd_path(manifestsdir)
1155
- if os.path.exists(manifestsdir) and os.path.isdir(manifestsdir):
1156
- for f in glob(f"{manifestsdir}/*.y*ml"):
1157
- pprint(f"Injecting manifest {f}")
1158
- copy2(f, f"{clusterdir}/openshift")
1159
- elif isinstance(manifestsdir, list):
1178
+ if sno_telco:
1179
+ manifestsdir = safe_load(open(f"{plandir}/telco_manifests.yml"))
1180
+ else:
1181
+ manifestsdir = data.get('manifests')
1182
+ manifestsdir = pwd_path(manifestsdir)
1183
+ if isinstance(manifestsdir, list):
1160
1184
  for manifest in manifestsdir:
1161
1185
  f, content = list(manifest.keys())[0], list(manifest.values())[0]
1162
1186
  if not f.endswith('.yml') and not f.endswith('.yaml'):
1163
1187
  warning(f"Skipping manifest {f}")
1164
1188
  continue
1189
+ if f == '99-openshift-disconnected-catalog.yaml':
1190
+ if disconnected_url is not None:
1191
+ content = content.replace('REGISTRY', disconnected_url).replace('TAG', OPENSHIFT_TAG)
1192
+ else:
1193
+ continue
1194
+ if f == '98-var-lib-containers-partitioned.yaml':
1195
+ content = content.replace('SNO_DISK', sno_disk or '/dev/sda')
1165
1196
  pprint(f"Injecting manifest {f}")
1166
1197
  with open(f'{clusterdir}/openshift/{f}', 'w') as f:
1167
1198
  f.write(content)
1199
+ elif os.path.exists(manifestsdir) and os.path.isdir(manifestsdir):
1200
+ for f in glob(f"{manifestsdir}/*.y*ml"):
1201
+ pprint(f"Injecting manifest {f}")
1202
+ copy2(f, f"{clusterdir}/openshift")
1168
1203
  for manifest in glob(f"{clusterdir}/*.yaml"):
1169
1204
  if os.stat(manifest).st_size == 0:
1170
1205
  warning(f"Skipping empty manifest {manifest}")
@@ -1244,10 +1279,11 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1244
1279
  _f.write(crondata)
1245
1280
  continue
1246
1281
  if '99-monitoring.yaml' in f:
1247
- monitoring_retention = data['monitoring_retention']
1248
- monitoringfile = config.process_inputfile(cluster, f, overrides={'retention': monitoring_retention})
1249
- with open(f"{clusterdir}/openshift/99-monitoring.yaml", 'w') as _f:
1250
- _f.write(monitoringfile)
1282
+ if not sno_telco:
1283
+ monitoring_retention = data['monitoring_retention']
1284
+ monitoringfile = config.process_inputfile(cluster, f, overrides={'retention': monitoring_retention})
1285
+ with open(f"{clusterdir}/openshift/99-monitoring.yaml", 'w') as _f:
1286
+ _f.write(monitoringfile)
1251
1287
  continue
1252
1288
  copy2(f, f"{clusterdir}/openshift")
1253
1289
  if virtualization_nightly:
@@ -1341,12 +1377,14 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1341
1377
  with open(f"{clusterdir}/openshift/99-kubevirt-fix-worker.yaml", 'w') as _f:
1342
1378
  _f.write(kubevirtworker)
1343
1379
  if sno:
1344
- sno_name = f"{cluster}-sno"
1345
1380
  sno_files = []
1346
1381
  sno_disable_nics = data['sno_disable_nics']
1347
1382
  if ipv6 or sno_disable_nics:
1348
1383
  nm_data = config.process_inputfile(cluster, f"{plandir}/kcli-ipv6.conf.j2", overrides=data)
1349
1384
  sno_files.append({'path': "/etc/NetworkManager/conf.d/kcli-ipv6.conf", 'data': nm_data})
1385
+ sno_hostname = data['sno_hostname']
1386
+ if sno_hostname is not None:
1387
+ sno_files.append({'path': "/etc/hostname", 'data': sno_hostname})
1350
1388
  sno_dns = data['sno_dns']
1351
1389
  if sno_dns is None:
1352
1390
  sno_dns = False
@@ -1403,7 +1441,7 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1403
1441
  disable_ipv6 = 'ipv6' in overrides and not overrides['ipv6']
1404
1442
  data['disable_ipv6'] = disable_ipv6
1405
1443
  overrides['disable_ipv6'] = disable_ipv6
1406
- move(f"{clusterdir}/bootstrap-in-place-for-live-iso.ign", f"./{sno_name}.ign")
1444
+ move(f"{clusterdir}/bootstrap-in-place-for-live-iso.ign", f"{cluster}-sno.ign")
1407
1445
  with open("iso.ign", 'w') as f:
1408
1446
  iso_overrides = data.copy()
1409
1447
  iso_overrides['image'] = 'rhcos4000'
@@ -1426,7 +1464,7 @@ def create(config, plandir, cluster, overrides, dnsconfig=None):
1426
1464
  else:
1427
1465
  sno_extra_args = bootstrap_data
1428
1466
  iso_overrides['sno_extra_args'] = sno_extra_args
1429
- result = config.create_vm(sno_name, overrides=iso_overrides, onlyassets=True)
1467
+ result = config.create_vm(f"{cluster}-sno", overrides=iso_overrides, onlyassets=True)
1430
1468
  pprint("Writing iso.ign to current dir")
1431
1469
  f.write(result['userdata'])
1432
1470
  live_url = os.environ.get('LIVEISO_URL') or overrides.get('liveiso_url')
@@ -11,7 +11,7 @@ until oc get crd/clusterimagesets.hive.openshift.io >/dev/null 2>&1 ; do sleep 1
11
11
 
12
12
  if [ "$(which openshift-install)" == "" ] ; then
13
13
  VERSION={{ version|default('stable') }}
14
- TAG={{ tag|default('4.19') }}
14
+ TAG={{ tag|default('4.20') }}
15
15
  kcli download openshift-install -P version=$VERSION -P tag=$TAG
16
16
  export PATH=.:$PATH
17
17
  fi
@@ -1,6 +1,7 @@
1
1
  acm_deploy_baremetal_console: false
2
2
  acm_disable_hub: false
3
3
  pull_secret: openshift_pull.json
4
+ acm_ibi: false
4
5
  acm_hypershift: true
5
6
  acm_mce_catalog:
6
7
  acm_siteconfig: true
@@ -23,3 +23,7 @@ oc -n open-cluster-management patch multiclusterhub multiclusterhub --type=merge
23
23
  {% if acm_siteconfig %}
24
24
  oc -n open-cluster-management patch multiclusterhub multiclusterhub --type=merge -p '{"spec":{"overrides":{"components":[{"name":"siteconfig","enabled": true}]}}}'
25
25
  {% endif %}
26
+
27
+ {% if acm_ibi %}
28
+ oc patch mce multiclusterengine --type=merge -p '{"spec":{"overrides":{"components":[{"name":"image-based-install-operator","enabled": true}]}}}'
29
+ {% endif %}
@@ -11,7 +11,7 @@ until oc get crd/clusterimagesets.hive.openshift.io >/dev/null 2>&1 ; do sleep 1
11
11
 
12
12
  if [ "$(which openshift-install)" == "" ] ; then
13
13
  VERSION={{ version|default('stable') }}
14
- TAG={{ tag|default('4.19') }}
14
+ TAG={{ tag|default('4.20') }}
15
15
  kcli download openshift-install -P version=$VERSION -P tag=$TAG
16
16
  export PATH=.:$PATH
17
17
  fi
@@ -4,6 +4,11 @@ metadata:
4
4
  name: odf-storagecluster
5
5
  namespace: {{ namespace }}
6
6
  spec:
7
+ {% if odf_encryption %}
8
+ encryption:
9
+ clusterWide: true
10
+ enable: true
11
+ {% endif %}
7
12
  {% if odf_public_network != None %}
8
13
  network:
9
14
  ipFamily: IPv4
@@ -1,6 +1,7 @@
1
1
  odf_disksize: 60
2
2
  odf_nodes: []
3
3
  odf_devicesets: 1
4
+ odf_encryption: false
4
5
  odf_storageclass: localstorage-sc
5
6
  odf_replicas: 3
6
7
  odf_accessmode: ReadWriteOnce
@@ -1,3 +1,4 @@
1
+ {{ "storagecluster" | wait_crd }}
1
2
  {% if odf_nodes %}
2
3
  {% set nodes = odf_nodes %}
3
4
  {% elif localstorage_nodes is defined %}
@@ -0,0 +1,16 @@
1
+ #!/bin/bash
2
+
3
+ VIP="{{ api_ip }}/32"
4
+
5
+ if [ "$(curl -sLk https://127.0.0.1:6443/readyz)" == "ok" ] ; then
6
+ if ! ip addr show dev lo | grep -q "$VIP"; then
7
+ ip addr add $VIP dev lo
8
+ echo "$(date): VIP added" >> /var/log/vip-monitor.log
9
+ fi
10
+ else
11
+ [ "$(hostname -s)" == "{{ cluster }}-bootstrap" ] && sleep 120
12
+ if ip addr show dev lo | grep -q "$VIP"; then
13
+ ip addr del $VIP dev lo
14
+ echo "$(date): VIP removed" >> /var/log/vip-monitor.log
15
+ fi
16
+ fi
@@ -20,9 +20,39 @@
20
20
  {% endif %}
21
21
  disks:
22
22
  - size: {{ disk_size }}
23
- {% if coredns or mdns or keepalived or ipv6 %}
23
+ {% if coredns or mdns or keepalived or ipv6 or bgp %}
24
24
  files:
25
25
  {% endif %}
26
+ {% if bgp %}
27
+ - path: /etc/kubernetes/manifests/bgp.yml
28
+ origin: staticpods/bgp.yml
29
+ - path: /etc/kubernetes/daemons
30
+ origin: frr_daemons
31
+ - path: /etc/kubernetes/frr.conf
32
+ origin: frr.conf
33
+ peers: {{ bgp_peers|filter_bgp_peers(0) }}
34
+ - path: /usr/local/bin/bgp-vip.sh
35
+ origin: bgp-vip.sh
36
+ mode: 700
37
+ - path: /etc/systemd/system/bgp-vip.service
38
+ content: |
39
+ [Unit]
40
+ Description=Manage BGP VIP
41
+ [Service]
42
+ Type=oneshot
43
+ ExecStart=/usr/local/bin/bgp-vip.sh
44
+ - path: /etc/systemd/system/bgp-vip.timer
45
+ content: |
46
+ [Unit]
47
+ Description=Run BGP VIP periodically
48
+ [Timer]
49
+ OnBootSec=5
50
+ OnUnitActiveSec=5
51
+ [Install]
52
+ WantedBy=timers.target
53
+ - path: /etc/systemd/system/timers.target.wants/bgp-vip.timer
54
+ target: /etc/systemd/system/bgp-vip.timer
55
+ {% endif %}
26
56
  {% if coredns %}
27
57
  - path: /etc/NetworkManager/dispatcher.d/99-kcli-forcedns
28
58
  origin: 99-kcli-forcedns
@@ -28,9 +28,39 @@
28
28
  {% endif %}
29
29
  nets: {{ [network] + extra_networks }}
30
30
  disks: {{ [disk_size] + extra_disks }}
31
- {% if coredns or mdns or keepalived %}
31
+ {% if coredns or mdns or keepalived or bgp %}
32
32
  files:
33
33
  {% endif %}
34
+ {% if bgp %}
35
+ - path: /etc/kubernetes/manifests/bgp.yml
36
+ origin: staticpods/bgp.yml
37
+ - path: /etc/kubernetes/daemons
38
+ origin: frr_daemons
39
+ - path: /etc/kubernetes/frr.conf
40
+ origin: frr.conf
41
+ peers: {{ bgp_peers|filter_bgp_peers(loop.index0) }}
42
+ - path: /usr/local/bin/bgp-vip.sh
43
+ origin: bgp-vip.sh
44
+ mode: 700
45
+ - path: /etc/systemd/system/bgp-vip.service
46
+ content: |
47
+ [Unit]
48
+ Description=manage VIP
49
+ [Service]
50
+ Type=oneshot
51
+ ExecStart=/usr/local/bin/bgp-vip.sh
52
+ - path: /etc/systemd/system/bgp-vip.timer
53
+ content: |
54
+ [Unit]
55
+ Description=Run BGP VIP periodically
56
+ [Timer]
57
+ OnBootSec=5
58
+ OnUnitActiveSec=5
59
+ [Install]
60
+ WantedBy=timers.target
61
+ - path: /etc/systemd/system/timers.target.wants/bgp-vip.timer
62
+ target: /etc/systemd/system/bgp-vip.timer
63
+ {% endif %}
34
64
  {% if coredns %}
35
65
  - path: /etc/NetworkManager/dispatcher.d/99-kcli-forcedns
36
66
  origin: 99-kcli-forcedns