diff --git a/files/uwsgi-generator b/files/uwsgi-generator new file mode 100755 index 0000000..f9f5d05 --- /dev/null +++ b/files/uwsgi-generator @@ -0,0 +1,23 @@ +#!/bin/sh + +# This systemd generator creates dependency symlinks that make all uWSGI apps +# in /etc/uwsgi/apps-enabled/ be started/stopped/reloaded when uwsgi.service is +# started/stopped/reloaded. + +set -eu + +gendir="$1" +wantdir="$1/uwsgi.service.wants" +uwsgiservice="/etc/systemd/system/uwsgi@.service" + +mkdir -p "$wantdir" + +for conf in /etc/uwsgi/apps-enabled/*.ini; do + test -e "$conf" || continue + base=$(basename $conf) + appname=$(basename $base .ini) + ln -s "$uwsgiservice" "$wantdir/uwsgi@$appname.service" +done + +exit 0 + diff --git a/files/uwsgi.service b/files/uwsgi.service new file mode 100644 index 0000000..ce46fce --- /dev/null +++ b/files/uwsgi.service @@ -0,0 +1,12 @@ +[Unit] +Description=uWSGI + +[Service] +Type=oneshot +ExecStart=/bin/true +ExecReload=/bin/true +RemainAfterExit=on + +[Install] +WantedBy=multi-user.target + diff --git a/files/uwsgi@.service b/files/uwsgi@.service new file mode 100644 index 0000000..d409cee --- /dev/null +++ b/files/uwsgi@.service @@ -0,0 +1,18 @@ +[Unit] +Description=uWSGI app %i +ConditionPathExists=/etc/uwsgi/apps-enabled/%i.ini +PartOf=uwsgi.service +ReloadPropagatedFrom=uwsgi.service +Before=uwsgi.service + +[Service] +Environment=UWSGI_DEB_CONFNAMESPACE=app +Environment=UWSGI_DEB_CONFNAME=%i +ExecStartPre=/bin/mkdir -p /run/uwsgi/app/%i +ExecStartPre=/bin/chmod 777 /run/uwsgi/app/%i +ExecStart=/usr/bin/uwsgi --ini /usr/share/uwsgi/conf/default.ini --ini /etc/uwsgi/apps-enabled/%i.ini --logto /var/log/uwsgi/app/%i.log +ExecStop=/bin/kill -INT $MAINPID +ExecReload=/bin/kill -HUP $MAINPID + +[Install] +WantedBy=multi-user.target diff --git a/manifests/init.pp b/manifests/init.pp index a9479a5..643ca49 100644 --- a/manifests/init.pp +++ b/manifests/init.pp @@ -1,59 +1,82 @@ # == Class: uwsgi # # Manage uwsgi configurations # # === Examples # # include ::uwsgi # # === Authors # # Nicolas Dandrimont # # === Copyright # # Copyright 2015 The Software Heritage developers # class uwsgi { $uwsgi_packages = ['uwsgi', 'uwsgi-plugin-python3'] $systemd_service_dir = '/etc/systemd/system/uwsgi.service.d' - $systemd_service_file = "${systemd_service_dir}/setrlimit.conf" + $systemd_service_snippet = "${systemd_service_dir}/setrlimit.conf" $uwsgi_filelimit = 65536 + $systemd_service_files = ['uwsgi.service', 'uwsgi@.service'] + $systemd_generator = '/lib/systemd/system-generators/uwsgi-generator' + include ::systemd package {$uwsgi_packages: ensure => installed, } service {'uwsgi': ensure => running, enable => true, require => [ Package[$uwsgi_packages], - File[$systemd_service_file], + File[$systemd_service_snippet], Exec['systemd-daemon-reload'], ] } + each($systemd_service_files) |$file| { + file {"/etc/systemd/system/${file}": + ensure => file, + owner => 'root', + group => 'root', + mode => '0644', + source => "puppet:///modules/uwsgi/${file}", + notify => Exec['systemd-daemon-reload'], + } + } + + file {$systemd_generator: + ensure => file, + owner => 'root', + group => 'root', + mode => '0755', + source => 'puppet:///modules/uwsgi/uwsgi-generator', + notify => Exec['systemd-daemon-reload'], + } + file {$systemd_service_dir: ensure => directory, owner => 'root', group => 'root', mode => '0755', } - file {$systemd_service_file: + file {$systemd_service_snippet: ensure => file, owner => 'root', group => 'root', mode => '0644', content => template('uwsgi/systemd-setrlimit.conf.erb'), require => File[$systemd_service_dir], notify => [ Service['uwsgi'], Exec['systemd-daemon-reload'], ] } } diff --git a/manifests/site.pp b/manifests/site.pp index f83de61..6212282 100644 --- a/manifests/site.pp +++ b/manifests/site.pp @@ -1,87 +1,96 @@ # == Defined Type: uwsgi::site # # uwsgi::site defines a site for uwsgi. # # === Parameters # # [*ensure*] # Whether the site should be enabled, present (but disabled) or absent. # # [*settings*] # a hash of settings for the given site. Keys with dashes in the # config are added with underscores. # # === Examples # # uwsgi::site {'foo': # ensure => enabled, # settings => { # plugin => 'python3', # protocol => $uwsgi_protocol, # socket => $uwsgi_listen_address, # workers => $uwsgi_workers, # max_requests => $uwsgi_max_requests, # max_requests_delta => $uwsgi_max_requests_delta, # worker_reload_mercy => $uwsgi_reload_mercy, # reload_mercy => $uwsgi_reload_mercy, # uid => $user, # gid => $user, # module => 'swh.storage.api.server', # callable => 'run_from_webserver', # } # } # # === Authors # # Nicolas Dandrimont # # === Copyright # # Copyright 2015 The Software Heritage developers # define uwsgi::site ( $ensure = 'enabled', $settings = {} ){ $uwsgi_config = "/etc/uwsgi/apps-available/${name}.ini" $uwsgi_link = "/etc/uwsgi/apps-enabled/${name}.ini" + $uwsgi_pidfile = "/var/run/uwsgi/app/${name}/pid" case $ensure { default: { err("Unknown value ensure => ${ensure}.") } 'enabled', 'present': { file {$uwsgi_config: ensure => present, owner => 'root', group => 'root', mode => '0644', content => template('uwsgi/uwsgi.ini.erb'), require => Package['uwsgi'], } } 'absent': { file {$uwsgi_config: ensure => absent, } } } case $ensure { default: { err("Unknown value ensure => ${ensure}.") } 'enabled': { file {$uwsgi_link: ensure => link, target => $uwsgi_config, require => File[$uwsgi_config], - notify => Service['uwsgi'], + notify => Exec["uwsgi reload ${name}"], } - File[$uwsgi_config] ~> Service['uwsgi'] + File[$uwsgi_config] ~> Exec["uwsgi reload ${name}"] } 'present', 'absent': { file {$uwsgi_link: ensure => absent, - notify => Service['uwsgi'], + notify => Exec["uwsgi stop ${name}"], } } } + + exec {"uwsgi reload ${name}": + command => "/usr/bin/systemctl reload uwsgi@${name}", + } + + exec {"uwsgi stop ${name}": + command => "/usr/bin/systemctl stop uwsgi@${name}", + } }