feat: add zfs modules

- add zfs_core module to puppetfile (provides zfs/zpool provider)
- add module to manage zfs
This commit is contained in:
Ben Vincent 2025-03-29 22:26:49 +11:00
parent 771b981d91
commit 9466bdaecf
6 changed files with 318 additions and 0 deletions

View File

@ -19,6 +19,7 @@ mod 'puppetlabs-haproxy', '8.0.0'
mod 'puppetlabs-java', '10.1.2' mod 'puppetlabs-java', '10.1.2'
mod 'puppetlabs-reboot', '5.0.0' mod 'puppetlabs-reboot', '5.0.0'
mod 'puppetlabs-docker', '10.0.1' mod 'puppetlabs-docker', '10.0.1'
mod 'puppetlabs-zfs_core', '1.6.1'
# puppet # puppet
mod 'puppet-python', '7.0.0' mod 'puppet-python', '7.0.0'

View File

@ -0,0 +1,14 @@
# frozen_string_literal: true
Facter.add('zfs_zpool_cache_present') do
confine kernel: 'Linux'
setcode do
File.exist?('/etc/zfs/zpool.cache')
end
end
Facter.add('zfs_zpool_cache_present') do
setcode do
false
end
end

View File

@ -0,0 +1,10 @@
# manage zfs config
class zfs::config {
file { $zfs::conf_dir:
ensure => directory,
owner => 0,
group => 0,
mode => '0644',
}
}

View File

@ -0,0 +1,52 @@
# Installs basic ZFS kernel and userland support.
#
# @example Declaring the class
# include zfs
#
# @example Tuning the ZFS ARC
# class { 'zfs':
# zfs_arc_max => to_bytes('256 M'),
# zfs_arc_min => to_bytes('128 M'),
# }
#
# @param conf_dir Top-level configuration directory, usually `/etc/zfs`.
# @param kmod_type Whether to use DKMS kernel packages or ones built to match
# the running kernel (only applies to RHEL platforms).
# @param manage_repo Whether to setup and manage external package repositories.
# @param package_name The name of the top-level metapackage that installs ZFS
# support.
# @param service_manage Whether to manage the various ZFS services.
# @param zfs_arc_max Maximum size of the ARC in bytes.
# @param zfs_arc_min Minimum size of the ARC in bytes.
class zfs (
Optional[Integer[0]] $zfs_arc_max,
Optional[Integer[0]] $zfs_arc_min,
Optional[Hash] $zpools,
Optional[Hash] $datasets,
Stdlib::Absolutepath $conf_dir = '/etc/zfs',
Enum['dkms', 'kabi'] $kmod_type = 'kabi',
Boolean $manage_repo = true,
Variant[String, Array[String, 1]] $package_name = 'zfs',
Boolean $service_manage = true,
) {
contain zfs::install
contain zfs::config
contain zfs::service
Class['zfs::install'] ~> Class['zfs::config'] ~> Class['zfs::service']
# create zpools
$zpools.each | $zpool, $data | {
zpool { $zpool:
* => $data
}
}
# create datasets
$datasets.each | $dataset, $data | {
zfs { $dataset:
* => $data
}
}
}

View File

@ -0,0 +1,151 @@
# manage zfs install/repos
class zfs::install {
if $zfs::manage_repo {
case $facts['os']['family'] {
'RedHat': {
$baseurl = 'http://download.zfsonlinux.org'
$release = $facts['os']['release']['major'] ? {
'6' => '6',
'7' => $facts['os']['release']['full'] ? {
/^7\.[012]/ => '7',
default => regsubst($facts['os']['release']['full'], '^7\.(\d+).*$', '7.\1'),
},
'8' => $facts['os']['release']['full'] ? {
/^8\.4/ => '8.3',
default => regsubst($facts['os']['release']['full'], '^8\.(\d+).*$', '8.\1'),
},
default => regsubst($facts['os']['release']['full'], '^(\d\.\d+).*$', '\1'),
}
yumrepo { 'zfs':
baseurl => "${baseurl}/epel/${release}/\$basearch/",
descr => "ZFS on Linux for EL${facts['os']['release']['major']} - dkms",
enabled => Integer($zfs::kmod_type == 'dkms'),
before => Package[$zfs::package_name],
}
yumrepo { 'zfs-kmod':
baseurl => "${baseurl}/epel/${release}/kmod/\$basearch/",
descr => "ZFS on Linux for EL${facts['os']['release']['major']} - kmod",
enabled => Integer($zfs::kmod_type == 'kabi'),
}
yumrepo { 'zfs-source':
baseurl => "${baseurl}/epel/${release}/SRPMS/",
descr => "ZFS on Linux for EL${facts['os']['release']['major']} - Source",
enabled => 0,
}
yumrepo { 'zfs-testing':
baseurl => "${baseurl}/epel-testing/${release}/\$basearch/",
descr => "ZFS on Linux for EL${facts['os']['release']['major']} - dkms - Testing",
enabled => 0,
}
yumrepo { 'zfs-testing-kmod':
baseurl => "${baseurl}/epel-testing/${release}/kmod/\$basearch/",
descr => "ZFS on Linux for EL${facts['os']['release']['major']} - kmod - Testing",
enabled => 0,
}
yumrepo { 'zfs-testing-source':
baseurl => "${baseurl}/epel-testing/${release}/SRPMS/",
descr => "ZFS on Linux for EL${facts['os']['release']['major']} - Testing Source",
enabled => 0,
}
}
default: {
# noop
}
}
}
# Handle these dependencies separately as they shouldn't be guarded by
# `$zfs::manage_repo`
case $facts['os']['family'] {
'RedHat': {
case $zfs::kmod_type {
'dkms': {
# Puppet doesn't like managing multiple versions of the same package.
# By using the version in the name Yum will do the right thing
ensure_packages(["kernel-devel-${facts['kernelrelease']}"], {
ensure => present,
before => Package[$zfs::package_name],
})
}
default: {
# noop
}
}
}
'Debian': {
case $facts['os']['name'] {
'Ubuntu': {
# noop
}
default: {
ensure_packages(["linux-headers-${facts['kernelrelease']}", "linux-headers-${facts['os']['architecture']}"], {
before => Package[$zfs::package_name],
})
}
}
}
default: {
# noop
}
}
# This is to work around the broken Debian 9 packages. Upon install the
# zfs-mount.service is started first which is the only unit that doesn't
# have an "ExecStartPre=-/sbin/modprobe zfs" line so the package can never
# be installed!
if $facts['os']['name'] == 'Debian' and $facts['os']['release']['major'] == '9' {
exec { 'zfs systemctl daemon-reload':
command => 'systemctl daemon-reload',
refreshonly => true,
path => $facts['path'],
}
Exec['zfs systemctl daemon-reload'] -> Package[$zfs::package_name]
file { '/etc/systemd/system/zfs-mount.service.d':
ensure => directory,
owner => 0,
group => 0,
mode => '0644',
}
file { '/etc/systemd/system/zfs-mount.service.d/override.conf':
ensure => file,
owner => 0,
group => 0,
mode => '0644',
content => @(EOS/L),
[Service]
ExecStartPre=-/sbin/modprobe zfs
| EOS
notify => Exec['zfs systemctl daemon-reload'],
}
}
# These need to be done here so the kernel settings are present before the
# package is installed and potentially loading the kernel module
$config = delete_undef_values({
'zfs_arc_max' => $zfs::zfs_arc_max,
'zfs_arc_min' => $zfs::zfs_arc_min,
})
$config.each |$option,$value| {
kmod::option { "zfs ${option}":
module => 'zfs',
option => $option,
value => $value,
before => Package[$zfs::package_name],
}
}
package { $zfs::package_name:
ensure => present,
}
}

View File

@ -0,0 +1,90 @@
# manage zfs services
class zfs::service {
if $zfs::service_manage {
exec { 'modprobe zfs':
path => $facts['path'],
unless => 'grep -q "^zfs " /proc/modules',
}
case $facts['service_provider'] {
'systemd': {
$cache_ensure = str2bool($facts['zfs_zpool_cache_present']) ? {
true => 'running',
default => 'stopped',
}
$scan_ensure = str2bool($facts['zfs_zpool_cache_present']) ? {
true => 'stopped',
default => 'running',
}
service { 'zfs-import-cache':
ensure => $cache_ensure,
enable => true,
hasstatus => true,
hasrestart => true,
require => Exec['modprobe zfs'],
before => Service['zfs-mount'],
}
service { 'zfs-import-scan':
ensure => $scan_ensure,
enable => true,
hasstatus => true,
hasrestart => true,
require => Exec['modprobe zfs'],
before => Service['zfs-mount'],
}
}
default: {
case $facts['os']['family'] {
'RedHat': {
service { 'zfs-import':
ensure => running,
enable => true,
hasstatus => true,
hasrestart => true,
require => Exec['modprobe zfs'],
before => Service['zfs-mount'],
}
}
'Debian': {
$import_ensure = str2bool($facts['zfs_zpool_cache_present']) ? {
true => 'running',
default => 'stopped',
}
service { 'zpool-import':
ensure => $import_ensure,
enable => true,
hasstatus => true,
hasrestart => true,
require => Exec['modprobe zfs'],
}
}
default: {
# noop
}
}
}
}
service { 'zfs-mount':
ensure => running,
enable => true,
hasstatus => true,
hasrestart => true,
before => Service['zfs-share'],
}
service { 'zfs-share':
ensure => running,
enable => true,
hasstatus => true,
hasrestart => true,
}
}
}