28
28
import requests
29
29
30
30
from bs4 import BeautifulSoup
31
+ from semantic_version import Version , SimpleSpec
31
32
from .utils import get_data
32
33
33
34
34
35
PROD_ROOT = "http://mirror.openshift.com/pub/openshift-v4/{}/clients/ocp/"
35
36
BUILD_ROOT = "https://openshift-release-artifacts.svc.ci.openshift.org/"
36
37
PREVIEW_ROOT = "http://mirror.openshift.com/pub/openshift-v4/{}/clients/ocp-dev-preview/"
37
38
38
- VERSION_RE = re .compile (r"^openshift-install- (?P<platform>\w+) "
39
- r"(-(?P<architecture>\w+))?-(?P<version>\d+.*)\.tar\.gz" )
39
+ VERSION_RE = re .compile (r"^openshift-install(-rhel (?P<rhel>\d+))?(-(?P<platform>(linux|mac)))? "
40
+ r"(-(?P<architecture>\w+))?( -(?P<version>\d+.*))? \.tar\.gz" )
40
41
EXTRACTION_RE = re .compile (r'.*Extracting tools for .*, may take up to a minute.*' )
41
42
42
43
43
- def _current_platform ():
44
+ def _current_platform () -> Tuple [ str , str ] :
44
45
if platform .system () == "Linux" and platform .machine () == "x86_64" :
45
46
return "linux" , "amd64"
46
47
if platform .system () == "Linux" and platform .machine () == "arm64" :
@@ -53,10 +54,14 @@ def _current_platform():
53
54
raise Exception (f"Unrecognized platform { platform .system ()} { platform .machine ()} " )
54
55
55
56
56
- def get_url (directory : str , arch : str ) -> Tuple [Optional [str ], Optional [str ]]:
57
+ def get_url (directory : str , arch : str , fips : bool = False ,
58
+ rhel_version : str = None ) -> Tuple [Optional [str ], Optional [str ]]:
57
59
"""Searches the http directory and returns both url to installer
58
60
and version.
59
61
"""
62
+ if fips and not rhel_version :
63
+ raise Exception ("Rhel version was not detected. Please download installer separatly." )
64
+
60
65
logging .debug ('Url for installers look-up %s' , directory )
61
66
lst = requests .get (directory , allow_redirects = True )
62
67
tree = BeautifulSoup (lst .content , 'html.parser' )
@@ -66,16 +71,26 @@ def get_url(directory: str, arch: str) -> Tuple[Optional[str], Optional[str]]:
66
71
for k in links :
67
72
logging .debug ('Parsing link: %s' , k .get ('href' ))
68
73
match = VERSION_RE .match (k .get ('href' ))
69
- if match and match .group ('platform' ) == os_name :
70
- if (local_arch == match .group ('architecture' )) \
71
- or (local_arch == arch and not match .group ('architecture' )):
72
- installer = lst .url + k .get ('href' )
74
+
75
+ if match :
76
+ if match .group ("version" ):
73
77
version = match .group ('version' )
78
+
79
+ if fips and match .group ("rhel" ) == rhel_version :
80
+ installer = lst .url + k .get ('href' )
74
81
break
82
+
83
+ if not fips and match .group ('platform' ) == os_name :
84
+ if (local_arch == match .group ('architecture' )) \
85
+ or (local_arch == arch and not match .group ('architecture' )):
86
+ installer = lst .url + k .get ('href' )
87
+ version = match .group ('version' )
88
+ break
75
89
return installer , version
76
90
77
91
78
- def get_devel_url (version : str , arch : str ) -> Tuple [Optional [str ], Optional [str ]]:
92
+ def get_devel_url (version : str , arch : str , fips : bool = False ,
93
+ rhel_version : str = None ) -> Tuple [Optional [str ], Optional [str ]]:
79
94
"""
80
95
Searches developement sources and returns url to installer
81
96
"""
@@ -88,17 +103,19 @@ def get_devel_url(version: str, arch: str) -> Tuple[Optional[str], Optional[str]
88
103
req = requests .get (BUILD_ROOT + version , allow_redirects = True )
89
104
ast = BeautifulSoup (req .content , 'html.parser' )
90
105
logging .debug ('Installer found on page, continuing' )
91
- return get_url (req .url , arch )
106
+ return get_url (req .url , arch , fips , rhel_version )
92
107
93
108
94
- def get_prev_url (version : str , arch : str ) -> Tuple [Optional [str ], Optional [str ]]:
109
+ def get_prev_url (version : str , arch : str , fips : bool = False ,
110
+ rhel_version : str = None ) -> Tuple [Optional [str ], Optional [str ]]:
95
111
"""Returns installer url from dev-preview sources"""
96
- return get_url (PREVIEW_ROOT .format (arch ) + version + "/" , arch )
112
+ return get_url (PREVIEW_ROOT .format (arch ) + version + "/" , arch , fips , rhel_version )
97
113
98
114
99
- def get_prod_url (version : str , arch : str ) -> Tuple [Optional [str ], Optional [str ]]:
115
+ def get_prod_url (version : str , arch : str , fips : bool = False ,
116
+ rhel_version : str = None ) -> Tuple [Optional [str ], Optional [str ]]:
100
117
"""Returns installer url from production sources"""
101
- return get_url (PROD_ROOT .format (arch ) + version + "/" , arch )
118
+ return get_url (PROD_ROOT .format (arch ) + version + "/" , arch , fips , rhel_version )
102
119
103
120
104
121
def _get_storage_path (version : str , install_base : str ) -> str :
@@ -114,12 +131,12 @@ def _extract_tar(buffer: NamedTemporaryFile, target: str) -> Path:
114
131
with tarfile .open (buffer .name ) as tar :
115
132
inst_info = None
116
133
for i in tar .getmembers ():
117
- if i .name == 'openshift-install' :
134
+ if i .name in [ 'openshift-install' , 'openshift-install-fips' ] :
118
135
inst_info = i
119
136
if inst_info is None :
120
137
raise Exception ("error" )
121
138
stream = tar .extractfile (inst_info )
122
- result = Path (target ).joinpath ('openshift-install' )
139
+ result = Path (target ).joinpath (inst_info . name )
123
140
with result .open ('wb' ) as output :
124
141
copyfileobj (stream , output )
125
142
result .chmod (result .stat ().st_mode | stat .S_IXUSR )
@@ -131,10 +148,13 @@ def get_installer(tar_url: str, target: str):
131
148
return get_data (tar_url , target , _extract_tar )
132
149
133
150
151
+ # pylint: disable=too-many-arguments
134
152
def download_installer (installer_version : str ,
135
153
installer_arch : str ,
136
154
dest_directory : str ,
137
- source : str ) -> str :
155
+ source : str ,
156
+ fips : bool = False ,
157
+ rhel_version : str = None ) -> str :
138
158
"""Starts search and extraction of installer"""
139
159
logging .debug ("Getting version %s of %s, storing to directory %s and devel is %r" ,
140
160
installer_version , installer_arch , dest_directory , source )
@@ -149,12 +169,21 @@ def download_installer(installer_version: str,
149
169
else :
150
170
raise Exception ("Error for source profile " + source )
151
171
152
- url , version = downloader (installer_version , installer_arch )
172
+ if fips and Version (installer_version .split ("-" )[- 1 ]+ ".0" ) in SimpleSpec ("<4.16" ):
173
+ # ocp <4.16 does not have dedicated openshift-install-fips,
174
+ # it just need to be run on fips enabled RHEL
175
+ fips = False
176
+ rhel_version = None
177
+
178
+ url , version = downloader (installer_version , installer_arch , fips , rhel_version )
153
179
logging .debug ('Installer\' s URL is %s and full version is %s' , url , version )
154
180
root = Path (dest_directory ).joinpath (version )
155
181
156
- if root .exists () and root .joinpath ('openshift-install' ).exists ():
182
+ installer_exe_name = 'openshift-install'
183
+ if fips :
184
+ installer_exe_name += '-fips'
185
+ if root .exists () and root .joinpath (installer_exe_name ).exists ():
157
186
logging .info ('Found installer at %s' , root .as_posix ())
158
- return root .joinpath ('openshift-install' ).as_posix ()
159
- root .mkdir (parents = True )
187
+ return root .joinpath (installer_exe_name ).as_posix ()
188
+ root .mkdir (parents = True , exist_ok = True )
160
189
return get_installer (url , root .as_posix ())
0 commit comments