├── .devcontainer ├── Dockerfile ├── README.md └── devcontainer.json ├── .fixtures.yml ├── .gitattributes ├── .gitchangelog.rc ├── .gitignore ├── .gitlab-ci.yml ├── .pdkignore ├── .pmtignore ├── .puppet-lint.rc ├── .readthedocs.yaml ├── .rspec ├── .rubocop.yml ├── .ruby-gemset ├── .ruby-version ├── .travis.yml ├── .vscode └── extensions.json ├── .yardopts ├── CHANGELOG.md ├── Gemfile ├── Gemfile.lock ├── LICENSE ├── README.md ├── Rakefile ├── Vagrantfile ├── appveyor.yml ├── data ├── common.yaml └── os │ └── RedHat │ └── 9.yaml ├── docs ├── contacts.md ├── contributing │ ├── index.md │ ├── layout.md │ ├── setup.md │ └── versioning.md ├── index.md ├── overview.md ├── rtfd.md └── vagrant.md ├── files ├── limits.memlock └── slurm_completion.sh ├── hiera.yaml ├── lib └── facter │ └── is_vagrant.rb ├── manifests ├── accounting.pp ├── acct │ ├── account.pp │ ├── cluster.pp │ ├── mgr.pp │ ├── qos.pp │ └── user.pp ├── build.pp ├── common.pp ├── common │ ├── debian.pp │ └── redhat.pp ├── config.pp ├── config │ ├── cgroup.pp │ ├── gres.pp │ ├── plugstack.pp │ └── topology.pp ├── download.pp ├── firewall.pp ├── init.pp ├── install.pp ├── install │ └── packages.pp ├── login.pp ├── munge.pp ├── pam.pp ├── params.pp ├── plugin.pp ├── plugins.pp ├── plugins │ └── lua.pp ├── pmix.pp ├── pmix │ ├── build.pp │ ├── download.pp │ └── install.pp ├── repo.pp ├── repo │ └── syncto.pp ├── slurmctld.pp ├── slurmd.pp └── slurmdbd.pp ├── metadata.json ├── mkdocs.yml ├── pdk.yaml ├── spec ├── default_facts.yml └── spec_helper.rb ├── templates ├── cgroup.conf.erb ├── cgroup_allowed_devices_file.conf.erb ├── gres.conf.erb ├── job_submit.lua.erb ├── munge_sysconfig.erb ├── pam_slurm.erb ├── plugstack.conf.erb ├── slurm.conf.erb ├── slurm_packages_build.sh.erb ├── slurmdbd.conf.erb └── topology.conf.erb ├── tests ├── absent.pp ├── advanced.pp ├── build.pp ├── download.pp ├── init.pp ├── login_node.pp ├── munge.pp ├── pam.pp ├── pmix.pp ├── repo.pp ├── slurmctld.pp ├── slurmd.pp ├── slurmdbd.pp └── vagrant │ ├── config.yaml │ ├── config.yaml.sample │ ├── puppet │ ├── .gitignore │ ├── Makefile │ ├── hiera.yaml │ ├── hieradata │ │ ├── .gitignore │ │ ├── defaults.yaml │ │ └── roles │ │ │ ├── controller.yaml │ │ │ ├── db.yaml │ │ │ ├── login.yaml │ │ │ └── node.yaml │ ├── manifests │ │ └── default.pp │ ├── modules │ │ └── .gitignore │ └── site │ │ └── profiles │ │ └── manifests │ │ ├── slurm.pp │ │ └── slurm │ │ ├── login.pp │ │ ├── slurmctld.pp │ │ ├── slurmd.pp │ │ └── slurmdbd.pp │ ├── rpmbuild │ └── .gitignore │ ├── scripts │ ├── bootstrap.sh │ ├── puppet_modules_setup.rb │ ├── setup_slurm_accounting.sh │ └── setup_testing_users_groups.sh │ └── shared │ └── .gitignore └── types └── entity.pp /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM puppet/pdk:latest 2 | 3 | # [Optional] Uncomment this section to install additional packages. 4 | # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 5 | # && apt-get -y install --no-install-recommends 6 | 7 | -------------------------------------------------------------------------------- /.devcontainer/README.md: -------------------------------------------------------------------------------- 1 | # devcontainer 2 | 3 | 4 | For format details, see https://aka.ms/devcontainer.json. 5 | 6 | For config options, see the README at: 7 | https://github.com/microsoft/vscode-dev-containers/tree/v0.140.1/containers/puppet 8 | 9 | ``` json 10 | { 11 | "name": "Puppet Development Kit (Community)", 12 | "dockerFile": "Dockerfile", 13 | 14 | // Set *default* container specific settings.json values on container create. 15 | "settings": { 16 | "terminal.integrated.profiles.linux": { 17 | "bash": { 18 | "path": "bash", 19 | } 20 | } 21 | }, 22 | 23 | // Add the IDs of extensions you want installed when the container is created. 24 | "extensions": [ 25 | "puppet.puppet-vscode", 26 | "rebornix.Ruby" 27 | ], 28 | 29 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 30 | "forwardPorts": [], 31 | 32 | // Use 'postCreateCommand' to run commands after the container is created. 33 | "postCreateCommand": "pdk --version", 34 | } 35 | ``` 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Puppet Development Kit (Community)", 3 | "dockerFile": "Dockerfile", 4 | 5 | "settings": { 6 | "terminal.integrated.profiles.linux": { 7 | "bash": { 8 | "path": "bash", 9 | } 10 | } 11 | }, 12 | 13 | "extensions": [ 14 | "puppet.puppet-vscode", 15 | "rebornix.Ruby" 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /.fixtures.yml: -------------------------------------------------------------------------------- 1 | # This file can be used to install module dependencies for unit testing 2 | # See https://github.com/puppetlabs/puppetlabs_spec_helper#using-fixtures for details 3 | --- 4 | fixtures: 5 | forge_modules: 6 | # stdlib: "puppetlabs/stdlib" 7 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.rb eol=lf 2 | *.erb eol=lf 3 | *.pp eol=lf 4 | *.sh eol=lf 5 | *.epp eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/* 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | .project 26 | .envrc 27 | /inventory.yaml 28 | /spec/fixtures/litmus_inventory.yaml 29 | .vagrant 30 | .falkor* 31 | -------------------------------------------------------------------------------- /.gitlab-ci.yml: -------------------------------------------------------------------------------- 1 | --- 2 | stages: 3 | - syntax 4 | - unit 5 | 6 | default: 7 | cache: 8 | paths: 9 | - vendor/bundle 10 | 11 | before_script: &before_script 12 | - bundle -v 13 | - rm Gemfile.lock || true 14 | - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner" 15 | - "# Set `rubygems_version` in the .sync.yml to set a value" 16 | - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set" 17 | - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION' 18 | - gem --version 19 | - bundle -v 20 | - bundle install --without system_tests --path vendor/bundle --jobs $(nproc) 21 | 22 | validate lint check rubocop-Ruby 2.5.7-Puppet ~> 6: 23 | stage: syntax 24 | image: ruby:2.5.7 25 | script: 26 | - bundle exec rake validate lint check rubocop 27 | variables: 28 | PUPPET_GEM_VERSION: '~> 6' 29 | 30 | parallel_spec-Ruby 2.5.7-Puppet ~> 6: 31 | stage: unit 32 | image: ruby:2.5.7 33 | script: 34 | - bundle exec rake parallel_spec 35 | variables: 36 | PUPPET_GEM_VERSION: '~> 6' 37 | 38 | validate lint check rubocop-Ruby 2.7.2-Puppet ~> 7: 39 | stage: syntax 40 | image: ruby:2.7.2 41 | script: 42 | - bundle exec rake validate lint check rubocop 43 | variables: 44 | PUPPET_GEM_VERSION: '~> 7' 45 | 46 | parallel_spec-Ruby 2.7.2-Puppet ~> 7: 47 | stage: unit 48 | image: ruby:2.7.2 49 | script: 50 | - bundle exec rake parallel_spec 51 | variables: 52 | PUPPET_GEM_VERSION: '~> 7' 53 | 54 | -------------------------------------------------------------------------------- /.pdkignore: -------------------------------------------------------------------------------- 1 | .git/ 2 | .*.sw[op] 3 | .metadata 4 | .yardoc 5 | .yardwarns 6 | *.iml 7 | /.bundle/ 8 | /.idea/ 9 | /.vagrant/ 10 | /coverage/ 11 | /bin/ 12 | /doc/ 13 | /Gemfile.local 14 | /Gemfile.lock 15 | /junit/ 16 | /log/ 17 | /pkg/ 18 | /spec/fixtures/manifests/ 19 | /spec/fixtures/modules/* 20 | /tmp/ 21 | /vendor/ 22 | /convert_report.txt 23 | /update_report.txt 24 | .DS_Store 25 | .project 26 | .envrc 27 | /inventory.yaml 28 | /spec/fixtures/litmus_inventory.yaml 29 | /.fixtures.yml 30 | /Gemfile 31 | /.gitattributes 32 | /.github/ 33 | /.gitignore 34 | /.pdkignore 35 | /.puppet-lint.rc 36 | /Rakefile 37 | /rakelib/ 38 | /.rspec 39 | /.rubocop.yml 40 | /..yml 41 | /.yardopts 42 | /spec/ 43 | /.vscode/ 44 | /tests/vagrant/ 45 | /.sync.yml 46 | /.devcontainer/ 47 | -------------------------------------------------------------------------------- /.pmtignore: -------------------------------------------------------------------------------- 1 | docs/ 2 | site/ 3 | tests/vagrant/ 4 | -------------------------------------------------------------------------------- /.puppet-lint.rc: -------------------------------------------------------------------------------- 1 | --relative 2 | -------------------------------------------------------------------------------- /.readthedocs.yaml: -------------------------------------------------------------------------------- 1 | # Read the Docs configuration file for MkDocs projects 2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details 3 | 4 | version: 2 5 | 6 | build: 7 | os: ubuntu-22.04 8 | tools: 9 | python: "3.12" 10 | 11 | mkdocs: 12 | configuration: mkdocs.yml 13 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --format documentation 3 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | puppet 2 | -------------------------------------------------------------------------------- /.ruby-version: -------------------------------------------------------------------------------- 1 | 3.2.4 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | os: linux 3 | dist: xenial 4 | language: ruby 5 | cache: bundler 6 | before_install: 7 | - bundle -v 8 | - rm -f Gemfile.lock 9 | - "# Update system gems if requested. This is useful to temporarily workaround troubles in the test runner" 10 | - "# See https://github.com/puppetlabs/pdk-templates/commit/705154d5c437796b821691b707156e1b056d244f for an example of how this was used" 11 | - "# Ignore exit code of SIGPIPE'd yes to not fail with shell's pipefail set" 12 | - '[ -z "$RUBYGEMS_VERSION" ] || (yes || true) | gem update --system $RUBYGEMS_VERSION' 13 | - gem --version 14 | - bundle -v 15 | script: 16 | - 'bundle exec rake $CHECK' 17 | bundler_args: --without system_tests 18 | rvm: 19 | - 2.5.7 20 | stages: 21 | - static 22 | - spec 23 | - acceptance 24 | - 25 | if: tag =~ ^v\d 26 | name: deploy 27 | jobs: 28 | fast_finish: true 29 | include: 30 | - 31 | env: CHECK="validate lint check rubocop" 32 | stage: static 33 | - 34 | env: PUPPET_GEM_VERSION="~> 6.0" CHECK=parallel_spec 35 | rvm: 2.5.7 36 | stage: spec 37 | - 38 | env: DEPLOY_TO_FORGE=yes 39 | stage: deploy 40 | branches: 41 | only: 42 | - main 43 | - /^v\d/ 44 | notifications: 45 | email: false 46 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "puppet.puppet-vscode", 4 | "Shopify.ruby-lsp" 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.yardopts: -------------------------------------------------------------------------------- 1 | --markup markdown 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source ENV['GEM_SOURCE'] || 'https://rubygems.org' 2 | 3 | def location_for(place_or_version, fake_version = nil) 4 | git_url_regex = %r{\A(?(https?|git)[:@][^#]*)(#(?.*))?} 5 | file_url_regex = %r{\Afile:\/\/(?.*)} 6 | 7 | if place_or_version && (git_url = place_or_version.match(git_url_regex)) 8 | [fake_version, { git: git_url[:url], branch: git_url[:branch], require: false }].compact 9 | elsif place_or_version && (file_url = place_or_version.match(file_url_regex)) 10 | ['>= 0', { path: File.expand_path(file_url[:path]), require: false }] 11 | else 12 | [place_or_version, { require: false }] 13 | end 14 | end 15 | 16 | group :development do 17 | gem 'falkorlib', ">= 0.9.1" #, :path => '~/git/github.com/Falkor/falkorlib' 18 | gem "json", '= 2.1.0', require: false if Gem::Requirement.create(['>= 2.5.0', '< 2.7.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 19 | gem "json", '= 2.3.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 20 | gem "json", '= 2.5.1', require: false if Gem::Requirement.create(['>= 3.0.0', '< 3.0.5']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 21 | gem "json", '= 2.6.1', require: false if Gem::Requirement.create(['>= 3.1.0', '< 3.1.3']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 22 | gem "json", '= 2.6.3', require: false if Gem::Requirement.create(['>= 3.2.0', '< 4.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 23 | gem "racc", '~> 1.4.0', require: false if Gem::Requirement.create(['>= 2.7.0', '< 3.0.0']).satisfied_by?(Gem::Version.new(RUBY_VERSION.dup)) 24 | gem "deep_merge", '~> 1.0', require: false 25 | gem "voxpupuli-puppet-lint-plugins", '~> 5.0', require: false 26 | gem "facterdb", '~> 1.18', require: false 27 | gem "metadata-json-lint", '~> 4.1.0', require: false 28 | gem "rspec-puppet-facts", '~> 3.0', require: false 29 | gem "dependency_checker", '~> 1.0.0', require: false 30 | gem "parallel_tests", '= 3.12.1', require: false 31 | gem "pry", '~> 0.10.0', require: false 32 | gem "simplecov-console", '~> 0.9', require: false 33 | gem "puppet-debugger", '~> 1.0', require: false 34 | gem "rubocop", '~> 1.50.0', require: false 35 | gem "rubocop-performance", '= 1.16.0', require: false 36 | gem "rubocop-rspec", '= 2.19.0', require: false 37 | gem "rb-readline", '= 0.5.5', require: false, platforms: [:mswin, :mingw, :x64_mingw] 38 | end 39 | group :development, :release_prep do 40 | gem "puppet-strings", '~> 4.0', require: false 41 | gem "puppetlabs_spec_helper", '~> 7.0', require: false 42 | end 43 | group :system_tests do 44 | gem "puppet_litmus", '~> 1.0', require: false, platforms: [:ruby, :x64_mingw] 45 | gem "CFPropertyList", '< 3.0.7', require: false, platforms: [:mswin, :mingw, :x64_mingw] 46 | gem "serverspec", '~> 2.41', require: false 47 | end 48 | 49 | puppet_version = ENV['PUPPET_GEM_VERSION'] 50 | facter_version = ENV['FACTER_GEM_VERSION'] 51 | hiera_version = ENV['HIERA_GEM_VERSION'] 52 | 53 | gems = {} 54 | 55 | gems['puppet'] = location_for(puppet_version) 56 | 57 | # If facter or hiera versions have been specified via the environment 58 | # variables 59 | 60 | gems['facter'] = location_for(facter_version) if facter_version 61 | gems['hiera'] = location_for(hiera_version) if hiera_version 62 | 63 | gems.each do |gem_name, gem_params| 64 | gem gem_name, *gem_params 65 | end 66 | 67 | # Evaluate Gemfile.local and ~/.gemfile if they exist 68 | extra_gemfiles = [ 69 | "#{__FILE__}.local", 70 | File.join(Dir.home, '.gemfile'), 71 | ] 72 | 73 | extra_gemfiles.each do |gemfile| 74 | if File.file?(gemfile) && File.readable?(gemfile) 75 | eval(File.read(gemfile), binding) 76 | end 77 | end 78 | # vim: syntax=ruby 79 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Rakefile - Configuration file for rake (http://rake.rubyforge.org/) 3 | # Time-stamp: 4 | # 5 | # Copyright (c) 2017 UL HPC Team 6 | # ____ _ __ _ _ 7 | # | _ \ __ _| | _____ / _(_) | ___ 8 | # | |_) / _` | |/ / _ \ |_| | |/ _ \ 9 | # | _ < (_| | < __/ _| | | __/ 10 | # |_| \_\__,_|_|\_\___|_| |_|_|\___| 11 | # 12 | # Use 'rake -T' to list the available actions 13 | # 14 | # Resources: 15 | # * http://www.stuartellis.eu/articles/rake/ 16 | # 17 | # See also https://github.com/garethr/puppet-module-skeleton 18 | ############################################################################## 19 | require 'falkorlib' 20 | 21 | # frozen_string_literal: true 22 | 23 | require 'bundler' 24 | require 'puppet_litmus/rake_tasks' if Gem.loaded_specs.key? 'puppet_litmus' 25 | require 'puppetlabs_spec_helper/rake_tasks' 26 | require 'puppet-syntax/tasks/puppet-syntax' 27 | 28 | ## placeholder for custom configuration of FalkorLib.config.* 29 | ## See https://github.com/Falkor/falkorlib 30 | 31 | # Adapt the versioning aspects 32 | FalkorLib.config.versioning do |c| 33 | c[:type] = 'puppet_module' 34 | end 35 | 36 | # Adapt the Git flow aspects 37 | FalkorLib.config.gitflow do |c| 38 | c[:branches] = { 39 | :master => 'production', 40 | :develop => 'devel' 41 | } 42 | end 43 | 44 | desc "Update changelog using gitchangelog https://pypi.org/project/gitchangelog/" 45 | task :gitchangelog do |t| 46 | info "#{t.comment}" 47 | run %{gitchangelog > CHANGELOG.md} 48 | info "=> about to commit changes in CHANGELOG.md" 49 | really_continue? 50 | FalkorLib::Git.add('CHANGELOG.md', 'Synchronize Changelog with latest commits') 51 | end 52 | namespace :pdk do 53 | ##### pdk:{build,validate} #### 54 | [ 'build', 'validate'].each do |action| 55 | desc "Run pdk #{action}" 56 | task action.to_sym do |t| 57 | info "#{t.comment}" 58 | run %{pdk #{action}} 59 | end 60 | end 61 | end # namespace pdk 62 | 63 | ########### up ########### 64 | desc "Update your local branches" 65 | task :up do |t| 66 | info "#{t.comment}" 67 | FalkorLib::Git.fetch 68 | branches = FalkorLib::Git.list_branch 69 | #puts branches.to_yaml 70 | unless FalkorLib::Git.dirty? 71 | FalkorLib.config.gitflow[:branches].each do |t, br| 72 | info "updating Git Flow #{t} branch '#{br}' with the 'origin' remote" 73 | run %{ git checkout #{br} && git merge origin/#{br} } 74 | end 75 | run %{ git checkout #{branches[0]} } # Go back to the initial branch 76 | else 77 | warning "Unable to update -- your local repository copy is dirty" 78 | end 79 | 80 | end # task up 81 | 82 | require 'falkorlib/tasks/git' 83 | 84 | task 'validate' => 'pdk:validate' 85 | %w(major minor patch).each do |level| 86 | task "version:bump:#{level}" => 'validate' 87 | end 88 | Rake::Task["version:release"].enhance do 89 | Rake::Task["gitchangelog"].invoke 90 | Rake::Task["pdk:build"].invoke 91 | end 92 | 93 | require 'puppet-strings/tasks' if Gem.loaded_specs.key? 'puppet-strings' 94 | 95 | PuppetLint.configuration.send('disable_relative') 96 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 1.1.x.{build} 3 | skip_branch_with_pr: true 4 | branches: 5 | only: 6 | - main 7 | - release 8 | skip_commits: 9 | message: /^\(?doc\)?.*/ 10 | clone_depth: 10 11 | init: 12 | - SET 13 | - 'mkdir C:\ProgramData\PuppetLabs\code && exit 0' 14 | - 'mkdir C:\ProgramData\PuppetLabs\facter && exit 0' 15 | - 'mkdir C:\ProgramData\PuppetLabs\hiera && exit 0' 16 | - 'mkdir C:\ProgramData\PuppetLabs\puppet\var && exit 0' 17 | environment: 18 | matrix: 19 | - 20 | RUBY_VERSION: 25-x64 21 | CHECK: validate lint check rubocop 22 | - 23 | PUPPET_GEM_VERSION: ~> 6.0 24 | RUBY_VERSION: 25 25 | CHECK: parallel_spec 26 | - 27 | PUPPET_GEM_VERSION: ~> 6.0 28 | RUBY_VERSION: 25-x64 29 | CHECK: parallel_spec 30 | matrix: 31 | fast_finish: true 32 | install: 33 | - set PATH=C:\Ruby%RUBY_VERSION%\bin;%PATH% 34 | - bundle install --jobs 4 --retry 2 --without system_tests 35 | - type Gemfile.lock 36 | build: off 37 | test_script: 38 | - bundle exec puppet -V 39 | - ruby -v 40 | - gem -v 41 | - bundle -v 42 | - bundle exec rake %CHECK% 43 | notifications: 44 | - provider: Email 45 | to: 46 | - nobody@nowhere.com 47 | on_build_success: false 48 | on_build_failure: false 49 | on_build_status_changed: false 50 | -------------------------------------------------------------------------------- /data/common.yaml: -------------------------------------------------------------------------------- 1 | --- {} 2 | -------------------------------------------------------------------------------- /data/os/RedHat/9.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | # EL9 moves the development packages to these repos 3 | slurm::package_install_options: 4 | - '--enablerepo=plus' 5 | - '--enablerepo=crb' 6 | -------------------------------------------------------------------------------- /docs/contacts.md: -------------------------------------------------------------------------------- 1 | This Puppet Module has been implemented in the context of the [UL HPC](http://hpc.uni.lu) Platform of the [University of Luxembourg](http://www.uni.lu). 2 | More precisely, the [UL HPC Team](https://hpc.uni.lu/about/team.html#system-administrators) took care of the development for this module. 3 | 4 | You can submit bug / issues / feature request using the [slurm Puppet Module Tracker](https://github.com/ULHPC/puppet-slurm/issues). 5 | Alternatively, you can contact them on the following email address: `hpc-sysadmins@uni.lu` 6 | -------------------------------------------------------------------------------- /docs/contributing/index.md: -------------------------------------------------------------------------------- 1 | This project is released under the terms of the [Apache-2.0 Licence](LICENSE). 2 | So you are more than welcome to contribute to its development as follows: 3 | 4 | 1. Fork it 5 | 2. Create your feature branch (`rake git:feature:start[]`) 6 | 3. Commit your changes (`git commit -am 'Added some feature'`) 7 | 4. Push to the branch (`git flow feature publish `) 8 | 5. Create new Pull Request 9 | 10 | This assumes that you have understood the [directory tree structure](layout.md) of this Puppet module. 11 | 12 | There is also a number of pre-requisite programs / framework you shall install to be able to correctly contribute to this Puppet module. This is detailed in the [Repository Setup and Developments](setup.md) page. 13 | 14 | Finally, you shall be aware of the way the [semantic versioning](versioning.md) procedure of this Puppet module are handled. 15 | -------------------------------------------------------------------------------- /docs/contributing/layout.md: -------------------------------------------------------------------------------- 1 | The directory hosting the implementation of this puppet module is organized as follows: 2 | 3 | ``` 4 | .gitignore # Git ignore file 5 | .ruby-{version,gemset} # [RVM](https://rvm.io/) configuration 6 | .vagrant_init.rb # Vagrant provisionner to test this module 7 | ├── Gemfile[.lock] # [Bundler](http://bundler.io/) configuration 8 | ├── LICENSE # Licence file 9 | ├── README.md # This file 10 | ├── Rakefile # Definition of the [rake](https://github.com/jimweirich/rake) tasks 11 | ├── Vagrantfile # Pilot Vagrant to test this module 12 | ├── docs/ # [Read the Docs](readthedocs.org) main directory 13 | ├── files/ # (eventually) Contains static files, which managed nodes can download 14 | ├── lib/ # (eventually) Custom facts/type/provider definitions 15 | ├── manifests/ 16 | │   ├── init.pp # Main manifests file which defines the class 17 | │   ├── common/ 18 | │   │   ├── debian.pp # Specific Debian setup for the main class 19 | │   │   └── redhat.pp # Specific Redhat setup for the main class 20 | │   ├── common.pp # Common class setup for all OS 21 | │   ├── ... # Implementation of the other slurm::* classes / definitions 22 | │   └── params.pp # Class parameters 23 | ├── metadata.json # Puppet module configuration file -- See http://tinyurl.com/puppet-metadata-json 24 | ├── mkdocs.yml # [Read the Docs](readthedocs.org) configuration 25 | ├── pkg/ # Hold build packages to be published on the [Puppet forge](https://forge.puppet.com/ULHPC/slurm) 26 | ├── spec/ # (eventually) [Rspec](https://www.relishapp.com/rspec/) tests 27 | ├── templates/ # (eventually) Module ERB template files 28 | └── tests/ # Tests cases for the module usage 29 | ├── .pp # Sample testing manifest 30 | └── vagrant/ # Place-holder for the vagrant deployment 31 | ├── config.yaml # Custom vagrant config overwritting defaults (not versionned) 32 | ├── config.yaml.sample # Sample example of the vagrant settings 33 | ├── puppet/ # Placeholder for vagrant puppet apply provisionning 34 | │ ├── hiera.yaml # Hiera configuration 35 | │ ├── hieradata/ # Hiera datadir 36 | │ ├── modules/ # puppet modules required for this one 37 | │ └── site/ # puppet profiles 38 | ├── rpmbuild/ # cross-VM shared directory for built RPMs 39 | ├── scripts/ # provisioning scripts 40 | └── shared/ # cross-VM shared directory 41 | ``` 42 | 43 | Globally, this module follows the [official PuppetLabs guidelines for the predictable directory tree structure of Puppet modules](http://docs.puppetlabs.com/puppet/latest/reference/modules_fundamentals.html#module-layout). 44 | -------------------------------------------------------------------------------- /docs/contributing/setup.md: -------------------------------------------------------------------------------- 1 | There is a number of pre-requisite programs / framework you shall install to be able to correctly contribute to this Puppet module. 2 | 3 | ### Git Branching Model 4 | 5 | The Git branching model for this repository follows the guidelines of [gitflow](http://nvie.com/posts/a-successful-git-branching-model/). 6 | In particular, the central repository holds two main branches with an infinite lifetime: 7 | 8 | * `production`: the branch holding tags of the successive releases of this tutorial 9 | * `devel`: the main branch where the sources are in a state with the latest delivered development changes for the next release. This is the *default* branch you get when you clone the repository, and the one on which developments will take places. 10 | 11 | You should therefore install [git-flow](https://github.com/nvie/gitflow), and probably also its associated [bash completion](https://github.com/bobthecow/git-flow-completion). 12 | 13 | ### Ruby, [RVM](https://rvm.io/) and [Bundler](http://bundler.io/) 14 | 15 | The various operations that can be conducted from this repository are piloted 16 | from a `Rakefile` and assumes you have a running Ruby installation. 17 | 18 | The bootstrapping of your repository is based on [RVM](https://rvm.io/), **thus 19 | ensure this tools are installed on your system** -- see 20 | [installation notes](https://rvm.io/rvm/install). 21 | 22 | The ruby stuff part of this repository corresponds to the following files: 23 | 24 | * `.ruby-{version,gemset}`: [RVM](https://rvm.io/) configuration, use the name of the 25 | project as [gemset](https://rvm.io/gemsets) name 26 | * `Gemfile[.lock]`: used by `[bundle](http://bundler.io/)` 27 | 28 | ### Repository Setup 29 | 30 | Then, to make your local copy of the repository ready to use the [git-flow](https://github.com/nvie/gitflow) workflow and the local [RVM](https://rvm.io/) setup, you have to run the following commands once you cloned it for the first time: 31 | 32 | $> gem install bundler # assuming it is not yet available 33 | $> bundle install 34 | $> rake -T # To list the available tasks 35 | $> rake setup 36 | 37 | You probably wants to activate the bash-completion for rake tasks. 38 | I personnaly use the one provided [here](https://github.com/ai/rake-completion) 39 | 40 | Also, some of the tasks are hidden. Run `rake -T -A` to list all of them. 41 | 42 | ### RSpec tests 43 | 44 | A set of unitary tests are defined to validate the different function of my library using [Rspec](http://rspec.info/) 45 | 46 | You can run these tests by issuing: 47 | 48 | $> rake rspec # NOT YET IMPLEMENTED 49 | 50 | By conventions, you will find all the currently implemented tests in the `spec/` directory, in files having the `_spec.rb` suffix. This is expected from the `rspec` task of the `Rakefile`. 51 | 52 | **Important** Kindly stick to this convention, and feature tests for all definitions/classes/modules you might want to add. 53 | -------------------------------------------------------------------------------- /docs/contributing/versioning.md: -------------------------------------------------------------------------------- 1 | The operation consisting of releasing a new version of this repository is 2 | automated by a set of tasks within the `Rakefile`. 3 | 4 | In this context, a version number have the following format: 5 | 6 | .. 7 | 8 | where: 9 | 10 | * `< major >` corresponds to the major version number 11 | * `< minor >` corresponds to the minor version number 12 | * `< patch >` corresponds to the patching version number 13 | 14 | Example: `1.2.0` 15 | 16 | The current version number is stored in the file `metadata.json`. 17 | For more information on the version, run: 18 | 19 | $> rake version:info 20 | 21 | If a new version number such be bumped, you simply have to run: 22 | 23 | $> rake version:bump:{major,minor,patch} 24 | 25 | This will start the release process for you using `git-flow`. 26 | Then, to make the release effective, just run: 27 | 28 | $> rake version:release 29 | 30 | This will finalize the release using `git-flow`, create the appropriate tag and merge all things the way they should be. 31 | -------------------------------------------------------------------------------- /docs/index.md: -------------------------------------------------------------------------------- 1 | -*- mode: markdown; mode: visual-line; -*- 2 | 3 | # slurm Puppet Module 4 | 5 | [![Puppet Forge](http://img.shields.io/puppetforge/v/slurm.svg)](https://forge.puppet.com/ULHPC/slurm) 6 | [![License](http://img.shields.io/:license-Apache2.0-blue.svg)](LICENSE) 7 | ![Supported Platforms](http://img.shields.io/badge/platform-debian-lightgrey.svg) 8 | [![Documentation Status](https://readthedocs.org/projects/ulhpc-puppet-slurm/badge/?version=latest)](https://readthedocs.org/projects/ulhpc-puppet-slurm/?badge=latest) 9 | [![By ULHPC](https://img.shields.io/badge/by-ULHPC-blue.svg)](http://hpc.uni.lu) 10 | 11 | Copyright (c) 2017-2019 UL HPC Team 12 | 13 | | [Project Page](https://github.com/ULHPC/puppet-slurm) | [Documentation](http://ulhpc-puppet-slurm.readthedocs.org/en/latest/) | [Issues](https://github.com/ULHPC/puppet-slurm/issues) | 14 | 15 | 16 | ----------- 17 | The [slurm](https://github.com/ULHPC/puppet-slurm) puppet module has been designed to configure and manage slurm: a highly scalable resource manager 18 | 19 | This is the main page of the documentation for this Puppet module, which is hosted and managed by [Read the Docs](http://slurm.readthedocs.org/en/latest/). 20 | It proposes to detail the following elements: 21 | 22 | * An [Overview](overview.md) of the module is proposed, describing the puppet classes and/or definitions it implements. 23 | - you might also wish to check the `tests/` directory for sample test cases 24 | * How to [test this module with Vagrant](vagrant.md) 25 | * How to [contribute](contributing/index.md) to this puppet module development. In particular, we detail: 26 | - the [directory tree structure](contributing/layout.md) 27 | - the steps to follow to [setup this repository](contributing/setup.md) 28 | - information as regard the [semantic versioning](contributing/versioning.md) of this Puppet module. 29 | - Apart form the directory layout, we will cover various configuration aspects ([git-flow](https://github.com/nvie/gitflow), [RVM](https://rvm.io/), [Bundler](http://bundler.io/) etc.) 30 | * Details on the [Read the Docs](http://ulhpc-puppet-slurm.readthedocs.org/en/latest/) management. 31 | -------------------------------------------------------------------------------- /docs/rtfd.md: -------------------------------------------------------------------------------- 1 | The documentation for this puppet module is handled by [Read the Docs](https://readthedocs.org/), a web service dedicated to documentation management for the open source community. 2 | 3 | * [Reference documentation](https://docs.readthedocs.org/en/latest/) 4 | 5 | By default, the [puppet-slurm](https://github.com/ULHPC/puppet-slurm) repository is bound to the [ulhpc-puppet-slurm](http://ulhpc-puppet-slurm.rtfd.org) project on Read the Docs (to avoid confusion with other slurm projects). 6 | 7 | You might wish to generate locally the docs: 8 | 9 | * Install [`mkdocs`](http://www.mkdocs.org/#installation) 10 | * Preview your documentation from the project root by running `mkdocs serve` and visite with your favorite browser the URL `http://localhost:8000` 11 | * build the full documentation locally by running `mkdocs build` 12 | 13 | 14 | -------------------------------------------------------------------------------- /docs/vagrant.md: -------------------------------------------------------------------------------- 1 | -*- mode: markdown; mode: visual-line; -*- 2 | 3 | # Slurm Puppet Module Tests with Vagrant 4 | 5 | The best way to test this module in a non-intrusive way is to rely on [Vagrant](http://www.vagrantup.com/). 6 | [Vagrant](http://vagrantup.com/) uses [Oracle's VirtualBox](http://www.virtualbox.org/) 7 | to build configurable, lightweight, and portable virtual machines dynamically. 8 | 9 | * [Reference installation notes](http://docs.vagrantup.com/v2/installation/) -- assuming you have installed [Oracle's VirtualBox](http://www.virtualbox.org/) 10 | * [installation notes on Mac OS](http://sourabhbajaj.com/mac-setup/Vagrant/README.html) using [Homebrew](http://brew.sh/) and [Cask](http://sourabhbajaj.com/mac-setup/Homebrew/Cask.html) 11 | 12 | The `Vagrantfile` at the root of the repository pilot the provisioning of a virtual cluster configuring Slurm from the puppet provisionning capability of Vagrant over _this_ module. 13 | In particular, by default, the following boxes will be deployed upon `vagrant up`: 14 | 15 | * `slurm-master`: 1 Slurm controller (_i.e._ a head node (running the `slurmctld` daemon) as well as the Slurm accounting DB _i.e._ `slurmdbd`) 16 | * `access`: 1 login node 17 | * `node-[1-2]`: 2 compute nodes (running the `slurmd` daemon) 18 | 19 | Of course, if you simply want to make a quick test on slurm.conf parameters, you simply need to deploy the `slurm-master` VM as follows: 20 | 21 | ``` 22 | vagrant up slurm-master 23 | ``` 24 | 25 | You can change the default settings of the deployment by overwriting them in the special file `tests/vagrant/config.yaml` (see `config.yaml.sample` as an example of all the settings you can pilot). 26 | More precisely, the [Hiera hierachy](https://github.com/ULHPC/puppet-slurm/blob/devel/tests/vagrant/puppet/hiera.yaml) places `hieradata/custom.yaml` (not tracked by default in the Git repository) at the highest hierachy to allow for quick and fast tests. 27 | 28 | For instance, to deploy 4 compute nodes instead of 2, you just need to use: 29 | 30 | ```yaml 31 | # -*- mode: yaml; -*- 32 | # Time-stamp: 33 | ################################################################################ 34 | # Complementary configuration for Vagrant 35 | # You can overwrite here the default settings defined in ../../Vagrantfile and 36 | # rework the SLURM configuration and VM deployed (i.e. the characteristics of 37 | # the virtual cluster deployed) 38 | # See config.yaml.sample for all possible settings 39 | 40 | :defaults: 41 | :nnodes: 4 42 | ``` 43 | 44 | You can also tweak the slurm partitions of their TRES settings. Ex: 45 | 46 | ```yaml 47 | :defaults: 48 | :nnodes: 4 49 | 50 | # Which Trackable RESources (TRES) will be tracked in addition to 51 | # billing, cpu, energy, memory and node 52 | slurm::accountingstorageTRES: gres/gpu,gres/gpu:volta 53 | 54 | slurm::partitions: 55 | 'DEFAULT': 56 | TRESbillingweights: 'CPU=1.0,Mem=0.25G,GRES/gpu=15.0' 57 | content: State=UP AllowGroups=clusterusers AllowAccounts=ALL DisableRootJobs=YES OverSubscribe=NO 58 | 'admin': 59 | priority: 100 60 | nodes: 'node-[1-4]' 61 | content: Hidden=YES DefaultTime=0-10:00:00 MaxTime=5-00:00:00 MaxNodes=UNLIMITED AllowQos=qos-admin 62 | 'interactive': 63 | priority: 20 64 | nodes: 'node-1' 65 | content: DefaultTime=0-1:00:00 MaxTime=0-4:00:00 AllowQos=qos-besteffort,qos-interactive DefMemPerCPU=400 MaxMemPerCPU=400 66 | 'batch': 67 | priority: 20 68 | nodes: 'node-[2-4]' 69 | content: DefaultTime=0-2:00:00 MaxTime=5-00:00:00 MaxNodes=UNLIMITED Default=YES AllowQos=qos-besteffort,qos-batch DefMemPerCPU=400 MaxMemPerCPU=400 70 | ``` 71 | 72 | Then you just need to provision the VMs using the [vagrant puppet apply provisionning](https://www.vagrantup.com/docs/provisioning/puppet_apply.html) 73 | 74 | 75 | vagrant provision --provision-with puppet [slurm-master] 76 | 77 | ## Default cluster deployment 78 | 79 | By default, the following boxes are deployed: 80 | 81 | ``` 82 | $> vagrant status 83 | Current machine states: 84 | 85 | slurm-master not created (virtualbox) 86 | access not created (virtualbox) 87 | node-1 not created (virtualbox) 88 | node-2 not created (virtualbox) 89 | 90 | This environment represents multiple VMs. The VMs are all listed 91 | above with their current state. For more information about a specific 92 | VM, run `vagrant status NAME`. 93 | 94 | $> vagrant up 95 | [...] 96 | +--------------|--------------------------|---------|----------|------------|-------------------------------|-------------+ 97 | | Puppet Testing infrastructure deployed on Vagrant | 98 | +--------------|--------------------------|---------|----------|------------|-------------------------------|-------------+ 99 | | Name | Hostname | OS | vCPU/RAM | Role | Description | IP | 100 | +--------------|--------------------------|---------|----------|------------|-------------------------------|-------------+ 101 | | slurm-master | slurm-master.vagrant.dev | centos7 | 2/2048 | controller | Slurm Controller #1 (primary) | 10.10.1.11 | 102 | | access | access.vagrant.dev | centos7 | 1/1024 | login | Cluster frontend | 10.10.1.2 | 103 | | node-1 | node-1.vagrant.dev | centos7 | 2/512 | node | Computing Node #1 | 10.10.1.101 | 104 | | node-2 | node-2.vagrant.dev | centos7 | 2/512 | node | Computing Node #2 | 10.10.1.102 | 105 | +--------------|--------------------------|---------|----------|------------|-------------------------------|-------------+ 106 | - Virtual Puppet Testing infrastructure deployed deployed! 107 | ``` 108 | 109 | You can ssh into any of the deployed machine afterwards: 110 | 111 | ```bash 112 | $> vagrant ssh [slurm-master | access | node-1 | node-2] 113 | ``` 114 | 115 | ## Vagrant boxes provisioning 116 | 117 | When you run `vagrant up ` to boot the VM, the following default provisioning are applied (shell scripts are located in `tests/vagrant/scripts/`): 118 | 119 | | Script | Type | Description | 120 | |---------------------------------|--------|-------------------------------------------------------------------------------| 121 | | `bootstrap.sh` | shell | Install puppet 4 and defaults packages and gems | 122 | | `puppet_modules_setup.rb` | shell | pre-install the necessary puppet modules in `tests/vagrant/puppet/modules/` | 123 | | `setup_testing_users_groups.sh` | shell | setup testing group `clusterusers` and users `user-[1-2]` | 124 | | | puppet | `default.pp`, profile-based deployment depending on the `role` | 125 | | inline | shell | create cluster and qos for the slurm accounting (if role is `controller`) | 126 | | `setup_slurm_accounting.sh` | shell | create cluster, default account and a set of users in the slurm accounting DB | 127 | | | | | 128 | 129 | It is worth to note the way the `puppet_modules_setup.rb` script behaves as this script is responsible for two main tasks: 130 | 131 | 1. pre-install the puppet modules listed as dependencies in `metadata.json` using [`librarian-puppet`](https://librarian-puppet.com/) under `tests/vagrant/puppet/modules/` 132 | 2. make the appropriate symbolic link `tests/vagrant/puppet/modules/slurm` (pointing to `/vagrant`) to ensure you can directly make changes and correct your own module transparently within the box. 133 | 134 | ## Testing manifests 135 | 136 | You can test the manifests of the `tests/` directory within the VM: 137 | 138 | $> vagrant ssh 139 | [...] 140 | (vagrant)$> sudo puppet apply -t /vagrant/tests/init.pp 141 | 142 | From now on, you can test (with --noop) the other manifests. 143 | -------------------------------------------------------------------------------- /files/limits.memlock: -------------------------------------------------------------------------------- 1 | # -*- mode: conf -*- 2 | ################################################################################ 3 | # SLURM limits (on memlock) 4 | # Time-stamp: 5 | # 6 | # Copyright (c) 2017 UL HPC Team 7 | ################################################################################ 8 | # Configure MEMLOCK limits to unlimited, needed by MPI 9 | # 10 | 11 | * hard memlock unlimited 12 | * soft memlock unlimited 13 | -------------------------------------------------------------------------------- /hiera.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | version: 5 3 | 4 | defaults: # Used for any hierarchy level that omits these keys. 5 | datadir: data # This path is relative to hiera.yaml's directory. 6 | data_hash: yaml_data # Use the built-in YAML backend. 7 | 8 | hierarchy: 9 | - name: "osfamily/major release" 10 | paths: 11 | # Used to distinguish between Debian and Ubuntu 12 | - "os/%{facts.os.name}/%{facts.os.release.major}.yaml" 13 | - "os/%{facts.os.family}/%{facts.os.release.major}.yaml" 14 | # Used for Solaris 15 | - "os/%{facts.os.family}/%{facts.kernelrelease}.yaml" 16 | - name: "osfamily" 17 | paths: 18 | - "os/%{facts.os.name}.yaml" 19 | - "os/%{facts.os.family}.yaml" 20 | - name: 'common' 21 | path: 'common.yaml' 22 | -------------------------------------------------------------------------------- /lib/facter/is_vagrant.rb: -------------------------------------------------------------------------------- 1 | Facter.add(:is_vagrant) do 2 | confine is_virtual: true 3 | setcode do 4 | File.directory?('/vagrant') 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /manifests/accounting.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: munge.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Class: slurm::accounting 11 | # 12 | # Setup the accounting structure 13 | # 14 | #@param ensure 15 | # Ensure the presence (or absence) of the Munge service - Default: 'present'. 16 | # 17 | class slurm::accounting ( 18 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 19 | Optional[String] $cluster = undef, 20 | Optional[String] $qos = undef, 21 | Optional[String] $account = undef, 22 | ) 23 | inherits slurm::params { 24 | ### Clusters 25 | $clusters = $cluster ? { 26 | undef => $slurm::clustername, 27 | default => $cluster 28 | } 29 | if $clusters.is_a(String) or $clusters.is_a(Array) { 30 | slurm::acct::cluster { $clusters: 31 | ensure => $ensure, 32 | } 33 | } 34 | elsif $clusters.is_a(Hash) { 35 | $clusters.each |$k, $v| { 36 | slurm::acct::cluster { $k: 37 | ensure => $ensure, 38 | options => $v, 39 | } 40 | } 41 | } 42 | 43 | ### QOS 44 | # Make the default qos out of the partitions definitions 45 | $slurm::partitions.each |$partition, $h| { 46 | if $partition != 'DEFAULT' { 47 | $qosname = "qos-${partition}" 48 | slurm::acct::qos { $qosname: 49 | ensure => $ensure, 50 | priority => ($h['priority'] + 0), 51 | } 52 | # Eventually complete it with entries from the $slurm::qos hash 53 | unless empty($qos) { 54 | if $slurm::qos[$qosname] { 55 | Slurm::Acct::Qos[$qosname] { 56 | options => $slurm::qos[$qosname], 57 | } 58 | } 59 | } 60 | } 61 | } 62 | $qoses = $qos ? { 63 | undef => $slurm::qos, 64 | default => $qos, 65 | } 66 | # Complete with the explicit qos hash 67 | $qoses.each |$qosname, $h| { 68 | unless $slurm::partitions[regsubst($qosname, '^qos-', '')] { 69 | slurm::acct::qos { $qosname: 70 | ensure => $ensure, 71 | } 72 | if $h.is_a(String) { 73 | Slurm::Acct::Qos[$qosname] { 74 | content => $h, 75 | } 76 | } 77 | else { 78 | Slurm::Acct::Qos[$qosname] { 79 | options => $h, 80 | } 81 | } 82 | } 83 | } 84 | # if $qos != undef { 85 | # if $qos.is_a(String) or $qos.is_a(Array) { 86 | # slurm::acct::qos{ $qos: 87 | # ensure => $ensure, 88 | # } 89 | # } 90 | # elsif $qos.is_a(Hash) { 91 | # $qos.each |$k, $v| { 92 | # slurm::acct::qos{ $k: 93 | # ensure => $ensure, 94 | # } 95 | # unless $v == undef { 96 | # Slurm::Acct::Qos[$k] { 97 | # options => $v, 98 | # } 99 | # } 100 | # } 101 | # } 102 | # } 103 | } 104 | -------------------------------------------------------------------------------- /manifests/acct/account.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: acct/account.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::acct::account 11 | # 12 | # This definition takes care of adding (or removing) a Slurm bank account, 13 | # typically specified at job submit time using the --account= option. These may 14 | # be arranged in a hierarchical fashion, for example accounts chemistry and 15 | # physics may be children of the account science. The hierarchy may have an 16 | # arbitrary depth. 17 | # 18 | # /!\ WARNING: this assumes you are using the MySQL plugin as SlurmDBD plugin 19 | # and a working SLURMDBD. 20 | # The name of this resource is expected to be the qos name. 21 | # 22 | # @param ensure 23 | # Ensure the presence (or absence) of the entity - Default: 'present' 24 | # @param cluster [String] Default: 'cluster' 25 | # Cluster name on which the specified resources are to be available 26 | # @param options [Hash] Default: {} 27 | # Specification options -- see https://slurm.schedmd.com/sacctmgr.html 28 | # Elligible keys: Clusters=, DefaultQOS=, Description=, Fairshare=, 29 | # GrpTRESMins=, GrpTRES=, GrpJobs=, GrpMemory=, 30 | # GrpNodes=, GrpSubmitJob=, GrpWall=, MaxTRESMins=, 31 | # MaxTRES=, MaxJobs=, MaxNodes=, MaxSubmitJobs=, 32 | # MaxWall=, Names=, Organization=, Parent=, 33 | # and QosLevel= 34 | define slurm::acct::account ( 35 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 36 | String $cluster = '', 37 | Hash $options = {}, 38 | ) { 39 | $real_clustername = empty($slurm::clustername) ? { 40 | true => '', 41 | default => $slurm::clustername, 42 | } 43 | $default_options = empty($real_clustername) ? { 44 | true => {}, 45 | default => { 'cluster' => $real_clustername, }, 46 | } 47 | slurm::acct::mgr { "acccount/${name}": 48 | ensure => $ensure, 49 | entity => 'account', 50 | value => $name, 51 | options => merge($default_options, $options), 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /manifests/acct/cluster.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: acct/cluster.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::acct::cluster 11 | # 12 | # This definition takes care of adding (or removing) a cluster to the slurm database. 13 | # /!\ WARNING: this assumes you are using the MySQL plugin as SlurmDBD plugin and a working SLURMDBD. 14 | # The name of this resource is expected to be the cluster name. 15 | # 16 | # @param ensure 17 | # Ensure the presence (or absence) of the entity - Default: 'present' 18 | # @param options [Hash] Default: {} 19 | # Specification options -- see https://slurm.schedmd.com/sacctmgr.html 20 | # Elligible keys: # Classification, Cluster, ClusterNodes, 21 | # ControlHost, ControlPort, DefaultQOS, 22 | # Fairshare, Flags, GrpTRESMins, GrpTRES GrpJobs, 23 | # GrpMemory, GrpNodes, GrpSubmitJob, MaxTRESMins, 24 | # MaxTRES, MaxJobs, MaxNodes, MaxSubmitJobs, 25 | # MaxWall, NodeCount, PluginIDSelect, RPC, TRES 26 | # 27 | # @example Adding the cluster 'thor' to Slurm 28 | # 29 | # slurm::acct::cluster { 'thor': 30 | # ensure => 'present', 31 | # } 32 | # 33 | # TODO/ from the manpage, we can provide the following options to this definition 34 | # 35 | # 36 | define slurm::acct::cluster ( 37 | Enum['present', 'absent'] $ensure = $slurm::ensure, 38 | Hash $options = {} 39 | ) { 40 | slurm::acct::mgr { "cluster/${name}": 41 | ensure => $ensure, 42 | entity => 'cluster', 43 | value => $name, 44 | options => $options, 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /manifests/acct/mgr.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: acct/mgr.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::acct::mgr 11 | # 12 | # Generic wrapper for all sacctmgr commands 13 | # See https://slurm.schedmd.com/sacctmgr.html 14 | # 15 | # /!\ WARNING: this assumes you are using the MySQL plugin as SlurmDBD plugin 16 | # and a working SLURMDBD. 17 | # 18 | # @param ensure 19 | # Ensure the presence (or absence) of the cluster - Default: 'present' 20 | # @param entity 21 | # the entity to consider for the name of this resource. 22 | # Elligible values in [ 'account', 23 | # 'association', 24 | # 'cluster', 25 | # 'coordinator', 26 | # 'event', 27 | # 'job', 28 | # 'qos', 29 | # 'Resource', 30 | # 'RunawayJobs', 31 | # 'stats', 32 | # 'transaction', 33 | # 'user', 34 | # 'wckeys', ] 35 | # @param value [String] 36 | # Value to associate to the entity. Uses $name by default 37 | # @param content [String] Default: '' 38 | # Eventual content as a string for the specifications of the entity. 39 | # You probably SHOULDN'T mix this with the options 40 | # @param options [Hash] Default: {} 41 | # Specification options, preferably as a hash -- depends on the entity 42 | # See https://slurm.schedmd.com/sacctmgr.html 43 | # 44 | define slurm::acct::mgr ( 45 | Enum['present','absent'] $ensure = $slurm::params::ensure, 46 | Slurm::Entity $entity = '', 47 | String $value = '', 48 | String $content = '', 49 | Optional[Hash] $options = undef, 50 | ) { 51 | include slurm 52 | include slurm::params 53 | 54 | $action = $ensure ? { 55 | 'absent' => 'del', 56 | default => 'add', 57 | } 58 | $real_name = empty($value) ? { 59 | true => $name, 60 | default => $value, 61 | } 62 | $cmd_options = ($options == undef) ? { 63 | true => [], 64 | default => ($options.is_a(String) or $options.is_a(Array)) ? { 65 | true => flatten([$options]), 66 | default => $options.map |$k, $v| { 67 | $key = ($k =~ /[A-Z]/) ? { 68 | true => $k, 69 | default => camelcase($k), 70 | } 71 | if ($k == 'content') { 72 | $v 73 | } 74 | else { 75 | join([$key, $v], '=') 76 | } 77 | }, 78 | } 79 | } 80 | $opts = empty($content) ? { 81 | true => join($cmd_options, ' '), 82 | default => join(concat($content, $cmd_options), ' '), 83 | } 84 | case $ensure { 85 | 'absent': { 86 | $label = "delete-${entity}-${real_name}" 87 | $cmd = "sacctmgr -i del ${entity} ${real_name}" 88 | $check_unless = undef 89 | } 90 | default: { 91 | $label = "add-${entity}-${real_name}" 92 | $cmd = "sacctmgr -i add ${entity} ${real_name} ${opts}" 93 | $check_unless = "test -n \"$(sacctmgr --noheader -p list ${entity} | grep ${real_name})\"" 94 | } 95 | } 96 | if $slurm::service_manage { 97 | #notice($cmd) 98 | exec { $label: 99 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 100 | command => $cmd, 101 | unless => $check_unless, 102 | require => Class['slurm::config'], 103 | } 104 | } 105 | else { 106 | warning("SKIPPING Application of ${module_name}{'${label}'} as slurm::service_manage == ${slurm::service_manage}") 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /manifests/acct/qos.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: acct/qos.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::acct::qos 11 | # 12 | # This definition takes care of adding (or removing) a Quality of Service (QOS) 13 | # for each job submitted to Slurm. 14 | # For more details: see 15 | # 16 | # /!\ WARNING: this assumes you are using the MySQL plugin as SlurmDBD plugin 17 | # and a working SLURMDBD. 18 | # The name of this resource is expected to be the qos name. 19 | # 20 | # @param ensure 21 | # Ensure the presence (or absence) of the entity - Default: 'present' 22 | # @param priority [Integer] Default: 0 23 | # @param options [Hash] Default: {} 24 | # Specification options -- see https://slurm.schedmd.com/sacctmgr.html 25 | # Elligible keys: Description=, Flags=, GraceTime=, GrpJobs=, 26 | # GrpSubmitJob=, GrpTRES=, GrpTRESMins=, GrpWall=, 27 | # MaxJobs=, MaxSubmitJobsPerUser=, MaxTRESMins=, 28 | # MaxTRESPerJob=, MaxTRESPerNode=, MaxTRESPerUser=, 29 | # MaxWall=, Names=, Preempt=, PreemptMode=, 30 | # Priority=, UsageFactor=, and UsageThreshold= 31 | # 32 | # @example Adding the qos 'qos-interactive' to Slurm 33 | # 34 | # slurm::acct::qos { 'qos-interactive': 35 | # ensure => 'present', 36 | # priority => 20, 37 | # options => { 38 | # preempt => 'qos-besteffort', 39 | # grpnodes => 30, 40 | # } 41 | # } 42 | # 43 | # this will run the following command: 44 | # sacctmgr -i add qos qos-interactive Priority=20 Preempt=qos-besteffort Grpnodes=30 45 | # 46 | # @example 47 | define slurm::acct::qos ( 48 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 49 | Integer $priority = 0, 50 | String $content = '', 51 | Hash $options = {}, 52 | ) { 53 | $default_options = { 54 | 'priority' => $priority, 55 | } 56 | if $options == undef { 57 | $real_options = $default_options 58 | } 59 | elsif $options.is_a(String) { 60 | $real_options = ($options =~ /[pP]riority=/) ? { 61 | true => { 'content' => $options, }, 62 | default => merge($default_options, { 'content' => $options }), 63 | } 64 | } 65 | elsif $options.is_a(Array) { 66 | $real_options = merge($default_options, { content => join($options, ' ') }) 67 | } 68 | else { 69 | $real_options = merge($default_options, $options) 70 | } 71 | slurm::acct::mgr { "qos/${name}": 72 | ensure => $ensure, 73 | entity => 'qos', 74 | value => $name, 75 | options => $real_options, 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /manifests/acct/user.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: acct/user.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::acct::user 11 | # 12 | # This definition takes care of adding (or removing) a login name into Slurm. 13 | # Only lowercase usernames are supported. 14 | # 15 | # /!\ WARNING: this assumes you are using the MySQL plugin as SlurmDBD plugin 16 | # and a working SLURMDBD. 17 | # The name of this resource is expected to be the qos name. 18 | # 19 | # @param ensure 20 | # Ensure the presence (or absence) of the entity - Default: 'present' 21 | # @param $defaultaccount [String] 22 | # Identify the default bank account name to be used for a job if none is 23 | # specified at submission time. 24 | # @param options [Hash] Default: {} 25 | # Specification options -- see https://slurm.schedmd.com/sacctmgr.html 26 | # Elligible keys: 27 | # 28 | define slurm::acct::user ( 29 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 30 | String $defaultaccount = '', 31 | Hash $options = {}, 32 | ) { 33 | $default_options = empty($defaultaccount) ? { 34 | true => {}, 35 | default => { 'DefaultAccount' => $defaultaccount, } 36 | } 37 | slurm::acct::mgr { "user/${name}": 38 | ensure => $ensure, 39 | entity => 'user', 40 | value => $name, 41 | options => merge($default_options, $options), 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /manifests/build.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: build.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::build 11 | # 12 | # This definition takes care of building Slurm sources into RPMs using 'rpmbuild'. 13 | # It expect to get as resource name the SLURM version to build 14 | # This assumes the sources have been downloaded using slurm::download 15 | # 16 | # 17 | # @param ensure 18 | # Ensure the presence (or absence) of building - Default: 'present' 19 | # @param srcdir [String] Default: '/usr/local/src' 20 | # Where the [downloaded] Slurm sources are located 21 | # @param dir [String] Default: '/root/rpmbuild' on redhat systems 22 | # Top directory of the sources builds (i.e. RPMs, debs...) 23 | # For instance, built RPMs will be placed under 24 | # /RPMS/${::architecture} 25 | # @param with [Array] Default: [ 'lua', ... ] -- see slurm::params 26 | # see https://github.com/SchedMD/slurm/blob/master/slurm.spec 27 | # List of --with build options to pass to rpmbuild 28 | # @param without [Array] Default: [] -- see slurm::params 29 | # see https://github.com/SchedMD/slurm/blob/master/slurm.spec 30 | # List of --without build options to pass to rpmbuild 31 | # 32 | # @example Building version 19.05.3-2 of SLURM 33 | # 34 | # slurm::build { '19.05.3-2': 35 | # ensure => 'present', 36 | # srcdir => '/usr/local/src', 37 | # dir => '/root/rpmbuild', 38 | # with => [ 'hdf5', 'hwloc', lua', 'mysql', 'numa', 'pmix' ] 39 | # } 40 | # 41 | # This will typically run the following rpmbuild command: 42 | # 43 | # rpmbuild -ta --with hdf5 --with hwloc --with lua --with mysql --with numa --with pmix \ 44 | # --define "_topdir /root/rpmbuild" --define "_with_pmix --with-pmix=/usr" \ 45 | # /usr/local/src/slurm-19.05.3-2.tar.bz2 46 | # 47 | # and thus produce the following RPMs under /root/rpmbuild/RPMS/x86_64/: 48 | # 49 | # slurm-19.05.3-2.el7.x86_64.rpm 50 | # slurm-contribs-19.05.3-2.el7.x86_64.rpm 51 | # slurm-devel-19.05.3-2.el7.x86_64.rpm 52 | # slurm-example-configs-19.05.3-2.el7.x86_64.rpm 53 | # slurm-libpmi-19.05.3-2.el7.x86_64.rpm 54 | # slurm-openlava-19.05.3-2.el7.x86_64.rpm 55 | # slurm-pam_slurm-19.05.3-2.el7.x86_64.rpm 56 | # slurm-perlapi-19.05.3-2.el7.x86_64.rpm 57 | # slurm-slurmctld-19.05.3-2.el7.x86_64.rpm 58 | # slurm-slurmd-19.05.3-2.el7.x86_64.rpm 59 | # slurm-slurmdbd-19.05.3-2.el7.x86_64.rpm 60 | # slurm-torque-19.05.3-2.el7.x86_64.rpm 61 | # 62 | define slurm::build ( 63 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 64 | String $srcdir = $slurm::params::srcdir, 65 | String $dir = $slurm::params::builddir, 66 | Array $with = $slurm::params::build_with, 67 | Array $without = $slurm::params::build_without, 68 | ) { 69 | include slurm::params 70 | 71 | # $name is provided at define invocation 72 | $version = $name ? { 73 | Pattern[/\d+[\.-]?/] => $name, 74 | Integer => $name, 75 | default => fail("\$name must contain only digits, periods, and dashes") 76 | } 77 | 78 | # Path to the SLURM sources 79 | $src = "${srcdir}/slurm-${version}.tar.bz2" 80 | 81 | # Prepare the [RPM] build option 82 | $with_options = empty($with) ? { 83 | true => '', 84 | default => join(prefix($with, '--with '), ' ') 85 | } 86 | # NOT YET IMPLEMENTED: 87 | # if ('pmix' in $with) 88 | # find a way to set --with pmix=${slurm[::params]::pmix_install_path} 89 | # (by default, installed under /usr so all good...) 90 | 91 | $without_options = empty($without) ? { 92 | true => '', 93 | default => join(prefix($without, '--without '), ' ') 94 | } 95 | 96 | # Label for the exec 97 | $buildname = $ensure ? { 98 | 'absent' => "uninstall-slurm-${version}", 99 | default => "build-slurm-${version}", 100 | } 101 | 102 | # Management of PMIx 103 | if ($slurm::with_pmix or ('pmix' in $with)) { 104 | if !defined(Class['slurm::pmix']) { 105 | include slurm::pmix 106 | Class['slurm::pmix'] -> Exec[$buildname] 107 | # Slurm::Pmix::Install[$slurm::pmix::version] -> Exec[$buildname] 108 | } 109 | $define_pmix = "--define \"_with_pmix --with-pmix=${slurm::params::pmix_install_path}\"" 110 | } else { 111 | $define_pmix = '' 112 | } 113 | 114 | case $facts['os']['family'] { 115 | 'Redhat': { 116 | include epel 117 | include yum 118 | if !defined(Yum::Group[$slurm::params::groupinstall]) { 119 | yum::group { $slurm::params::groupinstall: 120 | ensure => 'present', 121 | timeout => 600, 122 | require => Class['epel'], 123 | } 124 | } 125 | Yum::Group[$slurm::params::groupinstall] -> Exec[$buildname] 126 | 127 | $rpmdir = "${dir}/RPMS/${facts['os']['architecture']}" 128 | $rpms = prefix(suffix(concat($slurm::params::common_rpms_basename, $slurm::params::slurmdbd_rpms_basename), 129 | "-${version}*.rpm"), "${rpmdir}/") 130 | # the below command should typically produce the following RPMs 131 | # slurm[-suffix]--1.el7.centos.x86_64.rpm 132 | case $ensure { 133 | 'absent': { 134 | $cmd = "rm -f ${rpmdir}/slurm*-${version}*.rpm" 135 | $check_onlyif = "test -n \"$(ls ${rpms[0]} 2>/dev/null)\"" 136 | $check_unless = undef 137 | } 138 | default: { 139 | $cmd = "rpmbuild -ta ${with_options} ${without_options} --define \"_topdir ${dir}\" ${define_pmix} ${src}" 140 | $check_onlyif = undef 141 | $check_unless = suffix(prefix($rpms, 'test -n "$(ls '), ' 2>/dev/null)"') 142 | #"test -n \"$(ls ${main_rpm} 2>/dev/null)\"" 143 | } 144 | } 145 | } 146 | default: { 147 | fail("Module ${module_name} is not supported on ${facts['os']['name']}") 148 | } 149 | } 150 | 151 | # notice($cmd) 152 | exec { $buildname: 153 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 154 | command => $cmd, 155 | cwd => '/root', 156 | user => 'root', 157 | timeout => 600, 158 | onlyif => $check_onlyif, 159 | unless => $check_unless, 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /manifests/common.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: common.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Class: slurm::common 11 | # 12 | # Base class to be inherited by the other slurm classes, containing the common code. 13 | # 14 | 15 | class slurm::common { 16 | # Load the variables used in this module. Check the params.pp file 17 | require slurm::params 18 | 19 | # Packages required for building SLURM 20 | $build_required_pkgs = if $slurm::do_build { 21 | concat($slurm::params::pre_requisite_packages, $slurm::params::munge_extra_packages) 22 | } else { 23 | [] 24 | } 25 | 26 | # Other packages for use with SLURM 27 | $required_pkgs = concat($build_required_pkgs, $slurm::params::extra_packages) 28 | 29 | $all_packages = $required_pkgs.filter |String $pkg_name| { 30 | # Safeguard to avoid incompatibility with other puppet modules 31 | !(Package[$pkg_name].defined) 32 | } 33 | 34 | package { $all_packages: 35 | ensure => 'present', 36 | install_options => $slurm::package_install_options, 37 | } 38 | 39 | # Prepare the user and group 40 | group { 'slurm': 41 | ensure => $slurm::ensure, 42 | name => $slurm::params::group, 43 | gid => $slurm::gid, 44 | } 45 | user { 'slurm': 46 | ensure => $slurm::ensure, 47 | name => $slurm::params::username, 48 | uid => $slurm::uid, 49 | gid => $slurm::gid, 50 | comment => $slurm::params::comment, 51 | home => $slurm::params::home, 52 | managehome => true, 53 | system => true, 54 | shell => $slurm::params::shell, 55 | } 56 | 57 | # Order 58 | if ($slurm::ensure == 'present') { 59 | Group['slurm'] -> User['slurm'] 60 | } 61 | else { 62 | User['slurm'] -> Group['slurm'] 63 | } 64 | 65 | if ($slurm::manage_pam and $slurm::use_pam and ($slurm::with_slurmd or defined(Class['slurm::slurmd']))) { 66 | include slurm::pam 67 | } 68 | 69 | if ($slurm::with_pmix or ('pmix' in $slurm::build_with)) { 70 | include slurm::pmix 71 | # class { '::slurm::pmix': 72 | # ensure => $slurm::ensure, 73 | # version => $slurm::pmix_version, 74 | # src_checksum => $slurm::pmix_src_checksum, 75 | # src_checksum_type => $slurm::pmix_src_checksum_type, 76 | # srcdir => $slurm::srcdir, 77 | # builddir => $slurm::builddir, 78 | # } 79 | } 80 | 81 | if ($slurm::manage_munge and $slurm::authtype =~ /munge/) { 82 | # include ::slurm::munge 83 | class { 'slurm::munge': 84 | ensure => $slurm::ensure, 85 | create_key => $slurm::munge_create_key, 86 | daemon_args => $slurm::munge_daemon_args, 87 | uid => $slurm::munge_uid, 88 | gid => $slurm::munge_gid, 89 | key_source => $slurm::munge_key_source, 90 | key_content => $slurm::munge_key_content, 91 | key_filename => $slurm::munge_key_filename, 92 | } 93 | if $slurm::ensure == 'absent' and $slurm::do_package_install { 94 | Slurm::Install::Packages[$slurm::version] -> Class['slurm::munge'] 95 | } 96 | } 97 | 98 | if $slurm::with_slurmdbd { 99 | include slurm::slurmdbd 100 | } 101 | if $slurm::with_slurmctld { 102 | include slurm::slurmctld 103 | } 104 | if $slurm::with_slurmd { 105 | include slurm::slurmd 106 | } 107 | } 108 | 109 | #} 110 | -------------------------------------------------------------------------------- /manifests/common/debian.pp: -------------------------------------------------------------------------------- 1 | # File:: common/debian.pp 2 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 3 | # Copyright:: Copyright (c) 2017 UL HPC Team 4 | # License:: Apache-2.0 5 | # 6 | # ------------------------------------------------------------------------------ 7 | # = Class: slurm::common::debian 8 | # 9 | # Specialization class for Debian systems 10 | class slurm::common::debian inherits slurm::common {} 11 | -------------------------------------------------------------------------------- /manifests/common/redhat.pp: -------------------------------------------------------------------------------- 1 | # File:: common/redhat.pp 2 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 3 | # Copyright:: Copyright (c) 2017 UL HPC Team 4 | # License:: Apache-2.0 5 | # 6 | # ------------------------------------------------------------------------------ 7 | # = Class: slurm::common::redhat 8 | # 9 | # Specialization class for Redhat systems 10 | class slurm::common::redhat inherits slurm::common { 11 | include epel 12 | include yum 13 | include selinux 14 | 15 | if $slurm::do_build { 16 | yum::group { $slurm::params::groupinstall: 17 | ensure => 'present', 18 | timeout => 600, 19 | require => Class['epel'], 20 | } 21 | 22 | # Resource default statements 23 | Package { 24 | require => Yum::Group[$slurm::params::groupinstall], 25 | } 26 | } 27 | 28 | if $slurm::manage_firewall and versioncmp($facts['os']['release']['major'], '7') >= 0 { 29 | include firewalld 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /manifests/config.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: config.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::config 11 | # 12 | # This PRIVATE class handles the configuration of SLURM daemons 13 | # More details on and also on 14 | # - https://slurm.schedmd.com/slurm.conf.html 15 | # - https://slurm.schedmd.com/slurmdbd.conf.html 16 | # - https://slurm.schedmd.com/topology.conf.html 17 | # - https://slurm.schedmd.com/cgroup.conf.html 18 | # 19 | class slurm::config { 20 | include slurm 21 | include slurm::params 22 | 23 | # Prepare the directory structure 24 | $pluginsdir = "${slurm::configdir}/${slurm::params::pluginsdir}" 25 | $slurmdirs = [ 26 | $slurm::configdir, 27 | $slurm::params::logdir, 28 | #$slurm::params::piddir, # NO support for specialized piddir as per service definitions 29 | # $pluginsdir, 30 | ] 31 | if $slurm::ensure == 'present' { 32 | file { $slurmdirs: 33 | ensure => 'directory', 34 | owner => $slurm::params::username, 35 | group => $slurm::params::group, 36 | mode => $slurm::params::configdir_mode, 37 | } 38 | # Plugins directory plugstack.conf.d 39 | File[$slurm::configdir] -> File[$pluginsdir] 40 | if ($slurm::pluginsdir_target != undef) { 41 | File[$pluginsdir] { 42 | ensure => 'link', 43 | } 44 | } else { 45 | File[$pluginsdir] { 46 | ensure => 'directory', 47 | target => 'notlink', 48 | } 49 | } 50 | file { $pluginsdir: 51 | target => $slurm::pluginsdir_target, 52 | owner => $slurm::params::username, 53 | group => $slurm::params::group, 54 | } 55 | if (!empty($slurm::plugins)) { 56 | $slurm::plugins.each |String $plugin| { 57 | file { "${pluginsdir}/${plugin}.conf": 58 | ensure => $slurm::ensure, 59 | owner => $slurm::params::username, 60 | group => $slurm::params::group, 61 | require => File[$pluginsdir], 62 | } 63 | if ($facts['os']['family'] == 'RedHat') { 64 | File["${pluginsdir}/${plugin}.conf"] { 65 | seltype => 'etc_t', 66 | } 67 | } 68 | } 69 | } 70 | } 71 | else { 72 | file { flatten([$slurmdirs, $pluginsdir]): 73 | ensure => $slurm::ensure, 74 | force => true, 75 | } 76 | File[$pluginsdir] -> File[$slurm::configdir] 77 | } 78 | 79 | # Now let's deal with slurm.conf 80 | $slurm_content = $slurm::content ? { 81 | undef => $slurm::source ? { 82 | undef => $slurm::target ? { 83 | undef => template('slurm/slurm.conf.erb'), 84 | default => $slurm::content, 85 | }, 86 | default => $slurm::content 87 | }, 88 | default => $slurm::content, 89 | } 90 | $ensure = $slurm::target ? { 91 | undef => $slurm::ensure, 92 | default => 'link', 93 | } 94 | 95 | # Bash completion 96 | file { '/etc/bash_completion.d/slurm_completion.sh': 97 | ensure => $slurm::ensure, 98 | source => 'puppet:///modules/slurm/slurm_completion.sh', 99 | mode => '0644', 100 | } 101 | 102 | # Main slurm.conf 103 | $filename = "${slurm::configdir}/${slurm::params::configfile}" 104 | file { $slurm::params::configfile: 105 | ensure => $ensure, 106 | path => $filename, 107 | owner => $slurm::username, 108 | group => $slurm::group, 109 | mode => $slurm::params::configfile_mode, 110 | content => $slurm_content, 111 | source => $slurm::source, 112 | target => $slurm::target, 113 | tag => 'slurm::configfile', 114 | } 115 | 116 | # Now add the other configuration files 117 | include slurm::config::cgroup 118 | include slurm::config::gres 119 | include slurm::config::plugstack 120 | include slurm::config::topology 121 | 122 | # Eventually, add the [default] plugins 123 | if member($slurm::build_with, 'lua') { 124 | include slurm::plugins::lua 125 | } 126 | 127 | if $slurm::ensure == 'present' { 128 | File <| tag == 'slurm::configfile' |> { 129 | require +> File[$slurm::configdir], 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /manifests/config/cgroup.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: config/cgroup.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::config::cgroup 11 | # 12 | # This PRIVATE class handles the Slurm configuration file for the cgroup support 13 | # i.e. 'cgroup.conf' 14 | # 15 | # More details: see 16 | # 17 | # For general Slurm Cgroups information, see the Cgroups Guide at 18 | # . 19 | # 20 | class slurm::config::cgroup inherits slurm::config { 21 | # NOTE: Debian and derivatives (e.g. Ubuntu) usually exclude the memory and 22 | # memsw (swap) cgroups by default. To include them, add the following 23 | # parameters to the kernel command line: cgroup_enable=memory swapaccount=1 24 | # This is not covered in this class 25 | 26 | $cgroup_content = $slurm::cgroup_content ? { 27 | undef => $slurm::cgroup_source ? { 28 | undef => $slurm::cgroup_target ? { 29 | undef => template('slurm/cgroup.conf.erb'), 30 | default => $slurm::cgroup_content, 31 | }, 32 | default => $slurm::cgroup_content 33 | }, 34 | default => $slurm::cgroup_content, 35 | } 36 | $ensure = $slurm::cgroup_target ? { 37 | undef => $slurm::ensure, 38 | default => 'link', 39 | } 40 | $cgroup_filename = "${slurm::configdir}/${slurm::params::cgroup_configfile}" 41 | $allowed_devices_filename = "${slurm::configdir}/${slurm::params::cgroup_alloweddevices_configfile}" 42 | 43 | # cgroup.conf 44 | file { $slurm::params::cgroup_configfile: 45 | ensure => $ensure, 46 | path => $cgroup_filename, 47 | owner => $slurm::username, 48 | group => $slurm::group, 49 | mode => $slurm::params::configfile_mode, 50 | content => $cgroup_content, 51 | source => $slurm::cgroup_source, 52 | target => $slurm::cgroup_target, 53 | tag => 'slurm::configfile', 54 | } 55 | 56 | # ~~[eventually] cgroup_allowed_devices_file.conf~~ 57 | # UPDATE Slurm > 18.08: cgroup_allowed_devices_file.conf is no longer required. 58 | # By default all devices are allowed and GRES, that are associated with a 59 | # device file, that are not requested are restricted. 60 | # if !empty($slurm::cgroup_alloweddevices) { 61 | # file { $slurm::params::cgroup_alloweddevices_configfile: 62 | # ensure => $slurm::ensure, 63 | # path => $allowed_devices_filename, 64 | # owner => $slurm::username, 65 | # group => $slurm::group, 66 | # mode => $slurm::params::configfile_mode, 67 | # content => template('slurm/cgroup_allowed_devices_file.conf.erb'), 68 | # tag => 'slurm::configfile', 69 | # } 70 | # } 71 | } 72 | -------------------------------------------------------------------------------- /manifests/config/gres.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: config/gres.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::config::gres 11 | # 12 | # This PRIVATE class handles the Slurm configuration file for generic resource 13 | # management i.e. 'gres.conf' 14 | # 15 | # More details: see 16 | # 17 | class slurm::config::gres inherits slurm::config { 18 | $gres_content = $slurm::gres_content ? { 19 | undef => $slurm::gres_source ? { 20 | undef => $slurm::gres_target ? { 21 | undef => template('slurm/gres.conf.erb'), 22 | default => $slurm::gres_content, 23 | }, 24 | default => $slurm::gres_content 25 | }, 26 | default => $slurm::gres_content, 27 | } 28 | $ensure = $slurm::gres_target ? { 29 | undef => $slurm::ensure, 30 | default => 'link', 31 | } 32 | 33 | # gres.conf 34 | $gres_filename = "${slurm::configdir}/${slurm::params::gres_configfile}" 35 | file { $slurm::params::gres_configfile: 36 | ensure => $ensure, 37 | path => $gres_filename, 38 | owner => $slurm::username, 39 | group => $slurm::group, 40 | mode => $slurm::params::configfile_mode, 41 | content => $gres_content, 42 | source => $slurm::gres_source, 43 | target => $slurm::gres_target, 44 | tag => 'slurm::configfile', 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /manifests/config/plugstack.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: config/plugstack.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2019 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::config::plugstack 11 | # 12 | # This PRIVATE class handles the Slurm SPANK configuration file i.e. 'plugstack.conf' 13 | # 14 | # Documentation: https://slurm.schedmd.com/spank.html 15 | # 16 | # SPANK provides a very generic interface for stackable plug-ins which may be 17 | # used to dynamically modify the job launch code in Slurm. SPANK plugins may be 18 | # built without access to Slurm source code. They need only be compiled against 19 | # Slurm's spank.h header file, added to the SPANK config file plugstack.conf, 20 | # and they will be loaded at runtime during the next job launch 21 | # 22 | class slurm::config::plugstack inherits slurm::config { 23 | $plugstack_content = $slurm::plugstack_content ? { 24 | undef => $slurm::plugstack_source ? { 25 | undef => $slurm::plugstack_target ? { 26 | undef => template('slurm/plugstack.conf.erb'), 27 | default => $slurm::plugstack_content, 28 | }, 29 | default => $slurm::plugstack_content 30 | }, 31 | default => $slurm::plugstack_content, 32 | } 33 | $ensure = $slurm::plugstack_target ? { 34 | undef => $slurm::ensure, 35 | default => 'link', 36 | } 37 | 38 | $plugstack_filename = "${slurm::configdir}/${slurm::params::plugstack_configfile}" 39 | 40 | file { $slurm::params::plugstack_configfile: 41 | ensure => $ensure, 42 | path => $plugstack_filename, 43 | owner => $slurm::username, 44 | group => $slurm::group, 45 | mode => $slurm::params::configfile_mode, 46 | content => $plugstack_content, 47 | source => $slurm::plugstack_source, 48 | target => $slurm::plugstack_target, 49 | tag => 'slurm::configfile', 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /manifests/config/topology.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: config/topology.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::config::topology 11 | # 12 | # This PRIVATE class handles the Slurm configuration file for defining the network 13 | # topology i.e. 'topology.conf' 14 | # 15 | # More details: see 16 | # 17 | class slurm::config::topology inherits slurm::config { 18 | $topology_content = $slurm::topology_content ? { 19 | undef => $slurm::topology_source ? { 20 | undef => $slurm::topology_target ? { 21 | undef => template('slurm/topology.conf.erb'), 22 | default => $slurm::topology_content, 23 | }, 24 | default => $slurm::topology_content 25 | }, 26 | default => $slurm::topology_content, 27 | } 28 | $ensure = $slurm::topology_target ? { 29 | undef => $slurm::ensure, 30 | default => 'link', 31 | } 32 | 33 | if $slurm::topology == 'tree' { 34 | $topology_filename = "${slurm::configdir}/${slurm::params::topology_configfile}" 35 | file { $slurm::params::topology_configfile: 36 | ensure => $ensure, 37 | path => $topology_filename, 38 | owner => $slurm::username, 39 | group => $slurm::group, 40 | mode => $slurm::params::configfile_mode, 41 | content => $topology_content, 42 | source => $slurm::topology_source, 43 | target => $slurm::topology_target, 44 | tag => 'slurm::configfile', 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /manifests/download.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: download.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::download 11 | # 12 | # This definition takes care of downloading the SLURM sources for a given version 13 | # (passed as name to this resource) and placing them into $target directory. 14 | # You can also invoke this definition with the full archive filename i.e. 15 | # slurm-.tar.bz2. 16 | # 17 | # @param ensure 18 | # Ensure the presence (or absence) of building - Default: 'present' 19 | # @param target [String] Default: '/usr/local/src' 20 | # Target directory for the downloaded sources 21 | # @param checksum [String] Default: '' 22 | # archive file checksum (match checksum_type) 23 | ## @param checksum_type [String] Default: 'sha1' 24 | # archive file checksum type (none|md5|sha1|sha2|sh256|sha384| sha512). 25 | # @param checksum_verify [Boolean] Default: false 26 | # whether checksum will be verified (true|false). 27 | 28 | # @example Downloading version 19.05.3-2 of SLURM 29 | # 30 | # slurm::download { '19.05.3-2': 31 | # ensure => 'present', 32 | # checksum => '6fe2c6196f089f6210d5ba79e99b0656f5a527b4', 33 | # checksum_type => 'sha1', 34 | # target => '/usr/local/src/', 35 | # } 36 | # 37 | define slurm::download ( 38 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 39 | String $target = $slurm::params::srcdir, 40 | String $checksum = '', 41 | String $checksum_type = $slurm::params::src_checksum_type, 42 | Boolean $checksum_verify = false, 43 | ) { 44 | include slurm::params 45 | 46 | # $name is provided at define invocation 47 | if $name =~ /slurm-(.*)\.tar\.bz2/ { # Full archive name provided 48 | $archive = $name 49 | $version = $1 50 | } 51 | elsif ($name =~ /\d+[\.-]?/ ) { # only the version was provided 52 | $version = $name 53 | $archive = "slurm-${version}.tar.bz2" 54 | } 55 | else { fail("Wrong specification for ${module_name}") } 56 | 57 | # URL from where to download the sources 58 | $url = "${slurm::params::download_baseurl}/${archive}" 59 | # Absolute path to the downloaded source file 60 | $path = "${target}/${archive}" 61 | 62 | $real_checksum_type = empty($checksum) ? { 63 | true => 'none', 64 | default => $checksum_type 65 | } 66 | # notice("checksum = ${checksum}") 67 | # notice("checksum_type = ${real_checksum_type}") 68 | 69 | # Download the sources using puppet-archive module 70 | archive { $archive: 71 | ensure => $ensure, 72 | path => $path, 73 | source => $url, 74 | user => $slurm::params::username, 75 | group => $slurm::params::group, 76 | checksum_type => $real_checksum_type, 77 | checksum_verify => ($checksum_verify or ! empty($checksum)), 78 | checksum => $checksum, 79 | cleanup => false, 80 | extract => false, 81 | creates => $path, 82 | } 83 | if $ensure == 'absent' { 84 | file { $path: 85 | ensure => $ensure, 86 | require => Archive[$archive], 87 | } 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /manifests/firewall.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: firewall.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::firewall 11 | # 12 | # This definition takes care of firewall aspects for SLURM 13 | # 14 | # 15 | define slurm::firewall ( 16 | Enum['present', 'absent'] $ensure = 'present', 17 | String $zone = 'public', 18 | Optional[String] $port = undef, 19 | String $seltype = '', 20 | String $protocol = 'tcp', 21 | ) { 22 | include slurm::params 23 | 24 | if (($facts['os']['family'] != 'RedHat') or (versioncmp($facts['os']['release']['major'], '7') < 0)) { 25 | fail("Module ${module_name} is not supported on ${facts['os']['name']}") 26 | } 27 | 28 | # $name is provided at define invocation 29 | $port_range = $port ? { 30 | undef => $name, 31 | default => $port, 32 | } 33 | 34 | if (defined(Class['firewalld'])) { 35 | ###### CentOS/RHEL 7 with firewalld 36 | firewalld_port { "slurm-${port_range}": 37 | ensure => $ensure, 38 | zone => $zone, 39 | port => $port_range, 40 | protocol => $protocol, 41 | } 42 | if (defined(Class['selinux']) and $facts['os']['selinux']['enabled'] and !empty($seltype)) { 43 | $array_range = split($port_range, '-') 44 | selinux::port { "slurm-allow-${seltype}-port-${port_range}": 45 | ensure => $ensure, 46 | seltype => $seltype, 47 | protocol => $protocol, 48 | port_range => [($array_range[0]+0), ($array_range[1]+0)], 49 | } 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /manifests/install.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: install.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::install 11 | # 12 | # This PRIVATE class handles the installation of SLURM 13 | # 14 | class slurm::install { 15 | include slurm 16 | include slurm::params 17 | 18 | Class['slurm::common'] -> Class['slurm::install'] 19 | 20 | # [Eventually] download and build slurm sources 21 | if $slurm::do_build { 22 | # Download the Slurm sources 23 | slurm::download { $slurm::version : 24 | ensure => $slurm::ensure, 25 | target => $slurm::srcdir, 26 | checksum => $slurm::src_checksum, 27 | checksum_type => $slurm::src_checksum_type, 28 | } 29 | 30 | # Now build them 31 | slurm::build { $slurm::version : 32 | ensure => $slurm::ensure, 33 | srcdir => $slurm::srcdir, 34 | dir => $slurm::builddir, 35 | with => $slurm::build_with, 36 | without => $slurm::build_without, 37 | require => Slurm::Download[$slurm::version], 38 | } 39 | } 40 | 41 | # [Eventually] Install the built packages/RPMs 42 | if $slurm::do_package_install { 43 | slurm::install::packages { $slurm::version : 44 | ensure => $slurm::ensure, 45 | pkgdir => $slurm::builddir, 46 | slurmd => ($slurm::with_slurmd or defined(Class['slurm::slurmd'])), 47 | slurmctld => ($slurm::with_slurmctld or defined(Class['slurm::slurmctld'])), 48 | slurmdbd => ($slurm::with_slurmdbd or defined(Class['slurm::slurmdbd'])), 49 | wrappers => $slurm::wrappers, 50 | require => $slurm::do_build ? { 51 | true => Slurm::Build[$slurm::version], 52 | false => undef 53 | }, 54 | } 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /manifests/install/packages.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: install/packages.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::install::packages 11 | # 12 | # This definition takes care of installing the Slurm packages, typically built 13 | # from slurm::build, for a given version passed as resource name. 14 | # 15 | # @param ensure 16 | # Ensure the presence (or absence) of building - Default: 'present' 17 | # @param pkgdir [String] Default: '/root/rpmbuild' on redhat systems 18 | # Top directory of the sources builds (i.e. RPMs, debs...) 19 | # For instance, built RPMs will be placed under 20 | # /RPMS/${::architecture} 21 | # @param slurmd [Boolean] Default: false 22 | # Install Slurmd packages (compute and head node) 23 | # @param slurmctld [Boolean] Default: false 24 | # Install Slurmctrld (controller node) 25 | # @param slurmdbd [Boolean] Default: false 26 | # Install Slurm DBD Node 27 | # @param packages [Array] (optional) 28 | # Exhaustive list of the packages (RPM basenames - without versions and 29 | # os specific suffixes.) to install 30 | # 31 | # @example install version 19.05.3-2 for a head (controller) node running also the SlurmDBD: 32 | # 33 | # slurm::install::packages { '19.05.3-2': 34 | # ensure => 'present', 35 | # pkgdir => "/root/rpmbuild/', 36 | # slurmctld => true, 37 | # slurmd => true, 38 | # } 39 | # 40 | # @example install version 19.05.3-2 for a compute node (aimed at running SLURMd) 41 | # 42 | # slurm::install::packages { '19.05.3-2': 43 | # ensure => 'present', 44 | # pkgdir => "/root/rpmbuild/', 45 | # slurmd => true, 46 | # } 47 | # 48 | # @example install version 19.05.3 for a login node: 49 | # slurm::install::packages { '19.05.3-2': 50 | # ensure => 'present', 51 | # pkgdir => "/root/rpmbuild/', 52 | # } 53 | # 54 | define slurm::install::packages ( 55 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 56 | String $pkgdir = $slurm::params::builddir, 57 | Boolean $slurmd = $slurm::params::with_slurmd, 58 | Boolean $slurmctld = $slurm::params::with_slurmctld, 59 | Boolean $slurmdbd = $slurm::params::with_slurmdbd, 60 | Optional[Array] $wrappers = [], 61 | Optional[Array] $packages = [] 62 | ) { 63 | include slurm::params 64 | 65 | # $name is provided at define invocation 66 | $version = $name ? { 67 | Pattern[/\d+[\.-]?/] => $name, 68 | Integer => $name, 69 | default => fail("\$name must contain only digits, periods, and dashes") 70 | } 71 | 72 | if !($slurmd or $slurmctld or $slurmdbd or defined(Class['slurm::login']) or !empty($packages)) { 73 | fail( 74 | "Module ${module_name} expects a non-empty list of [built] packages to install " + 75 | 'OR specification of which daemon to install (i.e slurm{d,ctld,dbd}) or ' + 76 | "invocation of 'slurm::login' class for Login nodes" 77 | ) 78 | } 79 | 80 | # notice("Package installation for slurmd = ${slurmd}") 81 | # notice("Package installation for slurmctld = ${slurmctld}") 82 | # notice("Package installation for slurmdbd = ${slurmdbd}") 83 | 84 | # Let's build the [default] package list 85 | if $facts['os']['family'] == 'RedHat' { 86 | $common_rpms = $slurm::params::common_rpms_basename 87 | $slurmdbd_rpms = $slurm::params::slurmdbd_rpms_basename 88 | $slurmctld_rpms = $slurm::params::slurmctld_rpms_basename 89 | $slurmd_rpms = $slurm::params::slurmd_rpms_basename 90 | 91 | # Official guidelines -- https://slurm.schedmd.com/quickstart_admin.html 92 | # The RPMs needed on the head node, compute nodes, and slurmdbd node can 93 | # vary by configuration, but here is a suggested starting point: 94 | # Head Node (where the slurmctld daemon runs), 95 | # Compute and Login Nodes 96 | # - slurm 97 | # - slurm-perlapi 98 | # - slurm-slurmctld (only on the head node) 99 | # - slurm-slurmd (only on the compute nodes) 100 | # - In addition: 101 | # * pmix (but NOT pmix-libmpi) 102 | # * slurm-libpmi 103 | # SlurmDBD Node 104 | # - slurm 105 | # - slurm-slurmdbd 106 | ################ 107 | $default_packages = ($slurmdbd ? { 108 | # Slurm DB 109 | true => ($slurmctld ? { 110 | true => ($slurmd ? { 111 | true => concat($common_rpms, $slurmdbd_rpms, $slurmctld_rpms, $slurmd_rpms, $wrappers), # slurmDB + slurmctld + slurmd 112 | default => concat($common_rpms, $slurmdbd_rpms, $slurmctld_rpms, $wrappers), # slurmDB + slurmctld 113 | }), 114 | default => ($slurmd ? { 115 | true => concat($common_rpms, $slurmdbd_rpms, $slurmd_rpms, $wrappers), # slurmDB + slurmd 116 | default => concat($common_rpms, $slurmdbd_rpms, $wrappers), # slurmDB 117 | }), 118 | }), 119 | # NO Slurm DB 120 | default => ($slurmctld ? { 121 | true => ($slurmd ? { 122 | true => concat($common_rpms, $slurmctld_rpms, $slurmd_rpms, $wrappers) , # slurmctld + slurmd 123 | default => concat($common_rpms, $slurmctld_rpms, $wrappers), # slurmctld 124 | }), 125 | default => ($slurmd ? { 126 | true => concat($common_rpms, $slurmd_rpms, $wrappers) , # slurmd 127 | default => concat($common_rpms, $wrappers), # None of the daemons are requested - 128 | }), 129 | }), 130 | }) 131 | } 132 | else { 133 | $default_packages = [] # TODO ;) 134 | } 135 | # Real Full list 136 | $pkglist = empty($packages) ? { 137 | true => $default_packages, 138 | default => $packages 139 | } 140 | #notice("Package list: ${pkglist}") 141 | # ... including the version numbers 142 | $pkgs = suffix($pkglist, "-${version}") 143 | 144 | case $facts['os']['family'] { 145 | 'Redhat': { 146 | include epel 147 | include yum 148 | if $slurm::do_build { 149 | $rpms = suffix($pkgs, '*.rpm') 150 | $cwddir = "${pkgdir}/RPMS/${facts['os']['architecture']}" 151 | # $cwddir = ($pkgdir == $slurm::params::builddir) ? { 152 | # true => "${pkgdir}/RPMS/${::architecture}", 153 | # default => $pkgdir, 154 | } 155 | case $ensure { 156 | 'absent': { 157 | #$execname = "yum-remove-slurm*${version}*.rpm" 158 | $cmd ="yum -y remove slurm*-${version}*" 159 | $check_onlyif = "test -n \"$(rpm -qa | grep -E 'slurm.*${version}')\"" 160 | $check_unless = "test -z \"$(rpm -qa | grep -E 'slurm.*${version}')\"" 161 | } 162 | default: { 163 | $pkglist.each |String $pkg| { 164 | if $pkg != 'slurm' { 165 | Package[$pkg] { 166 | require => Package['slurm'] 167 | } 168 | } 169 | if $slurm::do_build { 170 | Package[$pkg] { 171 | provider => 'rpm', 172 | install_options => ['--nodeps'], 173 | source => "${cwddir}/${pkg}-${version}*.rpm", 174 | } 175 | } 176 | } 177 | } 178 | } 179 | } 180 | default: { 181 | fail("Module ${module_name} is not supported on ${facts['os']['name']}") 182 | } 183 | } 184 | 185 | # Let's go (independently of the distribution) 186 | if $ensure == 'present' { 187 | $pkglist.each |String $pkg| { 188 | package { $pkg: 189 | ensure => $ensure, 190 | } 191 | } 192 | } 193 | else { 194 | #notice($cmd) 195 | exec { "uninstall-slurm*${version}*": 196 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 197 | command => $cmd, 198 | onlyif => $check_onlyif, 199 | unless => $check_unless, 200 | user => 'root', 201 | } 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /manifests/login.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: slurmd.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::login 11 | # 12 | # The main helper class specializing the main slurm class for setting up a 13 | # Login node 14 | # 15 | # === Warnings 16 | # 17 | # /!\ Always respect the style guide available here[http://docs.puppetlabs.com/guides/style_guide] 18 | # 19 | # [Remember: No empty lines between comments and class definition] 20 | # 21 | class slurm::login inherits slurm { 22 | case $facts['os']['family'] { 23 | 'Redhat': {} 24 | default: { fail("Module ${module_name} is not supported on ${facts['os']['name']}") } 25 | } 26 | 27 | include slurm::install 28 | include slurm::config 29 | Class['slurm::install'] -> Class['slurm::config'] 30 | 31 | if $slurm::ensure == 'present' { 32 | File <| tag == 'slurm::configfile' |> { 33 | require => File[$slurm::configdir], 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /manifests/munge.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: munge.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Class: slurm::munge 11 | # 12 | # MUNGE (MUNGE Uid 'N' Gid Emporium) is an authentication service for creating 13 | # and validating credentials. It is designed to be highly scalable for use in an 14 | # HPC cluster environment. 15 | # It allows a process to authenticate the UID and GID of another local or 16 | # remote process within a group of hosts having common users and groups. These 17 | # hosts form a security realm that is defined by a shared cryptographic key. 18 | # Clients within this security realm can create and validate credentials without 19 | # the use of root privileges, reserved ports, or platform-specific methods. 20 | # 21 | # For more information, see https://github.com/dun/munge 22 | # 23 | # This Puppet class is responsible for setting up a working Munge environment to 24 | # be used by the SLURM daemons. 25 | # 26 | # See https://slurm.schedmd.com/authplugins.html 27 | # 28 | # @param ensure 29 | # Ensure the presence (or absence) of the Munge service - Default: 'present' 30 | # @param create_key [Boolean] Default: true 31 | # Whether or not to generate a new key if it does not exists 32 | # @param daemon_args [Array] Default: [] 33 | # Set the content of the DAEMON_ARGS variable, which permits to set 34 | # additional command-line options to the daemon. For example, this can 35 | # be used to override the location of the secret key (--key-file) or 36 | # set the number of worker threads (--num-threads) See 37 | # https://github.com/dun/munge/wiki/Installation-Guide#starting-the-daemon 38 | # @param gid [Integer] Default: 992 39 | # GID of the munge group 40 | # @param key_content [String,Binary] Default: undef 41 | # The desired content of the munge key file, as a string or binary object. 42 | # This attribute is mutually exclusive with source and target. 43 | # @param key_filename [String] Default: '/etc/munge/munge.key' 44 | # The secret key filename 45 | # @param key_source [String] Default: undef 46 | # A source file, which will be copied into place on the local system. 47 | # This attribute is mutually exclusive with content. 48 | # The normal form of a puppet: URI is 49 | # puppet:///modules// 50 | # @param uid [Integer] Default: 992 51 | # UID of the munge user 52 | # 53 | # /!\ We assume the RPM 'slurm-munge' has been already installed -- this class 54 | # does not care about it 55 | # 56 | class slurm::munge ( 57 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 58 | Boolean $create_key = $slurm::params::munge_create_key, 59 | Array $daemon_args = $slurm::params::munge_daemon_args, 60 | Integer $uid = $slurm::params::munge_uid, 61 | Integer $gid = $slurm::params::munge_gid, 62 | String $key_filename = $slurm::params::munge_key, 63 | Optional[String] $key_source = undef, 64 | Optional[Variant[String,Binary]] $key_content = undef, 65 | Boolean $service_manage = $slurm::service_manage, 66 | ) 67 | inherits slurm::params { 68 | if ($facts['os']['family'] == 'RedHat') { 69 | include epel 70 | } 71 | 72 | # Order 73 | if ($ensure == 'present') { 74 | Group['munge'] -> User['munge'] -> Package['munge'] 75 | } 76 | else { 77 | Package['munge'] -> User['munge'] -> Group['munge'] 78 | } 79 | 80 | # Install the required packages 81 | package { 'munge': 82 | ensure => $ensure, 83 | name => $slurm::params::munge_package, 84 | } 85 | $slurm::params::munge_extra_packages.each |String $pkg| { 86 | # Safeguard to avoid incompatibility with other puppet modules 87 | if (!defined(Package[$pkg])) { 88 | package { $slurm::params::munge_extra_packages: 89 | ensure => $ensure, 90 | require => Package['munge'], 91 | } 92 | } 93 | } 94 | # Prepare the user and group 95 | group { 'munge': 96 | ensure => $ensure, 97 | name => $slurm::params::munge_group, 98 | gid => $gid, 99 | } 100 | user { 'munge': 101 | ensure => $ensure, 102 | name => $slurm::params::munge_username, 103 | uid => $uid, 104 | gid => $gid, 105 | comment => $slurm::params::munge_comment, 106 | home => $slurm::params::munge_home, 107 | managehome => true, 108 | system => true, 109 | shell => $slurm::params::munge_shell, 110 | } 111 | 112 | if $ensure == 'present' { 113 | file { [$slurm::params::munge_configdir, $slurm::params::munge_logdir]: 114 | ensure => 'directory', 115 | owner => $slurm::params::munge_username, 116 | group => $slurm::params::munge_group, 117 | mode => '0700', 118 | require => Package['munge'], 119 | } 120 | file { $slurm::params::munge_piddir: 121 | ensure => 'directory', 122 | owner => $slurm::params::munge_username, 123 | group => $slurm::params::munge_group, 124 | mode => '0755', 125 | require => Package['munge'], 126 | } 127 | } 128 | else { 129 | file { 130 | [ 131 | $slurm::params::munge_configdir, 132 | $slurm::params::munge_logdir, 133 | $slurm::params::munge_piddir, 134 | ]: 135 | ensure => $ensure, 136 | force => true, 137 | } 138 | } 139 | 140 | # Create the key if needed 141 | if ($create_key and $ensure == 'present') { 142 | class { 'rngd': 143 | hwrng_device => '/dev/urandom', 144 | } 145 | exec { "create Munge key ${slurm::params::munge_key}": 146 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 147 | command => "dd if=/dev/urandom bs=1 count=1024 > ${key_filename}", # OR "create-munge-key", 148 | unless => "test -f ${key_filename}", 149 | user => 'root', 150 | before => File[$key_filename], 151 | require => [ 152 | File[dirname($key_filename)], 153 | Package['munge'], 154 | Class['rngd'] 155 | ], 156 | } 157 | } 158 | # ensure the munge key /etc/munge/munge.key 159 | file { $key_filename: 160 | ensure => $ensure, 161 | owner => $slurm::params::munge_username, 162 | group => $slurm::params::munge_group, 163 | mode => '0400', 164 | content => $key_content, 165 | source => $key_source, 166 | } 167 | 168 | # Eventually prepare /etc/{default,sysconfig}/munge 169 | if ($key_filename == '/etc/munge/munge.key') { 170 | $options = $daemon_args 171 | } 172 | else { 173 | $options = concat($daemon_args, "--key-file ${key_filename}") 174 | } 175 | file { $slurm::params::munge_default_sysconfig: 176 | ensure => $ensure, 177 | owner => $slurm::params::munge_username, 178 | group => $slurm::params::munge_group, 179 | mode => '0644', 180 | content => template('slurm/munge_sysconfig.erb'), 181 | } 182 | 183 | if $service_manage == true { 184 | # Run munge service 185 | service { 'munge': 186 | ensure => ($ensure == 'present'), 187 | name => $slurm::params::munge_servicename, 188 | enable => ($ensure == 'present'), 189 | pattern => $slurm::params::munge_processname, 190 | hasrestart => $slurm::params::hasrestart, 191 | hasstatus => $slurm::params::hasstatus, 192 | require => [ 193 | Package['munge'], 194 | File[$key_filename], 195 | File[$slurm::params::munge_configdir], 196 | File[$slurm::params::munge_logdir], 197 | File[$slurm::params::munge_piddir] 198 | ], 199 | subscribe => File[$key_filename], 200 | } 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /manifests/pam.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: pam.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Class: slurm::pam 11 | # 12 | # Setup Pluggable Authentication Modules (PAM) (i.e. the module 'pam_slurm') for slurmd, 13 | # i.e. /etc/pam.d/slurm and 14 | # See https://slurm.schedmd.com/faq.html#pam 15 | # 16 | # == Parameters 17 | # 18 | # @param ensure 19 | # Ensure the presence (or absence) of slurm::pam - Default: 'present' 20 | # @param allowed_users [Array] Default: [] 21 | # Manage login access (see PAM_ACCESS(8)) in addition to 'root' 22 | # @param content [String] Default: see 'templates/pam_slurm.erb' 23 | # Content of /etc/pam.d/slurm 24 | # @param ulimits [Hash] 25 | # Default: { 26 | # 'memlock' => 'unlimited', 27 | # 'stack' => 'unlimited', 28 | # 'nproc' => 10240, 29 | # } 30 | # @param ulimits_source [String] 31 | # Source file for /etc/security/limits.d/80_slurm.conf 32 | # @param use_pam_slurm_adopt [Boolean] Default: false 33 | # Whether or not use the pam_slurm_adopt module (to Adopt incoming 34 | # connections into jobs) -- see 35 | # https://github.com/SchedMD/slurm/tree/master/contribs/pam_slurm_adopt 36 | # 37 | # /!\ We assume the RPM 'slurm-pam_slurm' has been already installed 38 | # 39 | class slurm::pam ( 40 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 41 | Array $allowed_users = $slurm::params::pam_allowed_users, 42 | String $configfile = $slurm::params::pam_configfile, 43 | String $content = $slurm::params::pam_content, 44 | Hash $ulimits = $slurm::params::ulimits, 45 | Optional[String] $ulimits_source = undef, 46 | Boolean $use_pam_slurm_adopt = $slurm::params::use_pam_slurm_adopt, 47 | ) 48 | inherits slurm::params { 49 | # PAM access 50 | # Detect vagrant environment to include 'vagrant' in the list of allowed host otherwise 51 | # the application of this class will prevent the vagrant user to work as expected 52 | # Trick is to detect ::is_virtual facter + the presence of the /vagrant directory 53 | # See custom fact 'lib/facter/is_vagrant.rb' 54 | $default_allowed_users = $facts['is_vagrant'] ? { 55 | true => ['root', 'vagrant'], 56 | default => ['root'], 57 | } 58 | $__allowed_users = empty($allowed_users) ? { 59 | true => $default_allowed_users, 60 | default => concat( $allowed_users, $default_allowed_users), 61 | } 62 | #notice($__allowed_users) 63 | # if (! defined(Class['pam'])) { 64 | # class { '::pam': 65 | # allowed_users => $__allowed_users, 66 | # } 67 | # # the above class will lead to sssd errors on Redhat systems 68 | # # you might want to enforce the installation of the sssd package in this case 69 | # if $::osfamily == 'RedHat' and !defined(Package['sssd']) { 70 | # package { 'sssd': 71 | # ensure => 'present', 72 | # } 73 | # } 74 | # } 75 | 76 | # Establish a PAM configuration file for slurm /etc/pam.d/slurm 77 | # pam::service { $slurm::params::pam_servicename: 78 | # ensure => $ensure, 79 | # content => $content, 80 | # } 81 | # 82 | if !defined(File[$configfile]) { 83 | file { $configfile: 84 | ensure => $ensure, 85 | content => $content, 86 | } 87 | } 88 | 89 | if ($use_pam_slurm_adopt) { 90 | # TODO: 91 | notice('use pam_slurm_adopt') 92 | } 93 | 94 | # PAM limits 95 | # Ex: Update PAM MEMLOCK limits (required for MPI) + nproc 96 | include limits 97 | 98 | if $ulimits_source != undef { 99 | file { "${limits::limits_dir}/50_slurm.conf": 100 | ensure => $ensure, 101 | owner => 'root', 102 | group => 'root', 103 | mode => '0644', 104 | source => $ulimits_source, 105 | } 106 | # ulimit::rule { 'slurm': 107 | # ensure => $ensure, 108 | # source => $ulimits_source, 109 | # } 110 | } 111 | else { 112 | $ulimits.each |String $item, $value| { 113 | limits::limits { "*/${item}": 114 | ensure => $ensure, 115 | both => $value, 116 | } 117 | # ulimit::rule { "slurm-${item}": 118 | # ensure => $ensure, 119 | # ulimit_domain => '*', 120 | # ulimit_type => [ 'soft', 'hard' ], 121 | # ulimit_item => $item, 122 | # ulimit_value => $value, 123 | # } 124 | } 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /manifests/plugin.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: plugin.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::plugin 11 | # 12 | # This definition takes care of managing SLURM plugins. 13 | # 14 | # @param ensure 15 | # Ensure the presence (or absence) of building - Default: 'present' 16 | # @param path 17 | # Target directory for the downloaded sources - Default '/usr/local/src' 18 | # @param content [String] Default: undef 19 | # The desired contents of a topology file, as a string. This attribute is 20 | # mutually exclusive with topology_source and topology_target. 21 | # @param source [String] Default: undef 22 | # A source file, which will be copied into place on the local system. 23 | # This attribute is mutually exclusive with {content,target}. 24 | # @param target [String] Default: undef 25 | # Target link path 26 | # 27 | # 28 | define slurm::plugin ( 29 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 30 | Optional[Stdlib::Absolutepath] $path = '/usr/local/src', 31 | Optional[Stdlib::Absolutepath] $target = undef, 32 | Optional[String] $source = undef, 33 | Optional[String] $content = undef, 34 | ) { 35 | include slurm::params 36 | 37 | # $name is provided at define invocation 38 | # if $name =~ /slurm-(.*)\.tar\.bz2/ { # Full archive name provided 39 | # $archive = $name 40 | # $version = $1 41 | # } 42 | # elsif ($name =~ /\d+[\.-]?/ ) { # only the version was provided 43 | # $version = $name 44 | # $archive = "slurm-${version}.tar.bz2" 45 | # } 46 | # else { fail("Wrong specification for ${module_name}") } 47 | # # URL from where to download the sources 48 | # $url = "${slurm::params::download_baseurl}/${archive}" 49 | # # Absolute path to the downloaded source file 50 | # $path = "${target}/${archive}" 51 | 52 | # # Download the sources using puppet-archive module 53 | # archive { $archive: 54 | # ensure => $ensure, 55 | # path => $path, 56 | # source => $url, 57 | # user => $slurm::params::username, 58 | # group => $slurm::params::group, 59 | # checksum_type => $checksum_type, 60 | # checksum_verify => ($checksum_verify or ! empty($checksum)), 61 | # checksum => $checksum, 62 | # cleanup => false, 63 | # extract => false, 64 | # creates => $path, 65 | # } 66 | } 67 | -------------------------------------------------------------------------------- /manifests/plugins.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: plugins.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::plugins 11 | # 12 | # This PRIVATE class handles all default plugins 13 | # More details on 14 | # 15 | # NOT YET IMPLEMENTED 16 | # 17 | class slurm::plugins inherits slurm {} 18 | -------------------------------------------------------------------------------- /manifests/plugins/lua.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: plugins/lua.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::plugins::lua 11 | # 12 | # This PRIVATE class handles the configuration of Job Submit plugin 'lua' i.e. 13 | # of the file 'job_submit.lua' 14 | # Ex: https://github.com/SchedMD/slurm/blob/master/contribs/lua/job_submit.lua 15 | # 16 | # More details on 17 | # 18 | class slurm::plugins::lua inherits slurm::plugins { 19 | $lua_content = $slurm::lua_content ? { 20 | undef => $slurm::lua_source ? { 21 | undef => $slurm::lua_target ? { 22 | undef => template('slurm/job_submit.lua.erb'), 23 | default => $slurm::lua_content, 24 | }, 25 | default => $slurm::lua_content 26 | }, 27 | default => $slurm::lua_content, 28 | } 29 | $ensure = $slurm::lua_target ? { 30 | undef => $slurm::ensure, 31 | default => 'link', 32 | } 33 | 34 | $filename = "${slurm::configdir}/${slurm::params::job_submit_lua}" 35 | 36 | file { $slurm::params::job_submit_lua: 37 | ensure => $ensure, 38 | path => $filename, 39 | owner => $slurm::username, 40 | group => $slurm::group, 41 | mode => $slurm::params::configfile_mode, 42 | content => $lua_content, 43 | source => $slurm::lua_source, 44 | target => $slurm::lua_target, 45 | tag => 'slurm::configfile', 46 | require => File[$slurm::configdir], 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /manifests/pmix.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: pmix.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2019 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::pmix 11 | # 12 | # This facility class handles the installation of PMIx. 13 | # It is meant to be a simple wrapper around the slurm::pmix::* definitions 14 | # 15 | # @param ensure [String] Default: 'present' 16 | # Ensure the presence (or absence) of building 17 | # @param version [String] Default: 3.1.4' (see params.pp) 18 | # PMIx version to install 19 | # @param srcdir [String] Default: '/usr/local/src' 20 | # Target directory for the downloaded sources 21 | # @param checksum_type [String] Default: 'sha1' 22 | # archive file checksum type (none|md5|sha1|sha2|sh256|sha384| sha512). 23 | # @param checksum [String] Default: see params.pp 24 | # archive file checksum (match checksum_type) 25 | # @param builddir [String] Default: '/root/rpmbuild' on redhat systems 26 | # Top directory of the sources builds (i.e. RPMs, debs...) 27 | # For instance, built RPMs will be placed under 28 | # /RPMS/${::architecture} 29 | # @param do_build [Boolean] Default: true 30 | # Do we perform the build of the OpenPMIx packages from sources or not? 31 | # @param do_package_install [Boolean] Default: true 32 | # Do we perform the install of the OpenPMIx packages or not? 33 | # 34 | # @example install version 3.2.3 of PMIx 35 | # 36 | # slurm::pmix { '3.1.4': 37 | # ensure => 'present', 38 | # builddir => "/root/rpmbuild/", 39 | # } 40 | # 41 | class slurm::pmix ( 42 | String $ensure = $slurm::params::ensure, 43 | String $version = $slurm::params::pmix_version, 44 | String $srcdir = $slurm::params::srcdir, 45 | String $src_checksum = $slurm::params::pmix_src_checksum, 46 | String $src_checksum_type = $slurm::params::pmix_src_checksum_type, 47 | String $builddir = $slurm::params::builddir, 48 | Boolean $do_build = $slurm::params::do_build, 49 | Boolean $do_package_install = $slurm::params::do_package_install, 50 | ) { 51 | include slurm::params 52 | 53 | # Download the PMIx sources 54 | slurm::pmix::download { $version : 55 | ensure => $ensure, 56 | target => $srcdir, 57 | checksum => $src_checksum, 58 | checksum_type => $src_checksum_type, 59 | } 60 | 61 | if $do_build { 62 | # Now build them 63 | slurm::pmix::build { $version : 64 | ensure => $ensure, 65 | srcdir => $srcdir, 66 | dir => $builddir, 67 | require => Slurm::Pmix::Download[$version], 68 | } 69 | } 70 | 71 | if $do_package_install { 72 | # And install it 73 | slurm::pmix::install { $version : 74 | ensure => $ensure, 75 | builddir => $builddir, 76 | require => Slurm::Pmix::Build[$version], 77 | } 78 | } 79 | } 80 | -------------------------------------------------------------------------------- /manifests/pmix/build.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: pmix/build.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2019 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::pmix::build 11 | # 12 | # This definition takes care of building PMIx sources into RPMs using 'rpmbuild'. 13 | # It expect to get as resource name the PMIx version to build 14 | # This assumes the sources have been downloaded using slurm::pmix::download 15 | # 16 | # 17 | # @param ensure 18 | # Ensure the presence (or absence) of building - Default: 'present' 19 | # @param srcdir [String] Default: '/usr/local/src' 20 | # Where the [downloaded] Slurm sources are located 21 | # @param dir [String] Default: '/root/rpmbuild' on redhat systems 22 | # Top directory of the sources builds (i.e. RPMs, debs...) 23 | # For instance, built RPMs will be placed under 24 | # /RPMS/${::architecture} 25 | # @param defines [Array] Default: [] 26 | # Extra options that can be passed in via rpmbuild's --define option, 27 | # knowing that the options '_topdir' and 'build_all_in_one_rpm' are 28 | # already set by this definition. 29 | # Note that --define takes *1* argument i.e. a multi-token string where 30 | # the first token is the name of the variable to define, and all 31 | # remaining tokens are the value. Pass each such string as elements of 32 | # this array. 33 | # 34 | # @example Building version 3.1.4 (latest at the time of writing) of PMIx 35 | # 36 | # slurm::pmix::build { '3.1.4': 37 | # ensure => 'present', 38 | # srcdir => '/usr/local/src', 39 | # dir => '/root/rpmbuild', 40 | # defines => [ 'install_in_opt 1' ], 41 | # } 42 | # 43 | # NOTE: on purpose, this definition will build separate RPMs in ${dir}/RPMS/${::architecture}: 44 | # 1. pmix--*.rpm: the main package 45 | # 2. pmix-libmpi--*.rpm: PMI-1 and PMI-2 compatibility libraries (i.e. 46 | # libpmi and libpmi2 libraries) that provide the respective APIs and a copy of 47 | # the PMIx library – each API is translated into its PMIx equivalent. This 48 | # package conflicts with slurm-libpmi, which provides its own, incompatible 49 | # versions of libpmi.so and libpmi2.so. 50 | # 51 | # In particular, ONLY THE FIRST RPM will be installed (to avoid the conflict 52 | # with slurm-libmpi). 53 | # 54 | define slurm::pmix::build ( 55 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 56 | String $srcdir = $slurm::params::srcdir, 57 | String $dir = $slurm::params::builddir, 58 | Array $defines = [], 59 | ) { 60 | include slurm::params 61 | 62 | # $name is provided at define invocation 63 | $version = $name ? { 64 | Pattern[/\d+[\.-]?/] => $name, 65 | Integer => $name, 66 | default => fail("\$name must contain only digits, periods, and dashes") 67 | } 68 | 69 | # Path to the PMIx sources 70 | $src = "${srcdir}/pmix-${version}.tar.bz2" 71 | 72 | # Label for the exec 73 | $buildname = $ensure ? { 74 | 'absent' => "uninstall-pmix-${version}", 75 | default => "build-pmix-${version}", 76 | } 77 | 78 | case $facts['os']['family'] { 79 | 'Redhat': { 80 | include epel 81 | include yum 82 | if !defined(Yum::Group[$slurm::params::groupinstall]) { 83 | yum::group { $slurm::params::groupinstall: 84 | ensure => 'present', 85 | timeout => 600, 86 | require => Class['epel'], 87 | } 88 | } 89 | if !defined(Package['libevent-devel']) { 90 | package { 'libevent-devel': 91 | ensure => 'present', 92 | } 93 | } 94 | if !defined(Package['python3-devel']) { 95 | package { 'python3-devel': 96 | ensure => 'present', 97 | } 98 | } 99 | Yum::Group[$slurm::params::groupinstall] -> Exec[$buildname] 100 | Package['libevent-devel'] -> Package['python3-devel'] -> Exec[$buildname] 101 | 102 | $rpmdir = "${dir}/RPMS/${facts['os']['architecture']}" 103 | $rpms = prefix(suffix($slurm::params::pmix_rpms, "-${version}*.rpm"), "${rpmdir}/") 104 | $extra_define_opts = join(suffix(prefix($defines, "--prefix \""), "\""), ' ') 105 | 106 | # the below command should typically produce the following RPMs 107 | # pmix[-libpmi][-devel]--1.el7.x86_64.rpm 108 | case $ensure { 109 | 'absent': { 110 | $cmd = "rm -f ${rpmdir}/pmix*-${version}*.rpm" 111 | $check_onlyif = "test -n \"$(ls ${rpms[0]} 2>/dev/null)\"" 112 | $check_unless = undef 113 | } 114 | default: { 115 | $cmd = "rpmbuild -ta --define \"_topdir ${dir}\" --define \"build_all_in_one_rpm 0\" ${extra_define_opts} ${src}" 116 | $check_onlyif = undef 117 | $check_unless = suffix(prefix($rpms, 'test -n "$(ls '), ' 2>/dev/null)"') 118 | #"test -n \"$(ls ${main_rpm} 2>/dev/null)\"" 119 | } 120 | } 121 | } 122 | default: { 123 | fail("Module ${module_name} is not supported on ${facts['os']['name']}") 124 | } 125 | } 126 | 127 | #notice($cmd) 128 | exec { $buildname: 129 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 130 | command => $cmd, 131 | cwd => '/root', 132 | user => 'root', 133 | timeout => 600, 134 | onlyif => $check_onlyif, 135 | unless => $check_unless, 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /manifests/pmix/download.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: pmix/download.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2019 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::pmix::download 11 | # 12 | # This definition takes care of downloading PMIx sources sources for a given version 13 | # (passed as name to this resource) and placing them into $target directory 14 | # according to the guidelines provided on 15 | # https://pmix.org/support/how-to/slurm-support/#building 16 | # 17 | # Latest PMIx releases: https://github.com/openpmix/openpmix/releases 18 | # 19 | # @param ensure 20 | # Ensure the presence (or absence) of building - Default: 'present' 21 | # @param target [String] Default: '/usr/local/src' 22 | # Target directory for the downloaded sources 23 | # @param checksum_type [String] Default: 'sha1' 24 | # archive file checksum type (none|md5|sha1|sha2|sh256|sha384| sha512). 25 | # @param checksum_verify [Boolean] Default: false 26 | # whether checksum will be verified (true|false). 27 | # @param checksum [String] Default: '' 28 | # archive file checksum (match checksum_type) 29 | # 30 | # 31 | # @example install version 3.1.4 (see 32 | # https://github.com/openpmix/openpmix/releases/tag/v3.1.4): 33 | # 34 | # slurm::pmix::download { '3.1.4': 35 | # ensure => 'present', 36 | # checksum => '0f3f575e486d8492441c34276d1d56cbb48b4c37', 37 | # checksum_type => 'sha1', 38 | # target => '/usr/local/src/', 39 | # } 40 | # 41 | define slurm::pmix::download ( 42 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 43 | String $target = $slurm::params::srcdir, 44 | String $url = '', 45 | String $checksum = '', 46 | String $checksum_type = $slurm::params::pmix_src_checksum_type, 47 | Boolean $checksum_verify = false, 48 | ) { 49 | include slurm::params 50 | 51 | # $name is provided at define invocation 52 | if $name =~ /pmix-(.*)\.tar\.bz2/ { # Full archive name provided 53 | $archive = $name 54 | $version = $1 55 | } 56 | elsif ($name =~ /\d+[\.-]?/ ) { # only the version was provided 57 | $version = $name 58 | $archive = "pmix-${version}.tar.bz2" 59 | } 60 | else { fail("Wrong specification for ${module_name}") } 61 | 62 | # URL from where to download the sources 63 | $source = empty($url) ? { 64 | true => "${slurm::params::pmix_download_baseurl}/v${version}/${archive}", 65 | default => $url, 66 | } 67 | 68 | # Absolute path to the downloaded source file 69 | $path = "${target}/${archive}" 70 | # $basename = basename($archive, '.tar.bz2') 71 | # $extract_path = "${target}/${basename}/" 72 | 73 | $real_checksum_type = empty($checksum) ? { 74 | true => 'none', 75 | default => $checksum_type 76 | } 77 | 78 | # Download the sources using puppet-archive module 79 | archive { $archive: 80 | ensure => $ensure, 81 | path => $path, 82 | source => $source, 83 | user => $slurm::params::username, 84 | group => $slurm::params::group, 85 | checksum_type => $real_checksum_type, 86 | checksum_verify => ($checksum_verify or ! empty($checksum)), 87 | checksum => $checksum, 88 | cleanup => false, 89 | extract => false, 90 | # extract => true, 91 | # extract_path => $target, 92 | creates => $path, 93 | } 94 | if $ensure == 'absent' { 95 | file { $path: 96 | ensure => $ensure, 97 | require => Archive[$archive], 98 | } 99 | } 100 | # else { 101 | # file {$extract_path: 102 | # ensure => 'directory', 103 | # owner => $slurm::params::username, 104 | # group => $slurm::params::group, 105 | # mode => '0755', 106 | # before => Archive[$archive] 107 | # } 108 | # } 109 | } 110 | -------------------------------------------------------------------------------- /manifests/pmix/install.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: pmix/install.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2019 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Defines: slurm::pmix::install 11 | # 12 | # This definition takes care of installing the PMIx packages typically built 13 | # from the slurm::pmix::build (to ensure *separate* RPMs builds have been 14 | # produced to avoid conflicts with slurm-libpmi, which provides its own, 15 | # incompatible versions of libpmi.so and libpmi2.so.), for a given version for 16 | # PMIx passed as resource name. 17 | # 18 | # @param ensure 19 | # Ensure the presence (or absence) of installation - Default: 'present' 20 | # @param builddir [String] Default: '/root/rpmbuild/' on redhat systems 21 | # Top directory of the sources builds (i.e. RPMs, debs...) 22 | # For instance, built RPMs will be placed under 23 | # /RPMS/${::architecture} 24 | # 25 | # @example install version 3.1.4 (latest at the time of writing) of PMIx 26 | # 27 | # slurm::pmix::install { '3.1.4': 28 | # ensure => 'present', 29 | # builddir => "/root/rpmbuild/", 30 | # } 31 | # 32 | # 33 | define slurm::pmix::install ( 34 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 35 | String $builddir = $slurm::params::builddir, 36 | ) { 37 | include slurm::params 38 | 39 | # $name is provided at define invocation 40 | $version = $name ? { 41 | Pattern[/\d+[\.-]?/] => $name, 42 | Integer => $name, 43 | default => fail("\$name must contain only digits, periods, and dashes") 44 | } 45 | 46 | case $facts['os']['family'] { 47 | 'Redhat': { 48 | include epel 49 | include yum 50 | $rpmdir = "${builddir}/RPMS/${facts['os']['architecture']}" 51 | $rpm = "pmix-${version}*.rpm" 52 | $rpmdevel = "pmix-devel-${version}*.rpm" 53 | 54 | case $ensure { 55 | 'absent': { 56 | $cmd = "yum -y remove pmix*-${version}*" 57 | $check_onlyif = "test -n \"$(rpm -qa | grep -E 'pmix.*${version}')\"" 58 | $check_unless = "test -z \"$(rpm -qa | grep -E 'pmix.*${version}')\"" 59 | } 60 | default: { 61 | # $cmd = "yum -y --nogpgcheck localinstall pmix*-${version}*" 62 | # $check_onlyif = "test -z \"$(rpm -qa | grep -E 'pmix.*${version}')\"" 63 | # $check_unless = "test -n \"$(rpm -qa | grep -E 'pmix.*${version}')\"" 64 | Package["pmix-${version}"] { 65 | provider => 'rpm', 66 | install_options => ['--nodeps'], 67 | source => "${rpmdir}/${rpm}", 68 | } 69 | Package["pmix-devel-${version}"] { 70 | provider => 'rpm', 71 | install_options => ['--nodeps'], 72 | source => "${rpmdir}/${rpmdevel}", 73 | } 74 | } 75 | } 76 | } 77 | default: { 78 | fail("Module ${module_name} is not supported on ${facts['os']['name']}") 79 | } 80 | } 81 | 82 | # Let's go (independently of the distribution) 83 | if $ensure == 'present' { 84 | package { ["pmix-${version}", "pmix-devel-${version}"]: 85 | ensure => $ensure, 86 | } 87 | } 88 | else { 89 | #notice($cmd) 90 | exec { "uninstall-pmix*${version}*": 91 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 92 | command => $cmd, 93 | onlyif => $check_onlyif, 94 | unless => $check_unless, 95 | user => 'root', 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /manifests/repo.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: repo.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Class: slurm::repo 11 | # 12 | # This class takes care of the control repository for the slurm configuration, which 13 | # version your slurm configuration files. 14 | # For many reasons, we decided NOT to directly version the /etc/slurm directory, 15 | # but rather to have a control repository cloned in another directory and 16 | # following a specific layout depicted below: 17 | # 18 | # * for the cluster '${clustername}', a root directory named'${clustername}' 19 | # hosts all common slurm configuration files 20 | # * a script '${syncscript}' (typically 'bin/commit_slurm_configs.sh') is 21 | # responsible for synchronizing the configuration and commit it into this 22 | # 23 | # . 24 | # ├── bin/ 25 | # | └── commit_slurm_configs.sh 26 | # └── / 27 | # ├── cgroup.conf 28 | # ├── gres.conf 29 | # ├── plugstack.conf 30 | # ├── plugstack.conf.d 31 | # │   └── x11.conf 32 | # ├── slurm.conf 33 | # └── topology.conf 34 | # 35 | # 36 | # Also, this server is expected to have push writes on the branch 'server/${::hostname}' 37 | # 38 | # @param ensure 39 | # Ensure the presence (or absence) of the repository - Default: 'present' 40 | # @param force [Boolean] Default: force 41 | # Specifies whether to delete any existing files in the repository path 42 | # if creating a new repository. Use with care. 43 | # @param provider [String] Default: 'git' 44 | # Specifies the backend to use for this vcsrepo resource. 45 | # Valid options: 'bzr', 'git', 'hg', and 'svn'. 46 | # @param basedir [String] Default: '/usr/local/src/git' 47 | # Base directory where to clone the repository 48 | # @param path [String] Default: '' 49 | # Specifies a location for the managed repository. 50 | # It this stays empty, the repository will be cloned under $basedir/$namespace/$reponame 51 | # @param source [String or Hash] 52 | # Specifies a source repository to serve as the upstream for your managed repository. 53 | # Typically a Git repository URL or a hash of remotename => URL mappings 54 | # @param branch [String] Default: 'HEAD' 55 | # The branch/revision to pull 56 | # @param linkdir [String] Default: '' 57 | # An Optional link to create pointing to the working copy of the repository (Ex: "/etc/slurm-${slurm::clustername}") 58 | # @param link_subdir [String] Default: '' 59 | # An Optional subdirectory within the control repository the link is supposed to point to 60 | # 61 | # @example Clone the SLURM control repository into '/usr/local/src/git/ULHPC/slurm' 62 | # # Create the SSH key, using for instance the maestrodev/ssh_keygen module 63 | # ssh_keygen { $slurm::username: 64 | # comment => "${slurm::username}@${::fqdn}", 65 | # home => $slurm::params::home, 66 | # } 67 | # # /!\ Render the host key known globally using sshkey { ... } 68 | # # Now you can expect the clone to work 69 | # class { 'slurm::repo': 70 | # ensure => 'present', 71 | # source => 'ssh://git@gitlab.uni.lu:8022/ULHPC/slurm.git', 72 | # } 73 | # 74 | class slurm::repo ( 75 | Enum['present', 'absent', 'latest'] $ensure = $slurm::params::ensure, 76 | Enum['git', 'bzr', 'hg', 'svn'] $provider = 'git', 77 | String $basedir = $slurm::params::repo_basedir, 78 | String $path = '', 79 | Optional[String] $source = undef, 80 | String $branch = 'HEAD', 81 | String $syncscript = '', 82 | String $linkdir = '', 83 | String $link_subdir = '', 84 | Boolean $force = false, 85 | ) 86 | inherits slurm::params { 87 | if ($source == undef or empty($source)) { 88 | fail("Module ${module_name} requires a valid source to clone the SLURM control repository") 89 | } 90 | 91 | $reponame = basename($source, ".${provider}") 92 | $institute = basename(dirname($source)) 93 | 94 | $real_path = $path ? { 95 | '' => "${basedir}/${institute}/${reponame}", 96 | default => $path, 97 | } 98 | $user = defined(Class[slurm]) ? { 99 | true => $slurm::username, 100 | default => 'root', 101 | } 102 | $group = defined(Class[slurm]) ? { 103 | true => $slurm::group, 104 | default => 'root', 105 | } 106 | 107 | if $ensure in ['present', 'latest'] { 108 | exec { "mkdir -p ${real_path}": 109 | path => '/sbin:/usr/bin:/usr/sbin:/bin', 110 | unless => "test -d ${real_path}", 111 | before => File[$real_path], 112 | } 113 | [dirname($real_path), $real_path].each |String $d| { 114 | if !defined(File[$d]) { 115 | file { $d: 116 | ensure => 'directory', 117 | owner => $user, 118 | group => $group, 119 | mode => $slurm::params::configdir_mode, 120 | before => Vcsrepo[$real_path], 121 | } 122 | } 123 | } 124 | } 125 | else { 126 | file { "${basedir}/${institute}": 127 | ensure => $ensure, 128 | force => true, 129 | } 130 | } 131 | # notice($source) 132 | # notice($real_path) 133 | if !defined(Git::Config['push.default']) { 134 | git::config { 'push.default': 135 | value => 'matching', 136 | user => $slurm::params::username, 137 | } 138 | } 139 | if !defined(Git::Config['user.name']) { 140 | git::config { 'user.name': 141 | value => $slurm::params::comment, 142 | user => $slurm::params::username, 143 | } 144 | } 145 | if !defined(Git::Config['user.email']) { 146 | git::config { 'user.email': 147 | value => "${slurm::params::username}@${facts['networking']['fqdn']}", 148 | user => $slurm::params::username, 149 | } 150 | } 151 | 152 | vcsrepo { $real_path: 153 | ensure => $ensure, 154 | provider => $provider, 155 | source => $source, 156 | user => $user, 157 | revision => $branch, 158 | force => $force, 159 | } 160 | 161 | if !empty($linkdir) { 162 | $link_ensure = $ensure ? { 163 | /(present|latest)/ => 'link', 164 | default => $ensure 165 | } 166 | $link_target = empty($link_subdir) ? { 167 | true => $real_path, 168 | default => "${real_path}/${link_subdir}", 169 | } 170 | file { $linkdir: 171 | ensure => $link_ensure, 172 | target => $link_target, 173 | } 174 | } 175 | } 176 | -------------------------------------------------------------------------------- /manifests/repo/syncto.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: repo/syncto.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # = Define: slurm::repo::syncto 11 | # 12 | # This definition takes care of synchronizing the control repository of the 13 | # slurm configuration (which is cloned using the 'slurm::repo' class) toward a 14 | # directory (typically a shared mountpoint) 15 | # 16 | # @param subdir [String] 17 | # Specifies a source [sub]directory within the repository holding the 18 | # sources we wish to synchronize 19 | # @param target [String] 20 | # Target [shared] directory where to synchronize 21 | # @param purge [Boolean] Default: false 22 | # If set, rsync will use '--delete' 23 | define slurm::repo::syncto ( 24 | Enum['present', 'absent'] $ensure = $slurm::params::ensure, 25 | String $target = '', 26 | String $subdir = '', 27 | Boolean $purge = false, 28 | ) { 29 | include slurm::params 30 | if !defined(Class['slurm::repo']) { 31 | include slurm::repo 32 | } 33 | 34 | # $name is provided at define invocation 35 | $to = empty($target) ? { 36 | true => $name, 37 | default => $target, 38 | } 39 | 40 | $reponame = basename($slurm::repo::source, ".${slurm::repo::provider}") 41 | $institute = basename(dirname($slurm::repo::source)) 42 | $from = $slurm::repo::path ? { 43 | '' => "${slurm::repo::basedir}/${institute}/${reponame}", 44 | default => $slurm::repo::path, 45 | } 46 | rsync::put { "${to}/": 47 | source => "${from}/${subdir}/", 48 | purge => $purge, 49 | options => '-a --copy-links', 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /manifests/slurmctld.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: slurmctld.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::slurmctld 11 | # 12 | # The main helper class specializing the main slurm class for setting up a 13 | # Slurmctld daemon aka the slurm controller 14 | # 15 | # === Warnings 16 | # 17 | # /!\ Always respect the style guide available here[http://docs.puppetlabs.com/guides/style_guide] 18 | # 19 | # [Remember: No empty lines between comments and class definition] 20 | # 21 | class slurm::slurmctld inherits slurm { 22 | case $facts['os']['family'] { 23 | 'Redhat': {} 24 | default: { fail("Module ${module_name} is not supported on ${facts['os']['name']}") } 25 | } 26 | 27 | $dir_ensure = $slurm::ensure ? { 28 | 'present' => 'directory', 29 | default => $slurm::ensure 30 | } 31 | file { $slurm::statesavelocation: 32 | ensure => $dir_ensure, 33 | owner => $slurm::params::username, 34 | group => $slurm::params::group, 35 | mode => $slurm::params::configdir_mode, 36 | force => true, 37 | before => File[$slurm::configdir], 38 | } 39 | 40 | include slurm::install 41 | include slurm::config 42 | Class['slurm::install'] -> Class['slurm::config'] 43 | 44 | if $slurm::manage_firewall { 45 | slurm::firewall { String($slurm::slurmctldport): 46 | ensure => $slurm::ensure, 47 | } 48 | } 49 | 50 | if $slurm::ensure == 'present' { 51 | File <| tag == 'slurm::configfile' |> { 52 | require => File[$slurm::configdir], 53 | } 54 | } 55 | 56 | if $slurm::service_manage == true { 57 | File <| tag == 'slurm::configfile' |> { 58 | notify +> Service['slurmctld'], 59 | } 60 | 61 | service { 'slurmctld': 62 | ensure => ($slurm::ensure == 'present'), 63 | enable => ($slurm::ensure == 'present'), 64 | name => $slurm::params::controller_servicename, 65 | pattern => $slurm::params::controller_processname, 66 | hasrestart => $slurm::params::hasrestart, 67 | hasstatus => $slurm::params::hasstatus, 68 | require => Class['slurm::config'], 69 | } 70 | 71 | # if $slurm::ensure == 'present' { 72 | # Class['slurm::install'] -> 73 | # Class['slurm::config'] -> 74 | # Service['slurmctld'] 75 | # } 76 | # else { 77 | # Service['slurmctld'] -> 78 | # Class['slurm::install'] -> 79 | # Class['slurm::config'] 80 | # } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /manifests/slurmd.pp: -------------------------------------------------------------------------------- 1 | ################################################################################ 2 | # Time-stamp: 3 | # 4 | # File:: slurmd.pp 5 | # Author:: UL HPC Team (hpc-sysadmins@uni.lu) 6 | # Copyright:: Copyright (c) 2017 UL HPC Team 7 | # License:: Apache-2.0 8 | # 9 | # ------------------------------------------------------------------------------ 10 | # == Class: slurm::slurmd 11 | # 12 | # The main helper class specializing the main slurm class for setting up a 13 | # Slurmd daemon 14 | # 15 | # === Warnings 16 | # 17 | # /!\ Always respect the style guide available here[http://docs.puppetlabs.com/guides/style_guide] 18 | # 19 | # [Remember: No empty lines between comments and class definition] 20 | # 21 | class slurm::slurmd inherits slurm { 22 | case $facts['os']['family'] { 23 | 'Redhat': {} 24 | default: { fail("Module ${module_name} is not supported on ${facts['os']['name']}") } 25 | } 26 | 27 | include slurm::install 28 | include slurm::config 29 | Class['slurm::install'] -> Class['slurm::config'] 30 | 31 | if $slurm::manage_firewall { 32 | slurm::firewall { String($slurm::slurmdport): 33 | ensure => $slurm::ensure, 34 | } 35 | slurm::firewall { String($slurm::srunportrange): 36 | ensure => $slurm::ensure, 37 | } 38 | } 39 | 40 | if $slurm::ensure == 'present' { 41 | File <| tag == 'slurm::configfile' |> { 42 | require => File[$slurm::configdir], 43 | } 44 | } 45 | 46 | if $slurm::service_manage == true { 47 | File <| tag == 'slurm::configfile' |> { 48 | notify +> Service['slurmd'], 49 | } 50 | 51 | service { 'slurmd': 52 | ensure => ($slurm::ensure == 'present'), 53 | enable => ($slurm::ensure == 'present'), 54 | name => $slurm::params::servicename, 55 | pattern => $slurm::params::processname, 56 | hasrestart => $slurm::params::hasrestart, 57 | hasstatus => $slurm::params::hasstatus, 58 | require => Class['slurm::config'], 59 | } 60 | 61 | if ($slurm::with_slurmctld or defined(Class['slurm::slurmctld'])) { 62 | Service['slurmctld'] -> Service['slurmd'] 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /metadata.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ULHPC-slurm", 3 | "version": "1.5.2", 4 | "author": "UL HPC Team", 5 | "summary": "Configure and manage Slurm: A Highly Scalable Resource Manager", 6 | "license": "Apache-2.0", 7 | "source": "https://github.com/ULHPC/puppet-slurm", 8 | "project_page": "https://github.com/ULHPC/puppet-slurm", 9 | "issues_url": "https://github.com/ULHPC/puppet-slurm/issues", 10 | "dependencies": [ 11 | { 12 | "name": "puppetlabs-stdlib", 13 | "version_requirement": ">=4.2.2 <10.0.0" 14 | }, 15 | { 16 | "name": "puppetlabs-mysql", 17 | "version_requirement": ">=10.0.0 <16.0.0" 18 | }, 19 | { 20 | "name": "puppetlabs-vcsrepo", 21 | "version_requirement": ">=2.0.0 <6.0.0" 22 | }, 23 | { 24 | "name": "puppetlabs-firewall", 25 | "version_requirement": ">=1.9.0 <9.0.0" 26 | }, 27 | { 28 | "name": "puppet-archive", 29 | "version_requirement": ">=3.0.0 <7.2.0" 30 | }, 31 | { 32 | "name": "puppet-yum", 33 | "version_requirement": ">=2.0.0 <6.3.0" 34 | }, 35 | { 36 | "name": "puppet-selinux", 37 | "version_requirement": ">=1.3.0 <3.5.0" 38 | }, 39 | { 40 | "name": "puppet-epel", 41 | "version_requirement": ">=1.2.2 <6.0.0" 42 | }, 43 | { 44 | "name": "saz-limits", 45 | "version_requirement": ">=3.0.4 <4.0.0" 46 | }, 47 | { 48 | "name": "crayfishx-firewalld", 49 | "version_requirement": ">=3.4.0 <4.0.0" 50 | }, 51 | { 52 | "name": "bodgit-rngd", 53 | "version_requirement": ">=2.0.0 <4.0.0" 54 | } 55 | ], 56 | "operatingsystem_support": [ 57 | { 58 | "operatingsystem": "RedHat", 59 | "operatingsystemrelease": [ 60 | "6", 61 | "7", 62 | "8", 63 | "9" 64 | ] 65 | }, 66 | { 67 | "operatingsystem": "CentOS", 68 | "operatingsystemrelease": [ 69 | "6", 70 | "7", 71 | "8", 72 | "9" 73 | ] 74 | }, 75 | { 76 | "operatingsystem": "AlmaLinux", 77 | "operatingsystemrelease": [ 78 | "8", 79 | "9" 80 | ] 81 | } 82 | ], 83 | "requirements": [ 84 | { 85 | "name": "puppet", 86 | "version_requirement": ">= 4.10.0 < 9.0.0" 87 | } 88 | ], 89 | "mail": "hpc-team@uni.lu", 90 | "description": "Slurm is an open source, fault-tolerant, and highly scalable cluster management and job scheduling system for large and small Linux clusters. This puppet module is designed to configure and manage the different daemons (slurmd, slurmctld, slurmdbd) and components of a typical Slurm architecture", 91 | "docs_project": "ulhpc-puppet-slurm", 92 | "forge_url": "https://forge.puppet.com/ULHPC/slurm", 93 | "tags": [ 94 | "slurm", 95 | "munge", 96 | "pmix", 97 | "slurmd", 98 | "slurmctld", 99 | "slurmdbd" 100 | ], 101 | "pdk-version": "3.2.0", 102 | "template-url": "pdk-default#3.2.0", 103 | "template-ref": "tags/3.2.0-0-gb257ef1" 104 | } -------------------------------------------------------------------------------- /mkdocs.yml: -------------------------------------------------------------------------------- 1 | site_name: Slurm Puppet Module 2 | nav: 3 | - Home: 'index.md' 4 | - Overview: 'overview.md' 5 | - Tests with Vagrant: 'vagrant.md' 6 | - Contributing: 7 | - Overview: 'contributing/index.md' 8 | - Directory Layout: 'contributing/layout.md' 9 | - Repository Setup and Developments: 'contributing/setup.md' 10 | - Module Versioning: 'contributing/versioning.md' 11 | - Documentation/RTFD: 'rtfd.md' 12 | - Contacts: 'contacts.md' 13 | theme: readthedocs 14 | -------------------------------------------------------------------------------- /pdk.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | ignore: [] 3 | -------------------------------------------------------------------------------- /spec/default_facts.yml: -------------------------------------------------------------------------------- 1 | # Use default_module_facts.yml for module specific facts. 2 | # 3 | # Facts specified here will override the values provided by rspec-puppet-facts. 4 | --- 5 | networking: 6 | ip: "172.16.254.254" 7 | ip6: "FE80:0000:0000:0000:AAAA:AAAA:AAAA" 8 | mac: "AA:AA:AA:AA:AA:AA" 9 | is_pe: false 10 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | # frozen_string_literal: true 2 | 3 | RSpec.configure do |c| 4 | c.mock_with :rspec 5 | end 6 | 7 | require 'puppetlabs_spec_helper/module_spec_helper' 8 | require 'rspec-puppet-facts' 9 | 10 | require 'spec_helper_local' if File.file?(File.join(File.dirname(__FILE__), 'spec_helper_local.rb')) 11 | 12 | include RspecPuppetFacts 13 | 14 | default_facts = { 15 | puppetversion: Puppet.version, 16 | facterversion: Facter.version, 17 | } 18 | 19 | default_fact_files = [ 20 | File.expand_path(File.join(File.dirname(__FILE__), 'default_facts.yml')), 21 | File.expand_path(File.join(File.dirname(__FILE__), 'default_module_facts.yml')), 22 | ] 23 | 24 | default_fact_files.each do |f| 25 | next unless File.exist?(f) && File.readable?(f) && File.size?(f) 26 | 27 | begin 28 | require 'deep_merge' 29 | default_facts.deep_merge!(YAML.safe_load(File.read(f), permitted_classes: [], permitted_symbols: [], aliases: true)) 30 | rescue StandardError => e 31 | RSpec.configuration.reporter.message "WARNING: Unable to load #{f}: #{e}" 32 | end 33 | end 34 | 35 | # read default_facts and merge them over what is provided by facterdb 36 | default_facts.each do |fact, value| 37 | add_custom_fact fact, value, merge_facts: true 38 | end 39 | 40 | RSpec.configure do |c| 41 | c.default_facts = default_facts 42 | c.before :each do 43 | # set to strictest setting for testing 44 | # by default Puppet runs at warning level 45 | Puppet.settings[:strict] = :warning 46 | Puppet.settings[:strict_variables] = true 47 | end 48 | c.filter_run_excluding(bolt: true) unless ENV['GEM_BOLT'] 49 | c.after(:suite) do 50 | RSpec::Puppet::Coverage.report!(0) 51 | end 52 | 53 | # Filter backtrace noise 54 | backtrace_exclusion_patterns = [ 55 | %r{spec_helper}, 56 | %r{gems}, 57 | ] 58 | 59 | if c.respond_to?(:backtrace_exclusion_patterns) 60 | c.backtrace_exclusion_patterns = backtrace_exclusion_patterns 61 | elsif c.respond_to?(:backtrace_clean_patterns) 62 | c.backtrace_clean_patterns = backtrace_exclusion_patterns 63 | end 64 | end 65 | 66 | # Ensures that a module is defined 67 | # @param module_name Name of the module 68 | def ensure_module_defined(module_name) 69 | module_name.split('::').reduce(Object) do |last_module, next_module| 70 | last_module.const_set(next_module, Module.new) unless last_module.const_defined?(next_module, false) 71 | last_module.const_get(next_module, false) 72 | end 73 | end 74 | 75 | # 'spec_overrides' from sync.yml will appear below this line 76 | -------------------------------------------------------------------------------- /templates/cgroup.conf.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ##################################################################################### 3 | # cgroup.conf -- Slurm's cgroup support configuration file for the '<%= scope['slurm::clustername'] %>' 4 | # cluster 5 | ##################################################################################### 6 | # Documentation: 7 | # - https://slurm.schedmd.com/cgroup.conf.html 8 | # - For general Slurm Cgroups information, see the Cgroups Guide at 9 | # https://slurm.schedmd.com/cgroups.html 10 | # - Comprehensive description of Linux Control Groups (cgroups): 11 | # https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt 12 | # 13 | # Organization of Slurm Cgroups: 14 | # /cpuset/slurm/uid_/job_/step_0/tasks 15 | # 16 | # Detailed knowledge of cgroups is not required to use cgroups in Slurm, but a basic 17 | # understanding of the following features of cgroups is helpful: 18 | # 19 | # - __Cgroup__: a container for a set of processes subject to common controls or 20 | # monitoring, implemented as a directory and a set of files (state objects) in the 21 | # cgroup virtual filesystem. 22 | # - __Subsystem__ - a module, typically a resource controller, that applies a set of 23 | # parameters to the cgroups in a hierarchy. 24 | # - __Hierarchy__ - a set of cgroups organized in a tree structure, with one or more 25 | # associated subsystems. 26 | # - __State Objects__ - pseudofiles that represent the state of a cgroup or apply 27 | # controls to a cgroup: 28 | # * tasks - identifies the processes (PIDs) in the cgroup. 29 | # * additional state objects specific to each subsystem. 30 | ################################################################################### 31 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. 32 | # In particular, any further changes will be overwritten at the next puppet 33 | # invocation 34 | ################################################################################### 35 | # 36 | 37 | <% if scope['slurm::version'] <= '23.02.6' -%> 38 | CgroupAutomount=<%= scope['slurm::cgroup_automount'] ? 'yes' : 'no' %> 39 | <% end -%> 40 | CgroupMountpoint=<%= scope['slurm::cgroup_mountpoint'] %> 41 | 42 | ### Task/cgroup Plugin ### 43 | <% if scope['slurm::version'] <= '23.02.6' -%> 44 | <% unless scope['slurm::cgroup_allowedkmemspace'].nil? -%> 45 | # Constrain the job cgroup kernel memory to this amount of the allocated memory, specified in bytes 46 | AllowedKmemSpace=<%= scope['slurm::cgroup_allowedkmemspace'] %> 47 | 48 | <% end -%> 49 | <% end -%> 50 | <% if scope['slurm::cgroup_allowedramspace'] != 100 -%> 51 | # Constrain the job cgroup RAM to this percentage of the allocated memory 52 | AllowedRAMSpace=<%= scope['slurm::cgroup_allowedramspace'] %> 53 | 54 | <% end -%> 55 | <% if scope['slurm::cgroup_allowedswapspace'] != 0 -%> 56 | # Constrain the job cgroup swap space to this percentage of the allocated memory 57 | AllowedSwapSpace=<%= scope['slurm::cgroup_allowedswapspace'] %> 58 | 59 | <% end -%> 60 | <% if scope['slurm::cgroup_constraincores'] -%> 61 | # Constrain allowed cores to the subset of allocated resources. 62 | # This functionality makes use of the cpuset subsystem 63 | <% end -%> 64 | ConstrainCores=<%= scope['slurm::cgroup_constraincores'] ? 'yes' : 'no' %> 65 | <% if scope['slurm::cgroup_constraindevices'] or !scope['slurm::cgroup_alloweddevices'].empty? -%> 66 | 67 | # Constrain the job's allowed devices based on GRES allocated resources 68 | # See <%= scope['slurm::configdir'] %>/<%= scope['slurm::params::cgroup_alloweddevices_configfile'] %> 69 | ConstrainDevices=yes 70 | <% end -%> 71 | <% if scope['slurm::version'] <= '23.02.6' -%> 72 | ConstrainKmemSpace=<%= scope['slurm::cgroup_constrainkmemspace'] ? 'yes' : 'no' %> 73 | <% end -%> 74 | ConstrainRAMSpace=<%= scope['slurm::cgroup_constrainramspace'] ? 'yes' : 'no' %> 75 | ConstrainSwapSpace=<%= scope['slurm::cgroup_constrainswapspace'] ? 'yes' : 'no' %> 76 | <% if scope['slurm::cgroup_maxrampercent'] != 100 -%> 77 | 78 | # Upper bound in percent of total RAM on the RAM constraint for a job 79 | MaxRAMPercent=<%= scope['slurm::cgroup_maxrampercent'] %> 80 | 81 | <% end -%> 82 | <% if scope['slurm::cgroup_maxswappercent'] != 100 -%> 83 | # Upper bound (in percent of total RAM) on the amount of RAM+Swap that may be used for a job. 84 | MaxSwapPercent=<%= scope['slurm::cgroup_maxswappercent'] %> 85 | 86 | <% end -%> 87 | <% if scope['slurm::version'] <= '23.02.6' && scope['slurm::cgroup_maxkmempercent'] != 100 -%> 88 | # Upper bound in percent of total Kmem for a job 89 | MaxKmemPercent=<%= scope['slurm::cgroup_maxkmempercent'] %> 90 | 91 | <% end -%> 92 | <% if scope['slurm::version'] <= '23.02.6' -%> 93 | MinKmemSpace=<%= scope['slurm::cgroup_minkmemspace'] %> 94 | <% end -%> 95 | MinRAMSpace=<%= scope['slurm::cgroup_minramspace'] %> 96 | <% if scope['slurm::cgroup_taskaffinity'] -%> 97 | # Set a default task affinity to bind each step task to a subset of the 98 | # allocated cores using sched_setaffinity 99 | # /!\ This feature requires the Portable Hardware Locality (hwloc) library 100 | TaskAffinity=yes 101 | <% end -%> 102 | <% if scope['slurm::version'] >= '23.11.0' -%> 103 | SignalChildrenProcesses=<%= scope['slurm::cgroup_signalchildrenprocesses'] ? 'yes' : 'no' %> 104 | <% end -%> 105 | -------------------------------------------------------------------------------- /templates/cgroup_allowed_devices_file.conf.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ##################################################################################### 3 | # cgroup_allowed_devices_file.conf -- List of allowed devices for the '<%= scope['slurm::clustername'] %>' 4 | # cluster assuming ConstrainDevices=yes in cgroup.conf 5 | ##################################################################################### 6 | # Documentation: 7 | # - https://slurm.schedmd.com/cgroup.conf.html 8 | # - For general Slurm Cgroups information, see the Cgroups Guide at 9 | # https://slurm.schedmd.com/cgroups.html 10 | # - Comprehensive description of Linux Control Groups (cgroups): 11 | # https://www.kernel.org/doc/Documentation/cgroup-v1/cgroups.txt 12 | # 13 | ################################################################################### 14 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. 15 | # In particular, any further changes will be overwritten at the next puppet 16 | # invocation 17 | ################################################################################### 18 | # 19 | # /!\ UPDATE Slurm > 18.08: cgroup_allowed_devices_file.conf is no longer required. 20 | # By default all devices are allowed and GRES, that are associated with a 21 | # device file, that are not requested are restricted. 22 | 23 | <% scope['slurm::cgroup_alloweddevices'].each do |dev| -%> 24 | <%= dev %> 25 | <% end -%> 26 | -------------------------------------------------------------------------------- /templates/gres.conf.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ################################################################################### 3 | # gres.conf -- Slurm's Generic Resource (GRES) configuration file for the '<%= scope['slurm::clustername'] %>' 4 | # cluster 5 | ################################################################################### 6 | # Documentation: https://slurm.schedmd.com/gres.conf.html 7 | # Main supported Name for the generic resources (as per plugins): 8 | # - gpu: Graphics Processing Unit 9 | # - nic: Network Interface Card 10 | # - mic: Intel Many Integrated Core (MIC) processor 11 | # 12 | ################################################################################### 13 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. 14 | # In particular, any further changes will be overwritten at the next puppet 15 | # invocation 16 | ################################################################################### 17 | # 18 | # AutoDetect=nvml 19 | 20 | <% scope['slurm::gres'].each do |nodename, c| -%> 21 | <% child = [] -%> 22 | <% c.each do |k,v| -%> 23 | <% if k == 'comment' -%> 24 | # <%= v %> 25 | <% else -%> 26 | <% child << "#{k.capitalize}=#{v}" -%> 27 | <% end -%> 28 | <% end -%> 29 | NodeName=<%= nodename %> <%= child.join(' ') %> 30 | <% end -%> 31 | -------------------------------------------------------------------------------- /templates/job_submit.lua.erb: -------------------------------------------------------------------------------- 1 | -- -*- mode: lua; -*- 2 | -- Time-stamp: 3 | --[[ 4 | 5 | Copyright (c) 2017 UL HPC Team 6 | . https://hpc.uni.lu 7 | 8 | ------------------------------------------------------------- 9 | SLURM job submission rules/filter for the '<%= scope['slurm::clustername'] %>' cluster 10 | ------------------------------------------------------------- 11 | This program automatically analyzes properties of submitted jobs and selects 12 | the best partition and QOS to route jobs. 13 | 14 | __Changelog__ 15 | 2017-07-28 - Initial version, by V. Plugaru 16 | 2017-08-18 - code reworked and extended, by S.Varrette 17 | 18 | __Resources:__ 19 | - Sample job_submit.lua: 20 | https://github.com/SchedMD/slurm/blob/master/contribs/lua/job_submit.lua 21 | - Job Submit Plugin API: https://slurm.schedmd.com/job_submit_plugins.html 22 | - Slurm C Header: 23 | * https://github.com/SchedMD/slurm/blob/master/slurm/slurm.h.in 24 | * https://github.com/SchedMD/slurm/blob/master/slurm/slurm_errno.h 25 | - LLNL Slurm job_submit plugins, adapted by EDF/HPC Team 26 | https://github.com/edf-hpc/slurm-llnl-misc-plugins/blob/master/job_submit/job_submit.lua 27 | - Other sample code: 28 | * https://gist.github.com/treydock/9320af1c966a972692d2 29 | 30 | ----------------------------------------------------------------------- 31 | For use, this script should be copied into a file name "job_submit.lua" 32 | in the same directory as the SLURM configuration file, slurm.conf. 33 | ----------------------------------------------------------------------- 34 | LUA style guide: http://lua-users.org/wiki/LuaStyleGuide 35 | --]] 36 | 37 | --######################################################################## 38 | -- Default parameters (they can be overwritten in conf_file) 39 | --######################################################################## 40 | DEBUG = false 41 | SCRIPTDIR = debug.getinfo(1).source:match("@?(.*/)") 42 | --CONFIG_FILE = '/etc/slurm/job_submit.conf' 43 | 44 | -- constant list of admission rules, with their priority, description, and function 45 | ALL_RULES = { 46 | ["part"] = { priority = 0, desc = "Default partition", rule = 'rule_default_partition' }, 47 | } 48 | 49 | --[[ 50 | ######################################################################## 51 | Helpers functions 52 | ######################################################################## 53 | --]] 54 | function info(...) 55 | slurm.log_info(...) 56 | end 57 | 58 | ------------------------------------------------------------------------------------ 59 | -- print the formatted string depending on the value of the DEBUG constant 60 | ------------------------------------------------------------------------------------ 61 | function debug(...) 62 | if DEBUG then 63 | slurm.log_info(...) 64 | else 65 | slurm.log_debug(...) 66 | end 67 | end 68 | 69 | ------------------------------------------------------------------------------------ 70 | -- Log the application of a given rule to slurm with a pre-formatted style 71 | -- @param name (IN) short name of the rule, it SHOULD match an entry in ALL_RULES 72 | -- @param fmt, ... (IN) format string, as expected from slurm.log_info 73 | ------------------------------------------------------------------------------------ 74 | function log_rule_info(name, fmt, ...) 75 | local str = "[Rule %u/%s] %s - " .. fmt 76 | info(str, ALL_RULES[name].priority, name, ALL_RULES[name].desc, ...) 77 | end 78 | function log_rule_debug(name, fmt, ...) 79 | local str = "[Rule %u/%s] %s - " .. fmt 80 | debug(str, ALL_RULES[name].priority, name, ALL_RULES[name].desc, ...) 81 | end 82 | 83 | 84 | -- See https://stackoverflow.com/questions/132397/get-back-the-output-of-os-execute-in-lua 85 | ----------------------------------------- 86 | -- Return the output of a system command 87 | -- @param cmd (IN) command to be executed 88 | ----------------------------------------- 89 | function os.capture(cmd) 90 | local f = assert(io.popen(cmd, 'r')) 91 | local s = assert(f:read('*a')) 92 | f:close() 93 | s = string.gsub(s, '^%s+', '') 94 | s = string.gsub(s, '%s+$', '') 95 | s = string.gsub(s, '[\n\r]+', ' ') 96 | return s 97 | end 98 | 99 | 100 | -- See http://lua-users.org/wiki/SplitJoin 101 | ------------------------------------------------------------------------------------- 102 | -- Split separates a string containing a delimiter into the list of substrings 103 | -- between that delimiter 104 | -- @param str (IN) string to split 105 | -- @param sep (IN) separator 106 | ------------------------------------------------------------------------------------- 107 | function split(str, sep) 108 | local t = {} -- NOTE: use {n = 0} in Lua-5.0 109 | local fsep = "(.-)" .. sep 110 | local last_end = 1 111 | local s, e, cap = str:find(fsep, 1) 112 | while s do 113 | if s ~= 1 or cap ~= "" then 114 | table.insert(t,cap) 115 | end 116 | last_end = e+1 117 | s, e, cap = str:find(fsep, last_end) 118 | end 119 | if last_end <= #str then 120 | cap = str:sub(last_end) 121 | table.insert(t, cap) 122 | end 123 | return t 124 | end 125 | 126 | ----------------------------------------- 127 | -- Return the username based on POSIX UID 128 | -- @param submit_uid (IN) UID to check 129 | ----------------------------------------- 130 | function get_username(uid) 131 | local cmd = "id -nu " .. uid 132 | return os.capture(cmd) 133 | end 134 | 135 | ------------------------------------------------------------------------------------- 136 | -- Return the job's partition, using the following heuristics (whatever comes first): 137 | -- * as set by the user, or 138 | -- * as discovered as default partition 139 | -- Otherwise, nil is returned 140 | -- @param job_desc (IN) the job allocation request specifications 141 | -- see C structure: 142 | -- https://github.com/SchedMD/slurm/blob/master/slurm/slurm.h.in#L1374 143 | -- @param part_list (IN) List of pointer to partitions which this user is 144 | -- authorized to use. 145 | -- FIXME: need to check what happens with multiple partitions specified by user 146 | ------------------------------------------------------------------------------------- 147 | function get_job_partition(job_desc, part_list) 148 | local res = job_desc.partition 149 | if res == nil then 150 | for name, info in pairs(part_list) do 151 | if info.flag_default == 1 then 152 | res = info.name 153 | break 154 | end 155 | end 156 | end 157 | return res 158 | end 159 | 160 | 161 | --[[ 162 | ######################################################################## 163 | <%= scope['slurm::clustername'].upcase %> Job Submissions Rules 164 | ######################################################################## 165 | --]] 166 | ---------------------------------------------------------------------------------- 167 | -- Set job's partition, using the following heuristics (whatever comes first): 168 | -- * as set by the user, or 169 | -- * as discovered as default partition 170 | -- @param job_desc (IN/OUT) the job allocation request specifications 171 | -- see C structure: 172 | -- https://github.com/SchedMD/slurm/blob/master/slurm/slurm.h.in#L1374 173 | -- @param part_list (IN) List of pointer to partitions which this user is 174 | -- authorized to use. 175 | ----------------------------------------------------------------------------------- 176 | function rule_default_partition(job_desc, part_list) 177 | if job_desc.partition == nil then 178 | local new_partition = tostring(get_job_partition(job_desc, part_list)) 179 | log_rule_info('part', "job from uid %u(%s), setting default partition to '%s'", 180 | job_desc.user_id, get_username(job_desc.user_id), new_partition) 181 | job_desc.partition = new_partition 182 | end 183 | end 184 | 185 | --[[ 186 | ######################################################################## 187 | -- SLURM job_submit/lua interface 188 | 189 | See https://slurm.schedmd.com/job_submit_plugins.html 190 | ######################################################################## 191 | --]] 192 | 193 | ---------------------------------------------------------------------------------- 194 | -- This function is called by the slurmctld daemon with job submission parameters 195 | -- supplied by the salloc, sbatch or srun command. It can be used to log and/or 196 | -- modify the job parameters supplied by the user as desired. Note that this 197 | -- function has access to the slurmctld's global data structures, for example to 198 | -- examine the available partitions, reservations, etc. 199 | -- @param job_desc (IN/OUT) the job allocation request specifications. 200 | -- @param part_list (IN) List of pointer to partitions which this user is 201 | -- authorized to use. 202 | -- @param submit_uid (IN) user ID initiating the request. 203 | -- @return 0 on success, or an errno on failure. Slurm specific error numbers 204 | -- from slurm/slurm_errno.h may be used. On failure, the request will be 205 | -- rejected and the user will have an appropriate error message printed for that 206 | -- errno. 207 | ---------------------------------------------------------------------------------- 208 | function slurm_job_submit(job_desc, part_list, submit_uid) 209 | -- <%= scope['slurm::clustername'].upcase %> rules for job submission, sorted by priority 210 | table.sort(ALL_RULES, function (e1,e2) return e1.priority < e2.priority end) 211 | for name, v in pairs(ALL_RULES) do 212 | debug("Applying %s rule %s with priority %u", name, v.desc, v.priority) 213 | -- see https://stackoverflow.com/questions/1791234/lua-call-function-from-a-string-with-function-name 214 | _G[v.rule](job_desc, part_list, submit_uid) 215 | end 216 | return slurm.SUCCESS 217 | end 218 | 219 | function slurm_job_modify(job_desc, job_rec, part_list, modify_uid) 220 | return slurm.SUCCESS 221 | end 222 | 223 | -- slurm.log_info("initialized") 224 | return slurm.SUCCESS 225 | -------------------------------------------------------------------------------- /templates/munge_sysconfig.erb: -------------------------------------------------------------------------------- 1 | ############################################################################## 2 | # Extra daemon options for the Munge authentication service. 3 | # See https://github.com/dun/munge/wiki/Installation-Guide#starting-the-daemon 4 | ############################################################################## 5 | # 6 | ############################################################################## 7 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. # 8 | # In particular, any further changes will be overwritten at the next puppet # 9 | # invocation # 10 | ############################################################################## 11 | DAEMON_ARGS="<%= @options.join(' ') %>" 12 | USER="<%= @munge_username %>" 13 | -------------------------------------------------------------------------------- /templates/pam_slurm.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ######################################################################################## 3 | # PAM module for slurm (installed by the slurm-pam_slurm RPM) 4 | # 5 | # Documentation: https://slurm.schedmd.com/faq.html#pam 6 | # See also https://hpcworks.wordpress.com/2017/05/29/setup-slurm-pam-plugin-on-centos-7/ 7 | # 8 | # /!\ This file is being maintained by Puppet. 9 | # DO NOT EDIT 10 | auth required pam_localuser.so 11 | account required pam_unix.so 12 | session required pam_limits.so 13 | -------------------------------------------------------------------------------- /templates/plugstack.conf.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ################################################################################### 3 | # plugstack.conf -- SPANK configuration file for the '<%= scope['slurm::clustername'] %>' 4 | # cluster 5 | ################################################################################### 6 | # Documentation: https://slurm.schedmd.com/spank.html 7 | # 8 | # SPANK provides a very generic interface for stackable plug-ins which may be 9 | # used to dynamically modify the job launch code in Slurm. SPANK plugins may be 10 | # built without access to Slurm source code. They need only be compiled against 11 | # Slurm's spank.h header file, added to the SPANK config file plugstack.conf, 12 | # and they will be loaded at runtime during the next job launch 13 | # 14 | # Resources: 15 | # - https://github.com/grondo/slurm-spank-plugins 16 | # - https://github.com/hautreux/slurm-spank-x11 17 | # - https://github.com/edf-hpc/slurm-llnl-misc-plugins 18 | # 19 | #________________________ 20 | # Example of plugin build 21 | # (typically on one compute node) 22 | # 23 | # mkdir -p /usr/local/src/git 24 | # cd /usr/local/src/git 25 | # git clone https://github.com/hpc2n/spank-private-tmp.git 26 | # # Check the version of the plugin 27 | # grep -i Version spank-private-tmp/slurm-spank-private-tmpdir.spec 28 | # # ... and rename the directory accordingly 29 | # mv spank-private-tmp spank-private-tmp-0.0.2 30 | # tar cvf spank-private-tmp-0.0.2.tar.gz spank-private-tmp-0.0.2 31 | # # Create the RPM '/root/rpmbuild/RPMS/x86_64/spank-private-tmp-0.0.2-1.x86_64.rpm' 32 | # rpmbuild -ta spank-private-tmp-0.0.2.tar.gz 33 | # 34 | # # Now you can install it: 35 | # rpm -i ~/rpmbuild/RPMS/x86_64/spank-private-tmp-0.0.2-1.x86_64.rpm 36 | # # OR 37 | # yum -y --nogpgcheck localinstall ~/rpmbuild/RPMS/x86_64/spank-private-tmp-0.0.2-1.x86_64.rpm 38 | # 39 | ################################################################################### 40 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. 41 | # In particular, any further changes will be overwritten at the next puppet 42 | # invocation 43 | ################################################################################### 44 | # 45 | include /etc/slurm/<%= scope['slurm::params::pluginsdir'] %>/*.conf 46 | -------------------------------------------------------------------------------- /templates/slurmdbd.conf.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ##################################################################################### 3 | # slurmdbd.conf -- Slurm Database Daemon (SlurmDBD) configuration file for the 4 | # '<%= scope['slurm::clustername'] %>' cluster. 5 | # 6 | ##################################################################################### 7 | # Documentation: https://slurm.schedmd.com/slurmdbd.conf.html 8 | # 9 | # This file should be only on the computer where SlurmDBD executes and should only be 10 | # readable by the user which executes SlurmDBD (e.g. "slurm"). 11 | # /!\ This file should be protected from unauthorized access since it contains a 12 | # database password. 13 | ################################################################################### 14 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. 15 | # In particular, any further changes will be overwritten at the next puppet 16 | # invocation 17 | ################################################################################### 18 | # 19 | 20 | ##################### 21 | ### General Info ### 22 | ##################### 23 | SlurmUser=<%= scope['slurm::username'] %> 24 | #DefaultQOS=normal,standby 25 | # LOGGING 26 | DebugLevel=<%= scope['slurm::slurmdbd::debuglevel'] %> 27 | <% if scope['slurm::slurmdbd::debugflags'].empty? -%> 28 | #DebugFlags= 29 | <% else -%> 30 | DebugFlags=<%= scope['slurm::slurmdbd::debugflags'].join(',') %> 31 | <% end -%> 32 | LogFile=<%= scope['slurm::logdir'] %>/slurmdbd.log 33 | 34 | <% if scope['slurm::slurmdbddebugsyslog'].empty? -%> 35 | #DebugLevelSyslog= 36 | <% else -%> 37 | DebugLevelSyslog=<%= scope['slurm::slurmdbddebugsyslog']%> 38 | <% end -%> 39 | 40 | PidFile=/var/run/slurmdbd/slurmdbd.pid # created by RuntimeDirectory options in service 41 | # Authentication for communications with the other Slurm components 42 | AuthType=auth/<%= scope['slurm::authtype'] %> 43 | <% unless scope['slurm::authinfo'].empty? -%> 44 | AuthInfo=auth/<%= scope['slurm::authinfo'] %> 45 | <% end -%> 46 | 47 | <% if scope['slurm::authalttypes'].empty? -%> 48 | #AuthAltTypes= 49 | <% else -%> 50 | AuthAltTypes=<%= scope['slurm::authalttypes'].join(',') %> 51 | <% end -%> 52 | 53 | <% if scope['slurm::authaltparameters'].empty? -%> 54 | #AuthAltParameters= 55 | <% else -%> 56 | AuthAltParameters=<%= scope['slurm::authaltparameters'].join(',') %> 57 | <% end -%> 58 | 59 | # How many seconds between commits on a connection from a Slurmctld. This speeds 60 | # up inserts into the database dramatically. 61 | # /!\ There is a [very] small probability of data loss 62 | <% if scope['slurm::slurmdbd::commitdelay'] > 0 -%> 63 | CommitDelay=<%= scope['slurm::slurmdbd::commitdelay'] %> 64 | <% else -%> 65 | #CommitDelay=<%= scope['slurm::slurmdbd::commitdelay'] %> 66 | <% end -%> 67 | #MessageTimeout=300 68 | <% if scope['slurm::slurmdbd::privatedata'].empty? -%> 69 | #PrivateData=accounts,users,usage,jobs 70 | <% else -%> 71 | PrivateData=<%= scope['slurm::slurmdbd::privatedata'].join(',') %> 72 | <% end -%> 73 | 74 | #TrackWCKey=yes 75 | # If set the slurmdbd will mark all idle resources on the cluster as down when a 76 | # slurmctld disconnects or is no longer reachable. 77 | <% if scope['slurm::slurmdbd::trackslurmctlddown'] -%> 78 | TrackSlurmctldDown=yes 79 | <% else -%> 80 | #TrackSlurmctldDown= 81 | <% end -%> 82 | 83 | 84 | ##################### 85 | ### Archive Info ### 86 | ##################### 87 | <% if (scope['slurm::slurmdbd::archivedir'].empty? or scope['slurm::slurmdbd::archivedir'] == '/tmp') -%> 88 | #ArchiveDir="<%= scope['slurm::slurmdbd::archivedir'] %>" 89 | <% else -%> 90 | ArchiveDir="<%= scope['slurm::slurmdbd::archivedir'] %>" 91 | <% end -%> 92 | <% if scope['slurm::slurmdbd::archiveevents'] -%> 93 | ArchiveEvents=yes 94 | <% else -%> 95 | #ArchiveEvents=yes 96 | <% end -%> 97 | <% if scope['slurm::slurmdbd::archivejobs'] -%> 98 | ArchiveJobs=yes 99 | <% else -%> 100 | #ArchiveJobs=yes 101 | <% end -%> 102 | <% if scope['slurm::slurmdbd::archiveresvs'] -%> 103 | ArchiveResvs=yes 104 | <% else -%> 105 | #ArchiveResvs=yes 106 | <% end -%> 107 | #ArchiveScript= 108 | <% if scope['slurm::slurmdbd::archivesteps'] -%> 109 | ArchiveSteps=yes 110 | <% else -%> 111 | #ArchiveSteps=yes 112 | <% end -%> 113 | <% if scope['slurm::slurmdbd::archivesuspend'] -%> 114 | ArchiveSuspend=yes 115 | <% end -%> 116 | <% if scope['slurm::slurmdbd::archivetxn'] -%> 117 | ArchiveTXN=yes 118 | <% end -%> 119 | <% if scope['slurm::slurmdbd::archiveusage'] -%> 120 | ArchiveUsage=yes 121 | <% end -%> 122 | 123 | #################### 124 | ### SlurmDB Info ### 125 | #################### 126 | DbdHost=<%= scope['slurm::slurmdbd::dbdhost'] %> 127 | DbdAddr=<%= scope['slurm::slurmdbd::dbdaddr'] %> 128 | #DbdPort=<%= scope['slurm::slurmdbdport'] %> 129 | <% if scope['slurm::slurmdbd::dbdbackuphost'].empty? -%> 130 | #DbdBackupHost= 131 | <% else -%> 132 | DbdBackupHost=<%= scope['slurm::slurmdbd::dbdbackuphost'] %> 133 | <% end -%> 134 | <% unless scope['slurm::slurmdbd::purgeeventafter'].nil? -%> 135 | # Events happening on the cluster over this age are purged from the database 136 | PurgeEventAfter=<%= scope['slurm::slurmdbd::purgeeventafter'] %> 137 | <% end -%> 138 | <% unless scope['slurm::slurmdbd::purgejobafter'].nil? -%> 139 | # Individual job records over this age are purged from the database. 140 | PurgeJobAfter=<%= scope['slurm::slurmdbd::purgejobafter'] %> 141 | <% end -%> 142 | <% unless scope['slurm::slurmdbd::purgeresvafter'].nil? -%> 143 | PurgeResvAfter=<%= scope['slurm::slurmdbd::purgeresvafter'] %> 144 | <% end -%> 145 | <% unless scope['slurm::slurmdbd::purgestepafter'].nil? -%> 146 | PurgeStepAfter=<%= scope['slurm::slurmdbd::purgestepafter'] %> 147 | <% end -%> 148 | <% unless scope['slurm::slurmdbd::purgesuspendafter'].nil? -%> 149 | PurgeSuspendAfter=<%= scope['slurm::slurmdbd::purgesuspendafter'] %> 150 | <% end -%> 151 | <% unless scope['slurm::slurmdbd::purgetxnafter'].nil? -%> 152 | PurgeTXNAfter=<%= scope['slurm::slurmdbd::purgetxnafter'] %> 153 | <% end -%> 154 | <% unless scope['slurm::slurmdbd::purgeusageafter'].nil? -%> 155 | PurgeUsageAfter=<%= scope['slurm::slurmdbd::purgeusageafter'] %> 156 | <% end -%> 157 | 158 | ##################### 159 | ### Database Info ### 160 | ##################### 161 | StorageType=accounting_storage/<%= scope['slurm::slurmdbd::storagetype'] %> 162 | StorageHost=<%= scope['slurm::slurmdbd::storagehost'] %> 163 | <% if scope['slurm::slurmdbd::storagebackuphost'].empty? -%> 164 | #StorageBackupHost= 165 | <% else -%> 166 | StorageBackupHost=<%= scope['slurm::slurmdbd::storagebackuphost'] %> 167 | <% end -%> 168 | StoragePort=<%= scope['slurm::slurmdbd::storageport'] %> 169 | StorageLoc=<%= scope['slurm::slurmdbd::storageloc'].ljust(12) %> # Name of the database 170 | StorageUser=<%= scope['slurm::slurmdbd::storageuser'] %> 171 | # /!\ Password used to gain access to the database 172 | StoragePass=<%= scope['slurm::slurmdbd::storagepass'] %> 173 | -------------------------------------------------------------------------------- /templates/topology.conf.erb: -------------------------------------------------------------------------------- 1 | # -*- mode: conf; -*- 2 | ################################################################################### 3 | # topology.conf -- Slurm's network topology for the '<%= scope['slurm::clustername'] %>' cluster 4 | # for use with the 'topology/<%= scope['slurm::topology'] %>' plugin 5 | # 6 | ################################################################################### 7 | # Documentation: https://slurm.schedmd.com/topology.conf.html 8 | # 9 | # Note: the topology.conf file for an Infiniband switch can be automatically 10 | # generated using the slurmibtopology tool found here: 11 | # https://ftp.fysik.dtu.dk/Slurm/slurmibtopology.sh 12 | # 13 | # Use also 'ibnetdiscover -S [-p]' to feed/check this file. 14 | ################################################################################### 15 | # /!\ DO NOT EDIT THIS FILE: It has been automatically generated by Puppet. 16 | # In particular, any further changes will be overwritten at the next puppet 17 | # invocation 18 | ################################################################################### 19 | # 20 | <% scope['slurm::topology_tree'].each do |switchname, c| -%> 21 | <% child = [] -%> 22 | <% c.each do |k,v| -%> 23 | <% if k == 'comment' -%> 24 | # <%= v %> 25 | <% else -%> 26 | <% child << "#{k == 'linkspeed' ? 'LinkSpeed' : k.capitalize}=#{v}" -%> 27 | <% end -%> 28 | <% end -%> 29 | SwitchName=<%= switchname %> <%= child.join(' ') %> 30 | <% end -%> 31 | -------------------------------------------------------------------------------- /tests/absent.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply -t /vagrant/tests/absent.pp 5 | # sudo puppet apply -t /vagrant/tests/clean.pp 6 | # 7 | node default { 8 | class { 'slurm': 9 | ensure => 'absent', 10 | with_slurmdbd => true, 11 | with_slurmctld => true, 12 | with_slurmd => true, 13 | #manage_munge => false, 14 | } 15 | # class { 'slurm::munge': 16 | # ensure => 'absent' 17 | # } 18 | } 19 | -------------------------------------------------------------------------------- /tests/advanced.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply -t /vagrant/tests/advanced.pp 5 | # 6 | node default { 7 | include slurm::params 8 | 9 | $clustername = 'thor' 10 | # Example of the topology tree 11 | $tree = { 12 | 's0' => { nodes => 'dev[0-5]' }, 13 | 's1' => { nodes => 'dev-[6-11]' }, 14 | 's2' => { nodes => 'dev-[12-17]' }, 15 | 's3' => { 16 | comment => 'GUID: XXXXXX - switch 0', 17 | switches => 's[0-2]', 18 | linkspeed => '100Mb/s', }, 19 | } 20 | # Definition of the nodes 21 | $nodes = { 22 | 'DEFAULT' => { 23 | comment => 'Test', 24 | content => 'CPUs=1 Sockets=1 CoresPerSocket=1 ThreadsPerCore=1 RealMemory=512 State=UP', }, 25 | 'access' => 'CPUs=2 Sockets=1 CoresPerSocket=2 ThreadsPerCore=1 State=UNKNOWN', 26 | 'thor-[1-3]' => 'CPUs=2 Sockets=1 CoresPerSocket=2 ThreadsPerCore=1 RealMemory=400 State=UNKNOWN', 27 | } 28 | # Definition of the partitions 29 | $partitions = { 30 | 'DEFAULT' => 'State=UP AllowGroups=clusterusers AllowAccounts=ALL DisableRootJobs=YES OverSubscribe=NO', 31 | 'interactive' => { 32 | priority => 50, 33 | nodes => 'iris-[081-090]', 34 | }, 35 | 'admin' => { 36 | priority => 100, 37 | hidden => true, 38 | nodes => 'iris-[001-100]', 39 | allowaccounts => 'ulhpc', 40 | allowgroups => 'project_sysadmins', 41 | allowqos => 'qos-admin', 42 | content => 'DefaultTime=0-10:00:00 MaxTime=5-00:00:00 MaxNodes=UNLIMITED', 43 | }, 44 | 'batch' => { 45 | priority => 50, 46 | nodes => 'iris-[001-080]', 47 | allowqos => ['qos-besteffort', 'qos-batch', 'qos-batch-001'], 48 | content => 'DefaultTime=0-10:00:00 MaxTime=5-00:00:00 MaxNodes=UNLIMITED', 49 | }, 50 | } 51 | $qos = { 52 | 'qos-besteffort' => { priority => 0, }, 53 | 'qos-batch' => { 54 | priority => 100, 55 | preempt => 'qos-besteffort', 56 | grpnodes => 30, 57 | }, 58 | 'qos-interactive' => { 59 | preempt => 'qos-besteffort', 60 | grpnodes => 8, 61 | }, 62 | 'qos-long' => { 63 | preempt => 'qos-besteffort', 64 | grpnodes => 8, 65 | }, 66 | 'qos-batch-001' => 'Priority=100 Preempt=qos-besteffort GrpNodes=50 flags=OverPartQOS', 67 | } 68 | 69 | # Let's go, all-in-one run 70 | class { 'slurm': 71 | clustername => $clustername, 72 | with_slurmdbd => true, 73 | with_slurmctld => true, 74 | with_slurmd => true, 75 | manage_firewall => true, 76 | # topology => 'tree', 77 | # topology_tree => $tree, 78 | # nodes => $nodes, 79 | partitions => $partitions, 80 | qos => $qos, 81 | service_manage => false, 82 | } 83 | 84 | #notice(inline_template("<%= scope['slurm::qos'].to_yaml %>")) 85 | include slurm::accounting 86 | } 87 | -------------------------------------------------------------------------------- /tests/build.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | # 13 | # You can execute this manifest as follows in your vagrant box 14 | # 15 | # sudo puppet apply --modulepath /vagrant/tests/vagrant/puppet/modules -vt /vagrant/tests/build.pp 16 | # 17 | node default { 18 | require slurm::params 19 | $version = $::slurm::params::version 20 | $ensure = 'present' #'absent' 21 | 22 | slurm::download { $version: 23 | ensure => $ensure, 24 | } 25 | slurm::build { $version: 26 | ensure => $ensure, 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /tests/download.pp: -------------------------------------------------------------------------------- 1 | # Test download of SLURM sources 2 | # 3 | # You can execute this manifest as follows in your vagrant box 4 | # 5 | # sudo puppet apply --modulepath /vagrant/tests/vagrant/puppet/modules -t /vagrant/tests/download.pp 6 | # 7 | node default { 8 | include slurm::params 9 | $ensure = 'present' 10 | # $ensure = 'absent' 11 | 12 | slurm::download { $::slurm::params::version: 13 | ensure => $ensure, 14 | } 15 | slurm::download { 'slurm-18.08.8.tar.bz2': 16 | ensure => $ensure, 17 | checksum => '4a2c176b54a56763704bcc7abfd9b8a4f91c82b8', 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /tests/init.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | # 13 | # You can execute this manifest as follows in your vagrant box 14 | # 15 | # sudo puppet apply -t /vagrant/tests/init.pp 16 | # 17 | node default { 18 | include slurm 19 | } 20 | -------------------------------------------------------------------------------- /tests/login_node.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply -t /vagrant/tests/login_node.pp 5 | # 6 | node default { 7 | #include ::slurm::params 8 | 9 | include slurm 10 | include slurm::login 11 | } 12 | -------------------------------------------------------------------------------- /tests/munge.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | # 13 | # You can execute this manifest as follows in your vagrant box 14 | # 15 | # sudo puppet apply -t /vagrant/tests/munge.pp 16 | # 17 | node default { 18 | include slurm::munge 19 | } 20 | -------------------------------------------------------------------------------- /tests/pam.pp: -------------------------------------------------------------------------------- 1 | # The baseline for module testing used by Puppet Labs is that each manifest 2 | # should have a corresponding test manifest that declares that class or defined 3 | # type. 4 | # 5 | # Tests are then run by using puppet apply --noop (to check for compilation 6 | # errors and view a log of events) or by fully applying the test in a virtual 7 | # environment (to compare the resulting system state to the desired state). 8 | # 9 | # Learn more about module testing here 10 | # http://docs.puppetlabs.com/guides/tests_smoke.html 11 | # 12 | # 13 | # You can execute this manifest as follows in your vagrant box 14 | # 15 | # sudo puppet apply -t /vagrant/tests/pam.pp 16 | # 17 | node default { 18 | include slurm::pam 19 | } 20 | -------------------------------------------------------------------------------- /tests/pmix.pp: -------------------------------------------------------------------------------- 1 | # Test download and build of PMIx sources 2 | # 3 | # You can execute this manifest as follows in your vagrant box 4 | # 5 | # sudo puppet apply --modulepath /vagrant/tests/vagrant/puppet/modules -t /vagrant/tests/pmix.pp 6 | # 7 | node default { 8 | include slurm::params 9 | 10 | $version = $::slurm::params::pmix_version 11 | $checksum = $::slurm::params::pmix_src_checksum 12 | $ensure = 'present' 13 | # $ensure = 'absent' 14 | 15 | class { 'slurm::pmix': 16 | ensure => $ensure, 17 | version => $version, 18 | } 19 | 20 | # slurm::pmix::download { $version: 21 | # ensure => $ensure, 22 | # } 23 | # slurm::pmix::build { $version: 24 | # ensure => $ensure, 25 | # #defines => [ 'install_in_opt 1' ], 26 | # require => Slurm::Pmix::Download[$version] 27 | # } 28 | # slurm::pmix::install { $version: 29 | # ensure => $ensure, 30 | # require => Slurm::Pmix::Build[$version] 31 | # } 32 | } 33 | -------------------------------------------------------------------------------- /tests/repo.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply -t /vagrant/tests/repo.pp 5 | # 6 | node default { 7 | class { 'slurm::repo': 8 | ensure => 'present', 9 | source => 'https://github.com/SchedMD/slurm.git', 10 | #'ssh://git@github.com/ULHPC/slurm-control.git', 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /tests/slurmctld.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply --modulepath /vagrant/tests/vagrant/puppet/modules -t /vagrant/tests/slurmctld.pp 5 | # 6 | node default { 7 | include slurm::params 8 | 9 | class { 'slurm': 10 | clustername => 'thor', 11 | service_manage => false, 12 | manage_firewall => true, 13 | #wrappers => $slurm::params::extra_rpms_basename 14 | } 15 | include slurm::slurmctld 16 | } 17 | -------------------------------------------------------------------------------- /tests/slurmd.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply -t /vagrant/tests/slurmd.pp 5 | # 6 | node default { 7 | #include ::slurm::params 8 | 9 | class { 'slurm': 10 | service_manage => false, 11 | manage_firewall => true, 12 | } 13 | include slurm::slurmd 14 | } 15 | -------------------------------------------------------------------------------- /tests/slurmdbd.pp: -------------------------------------------------------------------------------- 1 | # 2 | # You can execute this manifest as follows in your vagrant box 3 | # 4 | # sudo puppet apply --modulepath /vagrant/tests/vagrant/puppet/modules -t /vagrant/tests/slurmdbd.pp 5 | # 6 | node default { 7 | # include ::slurm::params 8 | 9 | include slurm 10 | class { 'slurm::slurmdbd': 11 | privatedata => ['accounts', 'users', 'usage', 'jobs'], 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /tests/vagrant/config.yaml: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml; -*- 2 | # Time-stamp: 3 | ################################################################################ 4 | # Complementary configuration for Vagrant 5 | # You can overwrite here the default settings defined in ../../Vagrantfile and 6 | # rework the SLURM configuration and VM deployed (i.e. the characteristics of 7 | # the virtual cluster deployed) 8 | # See config.yaml.sample for all possible settings 9 | 10 | # :defaults: 11 | # :nnodes: 2 12 | 13 | # :slurm: 14 | # :clustername: iris 15 | -------------------------------------------------------------------------------- /tests/vagrant/config.yaml.sample: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml; -*- 2 | # Time-stamp: 3 | ################################################################################ 4 | # Complementary configuration for Vagrant 5 | # You can overwrite here the default settings defined in ../../Vagrantfile and 6 | # rework the SLURM configuration and VM deployed (i.e. the characteristics of 7 | # the virtual cluster deployed) 8 | 9 | #___________________________________________ 10 | # Complete / re-define the default boxes below 11 | # Format: 12 | # :: / # see https://vagrantcloud.com 13 | # :boxes: 14 | # :windows2012: 'opentable/win-2012r2-standard-amd64-nocm' 15 | # :freebsd12: 'freebsd/FreeBSD-12.0-RELEASE' 16 | # :centos7: 'centos/7', 17 | # :debian8: 'debian/contrib-jessie64', 18 | # :ubuntu14: 'ubuntu/trusty64' 19 | 20 | #_________________________________________________ 21 | # Default settings (in particular number of nodes) 22 | # :defaults: 23 | # :os: :centos7 # Default OS from the above box definition 24 | # :ram: 512 # Default RAM 25 | # :vcpus: 2 # Default number of virtual CPUs 26 | # :vbguest_auto_update: 1 # check/update box guest additions 27 | # :nnodes: 2 # Number of computing nodes to deploy in the cluster 28 | # 29 | #____________________ 30 | # Network settings 31 | # :network: 32 | # :domain: 'vagrant.dev' # network domain to use 33 | # :range: '10.10.1.0/24' # IP range to use 34 | # 35 | #_______________________________________________________________________ 36 | # Default setting for the simulated compute nodes of the virtual cluster 37 | # :nodes: 38 | # :cpus: 2 39 | # :sockets: 1 40 | # :ram: 512 41 | # :realmemory: 400 # this has to be reported to Slurm 42 | # :cores_per_socket: 2 43 | # :thread_per_core: 1 44 | # :state: UNKNOWN 45 | # 46 | #_______________________________________________________________________ 47 | # Main characteristics of the Slurm configuration (i.e. clustername and 48 | # partitions) which will be used to create the hiera config 49 | # hieradata/locals.yaml 50 | # :slurm: 51 | # :clustername: thor 52 | # # Partition Format -- associated QOS will be named 'qos-' 53 | # # '': 54 | # # :nodes: n # Number of nodes 55 | # # :priority: n # Job Scheduling Priority for the QOS 56 | # # :content: [...] # content/flags config expected for the partition 57 | # :partitions: 58 | # DEFAULT: 59 | # :content: 'State=UP AllowGroups=clusterusers AllowAccounts=ALL DisableRootJobs=YES OverSubscribe=NO' 60 | # admin: 61 | # :priority: 100 62 | # :content: 'Hidden=YES DefaultTime=0-10:00:00 MaxTime=5-00:00:00 MaxNodes=UNLIMITED AllowQos=qos-admin' 63 | # interactive: 64 | # :nodes: 1 65 | # :priority: 20 66 | # :content: 'DefaultTime=0-1:00:00 MaxTime=0-4:00:00 AllowQos=qos-besteffort,qos-interactive' 67 | # batch: 68 | # :nodes: 2 69 | # :priority: 20 70 | # :content: 'DefaultTime=0-2:00:00 MaxTime=5-00:00:00 MaxNodes=UNLIMITED Default=YES' 71 | # AllowQos=qos-besteffort,qos-batch 72 | 73 | #_____________________________________________________________ 74 | # VMs / Vagrant boxes to deploy (APART from the compute nodes) 75 | # Format: 76 | # : 77 | # :hostname: 78 | # :desc: 79 | # :os: 80 | # :ram: 81 | # :vcpus: 82 | # :role: 83 | # 84 | # :vms: 85 | # slurm-master: 86 | # :ram: 2048 87 | # :vcpus: 2 88 | # :desc: 'Slurm Controller #1 (primary)' 89 | # :role: controller 90 | # access: 91 | # :hostname: access 92 | # :ram: 1024 93 | # :vcpus: 1 94 | # :desc: Cluster frontend 95 | # :role: login 96 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/.gitignore: -------------------------------------------------------------------------------- 1 | *.lock 2 | metadata.json 3 | .librarian/ 4 | .tmp/ 5 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/Makefile: -------------------------------------------------------------------------------- 1 | ################################################################################## 2 | # Makefile - Configuration file for GNU make (http://www.gnu.org/software/make/) 3 | # Time-stamp: 4 | # 5 | # Copyright (c) 2018 Sebastien Varrette 6 | # 7 | ############################## Variables Declarations ############################ 8 | 9 | CURDIR = $(dir $(realpath $(firstword $(MAKEFILE_LIST)))) 10 | 11 | MODULES_DIR = modules 12 | MANIFESTS_DIR = manifests 13 | HIERADATA_DIR = hieradata 14 | 15 | MODULES = $(sort $(dir $(wildcard $(MODULES_DIR)/*/))) 16 | 17 | # all: setup 18 | 19 | # .PHONY: setup 20 | # setup: 21 | # r10k puppetfile install -v 22 | # $(MAKE) check 23 | 24 | # check: 25 | # puppet module --modulepath $(CURDIR)/modules --color true list --tree 26 | 27 | print: 28 | @echo "MODULES = $(MODULES)" 29 | 30 | clean: 31 | @if [ -f "$(HIERADATA_DIR)/custom.yaml" ]; then \ 32 | echo "=> remove custom hiera"; \ 33 | rm -f $(HIERADATA_DIR)/custom.yaml;\ 34 | fi 35 | 36 | distclean: clean 37 | @if [ -n "$(MODULES)" ]; then \ 38 | echo "=> remove puppet modules"; \ 39 | echo "(simulating) rm -rf $(MODULES)";\ 40 | fi 41 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hiera.yaml: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml; -*- 2 | # Time-stamp: 3 | ################################################################################ 4 | # _ _ _ ____ __ _ 5 | # | | | (_) ___ _ __ __ _ / ___|___ _ __ / _(_) __ _ 6 | # | |_| | |/ _ \ '__/ _` | | | / _ \| '_ \| |_| |/ _` | 7 | # | _ | | __/ | | (_| | | |__| (_) | | | | _| | (_| | 8 | # |_| |_|_|\___|_| \__,_| \____\___/|_| |_|_| |_|\__, | 9 | # |___/ 10 | ################################################################################ 11 | # Puppet Hiera configuration, which is used to configure the hierarchy, which 12 | # backend(s) to use, and settings for each backend. 13 | # - Doc: https://docs.puppet.com/puppet/latest/hiera_config_yaml_5.html 14 | # 15 | --- 16 | version: 5 # below version 5 are deprecated starting puppet 4.9 17 | 18 | ### default datadir and backend for hierarchy levels. 19 | defaults: # Used for any hierarchy level that omits these keys. 20 | datadir: hieradata # Should be absolute with vagrant 21 | data_hash: yaml_data # Use the built-in YAML backend. 22 | 23 | hierarchy: 24 | #______________________ 25 | - name: "Custom data" 26 | path: "custom.yaml" 27 | #___________________________ 28 | - name: "Role Specific data" 29 | path: "roles/%{::role}.yaml" 30 | #______________________ 31 | - name: "Local settings (from vagrant config)" 32 | path: "locals.yaml" 33 | #______________________ 34 | - name: "Default data" # Human-readable name. 35 | path: "defaults.yaml" # File path, relative to datadir. 36 | # ^^^^^ IMPORTANT: include the file extension! 37 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hieradata/.gitignore: -------------------------------------------------------------------------------- 1 | locals.yaml 2 | custom.yaml 3 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hieradata/defaults.yaml: -------------------------------------------------------------------------------- 1 | # Default Hiera values for Puppet 2 | --- 3 | msg: "serving %{::role} role" 4 | 5 | # Build in vagrant box 6 | # share the generated RPMs to avoid rebuild in each VM 7 | slurm::builddir: '/vagrant/tests/vagrant/rpmbuild' 8 | 9 | 10 | 11 | # SLURM general settings 12 | slurm::uid: 900 13 | slurm::gid: 900 14 | slurm::service_manage: true 15 | 16 | ## SlurmDBD settings 17 | slurm::slurmdbd::dbdhost: 'localhost' 18 | slurm::slurmdbd::dbdaddr: 'localhost' 19 | slurm::slurmdbd::storagehost: "%{::hostname}" 20 | slurm::slurmdbd::storageloc: 'slurm' 21 | slurm::slurmdbd::storageport: 3306 22 | slurm::slurmdbd::storagetype: 'mysql' 23 | 24 | 25 | # MUNGE Authentication 26 | slurm::manage_munge: true 27 | slurm::munge_create_key: false 28 | slurm::munge_uid: 950 29 | slurm::munge_gid: 950 30 | # Below key content should be normally encrypted with eyaml on prod systems 31 | # 32 | slurm::munge_key_content: 'GNAimY7vUIYoAiBgriWflMvK1vFzRPxm6kcVu/wduKI' 33 | 34 | # Slurm.conf parameters 35 | slurm::batchstarttimeout: 60 36 | slurm::getenvtimeout: 5 37 | 38 | slurm::acct_storageenforce: 39 | - 'qos' 40 | - 'limits' 41 | - 'associations' 42 | slurm::acct_gatherenergytype: 'rapl' 43 | 44 | #slurm::defmempercpu: 4096 45 | #slurm::maxmempercpu: 27000 46 | slurm::schedulertype: 'backfill' 47 | slurm::selecttype: 'cons_res' 48 | slurm::selecttype_params: 49 | - 'CR_Core_Memory' 50 | - 'CR_CORE_DEFAULT_DIST_BLOCK' 51 | 52 | slurm::grestypes: 53 | - 'gpu' 54 | 55 | slurm::licenses: 'forge:576,perfreport:64' 56 | slurm::mpidefault: 'pmi2' 57 | slurm::mpiparams: 'ports=55000-59999' 58 | slurm::srunportrange: '40000-50000' 59 | slurm::jobrequeue: false 60 | 61 | slurm::priorityweightage: 2000 62 | slurm::priorityweightfairshare: 10000 63 | slurm::priorityweightpartition: 1000 64 | slurm::priorityweightqos: 1 65 | slurm::priorityflags: 66 | - 'DEPTH_OBLIVIOUS' 67 | slurm::prologflags: 68 | - 'Alloc' 69 | - 'Contain' 70 | - 'X11' 71 | slurm::messagetimeout: 30 72 | slurm::resumetimeout: 600 73 | slurm::taskplugin: ['affinity', 'cgroup'] 74 | slurm::taskpluginparams : 75 | - 'none' 76 | 77 | ############################### 78 | ### cgroup.conf settings ### 79 | ################################# 80 | # new default in 18.08 SLURM and related to bug 81 | # https://bugs.schedmd.com/show_bug.cgi?id=5507 82 | slurm::cgroup_constrainkmemspace: false 83 | # ensure job constraints on GRES such as GPUs 84 | slurm::cgroup_constraindevices: true 85 | slurm::cgroup_alloweddevices: 86 | - '/dev/null' 87 | - '/dev/urandom' 88 | - '/dev/zero' 89 | - '/dev/sda*' 90 | - '/dev/cpu/*/*' 91 | - '/dev/pts/*' 92 | - '/dev/nvme0*' 93 | 94 | 95 | ### PAM Pluggable Authentication Modules (PAM) 96 | slurm::pam::allowed_users: 97 | - vagrant 98 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hieradata/roles/controller.yaml: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml -*- 2 | # Time-stamp: 3 | ########################################################################### 4 | # Puppet hiera settings for a SLURM controller = Head node + DBD node 5 | --- 6 | 7 | # Profiles key may be used to include profile classes 8 | profiles: 9 | - '::profiles::slurm' 10 | - '::profiles::slurm::slurmdbd' 11 | - '::profiles::slurm::slurmctld' 12 | 13 | slurm::with_slurmd: false 14 | slurm::with_slurmctld: true 15 | slurm::with_slurmdbd: true 16 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hieradata/roles/db.yaml: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml -*- 2 | # Time-stamp: 3 | ########################################################################### 4 | # Puppet hiera settings for a Slurm DBD node 5 | --- 6 | 7 | # Profiles key may be used to include profile classes 8 | profiles: 9 | - '::profiles::slurm' 10 | - '::profiles::slurm::slurmdbd' 11 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hieradata/roles/login.yaml: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml -*- 2 | # Time-stamp: 3 | ########################################################################### 4 | # Puppet hiera settings for a SLURM Compute nodes 5 | --- 6 | 7 | # Profiles key may be used to include profile classes 8 | profiles: 9 | - '::profiles::slurm' 10 | - '::profiles::slurm::login' 11 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/hieradata/roles/node.yaml: -------------------------------------------------------------------------------- 1 | # -*- mode: yaml -*- 2 | # Time-stamp: 3 | ########################################################################### 4 | # Puppet hiera settings for a SLURM Compute nodes 5 | --- 6 | 7 | # Profiles key may be used to include profile classes 8 | profiles: 9 | - '::profiles::slurm' 10 | - '::profiles::slurm::slurmd' 11 | 12 | slurm::with_slurmd: true 13 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/manifests/default.pp: -------------------------------------------------------------------------------- 1 | # File:: default.pp 2 | # Author:: Sebastien Varrette () 3 | # Copyright:: Copyright (c) 2018 Sebastien Varrette 4 | # License:: Apache-2.0 5 | # 6 | # ------------------------------------------------------------------------------ 7 | node default { 8 | # Setup pre and post run stages 9 | # Typically these are only needed in special cases but are good to have 10 | stage { ['pre', 'post']: } 11 | Stage['pre'] -> Stage['main'] -> Stage['post'] 12 | Package { ensure => 'present' } 13 | 14 | # Check that the hiera configuration is working... 15 | # if not the puppet provisioning will fail. 16 | $msg=lookup('msg') 17 | notice("Role: ${facts['role']}") 18 | #notice("Message: ${msg}") 19 | 20 | lookup('profiles', { merge => unique }).contain 21 | } 22 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/modules/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/site/profiles/manifests/slurm.pp: -------------------------------------------------------------------------------- 1 | # -*- mode: puppet; -*- 2 | # Time-stamp: 3 | ########################################################################################### 4 | # Profile (base) class used for slurm general settings 5 | 6 | class profiles::slurm { 7 | #require ::slurm::params 8 | include slurm 9 | } 10 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/site/profiles/manifests/slurm/login.pp: -------------------------------------------------------------------------------- 1 | # -*- mode: puppet; -*- 2 | # Time-stamp: 3 | ########################################################################################### 4 | # Profile class used for setting up a Login node (cluster frontend/access) 5 | # 6 | 7 | class profiles::slurm::login { 8 | include profiles::slurm 9 | include slurm::login 10 | } 11 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/site/profiles/manifests/slurm/slurmctld.pp: -------------------------------------------------------------------------------- 1 | # -*- mode: puppet; -*- 2 | # Time-stamp: 3 | ########################################################################################### 4 | # Profile class used for setting up a Slurm Head node (where the slurmctld daemon runs) 5 | # 6 | 7 | class profiles::slurm::slurmctld { 8 | include profiles::slurm 9 | include slurm::slurmctld 10 | } 11 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/site/profiles/manifests/slurm/slurmd.pp: -------------------------------------------------------------------------------- 1 | # -*- mode: puppet; -*- 2 | # Time-stamp: 3 | ########################################################################################### 4 | # Profile class used for setting up a Slurm Compute node 5 | # 6 | 7 | class profiles::slurm::slurmd { 8 | include profiles::slurm 9 | include slurm::slurmd 10 | } 11 | -------------------------------------------------------------------------------- /tests/vagrant/puppet/site/profiles/manifests/slurm/slurmdbd.pp: -------------------------------------------------------------------------------- 1 | # -*- mode: puppet; -*- 2 | # Time-stamp: 3 | ########################################################################################### 4 | # Profile class used for setting up a Slurm DBD (DataBase Daemon) node 5 | # 6 | 7 | class profiles::slurm::slurmdbd { 8 | include profiles::slurm 9 | include slurm::slurmdbd 10 | } 11 | -------------------------------------------------------------------------------- /tests/vagrant/rpmbuild/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /tests/vagrant/scripts/puppet_modules_setup.rb: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ########################################################################## 3 | # puppet_module_setup.rb 4 | # @author Sebastien Varrette 5 | # Time-stamp: 6 | # 7 | # @description Prepare the Vagrant box to test this Puppet module 8 | # 9 | # Copyright (c) 2014-2019 Sebastien Varrette 10 | # . http://varrette.gforge.uni.lu 11 | ############################################################################## 12 | 13 | require 'json' 14 | require 'yaml' 15 | require 'falkorlib' 16 | 17 | include FalkorLib::Common 18 | 19 | # Load metadata 20 | basedir = File.directory?('/vagrant') ? '/vagrant' : Dir.pwd 21 | jsonfile = File.join(basedir, 'metadata.json') 22 | puppetdir = File.join(basedir, 'tests', 'vagrant', 'puppet') 23 | 24 | error 'Unable to find the metadata.json' unless File.exist?(jsonfile) 25 | 26 | metadata = JSON.parse(IO.read(jsonfile)) 27 | name = metadata['name'].gsub(%r{^[^\/-]+[\/-]}, '') 28 | # modulepath = `puppet config print modulepath`.chomp 29 | # moduledir = modulepath.split(':').first 30 | moduledir = File.join(puppetdir, 'modules') 31 | 32 | # unless File.directory?(File.join(moduledir, 'stdlib')) 33 | # run %( cd #{moduledir}/.. && librarian-puppet clean && rm Puppetfile* ) 34 | # run %( ln -s /vagrant/metadata.json #{moduledir}/../ ) 35 | # run %( cd #{moduledir}/.. && librarian-puppet install --verbose ) 36 | # end 37 | 38 | metadata['dependencies'].each do |dep| 39 | lib = dep['name'] 40 | shortname = lib.gsub(%r{^.*[/-]}, '') 41 | action = File.directory?("#{moduledir}/#{shortname}") ? 'upgrade --force' : 'install' 42 | run %( puppet module #{action} --target-dir #{moduledir} #{lib} ) 43 | end 44 | 45 | # puts "Module path: #{modulepath}" 46 | puts "Moduledir: #{moduledir}" 47 | 48 | unless File.exist?("#{moduledir}/#{name}") 49 | info "set symlink to the '#{basedir}' module for local developments" 50 | run %( ln -s #{basedir} #{moduledir}/#{name} ) 51 | end 52 | -------------------------------------------------------------------------------- /tests/vagrant/scripts/setup_slurm_accounting.sh: -------------------------------------------------------------------------------- 1 | #! /bin/bash 2 | # Time-stamp: 3 | ################################################################################ 4 | # setup_slurm_accounting.sh - Utility script to create sample cluster, account 5 | # and a set of users in the slurm accounting database 6 | 7 | SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 8 | 9 | SLURM_CLUSTERNAME=thor 10 | SLURM_DEFAULTACCOUNT=ALLUSERS 11 | SLURM_ALLOWED_QOS=ALL 12 | 13 | print_error_and_exit(){ echo "***ERROR*** $*"; exit 1; } 14 | usage() { 15 | cat< Add cluster '${SLURM_CLUSTERNAME}' in accounting database" 39 | ${CMD_PREFIX} sacctmgr -i add cluster ${SLURM_CLUSTERNAME} 40 | 41 | qos_list="$(sacctmgr list qos -p --noheader | cut -d '|' -f 1 | paste -sd ',')" 42 | if [[ "${qos_list}" == *normal* ]]; then 43 | echo "=> removing the default 'normal' QOS" 44 | ${CMD_PREFIX} sacctmgr -i delete qos normal 45 | fi 46 | # list QOS (except qos-admin) 47 | [ "${SLURM_ALLOWED_QOS}" == 'ALL' ] && 48 | SLURM_ALLOWED_QOS="$(sacctmgr list qos -p --noheader | cut -d '|' -f 1 | grep -v 'admin' | paste -sd ',')" 49 | echo "=> add account ${SLURM_DEFAULTACCOUNT} (and associate users-* to it)" 50 | ${CMD_PREFIX} sacctmgr -i add account ${SLURM_DEFAULTACCOUNT} Cluster=${SLURM_CLUSTERNAME} QOS=${SLURM_ALLOWED_QOS} 51 | for u in $(getent passwd | grep '^user' | cut -d ':' -f 1); do 52 | ${CMD_PREFIX} sacctmgr -i add user ${u} DefaultAccount=${SLURM_DEFAULTACCOUNT} 53 | done 54 | echo "=> restarting slurmctld service" 55 | ${CMD_PREFIX} systemctl restart slurmctld 56 | } 57 | 58 | ######## Let's go ######### 59 | [ -z "$(which sacctmgr)" ] && print_error_and_exit "Unable to find 'sacctmgr' command" 60 | 61 | # Check for options 62 | while [ $# -ge 1 ]; do 63 | case $1 in 64 | -h | --help) usage; exit 0;; 65 | -n | --dry-run) CMD_PREFIX="echo";; 66 | -c | --cluster*) shift; SLURM_CLUSTERNAME=$1;; 67 | -a | --account | --defaultaccount) shift; SLURM_DEFAULTACCOUNT=$1;; 68 | -l | --qos*) shift; SLURM_ALLOWED_QOS=$1;; 69 | esac 70 | shift 71 | done 72 | 73 | vagrant_setup_slurm_accounting 74 | 75 | exit 0 # enforce successful completion 76 | -------------------------------------------------------------------------------- /tests/vagrant/scripts/setup_testing_users_groups.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | # Time-stamp: 3 | ############################################### 4 | # Utility script to create sample users 5 | 6 | STARTDIR="$(pwd)" 7 | SCRIPTFILENAME=$(basename $0) 8 | SCRIPTDIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 9 | 10 | # Shared directory hosting common files 11 | VAGRANT_SHARED_DIR='/shared' 12 | 13 | USERGROUP=clusterusers 14 | GID=666 15 | START_UID=5000 16 | LOGIN_PREFIX=user- 17 | HOME_BASEDIR=/shared/users 18 | 19 | usage() { 20 | cat< Add testing users and group" 47 | echo " - setup group '${USERGROUP}'" 48 | ${CMD_PREFIX} groupadd -g ${GID} ${USERGROUP} 49 | ${CMD_PREFIX} usermod -G ${USERGROUP} vagrant 50 | 51 | # echo ' - prepare a shared testing ssh key' 52 | # install -o vagrant -g vagrant -m 600 ${VAGRANT_SHARED_DIR}/.ssh/${ssh_id_rsa} ~vagrant/.ssh/${ssh_id_rsa} 53 | # sudo -u vagrant cat ${VAGRANT_SHARED_DIR}/.ssh/${ssh_id_rsa}.pub >> ~vagrant/.ssh/authorized_keys 54 | 55 | # echo ' - feeding /etc/skel/.ssh' 56 | # mkdir -p /etc/skel/.ssh 57 | # install -o root -g root -m 600 ${VAGRANT_SHARED_DIR}/.ssh/${ssh_id_rsa} /etc/skel/.ssh/${ssh_id_rsa} 58 | # cat ${VAGRANT_SHARED_DIR}/.ssh/${ssh_id_rsa}.pub >> /etc/skel/.ssh/authorized_keys 59 | 60 | # create two sample users 61 | for i in $(seq 1 2); do 62 | u="${LOGIN_PREFIX}$i" 63 | n=$(expr $START_UID + $i) 64 | echo "=> adding testing user '$u' with uid $n" 65 | ${CMD_PREFIX} useradd -b ${basedir} -u ${n} -g ${USERGROUP} ${u} --create-home 66 | done 67 | # On slurm controller, they should be know but not allowed to connect 68 | if [ -x '/sbin/slurmctld' ]; then 69 | access_conf=/etc/security/access.conf 70 | if grep --quiet "${USERGROUP}" ${access_conf}; then 71 | echo "=> group ${USERGROUP} already denied in ${access_conf}" 72 | else 73 | echo "=> denying access to group ${USERGROUP}" 74 | [ -z "${CMD_PREFIX}" ] && echo "-:${USERGROUP}:ALL" >> $access_conf 75 | fi 76 | fi 77 | } 78 | 79 | 80 | ######## Let's go ######### 81 | # Check for options 82 | while [ $# -ge 1 ]; do 83 | case $1 in 84 | -h | --help) usage; exit 0;; 85 | -g | --group) shift; USERGROUP=$1;; 86 | -n | --dry-run) CMD_PREFIX="echo";; 87 | -p | --prefix | --user*) shift; LOGIN_PREFIX=$1;; 88 | --gid) shift; GID=$1;; 89 | --*uid) shift; START_UID=$1;; 90 | esac 91 | shift 92 | done 93 | 94 | 95 | vagrant_setup_testing_users_groups 96 | 97 | exit 0 # enforce successful completion 98 | -------------------------------------------------------------------------------- /tests/vagrant/shared/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | -------------------------------------------------------------------------------- /types/entity.pp: -------------------------------------------------------------------------------- 1 | type Slurm::Entity = Enum['account', 'association', 'cluster', 'coordinator', 'event', 'job', 'qos', 'Resource', 'RunawayJobs', 'stats', 'transaction', 'user', 'wckeys'] 2 | --------------------------------------------------------------------------------