[pcluster-diag] List installed software and expected versions (#3298)
[pcluster-diag] List installed software and expected versions
[pcluster-diag] Read the NFS service from the node attributes and gate the NVIDIA checks on the node
CriticalServicesAreRunning: read the NFS server service from the node attributes (nfs.service.server) instead of hardcoding it per OS. Report a unit that does not exist as not installed (E3) rather than inactive.
CriticalSoftwareVersions: check the NVIDIA software on every instance with an NVIDIA GPU, without reading cluster.nvidia.enabled and cluster.nvidia.gdrcopy.enabled: the attributes dumped when the node is configured reset them to their defaults. Report a GPU without any NVIDIA driver as a single error (E3). The Fabric Manager version mismatch is now E2, and a missing Fabric Manager E4.
Compare the versions on the components of the shorter of the two, instead of a count per component.
Probe CUDA through the /usr/local/cuda symlink, so a different CUDA on the base image is a version mismatch instead of “not installed”, and drop the expected version from the version probes.
Read only the default level of the node attributes, where the cookbook defaults the checks read are set.
List the OS packages with the package manager of the OS: dpkg on Ubuntu, rpm on the other OSes.
Read the base OS of the node from a Context property.
[pcluster-diag] Update changelog
Co-authored-by: Helena Greebe <hgreebe@amazon> Co-authored-by: hanwen-cluster hanwenli@amazon.com
版权所有:中国计算机学会技术支持:开源发展技术委员会
京ICP备13000930号-9
京公网安备 11010802047560号
AWS ParallelCluster Cookbook
This repo contains the AWS ParallelCluster Chef cookbook used in AWS ParallelCluster.
Code structure
The root folder of the cookbook repository can be considered the main cookbook.
The main cookbook does not contain any recipe, attribute or library. They are distributed in the functional cookbooks under the
cookbooksfolder defined as follows:aws-parallelcluster-entrypointsis the cookbook to define the external interface, contains recipes called by AMI builder, cluster setup, cluster update, etc. The recipes in this cookbook are called directly by the CLI or CI/CD. It orchestrates invocation of recipes/resources from other cookbooks;aws-parallelcluster-platformOS packages and system configuration (directories, users, services, drivers);aws-parallelcluster-environmentAWS services configuration and usage, such as shared file systems, directory service and network interfaces;aws-parallelcluster-computefleetslurm specific scaling logic, compute fleet scripts and daemons;aws-parallelcluster-awsbatchfiles required to support AWS Batch as scheduler;aws-parallelcluster-slurmfiles required to support Slurm as a scheduler and its dependencies (Munge, MySQL for accounting, etc), it depends byaws-parallelcluster-computefleet;Finally, some common code, such as source/script directories, usernames, package installer etc., are located in a cookbook which every other cookbook depend on, that is
aws-parallelcluster-shared. Each cookbook hosts recipes and resources, attributes, functions, files and templates belonging to its functional area.Every cookbook contains ChefSpec and Kitchen tests for its code. However, the code in a cookbook might require that some other code from a different cookbook not listed among dependencies, to be executed as a prerequisite (test setup phase). For this reason
aws-parallelcluster-testscookbook must depend on every other cookbook.The
testfolder contains Python unit tests files and Kitchen environment files.The
kitchenfolder contains utility files used when running Inspec tests locally.The
iptables,line,nfs,openssh,yum,yum-epleare cookbooks from marketplace. They must be regularly updated and should not be modified by hand. They have been pre-downloaded and stored in our repository to avoid contacting Chef Marketplace at AMI build time and cluster creation. You can find more information about them in thecookbooks/THIRD-PARTY-LICENSES.txtfile.Development
About ChefSpec Tests
ChefSpec is a unit testing framework for testing Chef cookbooks. It is very fast, and we use it to verify recipes with multiple branches (e.g. HeadNode vs ComputeNode) work as expected. They don’t need virtual machines or cloud servers. They can be executed locally by executing:
They are automatically executed as GitHub actions, see definition in
.github/ci.yml.About Kitchen Tests
Kitchen is used to automatically test cookbooks across any combination of platforms and test suites. It requires cinc-workstation to be installed on your environment:
brew install --cask cinc-workstationon MacOSor
curl -L https://omnitruck.cinc.sh/install.sh | sudo bash -s -- -P cinc-workstation -v 23Make sure you have set a locale in your local shell environment, by exporting the
LC_ALLandLANGvariables, for example by adding to your.bashrcor.zshrcthe following and sourcing the file:To speed up the transfer of files when kitchens are run on ec2 instances, the transport selected is kitchen-transport-speedy. To install
kitchen-transport-speedyin the kitchen embedded ruby environment please run:/opt/cinc-workstation/embedded/bin/gem install kitchen-transport-speedy.In order to test on docker containers, you also need
dockerinstalled on your environment. Please note that not all the tests can run on docker so in any case we need to validate our recipes on EC2. You can useon_docker?condition to skip execution of some recipes steps, resource actions or controls execution on docker. Please look at “Known issues with docker” section of the README for specific issues (e.g. when running kitchen tests on nonamd64architectures).Kitchen tests helpers
kitchen.docker.shandkitchen.ec2.shhelp you run kitchen tests virtually without any further environment setup. They are wrappers of thekitchencommand, so you can pass them all the options exposed by it. Seekitchen --helpfor more details.You must do some initial setup on your AWS account in order to be able to use defaults from
kitchen.ec2.sh. Default values are the following. Take a look at comments at the top of the script in order to understand how to use it.Both scripts can be run as follows:
<context>is your test context, likeenvironment-configorplatform-install. For example./kitchen.docker.sh platform-install test nvidiawill executekitchen testcommand, executing all the tests for which the name starts withnvidiaprefix, incookbooks/aws-parallelcluster-platformdirectory on docker.It is important to keep in mind that the parameter after the kitchen action is a pattern, so it’s important to choose the appropriate naming for kitchen tests suites. For instance, we can use
nvidia-<context>for nvidia-related tests, so that they can be run separately or together. However, we should not havenvidiaandnvidia-somethingtests, as we wouldn’t be able to run only the first one on all OSes.Examples of submission are:
A context must have the format
$subject-$phase.Supported phases are:
install(on EC2 it defaults to a bare base AMI)config(on EC2 it defaults to a ParallelCluster official AMI)It will use
kitchen.${context}.ymlin the specific cookbook, i.e. incookbooks/aws-parallelcluster-$subjectdir.You can override default values by setting environment variables in a
.kitchen.env.shfile to be created in the cookbook root folder. Example of.kitchen.env.shfile:Testing against a locally-built AMI with dependency overrides
When validating a dependency upgrade, point the
configphase at the AMI you built and inject the sameExtraChefAttributesthe build used, so the converge resolves the AMI-baked versions instead of the cookbook defaults:KITCHEN_<OS>_AMI(e.g.KITCHEN_ALINUX2023_AMI,KITCHEN_RHEL8_AMI,KITCHEN_UBUNTU2404_AMI). If unset,kitchen.ec2.ymlimage_searchpicks the latest matchingaws-parallelcluster-<version>-<os>-*AMI (version fromKITCHEN_PCLUSTER_VERSION, default3.16.0).EXTRA_CHEF_ATTRIBUTES(the same JSON used to build the AMI).kitchen.ec2.ymlparses it and deep-merges itsclusterhash into the provisioner attributes for the converge (EC2 only — Docker runs are unaffected). Per-platformattributes.cluster(e.g.base_os) merges on top.If the converge can’t find an upgraded component on the AMI (e.g. a
pythonvenv path under/opt/parallelcluster/pyenv/versions/<python-version>/...or a version-pinned binary), the AMI and the injected attributes disagree — rebuild the AMI with the same overrides, or alignEXTRA_CHEF_ATTRIBUTESto what the AMI actually carries.Kitchen tests definition
The different
kitchen.${context}.ymlfiles in the functional cookbooks contain a list of Inspec tests for the different recipes and resources.Every test specifies:
run_listthat is the list of recipes to be executed as preparatory steps as part of thekitchen convergephase:recipe[aws-parallelcluster-tests::setup]is a utility recipe that should be added to every test to prepare the environment and automatically execute resources and recipes listed as dependencies in thedependenciesattributes.recipe[aws-parallelcluster-tests::test_resource]is a utility recipe to simplify testing of the custom resource defined in theresourceattribute. Please checktest_resourcecontent to see which parameters you can pass to it.verifierwith the list of controls to execute as part of thekitchen verifyphase, it’s possible to use regex here, it can accept regular expressions in format/regex/.attributesthat will be propagated in the test environment.resourceis a reserved attribute, used bytest_resourcerecipe mentioned before.dependenciesis a reserved attribute, used bysetuprecipe mentioned before.clusterstructure permits to pass specific parameters to the test to simulate environment condition (i.e. dna.json configuration that should come from the CLI when executing the recipes in a real cluster)Example of test definition:
When you execute a test like this with
kitchen testcommand it will execute the recipes or resources actions specified in therun_list, includingdependencies, will setclusterattributes in the environment and at the end will execute theverifysteps by executing the listedcontrols. Thekitchen testcommand will execute all the steps and will destroy the instance at the end. If you want to preserve the instance you can execute the step one by one, checkkitchen helpfor more details.Kitchen tests as GitHub actions and as part of CI/CD
As you can see in the
.github/workflows/dokken-system-tests.ymlwe are executing both install and config recipes as GitHub actions. We execute install steps in theKitchen Test Install(to simulate AMI build) and then re-using the container to validate the config steps, in theKitchen Test Config.In our daily CI/CD we build an AMI (calling the
aws-parallelcluster-entrypoints::installrecipe) and then execute kitchen tests on top of it.Both CI/CD and GitHub actions use the
kitchen.validate-config.ymlfile in the root folder to validate the config steps. If you look at it, you can see it runs all theinspec_testsfrom all the cookbooks by executing the controls matching the/tag:config/regex.This means that if you want a specific control to be executed as part of the CI/CD or GitHub action you should use
tag:config_as prefix in the control name.Note that not all the Inspec tests can run on GitHub and on the CI/CD because, as you can see in the
kitchen.validate-config.yml, in this case therun_listis defined as follows:without any attribute specified, so this could not match with the
run_listor theattributesspecified in the test definition. So before adding thetag:config_prefix to a control name, please be sure that it can run even without specific setup.If you want to execute some kitchen tests at the end of the build-image process, to validate that a created AMI contains what we expect, you can use the
tag:install_as prefix in the control name. They will be automatically executed by Image builder at the end of the build-image process (search fortag:install_in the CLI code to understand the details behind this mechanism). Please note that if this test fails the build of the image will fail as well.If you want to execute some kitchen tests as part of validate phase the build-image process without causing the build image to fail you can use the
tag:testami_as prefix. These tests will be executed when the image has already been created (search fortag:testami_in the CLI code to understand the details behind this mechanism).Please note that a test suite name can contain multiple tags (for instance,
tag:install_tag:config_), the code search for them with a regex so it’s not required to have them as prefix.Save and reuse Docker image
When you set the environment variable
KITCHEN_SAVE_IMAGE=true, a successfulkitchen verifyphase will lead to the Docker image being committed with the tagpcluster-${PHASE}/${INSTANCE_NAME}.For instance, if you successfully run
an image with tag
pcluster-install/directories-alinux2:latestwill be saved.To use it in a later Kitchen test,
export KITCHEN_${PLATFORM}_IMAGE=<your_image>.For instance, to reuse the image from the example above, set
KITCHEN_ALINUX2_IMAGE=pcluster-install/directories-alinux2.We are using this approach to re-use the docker image created by the
Kitchen Test Installin the followingKitchen Test Configphase as part of the GitHub actions.Save and reuse EC2 image
The procedure described above also applies to EC2, with minor differences.
kitchen testorkitchen destroycommands. Opt forkitchen verifyand destroy the instance once the AMI is ready.KITCHEN_${PLATFORM}_AMI=<ami_id>to reuse the AMI. For instance,KITCHEN_ALINUX2_AMI=ami-nnnnnnnnnnnnn.This is useful when you need a long list of dependencies to be installed in the AMI (e.g. Slurm recipes) to verify configuration steps.
Kitchen lifecycle hooks
Kitchen lifecycle hooks allow running commands before and/or after any phase of Kitchen tests (create, converge, verify, or destroy).
We leverage this feature in Kitchen tests to create/destroy AWS resources (see
kitchen.global.yamlfile.For each phase, a generic run script executes custom
${THIS_DIR}/${KITCHEN_COOKBOOK_PATH}/test/hooks/${KITCHEN_PHASE}/${KITCHEN_SUITE_NAME}/${KITCHEN_HOOK}.shscript, if it exists.Example.
network_interfacesKitchen test suite in theaws-parallelcluster-environmentcookbook requires a network interface to be attached to the node.cookbooks/aws-parallelcluster-environment/test/hooks/config/network_interfaces/post_create.sh: creates ENI and attaches it to the instancecookbooks/aws-parallelcluster-environment/test/hooks/config/network_interfaces/pre_destroy.sh: detaches and deletes ENI.Use variables from lifecycle hooks as resource properties
In the
kitchen.global.yamlwe’re configuring an environment.In the environment file (i.e.
test/environments/kitchen.rb), for every value to pass and for every OS, you have to define a line like:'<suite_name>-<variable_name>/<platform>' => 'placeholder'. For instance:These environment variables will be available to the kitchen tests as node attributes:
node['kitchen_hooks']['ebs_mount-vol_array/alinux2'].To permit to use these environment variables as parameters attributes you have to use th
FROM-HOOKkeyword in the test suite definition. e.g.resource: 'manage_ebs:mount {"shared_dir_array" : ["shared_dir"], "vol_array" : "FROM_HOOK-<suite_name>-<variable_name>"}'This value will be automatically replaced, searching for the
<suite_name>-<variable_name>/<platform>in the environment. You can find all the details of this mechanism in thetest_resource.rb.Note: the value of the property to be replaced must be a string even if it’s an array. It’s up to the post_create script to define an array in the environment.
Known issues with docker
Running kitchen tests on non
amd64architecturesRunning locally kitchen tests on system with CPU architecture other than
amd64(i.e. Apple Silicon that havearm64) may run in a known dokken issue (tracked as https://github.com/test-kitchen/kitchen-dokken/issues/288).All tests will fail with messages containing errors such as:
To work around the issue, please ensure that the
cinc-workstationversion is>= 23, as it’s the first one that has a dokken version that features platform support.Providing the correct platform configuration in
./kitchen.docker.yml:is required but not enough if images for different CPU architectures already are present in the local docker cache. Local images of different architectures should be removed in order to work around the issue, then in subsequent executions dokken will pull the ones for the specified platform and use those, since there are no other than those for the correct architecture available locally.
Here are some examples to clean up local docker containers and images:
kitchen tests fail in
docker_config_credswith NPEdokken expects that
~/.docker/config.jsoncontains an"auths"key, fails indocker_config_credswith NPE otherwise, this issue is tracked in upstream as: https://github.com/test-kitchen/kitchen-dokken/issues/290Known issues with EC2
Ubuntu22
On Ubuntu22,
kitchen createkeeps trying to connect to the instance via ssh indefinitely. If you interrupt it and try to runkitchen verify, you see authentication failures.This happens because Ubuntu22 does not accept authentication via RSA key. You need to re-create a key pair using
ED25519key type.About python tests
Python tests are configured in
tox.inifile, including paths to python files. If you move python files around, you need to fix python path accordingly.