diff --git a/pipelines/fast-test.yml b/pipelines/fast-test.yml index 79a383c75..2dcd32962 100644 --- a/pipelines/fast-test.yml +++ b/pipelines/fast-test.yml @@ -174,7 +174,7 @@ stages: - job: ubuntu_legacy pool: - vmImage: ubuntu-20.04 + vmImage: ubuntu-18.04 steps: - template: templates/install-dependencies.yml @@ -196,6 +196,7 @@ stages: displayName: Python unit test - script: | + export PATH=${PWD}/toolchain/node/bin:$PATH npm --prefix ts/nni_manager run test displayName: TypeScript unit test diff --git a/setup_ts.py b/setup_ts.py index 6431dd66f..ece43516a 100644 --- a/setup_ts.py +++ b/setup_ts.py @@ -27,6 +27,13 @@ from zipfile import ZipFile node_version = 'v18.12.1' yarn_version = 'v1.22.19' +def _print(*args, color='cyan'): + color_code = {'yellow': 33, 'cyan': 36}[color] + if sys.platform == 'win32': + print(*args, flush=True) + else: + print(f'\033[1;{color_code}m#', *args, '\033[0m', flush=True) + def _get_jupyter_lab_version(): try: import jupyterlab @@ -34,6 +41,51 @@ def _get_jupyter_lab_version(): except ImportError: return '3.x' +def _get_glibc_minor_version(): # type: () -> int | None + try: + from pip._internal.utils.glibc import glibc_version_string + glibc_version = glibc_version_string() + if glibc_version is None: + return None + glibc_major, glibc_minor = map(int, glibc_version.split('.')) + if glibc_major < 2: + raise RuntimeError('Unsupported glibc version: ' + glibc_version) + elif glibc_major == 2: + _print(f'Detected glibc version: {glibc_version}') + return glibc_minor + return None + except ImportError: + _print('Unsupported pip version. Assuming glibc not found.', color='yellow') + return None + +def _get_node_downloader(): + if platform.machine() == 'x86_64': + glibc_minor = _get_glibc_minor_version() + if glibc_minor is None or glibc_minor >= 28: + _arch = 'x64' + elif glibc_minor >= 27: + _print('Detected deprecated glibc version < 2.28. Please upgrade as soon as possible.', color='yellow') + _arch = 'glibc-2.27' + else: + _print('glibc version is too low. We will try to use the node version compiled with glibc 2.23, ' + 'but it might not work.', color='yellow') + _print('Please check your glibc version by running `ldd --version`, and upgrade it if necessary.', + color='yellow') + _arch = 'glibc-2.23' + else: + _arch = platform.machine() + + if _arch.startswith('glibc'): + node_legacy_version = 'v18.12.1' # We might not upgrade node version for legacy builds every time. + node_spec = f'node-{node_legacy_version}-{sys.platform}-x64' + node_download_url = f'https://nni.blob.core.windows.net/cache/toolchain/node-{node_legacy_version}-{sys.platform}-{_arch}.tar.gz' + node_extractor = lambda data: tarfile.open(fileobj=BytesIO(data), mode='r:gz') + else: + node_spec = f'node-{node_version}-{sys.platform}-' + _arch + node_download_url = f'https://nodejs.org/dist/{node_version}/{node_spec}.tar.xz' + node_extractor = lambda data: tarfile.open(fileobj=BytesIO(data), mode='r:xz') + return node_download_url, node_spec, node_extractor + jupyter_lab_major_version = _get_jupyter_lab_version().split('.')[0] def build(release): @@ -75,10 +127,7 @@ def clean(): if sys.platform == 'linux' or sys.platform == 'darwin': node_executable = 'node' - _arch = 'x64' if platform.machine() == 'x86_64' else platform.machine() - node_spec = f'node-{node_version}-{sys.platform}-' + _arch - node_download_url = f'https://nodejs.org/dist/{node_version}/{node_spec}.tar.xz' - node_extractor = lambda data: tarfile.open(fileobj=BytesIO(data), mode='r:xz') + node_download_url, node_spec, node_extractor = _get_node_downloader() node_executable_in_tarball = 'bin/node' npm_executable = 'bin/npm' @@ -86,7 +135,7 @@ if sys.platform == 'linux' or sys.platform == 'darwin': yarn_executable = 'yarn' yarn_download_url = f'https://github.com/yarnpkg/yarn/releases/download/{yarn_version}/yarn-{yarn_version}.tar.gz' - path_env_seperator = ':' + path_env_separator = ':' elif sys.platform == 'win32': node_executable = 'node.exe' @@ -100,7 +149,7 @@ elif sys.platform == 'win32': yarn_executable = 'yarn.cmd' yarn_download_url = f'https://github.com/yarnpkg/yarn/releases/download/{yarn_version}/yarn-{yarn_version}.tar.gz' - path_env_seperator = ';' + path_env_separator = ';' else: raise RuntimeError('Unsupported system') @@ -266,7 +315,7 @@ def copy_nni_node(version): _yarn_env = dict(os.environ) # `Path('nni_node').resolve()` does not work on Windows if the directory not exists -_yarn_env['PATH'] = str(Path().resolve() / 'nni_node') + path_env_seperator + os.environ['PATH'] +_yarn_env['PATH'] = str(Path().resolve() / 'nni_node') + path_env_separator + os.environ['PATH'] _yarn_path = Path().resolve() / 'toolchain/yarn/bin' / yarn_executable _npm_path = Path().resolve() / 'toolchain/node' / npm_executable @@ -292,14 +341,6 @@ def _symlink(target_file, link_location): link.symlink_to(relative, target.is_dir()) -def _print(*args, color='cyan'): - color_code = {'yellow': 33, 'cyan': 36}[color] - if sys.platform == 'win32': - print(*args, flush=True) - else: - print(f'\033[1;{color_code}m#', *args, '\033[0m', flush=True) - - generated_files = [ 'ts/nni_manager/dist', 'ts/nni_manager/node_modules',