From 19d7fa9030bbd60906b4c7f8664bab2a9fca1787 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Fri, 10 Jul 2026 11:49:47 -0400 Subject: [PATCH 1/4] Rename skip_upgrade to upgrade and add more use cases --- aws/infrastructure.tf | 2 +- azure/infrastructure.tf | 2 +- common/configuration/main.tf | 4 ++-- common/configuration/puppet.yaml.tftpl | 15 +++++++++------ common/variables.tf | 12 ++++++++---- docs/README.md | 15 ++++++++++----- gcp/infrastructure.tf | 2 +- incus/infrastructure.tf | 2 +- openstack/infrastructure.tf | 2 +- 9 files changed, 34 insertions(+), 22 deletions(-) diff --git a/aws/infrastructure.tf b/aws/infrastructure.tf index 25a10f3a..794ef737 100644 --- a/aws/infrastructure.tf +++ b/aws/infrastructure.tf @@ -31,7 +31,7 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - skip_upgrade = var.skip_upgrade + upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/azure/infrastructure.tf b/azure/infrastructure.tf index 72665924..354d6c42 100644 --- a/azure/infrastructure.tf +++ b/azure/infrastructure.tf @@ -31,7 +31,7 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - skip_upgrade = var.skip_upgrade + upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/common/configuration/main.tf b/common/configuration/main.tf index 180631e3..87c25591 100644 --- a/common/configuration/main.tf +++ b/common/configuration/main.tf @@ -23,7 +23,7 @@ variable "guest_passwd" {} variable "public_keys" {} -variable "skip_upgrade" {} +variable "upgrade" {} variable "bastion_tags" {} resource "tls_private_key" "ssh" { @@ -127,7 +127,7 @@ locals { ssh_authorized_keys = local.public_keys tf_ssh_public_key = chomp(tls_private_key.ssh.public_key_openssh) terraform_facts = local.terraform_facts - skip_upgrade = var.skip_upgrade + upgrade = var.upgrade module_path = path.module user_tf_required = contains(values.tags, "puppet") || length(setintersection(values.tags, var.bastion_tags)) > 0 hostkeys = { diff --git a/common/configuration/puppet.yaml.tftpl b/common/configuration/puppet.yaml.tftpl index 9a5a20b7..cfa13c05 100644 --- a/common/configuration/puppet.yaml.tftpl +++ b/common/configuration/puppet.yaml.tftpl @@ -64,10 +64,13 @@ runcmd: # upload the terraform_data.yaml dnf -y install git pciutils unzip dnf -y remove cockpit\* firewalld --exclude=iptables -%{ if ! skip_upgrade ~} - # Upgrade all packages except openvox if already installed - dnf -y upgrade -x openvox* -%{ endif ~} + fi + # Upgrade all packages except openvox if already installed +%{ if upgrade != "none" ~} + - %{ if startswith(upgrade, "vanilla") }test -f /etc/magic-castle-release || %{ endif }dnf -y upgrade -x openvox* %{ if strcontains(upgrade, "security") }--security%{ endif } +%{ endif } + - | + if ! test -f /etc/magic-castle-release; then # Puppet agent configuration and install dnf -y install https://yum.voxpupuli.org/openvox8-release-el-$(grep -oP 'VERSION_ID="\K\d*' /etc/os-release).noarch.rpm dnf -y install openvox-agent-8.23.1 @@ -148,7 +151,7 @@ runcmd: %{ endif ~} # If the current image has already been configured with Magic Castle Puppet environment, # we can start puppet and skip reboot, reducing the delay for bringing the node up. - - test -f /etc/magic-castle-release && systemctl start puppet || true + - dnf needs-restarting -r && test -f /etc/magic-castle-release && systemctl start puppet || true - test -f /run/cloud-init-failed && echo 'WARNING - some steps cloud-init runcmd failed, listed in /run/cloud-init-failed. Manual fixing and rebooting required. ' | tee /etc/motd || true write_files: @@ -241,7 +244,7 @@ output: { all: "| tee -a /var/log/cloud-init-output.log" } power_state: delay: now mode: reboot - condition: test ! -f /etc/magic-castle-release && test ! -f /run/cloud-init-failed + condition: "! dnf needs-restarting -r || (test ! -f /etc/magic-castle-release && test ! -f /run/cloud-init-failed)" # Configure owner of /var/log/cloud-init.log syslog_fix_perms: root:systemd-journal diff --git a/common/variables.tf b/common/variables.tf index b160e61d..21b2f3a2 100644 --- a/common/variables.tf +++ b/common/variables.tf @@ -150,10 +150,14 @@ variable "pool" { default = [] } -variable "skip_upgrade" { - type = bool - default = false - description = "If set to true, the packages already installed in the base image will not be upgraded on first boot." +variable "upgrade" { + type = string + default = "vanilla-all" + description = "If set to all, all base packages are upgraded on first boot. When prefixed with `vanilla-`, upgrade only happen with vanilla based image." + validation { + condition = contains(["all", "none", "security", "vanilla-all", "vanilla-security"], var.upgrade) + error_message = "Upgrade options are: all, none, security, vanilla-all, vanilla-security" + } } variable "puppetfile" { diff --git a/docs/README.md b/docs/README.md index c042eb1f..6ab5b097 100644 --- a/docs/README.md +++ b/docs/README.md @@ -951,16 +951,21 @@ managed by the workload scheduler through Terraform API. For more information, r will be instantiated, others will stay uninstantiated or will be destroyed if previously instantiated. -### 4.20 skip_upgrade (optional) +### 4.20 upgrade (optional) -**default_value** = `false` +**default_value** = `"vanilla-all"` -If true, the base image packages will not be upgraded during the first boot. By default, -all packages are upgraded. +Defines if base image packages are upgraded during the first boot. Possible values are: + +- `"all"`: upgrade all packages +- `"none"`: do not upgrade packages +- `"security"`: upgrade security packages only +- `"vanilla-all"`: upgrade all packages only when booting from a vanilla base image +- `"vanilla-security"`: upgrade security packages only when booting from a vanilla base image **Post build modification effect**: No effect on currently built instances. Ones created after the modification will take into consideration the new value of the parameter to determine -whether they should upgrade the base image packages or not. +how they should upgrade the base image packages. ### 4.21 puppetfile (optional) diff --git a/gcp/infrastructure.tf b/gcp/infrastructure.tf index ff5d1f97..70af17f6 100644 --- a/gcp/infrastructure.tf +++ b/gcp/infrastructure.tf @@ -31,7 +31,7 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - skip_upgrade = var.skip_upgrade + upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/incus/infrastructure.tf b/incus/infrastructure.tf index 218a45e9..0f23771e 100644 --- a/incus/infrastructure.tf +++ b/incus/infrastructure.tf @@ -27,7 +27,7 @@ module "configuration" { software_stack = var.software_stack cloud_provider = "incus" cloud_region = "local" - skip_upgrade = var.skip_upgrade + upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/openstack/infrastructure.tf b/openstack/infrastructure.tf index 07eb35f7..78cac3d6 100644 --- a/openstack/infrastructure.tf +++ b/openstack/infrastructure.tf @@ -26,7 +26,7 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - skip_upgrade = var.skip_upgrade + upgrade = var.upgrade puppet_conf = var.puppet_conf } From 7d80de372e6ef08a7441443f755d637220a7eaa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Fri, 10 Jul 2026 12:21:32 -0400 Subject: [PATCH 2/4] Apply grubby when reboots is required or vanilla image --- common/configuration/puppet.yaml.tftpl | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/common/configuration/puppet.yaml.tftpl b/common/configuration/puppet.yaml.tftpl index cfa13c05..2477a276 100644 --- a/common/configuration/puppet.yaml.tftpl +++ b/common/configuration/puppet.yaml.tftpl @@ -75,12 +75,6 @@ runcmd: dnf -y install https://yum.voxpupuli.org/openvox8-release-el-$(grep -oP 'VERSION_ID="\K\d*' /etc/os-release).noarch.rpm dnf -y install openvox-agent-8.23.1 install -m 700 /dev/null /opt/puppetlabs/bin/postrun - # kernel configuration -%{ if cloud_provider != "incus" ~} - systemctl disable kdump - grubby --update-kernel=ALL --args="rd.driver.blacklist=nouveau nouveau.modeset=0 crashkernel=0M initcall_blacklist=algif_aead_init" - grub2-mkconfig -o /boot/grub2/grub.cfg -%{ endif ~} %{ if cloud_provider == "gcp" ~} # Google Cloud user-data fact generates a warning because its size is greater than what is allowed (<4096 bytes). # We have no use for it, so we remove startup-script, user-data and user-data-encoding when running in GCE. @@ -89,6 +83,15 @@ runcmd: sed -i "/gce_data\['instance'\] = instance_data/i \ \ \ \ \ \ \ \ \ \ instance_data['attributes'].delete('user-data-encoding')" /opt/puppetlabs/puppet/lib/ruby/vendor_ruby/facter/resolvers/gce.rb %{ endif ~} fi +%{ if cloud_provider != "incus" ~} + # Kernel configuration + - | + if ! test -f /etc/magic-castle-release || ! dnf needs-restarting -r; then + systemctl disable kdump + grubby --update-kernel=ALL --args="rd.driver.blacklist=nouveau nouveau.modeset=0 crashkernel=0M initcall_blacklist=algif_aead_init" + grub2-mkconfig -o /boot/grub2/grub.cfg + fi +%{ endif ~} %{ if contains(tags, "puppet") ~} # Install puppetserver - dnf -y install openvox-server-8.11.0 From 82a9a3b6f5a5373dd0bcb03330c7d2b24fcfee6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Fri, 10 Jul 2026 12:35:19 -0400 Subject: [PATCH 3/4] Allow definition of upgrade value per instance --- aws/infrastructure.tf | 2 +- azure/infrastructure.tf | 2 +- common/configuration/main.tf | 3 +-- common/design/main.tf | 3 ++- common/design/variables.tf | 3 ++- gcp/infrastructure.tf | 2 +- incus/infrastructure.tf | 2 +- openstack/infrastructure.tf | 2 +- 8 files changed, 10 insertions(+), 9 deletions(-) diff --git a/aws/infrastructure.tf b/aws/infrastructure.tf index 794ef737..569cd3f4 100644 --- a/aws/infrastructure.tf +++ b/aws/infrastructure.tf @@ -14,6 +14,7 @@ module "design" { volumes = var.volumes firewall_rules = var.firewall_rules bastion_tags = var.bastion_tags + upgrade = var.upgrade } module "configuration" { @@ -31,7 +32,6 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/azure/infrastructure.tf b/azure/infrastructure.tf index 354d6c42..ff9e3756 100644 --- a/azure/infrastructure.tf +++ b/azure/infrastructure.tf @@ -14,6 +14,7 @@ module "design" { volumes = var.volumes firewall_rules = var.firewall_rules bastion_tags = var.bastion_tags + upgrade = var.upgrade } module "configuration" { @@ -31,7 +32,6 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/common/configuration/main.tf b/common/configuration/main.tf index 87c25591..e90b7db3 100644 --- a/common/configuration/main.tf +++ b/common/configuration/main.tf @@ -23,7 +23,6 @@ variable "guest_passwd" {} variable "public_keys" {} -variable "upgrade" {} variable "bastion_tags" {} resource "tls_private_key" "ssh" { @@ -127,7 +126,7 @@ locals { ssh_authorized_keys = local.public_keys tf_ssh_public_key = chomp(tls_private_key.ssh.public_key_openssh) terraform_facts = local.terraform_facts - upgrade = var.upgrade + upgrade = values.upgrade module_path = path.module user_tf_required = contains(values.tags, "puppet") || length(setintersection(values.tags, var.bastion_tags)) > 0 hostkeys = { diff --git a/common/design/main.tf b/common/design/main.tf index df4bf628..760bdc93 100644 --- a/common/design/main.tf +++ b/common/design/main.tf @@ -15,11 +15,12 @@ locals { for i in range(lookup(attrs, "count", 1)) : { (format("%s%d", prefix, i + 1)) = merge( { image = var.image }, + { upgrade = var.upgrade }, { disk_size = max(var.min_disk_size, [for tag in attrs.tags : lookup(local.min_disk_size_per_tags, tag, 0)]...) }, { for attr, value in attrs : attr => value if !contains(["count"], attr) }, { prefix = prefix, - specs = { for attr, value in attrs : attr => value if !contains(["count", "tags", "image"], attr) } + specs = { for attr, value in attrs : attr => value if !contains(["count", "tags", "image", "upgrade"], attr) } }, ) } diff --git a/common/design/variables.tf b/common/design/variables.tf index 4622943e..a4349013 100644 --- a/common/design/variables.tf +++ b/common/design/variables.tf @@ -6,4 +6,5 @@ variable "pool" {} variable "firewall_rules" {} variable "min_disk_size" {} variable "image" {} -variable "bastion_tags" {} \ No newline at end of file +variable "bastion_tags" {} +variable "upgrade" {} diff --git a/gcp/infrastructure.tf b/gcp/infrastructure.tf index 70af17f6..62759680 100644 --- a/gcp/infrastructure.tf +++ b/gcp/infrastructure.tf @@ -14,6 +14,7 @@ module "design" { volumes = var.volumes firewall_rules = var.firewall_rules bastion_tags = var.bastion_tags + upgrade = var.upgrade } module "configuration" { @@ -31,7 +32,6 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/incus/infrastructure.tf b/incus/infrastructure.tf index 0f23771e..150bd370 100644 --- a/incus/infrastructure.tf +++ b/incus/infrastructure.tf @@ -9,6 +9,7 @@ module "design" { volumes = var.volumes firewall_rules = var.firewall_rules bastion_tags = var.bastion_tags + upgrade = var.upgrade } module "configuration" { @@ -27,7 +28,6 @@ module "configuration" { software_stack = var.software_stack cloud_provider = "incus" cloud_region = "local" - upgrade = var.upgrade puppet_conf = var.puppet_conf } diff --git a/openstack/infrastructure.tf b/openstack/infrastructure.tf index 78cac3d6..7084e10a 100644 --- a/openstack/infrastructure.tf +++ b/openstack/infrastructure.tf @@ -9,6 +9,7 @@ module "design" { volumes = var.volumes firewall_rules = var.firewall_rules bastion_tags = var.bastion_tags + upgrade = var.upgrade } module "configuration" { @@ -26,7 +27,6 @@ module "configuration" { software_stack = var.software_stack cloud_provider = local.cloud_provider cloud_region = local.cloud_region - upgrade = var.upgrade puppet_conf = var.puppet_conf } From 40df35101f7169b6d5b538decf4d878a0f7c2ec7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?F=C3=A9lix-Antoine=20Fortin?= Date: Fri, 10 Jul 2026 12:43:49 -0400 Subject: [PATCH 4/4] Update docs and checks --- common/variables.tf | 4 ++++ docs/README.md | 9 +++++---- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/common/variables.tf b/common/variables.tf index 21b2f3a2..95f7fdbe 100644 --- a/common/variables.tf +++ b/common/variables.tf @@ -31,6 +31,10 @@ variable "instances" { condition = length(var.instances) == 0 || sum([for key, values in var.instances : contains(values["tags"], "login") ? 1 : 0]) < 2 error_message = "At most one type of instances in var.instances can have the _login_ tag" } + validation { + condition = alltrue(flatten([for key, values in var.instances : contains(["all", "none", "security", "vanilla-all", "vanilla-security"], lookup(values, "upgrade", "vanilla-all"))])) + error_message = "At least one instance's `upgrade` is invalid. Valid values are: all, none, security, vanilla-all, vanilla-security." + } } variable "image" { diff --git a/docs/README.md b/docs/README.md index 6ab5b097..54ab1dae 100644 --- a/docs/README.md +++ b/docs/README.md @@ -572,13 +572,14 @@ recommended minimum size per tag as specified in the following table. ``` features = ["skylake", "nvidia"] ``` +8. `upgrade`: specification of the package upgrade behavior to use for this instance type (default: global [`upgrade`](#420-upgrade-optional) value, whose default is `"vanilla-all"`). The instance specifications are retrieved from the cloud provider data source, but it is possible to explicitly specify them. -7. `cpus`: number of logical processors on the node - [`CPUs` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_CPUs) -8. `ram`: size of real memory on the node in megabyte - [`RealMemory` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_RealMemory) -9. `gpus`: number of graphics processors on the node - [`Gres=gpu:` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_Gres_1) -10. `gpu_type`: type of graphics processor on the node - [`Gres=gpu::` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_Gres_1) +9. `cpus`: number of logical processors on the node - [`CPUs` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_CPUs) +10. `ram`: size of real memory on the node in megabyte - [`RealMemory` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_RealMemory) +11. `gpus`: number of graphics processors on the node - [`Gres=gpu:` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_Gres_1) +12. `gpu_type`: type of graphics processor on the node - [`Gres=gpu::` in slurm.conf](https://slurm.schedmd.com/slurm.conf.html#OPT_Gres_1) For some cloud providers, it is possible to define additional attributes. The following sections present the available attributes per provider.