Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 35 additions & 20 deletions cli/src/pcluster/api/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,9 @@ def _assert_node_executable():


def _assert_node_version():
node_version_string = None

# Try to get version from node executable
try:
# A nosec comment is appended to the following line in order to disable the B607 and B603 checks.
# It is a false positive since the PATH search is wanted and the input of the check_output is static.
Expand All @@ -187,10 +190,17 @@ def _assert_node_version():
# untrusted source
node_version_string = subprocess.check_output( # nosec B607 B603
["node", "--version"], stderr=subprocess.STDOUT, shell=False, encoding="utf-8"
)
).strip()
LOGGER.debug("Found Node.js version (%s)", node_version_string)
except Exception:
LOGGER.debug("Unable to determine current Node.js version from node")
except subprocess.CalledProcessError as e:
LOGGER.debug("Node executable failed with exit code %s: %s", e.returncode, e.output)
except FileNotFoundError:
LOGGER.debug("Node executable not found")
except Exception as e:
LOGGER.debug("Unable to determine current Node.js version from node: %s", e)

# If node command failed, try nvm
if not node_version_string:
try:
# A nosec comment is appended to the following line in order to disable the B607 and B603 checks.
# It is a false positive since the PATH search is wanted and the input of the check_output is static.
Expand All @@ -200,24 +210,29 @@ def _assert_node_version():
# untrusted source
node_version_string = subprocess.check_output( # nosec B607 B603
["nvm", "current"], stderr=subprocess.STDOUT, shell=False, encoding="utf-8"
)
).strip()
LOGGER.debug("Found Node.js version '%s' in use", node_version_string)
except Exception:
message = "Unable to check Node.js version"
LOGGER.critical(message)
raise Exception(message)
# `nvm current` will return `none` if no versions of Node.js are currently installed.
if node_version_string == "none":
message = (
"Node.js does not appear to be installed. Please use the Node Version Manager (nvm) to install a"
" version of Node.js compatible with this platform."
)
else:
message = (
f"Unable to invoke Node.js for the installed version {node_version_string}. This version may not be"
" compatible with this platform. Please use the Node Version Manager (nvm) to install and use a"
" compatible version of Node.js compatible with this platform."
)
except FileNotFoundError:
LOGGER.debug("NVM not found")
except Exception as e:
LOGGER.debug("Unable to determine Node.js version from nvm: %s", e)

# Handle case where we couldn't get version info
if not node_version_string:
message = (
"Unable to check Node.js version. Node.js is required by the AWS CDK library used by ParallelCluster. "
"Please ensure Node.js is properly installed and accessible. "
"See installation instructions: https://docs.aws.amazon.com/parallelcluster/latest/ug/install-v3.html"
)
LOGGER.critical(message)
raise Exception(message)

# Handle nvm returning 'none'
if node_version_string == "none":
message = (
"Node.js does not appear to be installed. Please use the Node Version Manager (nvm) to install a"
" version of Node.js compatible with this platform."
)
LOGGER.critical(message)
raise Exception(message)

Expand Down
12 changes: 4 additions & 8 deletions tests/integration-tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,8 +399,7 @@ def _setup_custom_logger(log_file):


@pytest.fixture(scope="class")
@pytest.mark.usefixtures("setup_credentials")
def clusters_factory(request, region):
def clusters_factory(request, region, setup_credentials):
"""
Define a fixture to manage the creation and destruction of clusters.

Expand Down Expand Up @@ -512,8 +511,7 @@ def api_client(region, api_server_factory, api_uri):


@pytest.fixture(scope="class")
@pytest.mark.usefixtures("setup_credentials")
def images_factory(request):
def images_factory(request, setup_credentials):
"""
Define a fixture to manage the creation and destruction of images.

Expand Down Expand Up @@ -924,8 +922,7 @@ def cfn_stacks_factory(request):


@pytest.fixture()
@pytest.mark.usefixtures("setup_credentials")
def parameterized_cfn_stacks_factory(request):
def parameterized_cfn_stacks_factory(request, setup_credentials):
"""Define a fixture that returns a parameterized stack factory and manages the stack creation and deletion."""
factory = CfnStacksFactory(request.config.getoption("credential"))

Expand Down Expand Up @@ -1020,8 +1017,7 @@ def register_cli_credentials(initialize_cli_creds):


@pytest.fixture(scope="class")
@pytest.mark.usefixtures("clusters_factory", "images_factory")
def create_roles_stack(request, region):
def create_roles_stack(request, region, clusters_factory, images_factory):
"""Define a fixture that returns a stack factory for IAM roles."""
logging.info("Creating IAM roles stack")
factory = CfnStacksFactory(request.config.getoption("credential"))
Expand Down
3 changes: 2 additions & 1 deletion tests/integration-tests/requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ cfn_flip
click
decorator
#https://github.com/fabric/fabric/issues/2204
fabric==2.6.0
fabric>=3.2.2
filelock
jinja2
jsonpickle
Expand All @@ -30,3 +30,4 @@ retrying
troposphere
untangle
xmltodict
invoke>=2.2.0
Loading