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.
- {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/METADATA +1 -1
- {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/RECORD +68 -64
- {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/entry_points.txt +2 -1
- kvirt/baseconfig.py +4 -9
- kvirt/cli.py +65 -19
- kvirt/cluster/hypershift/__init__.py +15 -23
- kvirt/cluster/kubeadm/__init__.py +1 -1
- kvirt/cluster/kubeadm/crio-d.sh +4 -4
- kvirt/cluster/kubeadm/keepalived.sh +1 -1
- kvirt/cluster/microshift/kcli_default.yml +1 -1
- kvirt/cluster/microshift/scripts/01_clients.sh +1 -1
- kvirt/cluster/openshift/99-kcli-forcedns +8 -11
- kvirt/cluster/openshift/__init__.py +80 -42
- kvirt/cluster/openshift/apps/advanced-cluster-management/assisted-service.sh +1 -1
- kvirt/cluster/openshift/apps/advanced-cluster-management/kcli_default.yml +1 -0
- kvirt/cluster/openshift/apps/advanced-cluster-management/post.sh +4 -0
- kvirt/cluster/openshift/apps/multicluster-engine/assisted-service.sh +1 -1
- kvirt/cluster/openshift/apps/odf-operator/cr.yml +5 -0
- kvirt/cluster/openshift/apps/odf-operator/kcli_default.yml +1 -0
- kvirt/cluster/openshift/apps/odf-operator/pre.sh +1 -0
- kvirt/cluster/openshift/bgp-vip.sh +16 -0
- kvirt/cluster/openshift/bootstrap.yml +31 -1
- kvirt/cluster/openshift/ctlplanes.yml +31 -1
- kvirt/cluster/openshift/disconnected/mirror-config.yaml +6 -6
- kvirt/cluster/openshift/disconnected/scripts/01_packages.sh +2 -2
- kvirt/cluster/openshift/disconnected/scripts/02_registry.sh +5 -1
- kvirt/cluster/openshift/disconnected/scripts/03_mirror.sh +5 -1
- kvirt/cluster/openshift/frr.conf +29 -0
- kvirt/cluster/openshift/frr_daemons +38 -0
- kvirt/cluster/openshift/install-config.yaml +1 -1
- kvirt/cluster/openshift/kcli_default.yml +15 -10
- kvirt/cluster/openshift/sno_default.yml +1 -0
- kvirt/cluster/openshift/staticpods/bgp.yml +34 -0
- kvirt/cluster/openshift/telco_manifests.yml +790 -0
- kvirt/cluster/openshift/workers.yml +9 -0
- kvirt/common/__init__.py +63 -14
- kvirt/config.py +15 -9
- kvirt/containerconfig.py +2 -2
- kvirt/defaults.py +13 -7
- kvirt/examples.py +28 -15
- kvirt/expose/__init__.py +1 -1
- kvirt/extra_keywords/kvm.yaml +1 -0
- kvirt/internalplans/__init__.py +3 -10
- kvirt/jinjafilters/jinjafilters.py +9 -4
- kvirt/keywords.yaml +3 -0
- kvirt/kfish/__init__.py +1 -1
- kvirt/kmcp.py +55 -11
- kvirt/ksushy/__init__.py +19 -21
- kvirt/kubecommon/__init__.py +8 -6
- kvirt/providers/aws/__init__.py +2 -2
- kvirt/providers/azure/__init__.py +2 -2
- kvirt/providers/fake/__init__.py +1 -1
- kvirt/providers/gcp/__init__.py +2 -2
- kvirt/providers/hcloud/__init__.py +64 -50
- kvirt/providers/ibm/__init__.py +2 -2
- kvirt/providers/kubevirt/__init__.py +110 -43
- kvirt/providers/kvm/__init__.py +56 -38
- kvirt/providers/openstack/__init__.py +19 -5
- kvirt/providers/ovirt/__init__.py +1 -1
- kvirt/providers/proxmox/__init__.py +1 -1
- kvirt/providers/sampleprovider.py +1 -1
- kvirt/providers/vsphere/__init__.py +1 -1
- kvirt/providers/web/__init__.py +1 -1
- kvirt/version/git +1 -1
- kvirt/web/__init__.py +1 -3
- kvirt/cluster/hypershift/ignition.sh +0 -12
- {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/WHEEL +0 -0
- {kcli-99.0.202507120954.dist-info → kcli-99.0.202601080644.dist-info}/licenses/LICENSE +0 -0
- {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('
|
|
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
|
-
|
|
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
|
-
|
|
198
|
-
|
|
199
|
-
with open(f"{clusterdir}/
|
|
200
|
-
f.write(
|
|
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'
|
|
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) == '
|
|
392
|
-
tag = '
|
|
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'
|
|
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://
|
|
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:
|
kvirt/cluster/kubeadm/crio-d.sh
CHANGED
|
@@ -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://
|
|
8
|
-
echo "deb [signed-by=/etc/apt/keyrings/cri-o-apt-keyring.gpg] https://
|
|
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://
|
|
15
|
+
baseurl=https://download.opensuse.org/repositories/isv:/cri-o:/$PROJECT_PATH/rpm
|
|
16
16
|
enabled=1
|
|
17
17
|
gpgcheck=1
|
|
18
|
-
gpgkey=https://
|
|
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=$(
|
|
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
|
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
#!/bin/bash
|
|
2
2
|
|
|
3
|
-
|
|
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 [ "$
|
|
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
|
-
|
|
13
|
-
|
|
14
|
-
|
|
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 == '
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
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'
|
|
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'
|
|
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'
|
|
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
|
-
|
|
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
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
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"
|
|
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
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
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
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
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"
|
|
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(
|
|
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.
|
|
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
|
|
@@ -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.
|
|
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
|
|
@@ -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
|