diff options
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | files/vserver/build_vserver | 52 | ||||
-rw-r--r-- | manifests/vserver.pp | 524 | ||||
-rw-r--r-- | templates/rss.hard.erb | 1 | ||||
-rw-r--r-- | templates/rss.soft.erb | 1 |
5 files changed, 494 insertions, 85 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1377554 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.swp diff --git a/files/vserver/build_vserver b/files/vserver/build_vserver index 0f0cea7..f808122 100644 --- a/files/vserver/build_vserver +++ b/files/vserver/build_vserver @@ -1,36 +1,48 @@ #!/bin/bash -NAME=$1 -CONTEXT=$2 -RELEASE = $3 -DEBOOTSTRAP_MIRROR = $4 -# create basic vserver -vserver $NAME build -m debootstrap -- -d $RELEASE -m $DEBOOTSTRAP_MIRROR +NAME="$1" +CONTEXT="$2" +RELEASE="$3" +DEBOOTSTRAP_MIRROR="$4" +VHOSTNAME="$5" +VINTERFACE="$6" +PACKAGES="lsb-release,openssl,iproute,cron,sudo,openssh-server,locales" + +if [ "$VHOSTNAME" != "none" ]; then + VHOSTNAME_OPT="--hostname $VHOSTNAME" +fi + +if [ ! -z "$VINTERFACE" ]; then + VINTERFACE_OPT="--interface $VINTERFACE" + VIP="`echo $VINTERFACE | cut -d : -f 2 | cut -d '/' -f 1`" +fi -# default settings -echo $NAME >/etc/vservers/$NAME/uts/nodename -echo $CONTEXT >/etc/vservers/$NAME/context +# create basic vserver +vserver $NAME build -n $NAME --context $CONTEXT \ + $VHOSTNAME_OPT $VINTERFACE_OPT -m debootstrap -- \ + -d $RELEASE -m $DEBOOTSTRAP_MIRROR -- --include=$PACKAGES || exit 1 # copy in some some defaults TARGET=/etc/vservers/$NAME/vdir/ - cp /etc/apt/{preferences,sources.list} $TARGET/etc/apt/ -# this is needed so puppet can find the puppetmaster and creates the right -# certificate -grep -v $NAME /etc/hosts > $TARGET/etc/hosts +# add minimum /etc/hosts entries +if [ "$VHOSTNAME" != "none" ]; then + echo "$VIP $VHOSTNAME" > $TARGET/etc/hosts +fi + echo "127.0.0.1 $NAME" >> $TARGET/etc/hosts -#mkdir -p $TARGET/var/lib/puppet/modules/dbp -#cp /var/lib/puppet/modules/dbp/puppet_current.deb $TARGET/var/lib/puppet/modules/dbp/ # Setup is complete, now do the post-install stuff -vserver $NAME start -vserver $NAME exec dselect update -# install a few packages needed for facter -vserver $NAME exec apt-get -y install lsb-release iproute +vserver $NAME start || exit 1 +vserver $NAME exec apt-get update || exit 1 +vserver $NAME exec apt-get upgrade || exit 1 + +# custom puppet installation +#mkdir -p $TARGET/var/lib/puppet/modules/dbp +#cp /var/lib/puppet/modules/dbp/puppet_current.deb $TARGET/var/lib/puppet/modules/dbp/ #vserver $NAME exec dpkg --install var/lib/puppet/modules/dbp/puppet_current.deb #vserver $NAME exec apt-get -fy install - #echo "Please sign now: puppetca --sign $NAME" >&2 echo "VServer $NAME created" diff --git a/manifests/vserver.pp b/manifests/vserver.pp index 9e1566d..8f7437c 100644 --- a/manifests/vserver.pp +++ b/manifests/vserver.pp @@ -15,6 +15,10 @@ class vserver::host { default => latest, } + case $vserver_vdirbase { + '': { $vserver_vdirbase = "/var/lib/vservers" } + } + package { "util-vserver": ensure => $utilvserver_version; @@ -38,6 +42,14 @@ class vserver::host { mode => 0755, owner => root, group => root, require => [ Package['util-vserver'], Package[debootstrap]]; + "/etc/vservers/.defaults/vdirbase": + ensure => $vserver_vdirbase, + require => File[$vserver_vdirbase]; + + "$vserver_vdirbase": + ensure => directory, + mode => 000, owner => root, group => root; + # perhaps we should use hashify. # but i'm commenting this out until we learn how to properly use in case we want to use it. #"/etc/cron.daily/vserver-hashify": @@ -46,9 +58,10 @@ class vserver::host { } # remove dummy interfaces on the host - delete_lines { modules_dummy: - file => "/etc/modules", - pattern => "^dummy", + line { modules_dummy: + file => "/etc/modules", + line => "^dummy", + ensure => absent, } # Remove these dummy interfaces, they are annoying and we dont need them @@ -56,53 +69,72 @@ class vserver::host { "/etc/modprobe.d/local-dummy": ensure => absent, mode => 0644, owner => root, group => root; - - "/usr/local/share/munin-plugins/vserver_resources": - source => "puppet:///modules/virtual/munin/vserver_resources", - mode => 0755, owner => root, group => root; - - "/usr/local/share/munin-plugins/vserver_cpu_": - source => "puppet:///modules/virtual/munin/vserver_cpu_", - mode => 0755, owner => root, group => root; - - "/usr/local/share/munin-plugins/vserver_loadavg": - source => "puppet:///modules/virtual/munin/vserver_loadavg", - mode => 0755, owner => root, group => root; - } - - # This creates a load average graph combining the individual load averages of each vserver on the host - munin::plugin { - "vserver_loadavg": - config => "user root\n", - script_path_in => "/usr/local/share/munin-plugins"; - } - - # This creates a RSS graph for each vserver on the host (note after more than 4 vservers this can get noisy) - munin::plugin { - "vserver_resources_RSS": - ensure => "vserver_resources", - config => "user root\nenv.resource RSS", - script_path_in => "/usr/local/share/munin-plugins"; - } - - # This creates a VM graph for each vserver on the host (note after more than 4 vservers this can get noisy) - munin::plugin { - "vserver_resources_VM": - ensure => "vserver_resources", - config => "user root\nenv.resource VM", - script_path_in => "/usr/local/share/munin-plugins"; + } + + # Setup some plugins if munin is enabled in the system + case $virtual_munin { + false: {} + default: { + file { + "/usr/local/share/munin-plugins/vserver_resources": + source => "puppet:///modules/virtual/munin/vserver_resources", + mode => 0755, owner => root, group => root; + + "/usr/local/share/munin-plugins/vserver_cpu_": + source => "puppet:///modules/virtual/munin/vserver_cpu_", + mode => 0755, owner => root, group => root; + + "/usr/local/share/munin-plugins/vserver_loadavg": + source => "puppet:///modules/virtual/munin/vserver_loadavg", + mode => 0755, owner => root, group => root; + } + } } - # This creates a VM graph for each vserver on the host (note after more than 4 vservers this can get noisy) - munin::plugin { - "vserver_cpu_": - config => "user root\n", - script_path_in => "/usr/local/share/munin-plugins"; + # Setup some plugins if munin is enabled in the system + case $virtual_munin { + false: {} + default: { + # This creates a load average graph combining the individual load averages of each vserver on the host + munin::plugin { + "vserver_loadavg": + config => "user root\n", + script_path_in => "/usr/local/share/munin-plugins"; + } + + # This creates a RSS graph for each vserver on the host (note after more than 4 vservers this can get noisy) + munin::plugin { + "vserver_resources_RSS": + ensure => "vserver_resources", + config => "user root\nenv.resource RSS", + script_path_in => "/usr/local/share/munin-plugins"; + } + + # This creates a VM graph for each vserver on the host (note after more than 4 vservers this can get noisy) + munin::plugin { + "vserver_resources_VM": + ensure => "vserver_resources", + config => "user root\nenv.resource VM", + script_path_in => "/usr/local/share/munin-plugins"; + } + + # This creates a VM graph for each vserver on the host (note after more than 4 vservers this can get noisy) + munin::plugin { + "vserver_cpu_": + config => "user root\n", + script_path_in => "/usr/local/share/munin-plugins"; + } + } } } -define vs_create($in_domain, $context, $legacy = false, $distro = 'etch', $debootstrap_mirror = 'http://ftp.debian.org/debian') { - $vs_name = $legacy ? { true => $name, false => $in_domain ? { '' => $name, default => "${name}.${in_domain}" } } +define vs_create($in_domain, $context, $legacy = false, $distro = 'squeeze', + $debootstrap_mirror = 'http://cdn.debian.net/debian', + $hostname = false, $interface = false, + $memory_limit = false) { + $vs_name = $legacy ? { true => $name, false => $in_domain ? { '' => $name, default => "${name}.${in_domain}" } } + $vs_hostname = $hostname ? { false => 'none', default => $hostname } + $vs_interface = $interface ? { false => 'none', default => $interface } case $vs_name { '': { fail ( "Cannot create VServer with empty name" ) } } @@ -114,17 +146,67 @@ define vs_create($in_domain, $context, $legacy = false, $distro = 'etch', $deboo } } false: { - exec { "/usr/local/bin/build_vserver \"${vs_name}\" ${context} ${distro} ${debootstrap_mirror}": + exec { "/usr/local/bin/build_vserver \"${vs_name}\" ${context} ${distro} ${debootstrap_mirror} ${vs_hostname} ${vs_interface} ${memory_limit}": creates => "/etc/vservers/${vs_name}", - require => File["/usr/local/bin/build_vserver"], - alias => "vs_create_${vs_name}" + require => File["/usr/local/bin/build_vserver","/etc/vservers/.defaults/vdirbase"], + alias => "vs_create_${vs_name}", + # TODO: change when this is fixed: http://projects.puppetlabs.com/issues/4769 + timeout => $lsbdistcodename ? { "squeeze" => '31536000', # 1 year + default => '-1', }, + } + } + } + + file { "/etc/vservers/${vs_name}/rlimits": + ensure => directory, + mode => 0755, owner => root, group => root, + require => Exec["vs_create_${vs_name}"], + } + + case $memory_limit { + false: { + file { "/etc/vservers/${vs_name}/rlimits/rss.hard": + mode => 0644, owner => root, group => root, + ensure => absent, + } + + file { "/etc/vservers/${vs_name}/rlimits/rss.soft": + mode => 0644, owner => root, group => root, + ensure => absent, + } + + vs_cflags { "${vs_name}-virt_mem": + vserver => $vs_name, + flag => "virt_mem", + ensure => absent, + } + } + default: { + file { "/etc/vservers/${vs_name}/rlimits/rss.hard": + mode => 0644, owner => root, group => root, + content => template("virtual/rss.hard.erb"), + require => File["/etc/vservers/${vs_name}/rlimits"], + } + + file { "/etc/vservers/${vs_name}/rlimits/rss.soft": + mode => 0644, owner => root, group => root, + content => template("virtual/rss.soft.erb"), + require => File["/etc/vservers/${vs_name}/rlimits"], + } + + vs_cflags { "${vs_name}-virt_mem": + vserver => $vs_name, + flag => "virt_mem", + ensure => present, + require => Exec["vs_create_${vs_name}"], } } } } # ensure: present, stopped, running -define vserver($ensure, $context, $in_domain = '', $mark = '', $legacy = false, $distro = 'etch') { +define vserver($ensure, $context, $in_domain = '', $mark = '', $legacy = false, $distro = 'etch', + $hostname = false, $interface = false, $memory_limit = false) { case $in_domain { '': {} default: { err("${fqdn}: vserver ${name} uses deprecated \$in_domain" ) } } @@ -133,21 +215,64 @@ define vserver($ensure, $context, $in_domain = '', $mark = '', $legacy = false, case $vs_name { '': { fail ( "Cannot create VServer with empty name" ) } } - $if_dir = "/etc/vservers/${vs_name}/interfaces" + $nodename = $hostname ? { false => $vs_name, default => $hostname } + $if_dir = "/etc/vservers/${vs_name}/interfaces" $mark_file = "/etc/vservers/${vs_name}/apps/init/mark" # TODO: wasn't there a syntax for using arrays as case selectors?? case $ensure { - present: { vs_create{$name: in_domain => $in_domain, context => $context, legacy => $legacy, distro => $distro, } } - running: { vs_create{$name: in_domain => $in_domain, context => $context, legacy => $legacy, distro => $distro, } } - stopped: { vs_create{$name: in_domain => $in_domain, context => $context, legacy => $legacy, distro => $distro, } } - delete: { vs_create{$name: in_domain => $in_domain, context => $context, legacy => $legacy, distro => $distro, } } - default: { err("${fqdn}: vserver(${vs_name}): unknown ensure '${ensure}'") } + present: { + vs_create{ $name: + in_domain => $in_domain, + context => $context, + legacy => $legacy, + distro => $distro, + hostname => $hostname, + interface => $interface, + memory_limit => $memory_limit, + } + } + running: { + vs_create{ $name: + in_domain => $in_domain, + context => $context, + legacy => $legacy, + distro => $distro, + hostname => $hostname, + interface => $interface, + memory_limit => $memory_limit, + } + } + stopped: { + vs_create{ $name: + in_domain => $in_domain, + context => $context, + legacy => $legacy, + distro => $distro, + hostname => $hostname, + interface => $interface, + memory_limit => $memory_limit, + } + } + delete: { + vs_create{ $name: + in_domain => $in_domain, + context => $context, + legacy => $legacy, + distro => $distro, + hostname => $hostname, + interface => $interface, + memory_limit => $memory_limit, + } + } + default: { + err("${fqdn}: vserver(${vs_name}): unknown ensure '${ensure}'") + } } file { $if_dir: - ensure => directory, checksum => mtime, + ensure => directory, checksum => mtime, require => Exec["vs_create_${vs_name}"]; } @@ -161,7 +286,7 @@ define vserver($ensure, $context, $in_domain = '', $mark = '', $legacy = false, "/var/lib/puppet/modules/virtual/contexts/${context}": content => "\n"; "/etc/vservers/${vs_name}/uts/nodename": - content => "${vs_name}\n", + content => "${nodename}\n", notify => Exec["vs_restart_${vs_name}"], require => Exec["vs_create_${vs_name}"]; "/etc/vservers/${vs_name}/name": @@ -169,17 +294,25 @@ define vserver($ensure, $context, $in_domain = '', $mark = '', $legacy = false, require => Exec["vs_create_${vs_name}"]; } + # ensure a secure chroot barrier + # we have to do it for each vserver, see + # http://linux-vserver.org/Secure_chroot_Barrier#Solution:_Secure_Barrier + exec { "/usr/sbin/setattr --barrier /etc/vservers/${vs_name}/vdir/../": + unless => "/usr/sbin/showattr /etc/vservers/${vs_name}/vdir/../ | grep -- '----Bui- /etc/vservers/${vs_name}/vdir/../$'", + require => Exec["vs_create_${vs_name}"], + } + case $ensure { present: { # don't start or stop the vserver, just make sure it exists, we just run a dummy status test here - exec { "test -e \$(readlink -f /etc/vservers/${vs_name}/vdir)": + exec { "/usr/bin/test -e \$(readlink -f /etc/vservers/${vs_name}/vdir)": require => Exec["vs_create_${vs_name}"], alias => "vs_restart_${vs_name}", } } stopped: { - exec { "vserver ${vs_name} stop": - onlyif => "test -e \$(readlink -f /etc/vservers/${vs_name}/run || echo /doesntexist )", + exec { "/usr/sbin/vserver ${vs_name} stop": + onlyif => "/usr/bin/test -e \$(readlink -f /etc/vservers/${vs_name}/run || echo /doesntexist )", require => Exec["vs_create_${vs_name}"], # fake the restart exec in the stopped case, so the dependencies are fulfilled alias => "vs_restart_${vs_name}", @@ -187,16 +320,16 @@ define vserver($ensure, $context, $in_domain = '', $mark = '', $legacy = false, file { $mark_file: ensure => absent, } } delete: { - exec { "/usr/bin/yes | vserver ${vs_name} delete": + exec { "/usr/bin/yes | /usr/sbin/vserver ${vs_name} delete": alias => "vs_restart_${vs_name}", } } running: { - exec { "vserver ${vs_name} start": - unless => "test -e \$(readlink -f /etc/vservers/${vs_name}/run)", - require => [ Exec["vs_create_${vs_name}"], File["/etc/vservers/${vs_name}/context"] ] + exec { "/usr/sbin/vserver ${vs_name} start": + unless => "/usr/bin/test -e \$(readlink -f /etc/vservers/${vs_name}/run)", + require => [ Exec["vs_create_${vs_name}"], File["/etc/vservers/${vs_name}/context"] ], } - exec { "vserver ${vs_name} restart": + exec { "/usr/sbin/vserver ${vs_name} restart": refreshonly => true, require => Exec["vs_create_${vs_name}"], alias => "vs_restart_${vs_name}", @@ -277,3 +410,264 @@ define vs_ip_binding($vserver, $ip, $ensure) { } } } + +define vs_sched($ensure = present, $fill_rate = '', $fill_rate2 = '', + $interval = '', $interval2 = '', $tokens_min = '', $tokens_max = '', + $tokens = '', $idle_time = false, $priority_bias = '') { + + file { "/etc/vservers/${name}/sched": + ensure => directory, + owner => root, + group => root, + mode => 0755, + } + + case $fill_rate { + '': { + file { "/etc/vservers/${name}/sched/fill-rate": + ensure => absent, + } + } + default: { + $set_fill_rate = "--fill-rate $fill_rate" + + file { "/etc/vservers/${name}/sched/fill-rate": + ensure => $ensure, + content => "$fill_rate\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $fill_rate2 { + '': { + file { "/etc/vservers/${name}/sched/fill-rate2": + ensure => absent, + } + } + default: { + $set_fill_rate2 = "--fill-rate2 $fill_rate2" + + file { "/etc/vservers/${name}/sched/fill-rate2": + ensure => $ensure, + content => "$fill_rate2\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $interval { + '': { + file { "/etc/vservers/${name}/sched/interval": + ensure => absent, + } + } + default: { + $set_interval = "--interval $interval" + + file { "/etc/vservers/${name}/sched/interval": + ensure => $ensure, + content => "$interval\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $interval2 { + '': { + file { "/etc/vservers/${name}/sched/interval2": + ensure => absent, + } + } + default: { + $set_interval2 = "--interval2 $interval2" + + file { "/etc/vservers/${name}/sched/interval2": + ensure => $ensure, + content => "$interval2\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $tokens_min { + '': { + file { "/etc/vservers/${name}/sched/tokens-min": + ensure => absent, + } + } + default: { + $set_tokens_min = "--tokens-min $tokens_min" + + file { "/etc/vservers/${name}/sched/tokens-min": + ensure => $ensure, + content => "$tokens_min\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $tokens_max { + '': { + file { "/etc/vservers/${name}/sched/tokens-max": + ensure => absent, + } + } + default: { + $set_tokens_max = "--tokens-max $tokens_max" + + file { "/etc/vservers/${name}/sched/tokens-max": + ensure => $ensure, + content => "$tokens_max\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $tokens { + '': { + file { "/etc/vservers/${name}/sched/tokens": + ensure => absent, + } + } + default: { + $set_tokens = "--tokens $tokens" + + file { "/etc/vservers/${name}/sched/tokens": + ensure => $ensure, + content => "$tokens\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $priority_bias { + '': { + file { "/etc/vservers/${name}/sched/priority-bias": + ensure => absent, + } + } + default: { + $set_priority_bias = "--prio-bias $priority_bias" + + file { "/etc/vservers/${name}/sched/priority-bias": + ensure => $ensure, + content => "$priority_bias\n", + require => File["/etc/vservers/${name}/sched"], + } + } + } + + case $idle_time { + true: { + $set_idle_time = "--idle-time" + + file { "/etc/vservers/${name}/sched/idle-time": + ensure => $ensure, + } + } + default: { + file { "/etc/vservers/${name}/sched/idle-time": + ensure => absent, + } + } + } + + vs_cflags { "${name}-sched_hard": + vserver => $name, + flag => "sched_hard", + ensure => $ensure, + } + + vs_cflags { "${name}-sched_prio": + vserver => $name, + flag => "sched_prio", + ensure => $ensure, + } + + case $ensure { + present: { + + $vsched_params = "$set_fill_rate $set_fill_rate2 $set_interval $set_interval2 $set_tokens_min $set_tokens_max $set_tokens $set_idle_time $set_priority_bias" + + exec { "/usr/sbin/vsched --xid `cat /etc/vservers/$name/context` ${vsched_params} --force": + subscribe => File["/etc/vservers/$name/sched/fill-rate", "/etc/vservers/$name/sched/fill-rate2", + "/etc/vservers/$name/sched/interval", "/etc/vservers/$name/sched/interval2", + "/etc/vservers/$name/sched/tokens-min", "/etc/vservers/$name/sched/tokens-max", + "/etc/vservers/$name/sched/tokens", "/etc/vservers/$name/sched/idle-time"], + refreshonly => true, + require => Exec["vs_create_${name}"], + } + } + } +} + +define vs_cflags($vserver, $flag, $ensure = present) { + if ! defined(File["/etc/vservers/${vserver}/cflags"]) { + file { "/etc/vservers/${vserver}/cflags": + ensure => present, + } + } + + line {"vs_cflags-${vserver}-${flag}": + ensure => $ensure, + file => "/etc/vservers/${vserver}/cflags", + line => "${flag}", + require => Exec["vs_create_${vserver}"], + notify => Exec["vattribute-${vserver}-${flag}"], + } + + case $ensure { + present: { + exec { "/usr/sbin/vattribute-${vserver}-${flag}": + command => "vattribute --set --xid `cat /etc/vservers/$vserver/context` --flag ${flag}", + refreshonly => true, + require => Exec["vs_create_${vserver}"], + alias => "vattribute-${vserver}-${flag}", + } + } + default: { + exec { "/usr/sbin/vattribute-${vserver}-${flag}": + command => "vattribute --set --xid `cat /etc/vservers/$vserver/context` --flag ~${flag}", + refreshonly => true, + require => Exec["vs_create_${vserver}"], + alias => "vattribute-${vserver}-${flag}", + } + } + } +} + +define vs_rlimit($vserver, $limit, $soft = '', $hard = '', $min = '', $ensure = present) { + file { "/etc/vservers/${vserver}/rlimits/$limit.soft": + mode => 0644, owner => root, group => root, + content => "$soft\n", + ensure => $soft ? { + '' => absent, + default => $ensure, + }, + require => File["/etc/vservers/${vserver}/rlimits"], + notify => Exec["vs_restart_${vserver}"], + } + + file { "/etc/vservers/${vserver}/rlimits/$limit.hard": + mode => 0644, owner => root, group => root, + content => "$hard\n", + ensure => $hard ? { + '' => absent, + default => $ensure, + }, + require => File["/etc/vservers/${vserver}/rlimits"], + notify => Exec["vs_restart_${vserver}"], + } + + file { "/etc/vservers/${vserver}/rlimits/$limit.min": + mode => 0644, owner => root, group => root, + content => "$min\n", + ensure => $min? { + '' => absent, + default => $ensure, + }, + require => File["/etc/vservers/${vserver}/rlimits"], + notify => Exec["vs_restart_${vserver}"], + } +} diff --git a/templates/rss.hard.erb b/templates/rss.hard.erb new file mode 100644 index 0000000..31a8030 --- /dev/null +++ b/templates/rss.hard.erb @@ -0,0 +1 @@ +<%= memory_limit.to_i * 1_000_000 / 4096 %> diff --git a/templates/rss.soft.erb b/templates/rss.soft.erb new file mode 100644 index 0000000..31a8030 --- /dev/null +++ b/templates/rss.soft.erb @@ -0,0 +1 @@ +<%= memory_limit.to_i * 1_000_000 / 4096 %> |