From a7e54399776977f9724e48c0b787795660704a60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hugo=20H=C3=B6rnquist?= Date: Mon, 26 Jun 2023 17:29:21 +0200 Subject: Replace template based nspawn file with puppet based. --- manifests/machine.pp | 6 +- manifests/machine/nspawn.pp | 165 +++++++++++++++++++++++ templates/service.epp | 11 ++ templates/systemd/nspawn.epp | 313 ------------------------------------------- 4 files changed, 178 insertions(+), 317 deletions(-) create mode 100644 manifests/machine/nspawn.pp create mode 100644 templates/service.epp delete mode 100644 templates/systemd/nspawn.epp diff --git a/manifests/machine.pp b/manifests/machine.pp index d65ae00..d8a2d5f 100644 --- a/manifests/machine.pp +++ b/manifests/machine.pp @@ -48,11 +48,9 @@ define nspawn::machine ( message => $final_config, } - file { "${nspawn::nspawn_dir}/${name}.nspawn": + nspawn::machine::nspawn { $name: ensure => $ensure, - content => epp("${module_name}/systemd/nspawn.epp", { - 'data' => $final_config - }), + content => $final_config, } if $ensure == 'present' { diff --git a/manifests/machine/nspawn.pp b/manifests/machine/nspawn.pp new file mode 100644 index 0000000..f00df40 --- /dev/null +++ b/manifests/machine/nspawn.pp @@ -0,0 +1,165 @@ +# @summary Create a single nspawn file. +# @param config +# Configuration for the nspawn file. +# @param name +# Name of the machine, will be used for the filename. +# @param ensure +# @api private +define nspawn::machine::nspawn ( + Nspawn::Systemd::Nspawn $config, + String $machine_name = $name, + Enum['absent', 'present'] $ensure = 'present', +) { + $exec = $config['Exec'].map |$key, $value| { + if $value =~ Undef { + [] + } elsif $key in [ + 'Boot', 'Ephemeral', 'ProcessTwo', + 'NoNewPrivileges', 'NotifyReady', + ] { + $value_ = if $value { 'yes' } else { 'no' } + ["${key}=${value_}"] + } elsif $key in [ + 'User', 'WorkingDirectory', 'PivotRoot', 'AmbientCapability', + 'KillSignal', 'Personality', 'MachineID', 'Hostname', + 'ResolvConf', 'Timezone', 'LinkJournal', + ] { + ["${key}=${value}"] + } elsif $key == 'Parameters' { + $value_ = $value ? { + String => "${key}=${value}", + default => "${key}=" + ($value.map |$param| { + if ' ' in $param { + if '"' in $param { + "'${param}'" + } else { + "\"${param}\"" + } + } else { + $param + } + }.join(' ')) + } + ["${key}=${value_}"] + } elsif $key in ['Environment'] { + $value.map |$k, $v| { + "Environment=${k}=${v}" + } + } elsif $key in ['Capability', 'DropCapability'] { + $value_ = if $value == 'all' { + 'all' + } else { + $value.join(' ') + } + ["${key}=${value_}"] + } elsif $key in ['PrivateUsers'] { + $value_ = $value ? { + Boolean => if $value { 'yes' } else { 'no' }, + Tuple => $value.join(':'), + default => $value, + } + ["${key}=${value_}"] + } elsif $key in ['SystemCallFilter'] { + ["${key}=${$value.join(' ')}"] + } elsif $key =~ /^Limit.*/ { + $value_ = $value ? { + Tuple => $value.join(':'), + default => $value, + } + ["${key}=${value_}"] + } + } + + $files = $config['Files'].map |$key, $value| { + if $value =~ Undef { + [] + } elsif $key in ['ReadOnly'] { + if $value { + ["${key}=yes"] + } else { + ["${key}=no"] + } + } elsif $key in ['PrivateUsersOwnership'] { + ["${key}=${value}"] + } elsif $key in ['BindUser', 'Inaccessible'] { + $value.map |$v| { + "${key}=${value}" + } + } elsif $key in ['Volatile'] { + $value_ = $value ? { + Boolean => if $value { 'yes' } else { 'no' }, + default => $value, + } + ["${key}=${value_}"] + } elsif $key in ['Bind', 'BindReadOnly'] { + $value_ = $value.map |$v| { + $value_ = $v ? { + Tuple[String, String] => $v.join(':'), + Tuple[String, String, Array] => "${v[0]}:${v[1]}:${v[2].join(':')}", + Struct => "${v['source']}:${v['dest']}" + if $v['options'] =~ Undef { + '' + } else { + $v['options'].join(':') + }, + default => $v, + } + ["${key}=${value_}"] + } + } elsif $key in ['TemporaryFileSystem'] { + $value.map |$v| { + $value_ = $v ? { + Tuple => $v.join(':'), + default => $v, + } + "${key}=${value_}" + } + } elsif $key in ['Overlay'] { + $value.map |$v| { + "${key}=${$v.join(':')}" + } + } + } + + # TODO + $network = $config['Network'].map |$key, $value| { + if $key in [ + 'Private', 'VirtualEthernet', + ] { + if $value { + ["${key}=yes"] + } else { + ["${key}=no"] + } + } elsif $key in [ + 'Bridge', 'Zone', + ] { + ["${key}=${value}"] + } elsif $key in ['MACVLAN', 'IPVLAN', 'Interface'] { + "${key}=${value.join(' ')}" + } elsif $key in ['VirtualEthernetExtra'] { + $value.map |$v| { + $value_ = $v ? { + Tuple => $v.join(':'), + default => $v, + } + "${key}=${value_}" + } + } elsif $key in ['Port'] { + $value.map |$v| { + "${key}=${v.join(':')}" + } + } + } + + $hash = { + 'Exec' => $files.reduce([]) |$a, $b| { $a + $b }, + 'Files' => $exec.reduce([]) |$a, $b| { $a + $b }, + 'Network' => $network.reduce([]) |$a, $b| { $a + $b }, + }.map |$x| { $x } + + file { "${nspawn::nspawn_dir}/${machine_name}.nspawn": + ensure => $ensure, + content => epp("${module_name}/service.epp", { 'settings' => $hash }), + show_diff => true, + } +} diff --git a/templates/service.epp b/templates/service.epp new file mode 100644 index 0000000..0ce3778 --- /dev/null +++ b/templates/service.epp @@ -0,0 +1,11 @@ +<%- | Array[Tuple[String, Array[String]]] $settings | -%> +# File managed by Puppet. +# Local changes WILL be overwritten + +<%- $settings.each |$section| { -%> +[<%= $section[0] %>] +<%- $section[1].each |$line| { -%> +<%= $line %> +<%- } -%> + +<%- } -%> diff --git a/templates/systemd/nspawn.epp b/templates/systemd/nspawn.epp deleted file mode 100644 index ee79ba0..0000000 --- a/templates/systemd/nspawn.epp +++ /dev/null @@ -1,313 +0,0 @@ -<%- | Nspawn::Systemd::Nspawn $data | -%> - -[Exec] -<%- $exec = $data['Exec'] -%> -<%- if $exec['Boot'] == false { -%> -Boot=no -<%- } elsif $exec['Boot'] == true { -%> -Boot=yes -<%- } -%> -<%- if $exec['Ephemeral'] == false { -%> -Ephemeral=no -<%- } elsif $exec['Ephemeral'] == true { -%> -Ephemeral=yes -<%- } -%> -<%- if $exec['ProcessTwo'] == false { -%> -ProcessTwo=no -<%- } elsif $exec['ProcessTwo'] == true { -%> -ProcessTwo=yes -<%- } -%> -<%- unless $exec['Parameters'] =~ Undef { -%> -<%- if $exec['Parameters'] =~ String { -%> -Parameters=<%= $exec['Parameters'] %> -<%- } else { -%> -Parameters=<%= $exec['Parameters'].map |$param| { - if ' ' in $param { - if '"' in $param { - "'${param}'" - } else { - "\"${param}\"" - } - } else { - $param - } -}.join(' ') %> -<%- } } -%> -<%- unless $exec['Environment'] =~ Undef { -%> -<%- $exec['Environment'].each |$key, $value| { -%> -Environment=<%= $key %>=<%= $value %> -<%- } } -%> -<%- unless $exec['User'] =~ Undef { -%> -User=<%= $exec['User'] %> -<%- } -%> -<%- unless $exec['WorkingDirectory'] =~ Undef { -%> -WorkingDirectory=<%= $exec['WorkingDirectory'] %> -<%- } -%> -<%- unless $exec['PivotRoot'] =~ Undef { -%> -PivotRoot=<%= $exec['PivotRoot'] %> -<%- } -%> -<%- unless $exec['Capability'] =~ Undef { -%> -Capability=<% if $exec['Capability'] == 'all' {%>all<%} else { %><%= $exec['Capability'].join(' ') -%> -<%- } } -%> -<%- unless $exec['DropCapability'] =~ Undef { -%> -DropCapability=<% if $exec['DropCapability'] == 'all' {%>all<%} else { %><%= $exec['DropCapability'].join(' ') -%> -<%- } } -%> -<%- unless $exec['AmbientCapability'] =~ Undef { -%> -AmbientCapability=<%= $exec['AmbientCapability'].join(' ') -%> -<%- } -%> -<%- unless $exec['NoNewPrivileges'] =~ Undef { -%> -NoNewPrivileges=<%= if $exec['NoNewPrivileges'] { 'yes' } else { 'no' }%> -<%- } -%> -<%- unless $exec['KillSignal'] =~ Undef { -%> -KillSignal=<%= $exec['KillSignal'] %> -<%- } -%> -<%- unless $exec['Personality'] =~ Undef { -%> -Personality=<%= $exec['Personality'] %> -<%- } -%> -<%- unless $exec['MachineID'] =~ Undef { -%> -MachineID=<%= $exec['MachineID'] %> -<%- } -%> -<%- unless $exec['PrivateUsers'] =~ Undef { -%> -PrivateUsers=<%= -if $exec['PrivateUsers'] =~ Boolean { - if $exec['PrivateUsers'] { 'yes' } else { 'no' } -} elsif $exec['PrivateUsers'] =~ Tuple { - "<%= $exec['PrivateUsers'].join(':') %>" -} else { - $exec['PrivateUsers'] -} %><%- } -%> -<%- unless $exec['NotifyReady'] =~ Undef { -%> -NotifyReady=<%= if $exec['NotifyReady'] { 'yes' } else { 'no' }%> -<%- } -%> -<%- unless $exec['SystemCallFilter'] =~ Undef { -%> -SystemCallFilter=<%= $exec['SystemCallFilter'].join(' ') %> -<%- } -%> -<%- unless $exec['LimitCPU'] =~ Undef { -%> -<%- if $exec['LimitCPU'] =~ Tuple { -%> -LimitCPU=<%= $exec['LimitCPU'].join(':') %> -<%- } else { -%> -LimitCPU=<%= $exec['LimitCPU'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitFSIZE'] =~ Undef { -%> -<%- if $exec['LimitFSIZE'] =~ Tuple { -%> -LimitFSIZE=<%= $exec['LimitFSIZE'].join(':') %> -<%- } else { -%> -LimitFSIZE=<%= $exec['LimitFSIZE'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitDATA'] =~ Undef { -%> -<%- if $exec['LimitDATA'] =~ Tuple { -%> -LimitDATA=<%= $exec['LimitDATA'].join(':') %> -<%- } else { -%> -LimitDATA=<%= $exec['LimitDATA'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitSTACK'] =~ Undef { -%> -<%- if $exec['LimitSTACK'] =~ Tuple { -%> -LimitSTACK=<%= $exec['LimitSTACK'].join(':') %> -<%- } else { -%> -LimitSTACK=<%= $exec['LimitSTACK'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['limitSTACK'] =~ Undef { -%> -<%- if $exec['limitSTACK'] =~ Tuple { -%> -limitSTACK=<%= $exec['limitSTACK'].join(':') %> -<%- } else { -%> -limitSTACK=<%= $exec['limitSTACK'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitCORE'] =~ Undef { -%> -<%- if $exec['LimitCORE'] =~ Tuple { -%> -LimitCORE=<%= $exec['LimitCORE'].join(':')%> -<%- } else { -%> -LimitCORE=<%= $exec['LimitCORE'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LIMITRSS'] =~ Undef { -%> -<%- if $exec['LIMITRSS'] =~ Tuple { -%> -LIMITRSS=<%= $exec['LIMITRSS'].join(':') %> -<%- } else { -%> -LIMITRSS=<%= $exec['LIMITRSS'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitNOFILE'] =~ Undef { -%> -<%- if $exec['LimitNOFILE'] =~ Tuple { -%> -LimitNOFILE=<%= $exec['LimitNOFILE'].join(':') %> -<%- } else { -%> -LimitNOFILE=<%= $exec['LimitNOFILE'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitAS'] =~ Undef { -%> -<%- if $exec['LimitAS'] =~ Tuple { -%> -LimitAS=<%= $exec['LimitAS'].join(':') %> -<%- } else { -%> -LimitAS=<%= $exec['LimitAS'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitNPROC'] =~ Undef { -%> -<%- if $exec['LimitNPROC'] =~ Tuple { -%> -LimitNPROC=<%= $exec['LimitNPROC'].join(':') %> -<%- } else { -%> -LimitNPROC=<%= $exec['LimitNPROC'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitLOCKS'] =~ Undef { -%> -<%- if $exec['LimitLOCKS'] =~ Tuple { -%> -LimitLOCKS=<%= $exec['LimitLOCKS'].join(':') %> -<%- } else { -%> -LimitLOCKS=<%= $exec['LimitLOCKS'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitSIGPENDING'] =~ Undef { -%> -<%- if $exec['LimitSIGPENDING'] =~ Tuple { -%> -LimitSIGPENDING=<%= $exec['LimitSIGPENDING'].join(':') %> -<%- } else { -%> -LimitSIGPENDING=<%= $exec['LimitSIGPENDING'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitMSGQUEUE'] =~ Undef { -%> -<%- if $exec['LimitMSGQUEUE'] =~ Tuple { -%> -LimitMSGQUEUE=<%= $exec['LimitMSGQUEUE'].join(':') %> -<%- } else { -%> -LimitMSGQUEUE=<%= $exec['LimitMSGQUEUE'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitNICE'] =~ Undef { -%> -<%- if $exec['LimitNICE'] =~ Tuple { -%> -LimitNICE=<%= $exec['LimitNICE'].join(':') %> -<%- } else { -%> -LimitNICE=<%= $exec['LimitNICE'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitRTPRIO'] =~ Undef { -%> -<%- if $exec['LimitRTPRIO'] =~ Tuple { -%> -LimitRTPRIO=<%= $exec['LimitRTPRIO'].join(':') %> -<%- } else { -%> -LimitRTPRIO=<%= $exec['LimitRTPRIO'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['LimitRTTIME'] =~ Undef { -%> -<%- if $exec['LimitRTTIME'] =~ Tuple { -%> -LimitRTTIME=<%= $exec['LimitRTTIME'].join(':') %> -<%- } else { -%> -LimitRTTIME=<%= $exec['LimitRTTIME'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['OOMScoreAdjust'] =~ Undef { -%> -OOMScoreAdjust=<%= $exec['OOMScoreAdjust'] %> -<%- } -%> -<%- unless $exec['CPUAffinity'] =~ Undef { -%> -CPUAffinity=<%= $exec['CPUAffinity'].map |$aff| { - if $aff =~ Tuple { - "${aff[0]}-${aff[1]}" - } else { - "${aff}" - }.join(',') -} %> -<%- } -%> -<%- unless $exec['Hostname'] =~ Undef { -%> -Hostname=<%= $exec['Hostname'] %> -<%- } -%> -<%- unless $exec['ResolvConf'] =~ Undef { -%> -ResolvConf=<%= $exec['ResolvConf'] %> -<%- } -%> -<%- unless $exec['Timezone'] =~ Undef { -%> -Timezone=<%= $exec['Timezone'] %> -<%- } -%> -<%- unless $exec['LinkJournal'] =~ Undef { -%> -LinkJournal=<%= $exec['LinkJournal'] %> -<%- } -%> - -[Files] -<%- unless $exec['ReadOnly'] =~ Undef { -%> -ReadOnly=<%= if $exec['ReadOnly'] { 'yes' } else { 'no' } %> -<%- } -%> -<%- unless $exec['Volatile'] =~ Undef { -%> -<%- if $exec['Volatile'] =~ Boolean { -%> -Volatile=<%= if $exec['Volatile'] { 'yes' } else { 'no' } %> -<%- } else { -%> -Volatile=<%= $exec['Volatile'] %> -<%- } -%> -<%- } -%> -<%- unless $exec['Bind'] =~ Undef { $exec['Bind'].each |$bind| { -%> -<%- if $bind =~ Tuple[String, String] { -%> -Bind=<%= $bind[0] %>:<%= $bind[1] %> -<%- } elsif $bind =~ Tuple[String, String, Array[String]] { -%> -Bind=<%= $bind[0] %>:<%= $bind[1] %>:<%= $bind[2].join(':') %> -<%- } elsif $bind =~ Struct { -%> -Bind=<%= $bind['source'] %>:<%= $bind['dest'] %><%- -if $bind['options'] { %>:<%= $bind['options'].join(':') %><%- } -%> -<%- } else { -%> -Bind=<%= $exec['Bind'] %> -<%- } -%> -<%- }} -%> -<%- unless $exec['BindReadOnly'] =~ Undef { $exec['Bind'].each |$bind| { -%> -<%- if $bind =~ Tuple[String, String] { -%> -BindReadOnly=<%= $bind[0] %>:<%= $bind[1] %> -<%- } elsif $bind =~ Tuple[String, String, Array[String]] { -%> -BindReadOnly=<%= $bind[0] %>:<%= $bind[1] %>:<%= $bind[2].join(':') %> -<%- } elsif $bind =~ Struct { -%> -BindReadOnly=<%= $bind['source'] %>:<%= $bind['dest'] %><%- -if $bind['options'] { %>:<%= $bind['options'].join(':') %><%- } -%> -<%- } else { -%> -BindReadOnly=<%= $exec['Bind'] %> -<%- } -%> -<%- }} -%> -<%- unless $exec['BindUser'] =~ Undef {$exec['BindUser'].each |$user| { -%> -BindUser=<%= $user %> -<%- } } -%> -<%- unless $exec['TemporaryFileSystem'] =~ Undef {$exec['TemporaryFileSystem'].each |$fs| { -%> -TemporaryFileSystem=<%= -if $fs =~ Tuple { - $fs.join(':') -} else { - $fs -} -%> -<%- } } -%> -<%- unless $exec['Inaccessible'] =~ Undef {$exec['Inaccessible'].each |$path| { -%> -Inaccessible=<%= $path %> -<%- } } -%> -<%- unless $exec['Overlay'] =~ Undef {$exec['Overlay'].each |$paths| { -%> -Overlay=<%= $paths.join(':') %> -<%- } } -%> -<%- unless $exec['OverlayReadOnly'] =~ Undef {$exec['OverlayReadOnly'].each |$paths| { -%> -OverlayReadOnly=<%= $paths.join(':') %> -<%- } } -%> -<%- unless $exec['PrivateUsersOwnership'] =~ Undef { -%> -PrivateUsersOwnership=<%= $exec['PrivateUsersOwnership'] %> -<%- } -%> - -[Network] -<%- unless $exec['Private'] =~ Undef { -%> -Private=<%= if $exec['Private'] { 'yes' } else { 'no' } %> -<%- } -%> -<%- unless $exec['VirtualEthernet'] =~ Undef { -%> -VirtualEthernet=<%= if $exec['VirtualEthernet'] { 'yes' } else { 'no' } %> -<%- } -%> -<%- unless $exec['VirtualEthernetExtra'] =~ Undef { - $exec['VirtualEthernetExtra'].each |$interface| { -%> -VirtualEthernetExtra=<%= if $interface =~ Tuple { $interface.join(':') } else { $interface } %> -<%- } -%> -<%- } -%> -<%- unless $exec['Interface'] =~ Undef { -%> -Interface=<%= $exec['Interface'].join(' ') %> -<%- } -%> -<%- unless $exec['MACVLAN'] =~ Undef { -%> -MACVLAN=<%= $exec['MACVLAN'].join(' ') %> -<%- } -%> -<%- unless $exec['IPVLAN'] =~ Undef { -%> -IPVLAN=<%= $exec['IPVLAN'].join(' ') %> -<%- } -%> -<%- unless $exec['Bridge'] =~ Undef { -%> -Bridge=<%= $exec['Bridge'] %> -<%- } -%> -<%- unless $exec['Zone'] =~ Undef { -%> -Zone=<%= $exec['Zone'] %> -<%- } -%> -<%- unless $exec['Port'] =~ Undef { - $exec['Port'].each |$p| { -%> -Port=<%= $p.join(':') %> -<%- } -%> -<%- } -%> -- cgit v1.2.3