Skip to content

Commit f3f5e4d

Browse files
authored
Download oc from the cluster and use the same (#349)
1 parent de51dea commit f3f5e4d

3 files changed

Lines changed: 133 additions & 15 deletions

File tree

Dockerfile

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,6 @@ RUN apt-get update \
1717
&& apt-get autoremove --yes \
1818
&& rm -rf /var/lib/{apt,dpkg,cache,log}/
1919

20-
# Install the Rosa CLI
21-
RUN curl -L https://mirror.openshift.com/pub/openshift-v4/clients/rosa/latest/rosa-linux.tar.gz --output /tmp/rosa-linux.tar.gz \
22-
&& tar xvf /tmp/rosa-linux.tar.gz --no-same-owner \
23-
&& mv rosa /usr/bin/rosa \
24-
&& chmod +x /usr/bin/rosa \
25-
&& rosa version
26-
27-
# Install the OpenShift CLI (OC)
28-
RUN curl -L https://mirror.openshift.com/pub/openshift-v4/x86_64/clients/ocp/stable/openshift-client-linux.tar.gz --output /tmp/openshift-client-linux.tar.gz \
29-
&& tar xvf /tmp/openshift-client-linux.tar.gz --no-same-owner \
30-
&& mv oc /usr/bin/oc \
31-
&& chmod +x /usr/bin/oc
32-
3320
# Install grpcurl
3421
RUN curl -sSL "https://github.com/fullstorydev/grpcurl/releases/download/v1.9.2/grpcurl_1.9.2_linux_x86_64.tar.gz" --output /tmp/grpcurl_1.2.tar.gz \
3522
&& tar xvf /tmp/grpcurl_1.2.tar.gz --no-same-owner \

tests/conftest.py

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
import pytest
88
import shortuuid
99
import yaml
10+
from _pytest._py.path import LocalPath
11+
from _pytest.legacypath import TempdirFactory
1012
from _pytest.tmpdir import TempPathFactory
1113
from ocp_resources.config_map import ConfigMap
1214
from ocp_resources.dsc_initialization import DSCInitialization
@@ -32,6 +34,7 @@
3234
create_ns,
3335
login_with_user_password,
3436
get_openshift_token,
37+
download_oc_console_cli,
3538
)
3639
from utilities.constants import (
3740
AcceleratorType,
@@ -490,8 +493,7 @@ def junitxml_plugin(
490493
return record_testsuite_property if request.config.pluginmanager.has_plugin("junitxml") else None
491494

492495

493-
@pytest.fixture(scope="session", autouse=True)
494-
@pytest.mark.early(order=0)
496+
@pytest.fixture(scope="session")
495497
def cluster_sanity_scope_session(
496498
request: FixtureRequest,
497499
nodes: list[Node],
@@ -525,3 +527,40 @@ def related_images_refs(admin_client: DynamicClient) -> set[str]:
525527
related_images = get_csv_related_images(admin_client=admin_client)
526528
related_images_refs = {img["image"] for img in related_images}
527529
return related_images_refs
530+
531+
532+
@pytest.fixture(scope="session")
533+
def os_path_environment() -> str:
534+
return os.environ["PATH"]
535+
536+
537+
@pytest.fixture(scope="session")
538+
def bin_directory(tmpdir_factory: TempdirFactory) -> LocalPath:
539+
return tmpdir_factory.mktemp(basename="bin")
540+
541+
542+
@pytest.fixture(scope="session")
543+
def bin_directory_to_os_path(os_path_environment: str, bin_directory: LocalPath, oc_binary_path: str) -> None:
544+
LOGGER.info(f"OC binary path: {oc_binary_path}")
545+
LOGGER.info(f"Adding {bin_directory} to $PATH")
546+
os.environ["PATH"] = f"{bin_directory}:{os_path_environment}"
547+
548+
549+
@pytest.fixture(scope="session")
550+
def oc_binary_path(bin_directory: LocalPath) -> str:
551+
installed_oc_binary_path = os.getenv("OC_BINARY_PATH")
552+
if installed_oc_binary_path:
553+
LOGGER.warning(f"Using previously installed: {installed_oc_binary_path}")
554+
return installed_oc_binary_path
555+
556+
return download_oc_console_cli(tmpdir=bin_directory)
557+
558+
559+
@pytest.fixture(scope="session", autouse=True)
560+
@pytest.mark.early(order=0)
561+
def autouse_fixtures(
562+
bin_directory_to_os_path: None,
563+
cluster_sanity_scope_session: None,
564+
) -> None:
565+
"""Fixture to control the order of execution of some of the fixtures"""
566+
return

utilities/infra.py

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@
33
import os
44
import re
55
import shlex
6+
import stat
7+
import tarfile
68
import tempfile
9+
import zipfile
710
from contextlib import contextmanager
811
from functools import cache
912
from typing import Any, Generator, Optional, Set, Callable
1013
from json import JSONDecodeError
1114

1215
import kubernetes
16+
import platform
1317
import pytest
18+
import requests
19+
from _pytest._py.path import LocalPath
1420
from _pytest.fixtures import FixtureRequest
1521
from kubernetes.dynamic import DynamicClient
1622
from kubernetes.dynamic.exceptions import (
@@ -20,6 +26,7 @@
2026
from ocp_resources.catalog_source import CatalogSource
2127
from ocp_resources.cluster_service_version import ClusterServiceVersion
2228
from ocp_resources.config_map import ConfigMap
29+
from ocp_resources.console_cli_download import ConsoleCLIDownload
2330
from ocp_resources.data_science_cluster import DataScienceCluster
2431
from ocp_resources.deployment import Deployment
2532
from ocp_resources.dsc_initialization import DSCInitialization
@@ -1140,3 +1147,88 @@ def switch_user_context(context_name: str) -> Generator[None, None, None]:
11401147
# Restore original context
11411148
run_command(command=["oc", "config", "use-context", current_context], check=True)
11421149
LOGGER.info(f"Restored context: {current_context}")
1150+
1151+
1152+
def get_machine_platform() -> str:
1153+
os_machine_type = platform.machine()
1154+
return "amd64" if os_machine_type == "x86_64" else os_machine_type
1155+
1156+
1157+
def get_os_system() -> str:
1158+
os_system = platform.system().lower()
1159+
if os_system == "darwin" and platform.mac_ver()[0]:
1160+
os_system = "mac"
1161+
return os_system
1162+
1163+
1164+
def get_oc_console_cli_download_link() -> str:
1165+
oc_console_cli_download = ConsoleCLIDownload(name="oc-cli-downloads", ensure_exists=True)
1166+
os_system = get_os_system()
1167+
machine_platform = get_machine_platform()
1168+
oc_links = oc_console_cli_download.instance.spec.links
1169+
all_links = [
1170+
link_ref.href
1171+
for link_ref in oc_links
1172+
if link_ref.href.endswith(("oc.tar", "oc.zip"))
1173+
and os_system in link_ref.href
1174+
and machine_platform in link_ref.href
1175+
]
1176+
LOGGER.info(f"All oc console cli download links: {all_links}")
1177+
if not all_links:
1178+
raise ValueError(f"No oc console cli download link found for {os_system} {machine_platform} in {oc_links}")
1179+
1180+
return all_links[0]
1181+
1182+
1183+
def get_server_cert(tmpdir: LocalPath) -> str:
1184+
data = ConfigMap(name="kube-root-ca.crt", namespace="openshift-apiserver", ensure_exists=True).instance.data[
1185+
"ca.crt"
1186+
]
1187+
file_path = os.path.join(tmpdir, "cluster-ca.cert")
1188+
with open(file_path, "w") as fd:
1189+
fd.write(data)
1190+
return file_path
1191+
1192+
1193+
def download_oc_console_cli(tmpdir: LocalPath) -> str:
1194+
"""
1195+
Download and extract the OpenShift CLI binary.
1196+
1197+
Args:
1198+
tmpdir (str): Directory to download and extract the binary to
1199+
1200+
Returns:
1201+
str: Path to the extracted binary
1202+
1203+
Raises:
1204+
ValueError: If multiple files are found in the archive or if no download link is found
1205+
"""
1206+
oc_console_cli_download_link = get_oc_console_cli_download_link()
1207+
LOGGER.info(f"Downloading archive using: url={oc_console_cli_download_link}")
1208+
cert_file = get_server_cert(tmpdir=tmpdir)
1209+
local_file_name = os.path.join(tmpdir, oc_console_cli_download_link.split("/")[-1])
1210+
with requests.get(oc_console_cli_download_link, verify=cert_file, stream=True) as created_request:
1211+
created_request.raise_for_status()
1212+
with open(local_file_name, "wb") as file_downloaded:
1213+
for chunk in created_request.iter_content(chunk_size=8192):
1214+
file_downloaded.write(chunk)
1215+
LOGGER.info("Extract the downloaded archive.")
1216+
extracted_filenames = []
1217+
if oc_console_cli_download_link.endswith(".zip"):
1218+
zip_file = zipfile.ZipFile(file=local_file_name)
1219+
zip_file.extractall(path=tmpdir)
1220+
extracted_filenames = zip_file.namelist()
1221+
else:
1222+
with tarfile.open(name=local_file_name, mode="r") as tar_file:
1223+
tar_file.extractall(path=tmpdir)
1224+
extracted_filenames = tar_file.getnames()
1225+
LOGGER.info(f"Downloaded file: {extracted_filenames}")
1226+
1227+
if len(extracted_filenames) > 1:
1228+
raise ValueError(f"Multiple files found in {extracted_filenames}")
1229+
# Remove the downloaded file
1230+
if os.path.isfile(local_file_name):
1231+
os.remove(local_file_name)
1232+
binary_path = os.path.join(tmpdir, extracted_filenames[0])
1233+
os.chmod(binary_path, stat.S_IRUSR | stat.S_IXUSR)
1234+
return binary_path

0 commit comments

Comments
 (0)