Skip to content
Merged
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ CHANGELOG
------

**ENHANCEMENTS**
- Add the configuration parameter `DeploymentSettings/DefaultUserHome` to allow users to move the default user's home directory to `/local/home` instead of `/home` (default).
- Permit to update `MinCount`, `MaxCount`, `Queue` and `ComputeResource` configuration parameters without the need to
stop the compute fleet. It's now possible to update them by setting `Scheduling/SlurmSettings/QueueUpdateStrategy`
to TERMINATE. ParallelCluster will terminate only the nodes removed during a resize of the cluster capacity
Expand Down
15 changes: 13 additions & 2 deletions cli/src/pcluster/config/cluster_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,14 @@
from pcluster.aws.aws_api import AWSApi
from pcluster.aws.aws_resources import InstanceTypeInfo
from pcluster.aws.common import AWSClientError, get_region
from pcluster.config.common import AdditionalIamPolicy, BaseDeploymentSettings, BaseDevSettings, BaseTag, CapacityType
from pcluster.config.common import (
AdditionalIamPolicy,
BaseDeploymentSettings,
BaseDevSettings,
BaseTag,
CapacityType,
DefaultUserHomeType,
)
from pcluster.config.common import Imds as TopLevelImds
from pcluster.config.common import Resource
from pcluster.constants import (
Expand Down Expand Up @@ -1232,9 +1239,13 @@ def _register_validators(self, context: ValidatorContext = None):
class ClusterDeploymentSettings(BaseDeploymentSettings):
"""Represent the cluster-wide settings related to deployment."""

def __init__(self, disable_sudo_access_default_user: bool = None, **kwargs):
def __init__(self, default_user_home: str = None, disable_sudo_access_default_user: bool = None, **kwargs):
super().__init__(**kwargs)
self.disable_sudo_access_default_user = Resource.init_param(disable_sudo_access_default_user)
self.default_user_home = Resource.init_param(
default_user_home,
default=DefaultUserHomeType.SHARED.value,
)

def _register_validators(self, context: ValidatorContext = None):
super()._register_validators(context)
Expand Down
8 changes: 8 additions & 0 deletions cli/src/pcluster/config/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,13 @@ def __init__(self, imds_support: str = None, **kwargs):
self.imds_support = Resource.init_param(imds_support, default="v2.0")


class DefaultUserHomeType(Enum):
"""Define supported allocation strategies."""

SHARED = "Shared"
LOCAL = "Local"


class BaseDeploymentSettings(Resource):
"""
Represent the settings related to PCluster deployment, i.e. Lambda Functions for custom resources.
Expand All @@ -388,6 +395,7 @@ class BaseDeploymentSettings(Resource):

def __init__(self, lambda_functions_vpc_config: LambdaFunctionsVpcConfig = None, **kwargs):
super().__init__(**kwargs)

self.lambda_functions_vpc_config = Resource.init_param(lambda_functions_vpc_config)

def _register_validators(self, context: ValidatorContext = None):
Expand Down
8 changes: 7 additions & 1 deletion cli/src/pcluster/schemas/cluster_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
SlurmSettings,
Timeouts,
)
from pcluster.config.common import BaseTag, CapacityType
from pcluster.config.common import BaseTag, CapacityType, DefaultUserHomeType
from pcluster.config.update_policy import UpdatePolicy
from pcluster.constants import (
DELETION_POLICIES,
Expand Down Expand Up @@ -1162,6 +1162,12 @@ class ClusterDeploymentSettingsSchema(BaseDeploymentSettingsSchema):
metadata={"update_policy": UpdatePolicy.COMPUTE_AND_LOGIN_NODES_STOP},
)

default_user_home = fields.Str(
required=False,
metadata={"update_policy": UpdatePolicy.UNSUPPORTED},
validate=validate.OneOf([type.value for type in DefaultUserHomeType]),
)

@post_load
def make_resource(self, data, **kwargs):
"""Generate resource."""
Expand Down
9 changes: 9 additions & 0 deletions cli/src/pcluster/templates/cluster_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
SharedStorageType,
SlurmClusterConfig,
)
from pcluster.config.common import DefaultUserHomeType
from pcluster.constants import (
ALL_PORTS_RANGE,
CW_ALARM_DATAPOINTS_TO_ALARM_DEFAULT,
Expand Down Expand Up @@ -1250,6 +1251,14 @@ def _add_head_node(self):
"base_os": self.config.image.os,
"region": self.stack.region,
"shared_storage_type": self.config.head_node.shared_storage_type.lower(),
"default_user_home": (
self.config.deployment_settings.default_user_home.lower()
if (
self.config.deployment_settings is not None
and self.config.deployment_settings.default_user_home is not None
)
else DefaultUserHomeType.SHARED.value.lower()
),
"efs_fs_ids": get_shared_storage_ids_by_type(self.shared_storage_infos, SharedStorageType.EFS),
"efs_shared_dirs": to_comma_separated_string(self.shared_storage_mount_dirs[SharedStorageType.EFS]),
"efs_encryption_in_transits": to_comma_separated_string(
Expand Down
9 changes: 9 additions & 0 deletions cli/src/pcluster/templates/login_nodes_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

from pcluster.aws.aws_api import AWSApi
from pcluster.config.cluster_config import LoginNodesPool, SharedStorageType, SlurmClusterConfig
from pcluster.config.common import DefaultUserHomeType
from pcluster.constants import (
DEFAULT_EPHEMERAL_DIR,
NODE_BOOTSTRAP_TIMEOUT,
Expand Down Expand Up @@ -211,6 +212,14 @@ def _add_login_nodes_pool_launch_template(self):
"generate_ssh_keys_for_users": ds_generate_keys,
},
"shared_storage_type": self._config.head_node.shared_storage_type.lower(),
"default_user_home": (
self._config.deployment_settings.default_user_home.lower()
if (
self._config.deployment_settings is not None
and self._config.deployment_settings.default_user_home is not None
)
else DefaultUserHomeType.SHARED.value.lower()
),
"ebs_shared_dirs": to_comma_separated_string(
self._shared_storage_mount_dirs[SharedStorageType.EBS]
),
Expand Down
9 changes: 9 additions & 0 deletions cli/src/pcluster/templates/queues_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from pcluster.aws.aws_api import AWSApi
from pcluster.config.cluster_config import SharedStorageType, SlurmClusterConfig, SlurmComputeResource, SlurmQueue
from pcluster.config.common import DefaultUserHomeType
from pcluster.constants import (
DEFAULT_EPHEMERAL_DIR,
NODE_BOOTSTRAP_TIMEOUT,
Expand Down Expand Up @@ -314,6 +315,14 @@ def _add_compute_resource_launch_template(
"base_os": self._config.image.os,
"region": self._config.region,
"shared_storage_type": self._config.head_node.shared_storage_type.lower(), # noqa: E501 pylint: disable=line-too-long
"default_user_home": (
self._config.deployment_settings.default_user_home.lower()
if (
self._config.deployment_settings is not None
and self._config.deployment_settings.default_user_home is not None
)
else DefaultUserHomeType.SHARED.value.lower()
),
"efs_fs_ids": get_shared_storage_ids_by_type(self._shared_storage_infos, SharedStorageType.EFS),
"efs_shared_dirs": to_comma_separated_string(
self._shared_storage_mount_dirs[SharedStorageType.EFS]
Expand Down
7 changes: 7 additions & 0 deletions cli/tests/pcluster/templates/test_cluster_stack.py
Original file line number Diff line number Diff line change
Expand Up @@ -884,6 +884,13 @@ def test_login_nodes_traffic_management_resources_values_properties(
"scheduler": "slurm",
},
),
(
"default-user-local-home.yaml",
{
"scheduler": "slurm",
"default_user_home": "local",
},
),
],
)
# Datetime mocking is required because some template values depend on the current datetime value
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Image:
Os: alinux2
HeadNode:
InstanceType: t2.micro
Networking:
SubnetId: subnet-12345678
Ssh:
KeyName: ec2-key-name
Scheduling:
Scheduler: slurm
SlurmQueues:
- Name: queue1
Networking:
SubnetIds:
- subnet-12345678
ComputeResources:
- Name: compute_resource1
InstanceType: c5.2xlarge
- Name: compute_resource2
InstanceType: c4.2xlarge
DeploymentSettings:
DefaultUserHome: Local
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
"dcv_enabled": "false",
"dcv_port": "NONE",
"ddb_table": "NONE",
"default_user_home": "shared",
"disable_sudo_access_for_default_user": "false",
"ebs_shared_dirs": "",
"efs_encryption_in_transits": "",
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
DeploymentSettings:
DisableSudoAccessForDefaultUser: True
DefaultUserHome: Local
Region: us-east-1
Image:
Os: alinux2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"custom_awsbatchcli_package": "",
"custom_node_package": "",
"cw_logging_enabled": "true",
"default_user_home": "local",
"directory_service": {
"domain_read_only_user": "",
"enabled": "false",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"custom_awsbatchcli_package": "",
"custom_node_package": "",
"cw_logging_enabled": "true",
"default_user_home": "shared",
"directory_service": {
"domain_read_only_user": "cn=ReadOnlyUser,ou=Users,ou=CORP,dc=corp,dc=pcluster,dc=com",
"enabled": "true",
Expand Down Expand Up @@ -44,4 +45,4 @@
"stack_name": "clustername",
"use_private_hostname": "false"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,3 +28,4 @@ DirectoryService:
GenerateSshKeysForUsers: true
DeploymentSettings:
DisableSudoAccessForDefaultUser: True
DefaultUserHome: Local
Original file line number Diff line number Diff line change
@@ -1,50 +1,51 @@
{
"cluster": {
"cluster_name": "clustername",
"stack_name": "clustername",
"stack_arn": "{\"Ref\": \"AWS::StackId\"}",
"cluster_s3_bucket": "parallelcluster-a69601b5ee1fc2f2-v1-do-not-delete",
"base_os": "alinux2",
"cluster_config_s3_key": "parallelcluster/clusters/dummy-cluster-randomstring123/configs/cluster-config-with-implied-values.yaml",
"cluster_config_version": "",
"enable_efa": "NONE",
"raid_shared_dir": "",
"raid_type": "",
"base_os": "alinux2",
"region": "us-east-1",
"shared_storage_type": "ebs",
"efs_fs_ids": "",
"efs_shared_dirs": "",
"cluster_name": "clustername",
"cluster_s3_bucket": "parallelcluster-a69601b5ee1fc2f2-v1-do-not-delete",
"cluster_user": "ec2-user",
"custom_awsbatchcli_package": "",
"custom_node_package": "",
"cw_logging_enabled": "true",
"default_user_home": "shared",
"directory_service": {
"enabled": "false"
},
"disable_sudo_access_for_default_user": "false",
"dns_domain": "{\"Ref\": \"referencetoclusternameClusterDNSDomain8D0872E1Ref\"}",
"ebs_shared_dirs": "",
"efs_encryption_in_transits": "",
"efs_fs_ids": "",
"efs_iam_authorizations": "",
"fsx_fs_ids": "",
"fsx_mount_names": "",
"efs_shared_dirs": "",
"enable_efa": "NONE",
"enable_efa_gdr": "NONE",
"enable_intel_hpc_platform": "false",
"ephemeral_dir": "/scratch",
"fsx_dns_names": "",
"fsx_volume_junction_paths": "",
"fsx_fs_ids": "",
"fsx_fs_types": "",
"fsx_mount_names": "",
"fsx_shared_dirs": "",
"scheduler": "slurm",
"ephemeral_dir": "/scratch",
"ebs_shared_dirs": "",
"proxy": "NONE",
"slurm_ddb_table": "{\"Ref\": \"referencetoclusternameSlurmDynamoDBTable99119DBERef\"}",
"log_group_name": "/aws/parallelcluster/clustername-202401151530",
"dns_domain": "{\"Ref\": \"referencetoclusternameClusterDNSDomain8D0872E1Ref\"}",
"fsx_volume_junction_paths": "",
"head_node_private_ip": "{\"Ref\": \"referencetoclusternameHeadNodeENI6497A502PrimaryPrivateIpAddress\"}",
"hosted_zone": "{\"Ref\": \"referencetoclusternameRoute53HostedZone2388733DRef\"}",
"node_type": "ComputeFleet",
"cluster_user": "ec2-user",
"enable_intel_hpc_platform": "false",
"cw_logging_enabled": "true",
"log_group_name": "/aws/parallelcluster/clustername-202401151530",
"log_rotation_enabled": "true",
"scheduler_queue_name": "queue1",
"node_type": "ComputeFleet",
"proxy": "NONE",
"raid_shared_dir": "",
"raid_type": "",
"region": "us-east-1",
"scheduler": "slurm",
"scheduler_compute_resource_name": "cr1",
"enable_efa_gdr": "NONE",
"custom_node_package": "",
"custom_awsbatchcli_package": "",
"use_private_hostname": "false",
"head_node_private_ip": "{\"Ref\": \"referencetoclusternameHeadNodeENI6497A502PrimaryPrivateIpAddress\"}",
"directory_service": {
"enabled": "false"
},
"disable_sudo_access_for_default_user": "false"
"scheduler_queue_name": "queue1",
"shared_storage_type": "ebs",
"slurm_ddb_table": "{\"Ref\": \"referencetoclusternameSlurmDynamoDBTable99119DBERef\"}",
"stack_arn": "{\"Ref\": \"AWS::StackId\"}",
"stack_name": "clustername",
"use_private_hostname": "false"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
"custom_awsbatchcli_package": "",
"custom_node_package": "",
"cw_logging_enabled": "true",
"default_user_home": "local",
"directory_service": {
"enabled": "true"
},
Expand Down
7 changes: 7 additions & 0 deletions tests/integration-tests/configs/develop.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -831,3 +831,10 @@ test-suites:
- regions: ["eu-west-2"]
schedulers: ["slurm"]
oss: ["alinux2"]
users:
test_default_user_home.py::test_default_user_local_home:
dimensions:
- oss: [ "alinux2" ]
regions: [ "us-west-2" ]
instances: {{ common.INSTANCES_DEFAULT_X86 }}
schedulers: [ "slurm" ]
11 changes: 11 additions & 0 deletions tests/integration-tests/tests/users/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "LICENSE.txt" file accompanying this file.
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied.
# See the License for the specific language governing permissions and limitations under the License.
46 changes: 46 additions & 0 deletions tests/integration-tests/tests/users/test_default_user_home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License").
# You may not use this file except in compliance with the License.
# A copy of the License is located at
#
# http://aws.amazon.com/apache2.0/
#
# or in the "LICENSE.txt" file accompanying this file.
# This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, express or implied.
# See the License for the specific language governing permissions and limitations under the License.
import logging

import pytest
from assertpy import assert_that
from remote_command_executor import RemoteCommandExecutor

# flake8: noqa


@pytest.mark.usefixtures("os", "scheduler", "instance")
def test_default_user_local_home(
region,
scheduler,
pcluster_config_reader,
vpc_stack,
scheduler_commands_factory,
test_datadir,
clusters_factory,
):
"""Verify the default user's home directory is moved on all instance types when set to local"""

cluster_config = pcluster_config_reader()
cluster = clusters_factory(cluster_config)
remote_command_executor = RemoteCommandExecutor(cluster)
remote_command_executor_login_node = RemoteCommandExecutor(cluster, use_login_node=True)

_check_local_home(remote_command_executor)
_check_local_home(remote_command_executor_login_node)


def _check_local_home(remote_command_executor):
"""Check if the default user's home directory is mounted on the instance"""
logging.info("Testing the default user's home is local")
result = remote_command_executor.run_remote_command("pwd")
assert_that(result.stdout).matches(r"/local/home*")
Loading