snapshot of https://github.com/zulip/zulip.git @ 48c69911c7dd4e03b20552eb3bd77ad8151c1357 (2026-09-15)
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
Some checks failed
Code scanning / CodeQL (push) Failing after 15s
Zulip production suite / Ubuntu 22.04 production build (push) Failing after 26s
Zulip production suite / Debian 12 production install with custom db name and user (push) Has been skipped
Zulip production suite / Ubuntu 22.04 production install and PostgreSQL upgrade with pgroonga (push) Has been skipped
Zulip production suite / Ubuntu 24.04 production install (push) Has been skipped
Zulip production suite / Ubuntu 26.04 production install (push) Has been skipped
Zulip production suite / Debian 13 production install (push) Has been skipped
Zulip production suite / 7.0 Version Upgrade (push) Has been skipped
Zulip production suite / 8.0 Version Upgrade (push) Has been skipped
Zulip production suite / 6.0 Version Upgrade (push) Has been skipped
Zulip production suite / 10.0 Version Upgrade (push) Has been skipped
Zulip production suite / 9.0 Version Upgrade (push) Has been skipped
Zulip production suite / 12.0 Version Upgrade (push) Has been skipped
Zulip production suite / 11.0 Version Upgrade (push) Has been skipped
GitHub Actions Security Analysis with zizmor / zizmor (push) Failing after 3s
Zulip CI / Debian 12 (Python 3.11, backend + documentation) (push) Failing after 26s
Zulip CI / Ubuntu 22.04 (Python 3.10, backend + frontend) (push) Failing after 3s
Zulip CI / Ubuntu 24.04 (Python 3.12, backend) (push) Failing after 25s
Zulip CI / Ubuntu 26.04 (Python 3.14, backend) (push) Failing after 25s
Zulip CI / Debian 13 (Python 3.13, backend) (push) Failing after 28s
Zulip production suite / Required jobs (push) Has been cancelled
Zulip CI / Required jobs (push) Has been cancelled
API Documentation Update Check / check-feature-level-updated (push) Has been cancelled
API Documentation Update Check / notify-if-api-docs-changed (push) Has been cancelled
This commit is contained in:
43
puppet/zulip/manifests/apache_sso.pp
Normal file
43
puppet/zulip/manifests/apache_sso.pp
Normal file
@@ -0,0 +1,43 @@
|
||||
class zulip::apache_sso {
|
||||
include zulip::localhost_sso
|
||||
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$apache_packages = [ 'apache2', 'libapache2-mod-wsgi-py3', ]
|
||||
$conf_dir = '/etc/apache2'
|
||||
$apache2 = 'apache2'
|
||||
}
|
||||
'RedHat': {
|
||||
$apache_packages = [ 'httpd', 'python36u-mod_wsgi', ]
|
||||
$conf_dir = '/etc/httpd'
|
||||
$apache2 = 'httpd'
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
package { $apache_packages: ensure => installed }
|
||||
|
||||
apache2mod { [ 'headers', 'proxy', 'proxy_http', 'rewrite', 'ssl', 'wsgi', ]:
|
||||
ensure => present,
|
||||
require => Package[$apache2],
|
||||
}
|
||||
|
||||
file { "${conf_dir}/ports.conf":
|
||||
ensure => file,
|
||||
require => Package[$apache2],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0640',
|
||||
source => 'puppet:///modules/zulip/apache/ports.conf',
|
||||
}
|
||||
|
||||
file { "${conf_dir}/sites-available/":
|
||||
recurse => true,
|
||||
require => Package[$apache2],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0640',
|
||||
source => 'puppet:///modules/zulip/apache/sites/',
|
||||
}
|
||||
}
|
||||
318
puppet/zulip/manifests/app_frontend_base.pp
Normal file
318
puppet/zulip/manifests/app_frontend_base.pp
Normal file
@@ -0,0 +1,318 @@
|
||||
# Minimal configuration to run a Zulip application server.
|
||||
# Default nginx configuration is included in extension app_frontend.pp.
|
||||
class zulip::app_frontend_base {
|
||||
include zulip::nginx
|
||||
include zulip::tusd
|
||||
include zulip::sasl_modules
|
||||
include zulip::supervisor
|
||||
include zulip::tornado_sharding
|
||||
include zulip::hooks::base
|
||||
|
||||
if $facts['os']['family'] == 'Debian' {
|
||||
# Upgrade and other tooling wants to be able to get a database
|
||||
# shell. This is not necessary on CentOS because the PostgreSQL
|
||||
# package already includes the client.
|
||||
include zulip::postgresql_client
|
||||
}
|
||||
zulip::safepackage {
|
||||
[
|
||||
# For `manage.py compilemessages` when upgrading from Git.
|
||||
'gettext',
|
||||
# For Slack import.
|
||||
'unzip',
|
||||
# Ensures `/etc/ldap/ldap.conf` exists; the default
|
||||
# `TLS_CACERTDIR` specified there is necessary for LDAP
|
||||
# authentication to work. This package is "Recommended" by
|
||||
# `libldap` where is required by postgres, so has been on most
|
||||
# Zulip servers by default; adding it here explicitly ensures it
|
||||
# is available on those that don't include the database server.
|
||||
'libldap-common',
|
||||
]:
|
||||
ensure => installed,
|
||||
}
|
||||
|
||||
file { '/etc/nginx/zulip-include/app':
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-frontend/app',
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/uploads.types':
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-frontend/uploads.types',
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/app.d/':
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/localhost.d/':
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
}
|
||||
|
||||
$loadbalancers = split(zulipconf('loadbalancer', 'ips', ''), ',')
|
||||
if $loadbalancers != [] {
|
||||
file { '/etc/nginx/zulip-include/app.d/keepalive-loadbalancer.conf':
|
||||
require => File['/etc/nginx/zulip-include/app.d'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-app.d/keepalive-loadbalancer.conf',
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
} else {
|
||||
file { '/etc/nginx/zulip-include/app.d/keepalive-loadbalancer.conf':
|
||||
ensure => absent,
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/app.d/accept-loadbalancer.conf':
|
||||
# This moved to /etc/nginx/zulip-include/trusted-ip, via
|
||||
# nginx.pp. This block can be removed once direct Zulip upgrades
|
||||
# from Zulip 11 are no longer supported.
|
||||
ensure => absent,
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/app.d/healthcheck.conf':
|
||||
require => File['/etc/nginx/zulip-include/app.d'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/nginx/healthcheck.conf.template.erb'),
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
file { '/etc/nginx/zulip-include/upstreams':
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-frontend/upstreams',
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
$s3_memory_cache_size = zulipconf('application_server', 's3_memory_cache_size', '1M')
|
||||
$s3_disk_cache_size = zulipconf('application_server', 's3_disk_cache_size', '200M')
|
||||
$s3_cache_inactive_time = zulipconf('application_server', 's3_cache_inactive_time', '30d')
|
||||
$configured_nginx_resolver = zulipconf('application_server', 'nameserver', '')
|
||||
if $configured_nginx_resolver == '' {
|
||||
# This may fail in the unlikely change that there is no configured
|
||||
# resolver in /etc/resolv.conf, so only call it is unset in zulip.conf
|
||||
$nginx_resolver_ip = resolver_ip()
|
||||
} elsif (':' in $configured_nginx_resolver) and ! ('.' in $configured_nginx_resolver) and ! ('[' in $configured_nginx_resolver) {
|
||||
# Assume this is IPv6, which needs square brackets.
|
||||
$nginx_resolver_ip = "[${configured_nginx_resolver}]"
|
||||
} else {
|
||||
$nginx_resolver_ip = $configured_nginx_resolver
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/s3-cache':
|
||||
require => [
|
||||
Package[$zulip::common::nginx],
|
||||
File['/srv/zulip-uploaded-files-cache'],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/nginx/s3-cache.template.erb'),
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
file { '/etc/nginx/zulip-include/app.d/uploads-internal.conf':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-frontend/uploads-internal.conf',
|
||||
}
|
||||
|
||||
# This determines whether we run queue processors multithreaded or
|
||||
# multiprocess. Multiprocess scales much better, but requires more
|
||||
# RAM; we just auto-detect based on available system RAM.
|
||||
#
|
||||
# Because Zulip can run in the multiprocess mode with 4GB of memory,
|
||||
# and it's a common instance size, we aim for that to be the cutoff
|
||||
# for this higher-performance mode.
|
||||
#
|
||||
# We use a cutoff less than 4000 here to detect systems advertised
|
||||
# as "4GB"; some may have as little as 4 x 1000^3 / 1024^2 ≈ 3815 MiB
|
||||
# of memory.
|
||||
$queues_multiprocess_default = $zulip::common::total_memory_mb > 3800
|
||||
$queues_multiprocess = zulipconf('application_server', 'queue_workers_multiprocess', $queues_multiprocess_default)
|
||||
$base_queues = [
|
||||
'deferred_work',
|
||||
'digest_emails',
|
||||
'email_mirror',
|
||||
'embed_links',
|
||||
'embedded_bots',
|
||||
'email_senders',
|
||||
'deferred_email_senders',
|
||||
'missedmessage_emails',
|
||||
'missedmessage_mobile_notifications',
|
||||
'outgoing_webhooks',
|
||||
'thumbnail',
|
||||
'user_activity',
|
||||
'user_activity_interval',
|
||||
]
|
||||
# Soft reactivations normally share the deferred_work queue; larger
|
||||
# servers can opt into a dedicated queue (and worker process) for them.
|
||||
$queues = zulipconf('application_server', 'dedicated_soft_reactivation_queue', false) ? {
|
||||
true => $base_queues + ['soft_reactivation'],
|
||||
default => $base_queues,
|
||||
}
|
||||
|
||||
if $zulip::common::total_memory_mb > 24000 {
|
||||
$uwsgi_default_processes = 16
|
||||
} elsif $zulip::common::total_memory_mb > 12000 {
|
||||
$uwsgi_default_processes = 8
|
||||
} elsif $zulip::common::total_memory_mb > 6000 {
|
||||
$uwsgi_default_processes = 6
|
||||
} elsif $zulip::common::total_memory_mb > 3000 {
|
||||
$uwsgi_default_processes = 4
|
||||
} else {
|
||||
$uwsgi_default_processes = 3
|
||||
}
|
||||
|
||||
# Not the different naming scheme for sharded workers, where each gets its own queue,
|
||||
# vs when multiple workers service the same queue.
|
||||
$worker_counts = Hash(zulipconf_keys('application_server').filter |$key| {
|
||||
$key =~ /_workers$/
|
||||
}.map |$key| {
|
||||
[regsubst($key, '_workers$', ''), Integer(zulipconf('application_server', $key, 1))]
|
||||
})
|
||||
$mobile_notification_shards = Integer(zulipconf('application_server', 'mobile_notification_shards', 1))
|
||||
$user_activity_shards = Integer(zulipconf('application_server', 'user_activity_shards', 1))
|
||||
$tornado_ports = $zulip::tornado_sharding::tornado_ports
|
||||
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
|
||||
if ($proxy_host in ['localhost', '127.0.0.1', '::1']) and ($proxy_port == '4750') {
|
||||
include zulip::smokescreen
|
||||
}
|
||||
|
||||
$katex_server = zulipconf('application_server', 'katex_server', true)
|
||||
$katex_server_port = zulipconf('application_server', 'katex_server_port', '9700')
|
||||
|
||||
$tusd_server_listen = zulipconf('application_server', 'tusd_server_listen', '127.0.0.1')
|
||||
|
||||
# Supervisor sets this as HTTP_proxy/HTTPS_proxy in every process's
|
||||
# environment, so that all outgoing requests go through Smokescreen;
|
||||
# including those made directly by libraries rather than through
|
||||
# OutgoingSession.
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
$custom_ca_path = zulipconf('application_server','custom_ca_path', '')
|
||||
if $custom_ca_path != '' {
|
||||
file { '/usr/local/share/ca-certificates/custom-zulip-ca.crt':
|
||||
ensure => file,
|
||||
source => $custom_ca_path,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Exec['update-ca-certificates'],
|
||||
}
|
||||
exec { 'update-ca-certificates':
|
||||
command => '/usr/sbin/update-ca-certificates',
|
||||
require => Package['ca-certificates'],
|
||||
before => File["${zulip::common::supervisor_conf_dir}/zulip.conf"],
|
||||
refreshonly => true,
|
||||
}
|
||||
$ca_bundle=',REQUESTS_CA_BUNDLE="/etc/ssl/certs/ca-certificates.crt"'
|
||||
} else {
|
||||
$ca_bundle=''
|
||||
}
|
||||
file { "${zulip::common::supervisor_conf_dir}/zulip.conf":
|
||||
ensure => file,
|
||||
require => [Package[supervisor], Exec['stage_updated_sharding']],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/zulip.conf.template.erb'),
|
||||
notify => Service[$zulip::common::supervisor_service],
|
||||
}
|
||||
|
||||
$uwsgi_rolling_restart = zulipconf('application_server', 'rolling_restart', false)
|
||||
$uwsgi_listen_backlog_limit = zulipconf('application_server', 'uwsgi_listen_backlog_limit', 128)
|
||||
$uwsgi_processes = zulipconf('application_server', 'uwsgi_processes', $uwsgi_default_processes)
|
||||
$somaxconn = 2 * Integer($uwsgi_listen_backlog_limit)
|
||||
file { '/etc/zulip/uwsgi.ini':
|
||||
ensure => file,
|
||||
require => Package[supervisor],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/uwsgi.ini.template.erb'),
|
||||
notify => Service[$zulip::common::supervisor_service],
|
||||
}
|
||||
zulip::sysctl { 'uwsgi':
|
||||
comment => 'Allow larger listen backlog',
|
||||
key => 'net.core.somaxconn',
|
||||
value => $somaxconn,
|
||||
}
|
||||
|
||||
file { [
|
||||
'/home/zulip/tornado',
|
||||
'/home/zulip/prod-static',
|
||||
'/home/zulip/deployments',
|
||||
'/srv/zulip-locks',
|
||||
'/srv/zulip-emoji-cache',
|
||||
'/srv/zulip-uploaded-files-cache',
|
||||
]:
|
||||
ensure => directory,
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
mode => '0755',
|
||||
}
|
||||
# /home/zulip/uploads is documented as something administrators may
|
||||
# replace with a symlink to a different storage location, so we use
|
||||
# an exec with a `test -d` guard (which follows symlinks) rather
|
||||
# than a file resource that would replace the symlink.
|
||||
exec { 'create-uploads-dir':
|
||||
command => 'install -d -o zulip -g zulip -m 0755 /home/zulip/uploads',
|
||||
unless => 'test -d /home/zulip/uploads',
|
||||
path => '/usr/bin:/bin',
|
||||
}
|
||||
file { [
|
||||
'/var/log/zulip/queue_error',
|
||||
'/var/log/zulip/queue_stats',
|
||||
]:
|
||||
ensure => directory,
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
mode => '0750',
|
||||
}
|
||||
$access_log_retention_days = zulipconf('application_server','access_log_retention_days', 14)
|
||||
file { '/etc/logrotate.d/zulip':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/logrotate/zulip.template.erb'),
|
||||
}
|
||||
|
||||
zulip::nagios_plugins {'zulip_app_frontend': }
|
||||
|
||||
# This cron job does nothing unless RATE_LIMIT_TOR_TOGETHER is enabled.
|
||||
zulip::cron { 'fetch-tor-exit-nodes':
|
||||
minute => '17',
|
||||
}
|
||||
# This was originally added with a typo in the name.
|
||||
file { '/etc/cron.d/fetch-for-exit-nodes':
|
||||
ensure => absent,
|
||||
}
|
||||
}
|
||||
88
puppet/zulip/manifests/app_frontend_once.pp
Normal file
88
puppet/zulip/manifests/app_frontend_once.pp
Normal file
@@ -0,0 +1,88 @@
|
||||
# Cron jobs and other tools that should run on only one Zulip server
|
||||
# in a cluster.
|
||||
|
||||
class zulip::app_frontend_once {
|
||||
include zulip::hooks::send_zulip_update_announcements
|
||||
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
file { "${zulip::common::supervisor_conf_dir}/zulip-once.conf":
|
||||
ensure => file,
|
||||
require => [Package[supervisor], Exec['stage_updated_sharding']],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/zulip-once.conf.template.erb'),
|
||||
notify => Service[$zulip::common::supervisor_service],
|
||||
}
|
||||
|
||||
# Every-hour
|
||||
zulip::cron { 'update-analytics-counts':
|
||||
minute => '5',
|
||||
}
|
||||
zulip::cron { 'check-analytics-state':
|
||||
minute => '30',
|
||||
}
|
||||
zulip::cron { 'promote-new-full-members':
|
||||
minute => '35',
|
||||
}
|
||||
zulip::cron { 'send_zulip_update_announcements':
|
||||
minute => '47',
|
||||
}
|
||||
|
||||
# Daily
|
||||
zulip::cron { 'soft-deactivate-users':
|
||||
hour => '5',
|
||||
minute => '0',
|
||||
manage => 'soft_deactivate_users -d',
|
||||
}
|
||||
zulip::cron { 'delete-old-unclaimed-attachments':
|
||||
hour => '5',
|
||||
minute => '0',
|
||||
manage => 'delete_old_unclaimed_attachments -f',
|
||||
}
|
||||
# If changing the time of this job, then the global time string
|
||||
# generated by demo_organizations.get_scheduled_deletion_global_time
|
||||
# needs to be updated as well.
|
||||
zulip::cron { 'archive-messages':
|
||||
hour => '6',
|
||||
minute => '0',
|
||||
}
|
||||
zulip::cron { 'send-digest-emails':
|
||||
hour => '18',
|
||||
minute => '0',
|
||||
manage => 'enqueue_digest_emails',
|
||||
}
|
||||
# Most deploys will re-run this for all streams, daily; large
|
||||
# deploys may set this to a number >= 25 to only update streams with
|
||||
# recent potential changes.
|
||||
$update_subscriber_count_incremental = zulipconf('application_server', 'update_subscriber_count_incremental', '')
|
||||
if $update_subscriber_count_incremental != '' {
|
||||
$update_subscriber_count_arg = " --since ${update_subscriber_count_incremental}"
|
||||
} else {
|
||||
$update_subscriber_count_arg = ''
|
||||
}
|
||||
zulip::cron { 'update_subscriber_counts':
|
||||
hour => '6',
|
||||
minute => '0',
|
||||
manage => "update_subscriber_counts${update_subscriber_count_arg}"
|
||||
}
|
||||
zulip::cron { 'clearsessions':
|
||||
hour => '22',
|
||||
minute => '22',
|
||||
}
|
||||
|
||||
# Weekly
|
||||
zulip::cron { 'update-channel-recently-active-status':
|
||||
hour => '5',
|
||||
minute => '0',
|
||||
dow => '0',
|
||||
manage => 'update_channel_recently_active_status',
|
||||
}
|
||||
|
||||
}
|
||||
7
puppet/zulip/manifests/apt_repository.pp
Normal file
7
puppet/zulip/manifests/apt_repository.pp
Normal file
@@ -0,0 +1,7 @@
|
||||
class zulip::apt_repository {
|
||||
$setup_apt_repo_file = "${facts['zulip_scripts_path']}/lib/setup-apt-repo"
|
||||
exec{'setup_apt_repo':
|
||||
command => "bash -c '${setup_apt_repo_file}'",
|
||||
unless => "bash -c '${setup_apt_repo_file} --verify'",
|
||||
}
|
||||
}
|
||||
53
puppet/zulip/manifests/camo.pp
Normal file
53
puppet/zulip/manifests/camo.pp
Normal file
@@ -0,0 +1,53 @@
|
||||
class zulip::camo (String $listen_address = '0.0.0.0') {
|
||||
$version = $zulip::common::versions['go-camo']['version']
|
||||
$goversion = $zulip::common::versions['go-camo']['goversion']
|
||||
$dir = "/srv/zulip-go-camo-${version}"
|
||||
$bin = "${dir}/bin/go-camo"
|
||||
|
||||
zulip::external_dep { 'go-camo':
|
||||
version => $version,
|
||||
url => "https://github.com/cactus/go-camo/releases/download/v${version}/go-camo-${version}.go${goversion}.linux-${zulip::common::goarch}.tar.gz",
|
||||
tarball_prefix => "go-camo-${version}",
|
||||
bin => [$bin],
|
||||
cleanup_after => [Service[supervisor]],
|
||||
}
|
||||
|
||||
# We would like to not waste resources by going through Smokescreen,
|
||||
# as go-camo already prohibits private-IP access; but a
|
||||
# non-Smokescreen exit proxy may be required to access the public
|
||||
# Internet. The `enable_for_camo` flag, if it exists, can override
|
||||
# our guess, in either direction.
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
$proxy_is_smokescreen = ($proxy_host in ['localhost', '127.0.0.1', '::1']) and ($proxy_port == '4750')
|
||||
$camo_use_proxy = zulipconf('http_proxy', 'enable_for_camo', !$proxy_is_smokescreen)
|
||||
if $camo_use_proxy {
|
||||
if $proxy_is_smokescreen {
|
||||
include zulip::smokescreen
|
||||
}
|
||||
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
|
||||
$zulip_version = $facts['zulip_version']
|
||||
$external_uri = pick(get_django_setting_slow('ROOT_DOMAIN_URI'), 'https://zulip.com')
|
||||
file { "${zulip::common::supervisor_conf_dir}/go-camo.conf":
|
||||
ensure => file,
|
||||
require => [
|
||||
Package[supervisor],
|
||||
File[$bin],
|
||||
File['/usr/local/bin/secret-env-wrapper'],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/go-camo.conf.erb'),
|
||||
notify => Service[supervisor],
|
||||
}
|
||||
}
|
||||
12
puppet/zulip/manifests/certbot.pp
Normal file
12
puppet/zulip/manifests/certbot.pp
Normal file
@@ -0,0 +1,12 @@
|
||||
class zulip::certbot {
|
||||
package { 'certbot':
|
||||
ensure => installed,
|
||||
}
|
||||
file { ['/etc/letsencrypt/renewal-hooks', '/etc/letsencrypt/renewal-hooks/deploy']:
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
require => Package[certbot],
|
||||
}
|
||||
}
|
||||
224
puppet/zulip/manifests/common.pp
Normal file
224
puppet/zulip/manifests/common.pp
Normal file
@@ -0,0 +1,224 @@
|
||||
class zulip::common {
|
||||
# Common parameters
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$nagios_plugins = 'monitoring-plugins-basic'
|
||||
$nagios_plugins_dir = '/usr/lib/nagios/plugins'
|
||||
$nginx = 'nginx-full'
|
||||
$supervisor_system_conf_dir = '/etc/supervisor/conf.d'
|
||||
$supervisor_conf_file = '/etc/supervisor/supervisord.conf'
|
||||
$supervisor_service = 'supervisor'
|
||||
$supervisor_start = '/usr/sbin/service supervisor start'
|
||||
$supervisor_reload = @(EOT)
|
||||
# The init script's timeout waiting for supervisor is shorter
|
||||
# than supervisor's timeout waiting for its programs, so we need
|
||||
# to ask supervisor to stop its programs first.
|
||||
supervisorctl stop all &&
|
||||
service supervisor restart &&
|
||||
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=877086
|
||||
# "restart" is actually "stop" under sysvinit
|
||||
{ service supervisor start || true; } &&
|
||||
service supervisor status
|
||||
| EOT
|
||||
$supervisor_status = '/usr/sbin/service supervisor status'
|
||||
}
|
||||
'RedHat': {
|
||||
$nagios_plugins = 'nagios-plugins'
|
||||
$nagios_plugins_dir = '/usr/lib64/nagios/plugins'
|
||||
$nginx = 'nginx'
|
||||
$supervisor_system_conf_dir = '/etc/supervisord.d/conf.d'
|
||||
$supervisor_conf_file = '/etc/supervisord.conf'
|
||||
$supervisor_service = 'supervisord'
|
||||
$supervisor_start = 'systemctl start supervisord'
|
||||
$supervisor_reload = 'systemctl reload supervisord'
|
||||
$supervisor_status = 'systemctl status supervisord'
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
$supervisor_conf_dir = "${supervisor_system_conf_dir}/zulip"
|
||||
|
||||
if $facts['container_memory_limit_mb'] {
|
||||
$total_memory_mb = Integer($facts['container_memory_limit_mb'])
|
||||
} else {
|
||||
$total_memory_mb = Integer($facts['memory']['system']['total_bytes'] / 1024 / 1024)
|
||||
}
|
||||
|
||||
$goarch = $facts['os']['architecture'] ? {
|
||||
'amd64' => 'amd64',
|
||||
'aarch64' => 'arm64',
|
||||
}
|
||||
|
||||
$versions = {
|
||||
# https://github.com/cactus/go-camo/releases
|
||||
'go-camo' => {
|
||||
'version' => '2.7.3',
|
||||
'goversion' => '1260',
|
||||
'sha256' => {
|
||||
'amd64' => 'd1071300b6692d194a439cb4e380ff95e1f4d894e2318bf47aaec077722370b7',
|
||||
'aarch64' => '22afef25d43cb0cb44dac100ec5602846bd66de0d9d3a3c6fc2c98eae82e6639',
|
||||
},
|
||||
},
|
||||
|
||||
# https://go.dev/dl/
|
||||
'golang' => {
|
||||
'version' => '1.26.0',
|
||||
'sha256' => {
|
||||
'amd64' => 'aac1b08a0fb0c4e0a7c1555beb7b59180b05dfc5a3d62e40e9de90cd42f88235',
|
||||
'aarch64' => 'bd03b743eb6eb4193ea3c3fd3956546bf0e3ca5b7076c8226334afe6b75704cd',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/stripe/smokescreen/tags
|
||||
'smokescreen-src' => {
|
||||
'version' => '464b1115f802cbd91ffee555a41e71546646d396',
|
||||
# Source code, so arch-invariant sha256
|
||||
'sha256' => '800d455bbdd23df0587b72e05e9bb51ce80d0f5816bd1b7070c2c26f4340cfca',
|
||||
},
|
||||
|
||||
# https://github.com/tus/tusd/releases
|
||||
# Keep in sync with tools/setup/install-tusd
|
||||
'tusd' => {
|
||||
'version' => '2.9.1',
|
||||
'sha256' => {
|
||||
'amd64' => '140066be543e40493abd1fda1d1e33ab7fa0e8b9a61d247130f6777e64bf28f6',
|
||||
'aarch64' => 'c9c46eba6e46b8062f863af6a5423f6f72b5157939d967087cd9b6d7c6bd19cf',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/wal-g/wal-g/releases
|
||||
'wal-g' => {
|
||||
'version' => '3.0.8',
|
||||
'sha256' => {
|
||||
'amd64' => 'b0df1b484035eb5f131db7bbd303d1a460391848fdcce34ba1e0a564cca493e9', # wal-g-pg-22.04-amd64.tar.gz
|
||||
'aarch64' => '048b5033c34c1487dc1fccc0572db030e323230984ccc093e80e4e4081c797d1', # wal-g-pg-22.04-aarch64.tar.gz
|
||||
},
|
||||
},
|
||||
|
||||
### kandra packages
|
||||
|
||||
# https://docs.aws.amazon.com/rolesanywhere/latest/userguide/credential-helper.html
|
||||
'aws_signing_helper' => {
|
||||
'version' => '1.7.3',
|
||||
'sha256' => {
|
||||
'amd64' => 'ef609ae021e86a2778b63dc80f4280033fcb1450bddb8b234b4ccd30f917ed21',
|
||||
'aarch64' => '7aaf8b3a4ceac464931dec27bcfd58e4facc93fb48402381e3f96bb45de5a356',
|
||||
},
|
||||
},
|
||||
|
||||
# https://release-registry.services.sentry.io/apps/sentry-cli/latest
|
||||
'sentry-cli' => {
|
||||
'version' => '2.58.4',
|
||||
'sha256' => {
|
||||
'amd64' => 'a4932b4315b192b3d037678a16eb2a5a8731609f671fc4008e643b85c3c74cb6',
|
||||
'aarch64' => '672cb986b0c5d84ef724f39b3aa189be802bceb8bc7dc8c5776a0ca90fcf41bd',
|
||||
},
|
||||
},
|
||||
|
||||
# https://grafana.com/grafana/download?edition=oss
|
||||
'grafana' => {
|
||||
'version' => '12.3.3',
|
||||
'sha256' => {
|
||||
'amd64' => 'd69b850d02903bcfe27289661c5b0b1b9a67d0bf0c42d344d55d0e63e62a7bda',
|
||||
'aarch64' => 'a2a50f6a63c89c59914b604482500de2648d12ee266d8eac8886815710482614',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/fstab/grok_exporter/tags
|
||||
'grok_exporter' => {
|
||||
'version' => '1.0.0.RC5',
|
||||
'sha256' => {
|
||||
'amd64' => 'b8771a6d7ca8447c222548d6cb8b2f8ee058b55bfd1801c2f6eb739534df5ded',
|
||||
# No aarch64 builds
|
||||
},
|
||||
},
|
||||
|
||||
# https://prometheus.io/download/#node_exporter
|
||||
'node_exporter' => {
|
||||
'version' => '1.10.2',
|
||||
'sha256' => {
|
||||
'amd64' => 'c46e5b6f53948477ff3a19d97c58307394a29fe64a01905646f026ddc32cb65b',
|
||||
'aarch64' => 'de69ec8341c8068b7c8e4cfe3eb85065d24d984a3b33007f575d307d13eb89a6',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/prometheus-community/postgres_exporter/tags
|
||||
'postgres_exporter' => {
|
||||
'version' => '0.19.0',
|
||||
'sha256' => {
|
||||
'amd64' => '11033f9016d0c5a5b91742d17aa37490b170f055ec1bb0d7d69509d223952ed0',
|
||||
'aarch64' => '8a2f55b1a00694758ea4bfd96a8bb814c1b279cf9d233a24fecd28a9e87c6280',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/prometheus-community/postgres_exporter/pull/843
|
||||
'postgres_exporter-src' => {
|
||||
'version' => '86a2b77aa522f57a136d04ffa33f0e46713d1925',
|
||||
'sha256' => '03b3a4e794b6c01e911c3f7f4d77a2889d6946e2245f8d12d14844c29554a884',
|
||||
},
|
||||
|
||||
# https://github.com/ncabatoff/process-exporter/releases
|
||||
'process_exporter' => {
|
||||
'version' => '0.8.7',
|
||||
'sha256' => {
|
||||
'amd64' => '6d274cca5e94c6a25e55ec05762a472561859ce0a05b984aaedb67dd857ceee2',
|
||||
'aarch64' => '4a2502f290323e57eeeb070fc10e64047ad0cd838ae5a1b347868f75667b5ab0',
|
||||
}
|
||||
},
|
||||
|
||||
# https://prometheus.io/download/#prometheus
|
||||
'prometheus' => {
|
||||
'version' => '3.9.1',
|
||||
'sha256' => {
|
||||
'amd64' => '86a6999dd6aacbd994acde93c77cfa314d4be1c8e7b7c58f444355c77b32c584',
|
||||
'aarch64' => '4e7f291e527d8aca912a995c183128388c9e048065aff84f74f5a55c9bef3793',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/prometheus/pushgateway/releases
|
||||
'pushgateway' => {
|
||||
'version' => '1.11.2',
|
||||
'sha256' => {
|
||||
'amd64' => '2ec72315e150dda071fdeef09360780a386a67e5207ebaa53bb18f2f1a3b89cf',
|
||||
'aarch64' => 'b3fb835dbb0a29b1d6f9cd7ae3568a5615e59b96f8787965248cea67163d4db1',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/oliver006/redis_exporter/releases
|
||||
'redis_exporter' => {
|
||||
'version' => '1.81.0',
|
||||
'sha256' => {
|
||||
'amd64' => 'd2f4740fa81e1a274ca99677783f3fe1544f6022fed997d4cd632d01a8eff1bb',
|
||||
'aarch64' => '038d0d2d8f044075cc97acd323c16a8c3628f08ef7d186601fedaa38b71aad8f',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/alexmv/teleport-sd/releases
|
||||
'teleport-sd' => {
|
||||
'version' => '0.1.0',
|
||||
'sha256' => {
|
||||
'amd64' => '2128d78dd602c6a24c13fbd759bf19d0c3cebaa732ad0824019ced53163cf455',
|
||||
'aarch64' => 'df93ba9510cb8898ba0f15b293d7c6877173a8d06b1f284dcc42ffc7ff32978e',
|
||||
},
|
||||
},
|
||||
|
||||
# https://github.com/timonwong/uwsgi_exporter/releases
|
||||
'uwsgi_exporter' => {
|
||||
'version' => '1.3.0',
|
||||
'sha256' => {
|
||||
'amd64' => 'f83411b508676237bbd1b791c1bdc043a68bf914c7e48e005e2e295255f9245f',
|
||||
'aarch64' => 'ab7c9298d2fe5c5f58e3fe7c905929e93979d2b3b11c75eb8ba6ccc7a547238c',
|
||||
},
|
||||
},
|
||||
|
||||
# https://vector.dev/download/
|
||||
'vector' => {
|
||||
'version' => '0.53.0',
|
||||
'sha256' => {
|
||||
'amd64' => '5460f93310eb59cc9e7ee7717a179f1bf2ff8fbc046b7e3eb625159a5e8714bb',
|
||||
'aarch64' => '2722dec4f5c358793caeb86b4f4febd047b37a2d688af181e8264a764ecd28e5',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
50
puppet/zulip/manifests/cron.pp
Normal file
50
puppet/zulip/manifests/cron.pp
Normal file
@@ -0,0 +1,50 @@
|
||||
# @summary Install a cron file into /etc/cron.d
|
||||
#
|
||||
define zulip::cron(
|
||||
String $minute,
|
||||
String $hour = '*',
|
||||
String $dow = '*',
|
||||
String $user = 'zulip',
|
||||
Optional[String] $command = undef,
|
||||
Optional[String] $manage = undef,
|
||||
Boolean $use_proxy = true,
|
||||
) {
|
||||
if $use_proxy {
|
||||
$proxy_host = zulipconf('http_proxy', 'host', 'localhost')
|
||||
$proxy_port = zulipconf('http_proxy', 'port', '4750')
|
||||
if $proxy_host != '' and $proxy_port != '' {
|
||||
$proxy = "http://${proxy_host}:${proxy_port}"
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
} else {
|
||||
$proxy = ''
|
||||
}
|
||||
|
||||
$dsn = zulipconf('sentry', 'project_dsn', '')
|
||||
if $dsn != '' {
|
||||
include zulip::sentry_cli
|
||||
$environment = zulipconf('machine', 'deploy_type', 'development')
|
||||
$sentry = "sentry-cli monitors run -e ${environment} --schedule '${minute} ${hour} * * ${dow}' ${title} -- "
|
||||
$cron_require = [File['/usr/local/bin/sentry-cli']]
|
||||
} else {
|
||||
$sentry = ''
|
||||
$cron_require = []
|
||||
}
|
||||
if $command != undef {
|
||||
$run = "${sentry}${command}"
|
||||
} elsif $manage != undef {
|
||||
$run = "cd /home/zulip/deployments/current/ && ${sentry}./manage.py ${manage} >/dev/null"
|
||||
} else {
|
||||
$underscores = regsubst($title, '-', '_', 'G')
|
||||
$run = "cd /home/zulip/deployments/current/ && ${sentry}./manage.py ${underscores} >/dev/null"
|
||||
}
|
||||
file { "/etc/cron.d/${title}":
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/cron.template.erb'),
|
||||
require => $cron_require,
|
||||
}
|
||||
}
|
||||
4
puppet/zulip/manifests/dockervoyager.pp
Normal file
4
puppet/zulip/manifests/dockervoyager.pp
Normal file
@@ -0,0 +1,4 @@
|
||||
# @summary Temporary shim for docker all-in-one profile
|
||||
class zulip::dockervoyager {
|
||||
include zulip::profile::docker
|
||||
}
|
||||
69
puppet/zulip/manifests/external_dep.pp
Normal file
69
puppet/zulip/manifests/external_dep.pp
Normal file
@@ -0,0 +1,69 @@
|
||||
define zulip::external_dep(
|
||||
String $version,
|
||||
String $url,
|
||||
String $tarball_prefix = '',
|
||||
String $sha256 = '',
|
||||
String $mode = '0755',
|
||||
Array[String] $bin = [],
|
||||
Array[Type[Resource]] $cleanup_after = [],
|
||||
) {
|
||||
$arch = $facts['os']['architecture']
|
||||
if $sha256 == '' {
|
||||
if $zulip::common::versions[$title]['sha256'] =~ Hash {
|
||||
$sha256_filled = $zulip::common::versions[$title]['sha256'][$arch]
|
||||
if $sha256_filled == undef {
|
||||
err("No sha256 found for ${title} for architecture ${arch}")
|
||||
fail()
|
||||
}
|
||||
} else {
|
||||
# For things like source code which are arch-invariant
|
||||
$sha256_filled = $zulip::common::versions[$title]['sha256']
|
||||
}
|
||||
} else {
|
||||
$sha256_filled = $sha256
|
||||
}
|
||||
|
||||
$path = "/srv/zulip-${title}-${version}"
|
||||
|
||||
if $tarball_prefix == '' {
|
||||
zulip::sha256_file_to { $title:
|
||||
url => $url,
|
||||
sha256 => $sha256_filled,
|
||||
install_to => $path,
|
||||
notify => Exec["Cleanup ${title}"],
|
||||
}
|
||||
file { $path:
|
||||
ensure => file,
|
||||
require => Zulip::Sha256_File_To[$title],
|
||||
before => Exec["Cleanup ${title}"],
|
||||
mode => $mode,
|
||||
}
|
||||
} else {
|
||||
zulip::sha256_tarball_to { $title:
|
||||
url => $url,
|
||||
sha256 => $sha256_filled,
|
||||
install_from => $tarball_prefix,
|
||||
install_to => $path,
|
||||
notify => Exec["Cleanup ${title}"],
|
||||
}
|
||||
file { $path:
|
||||
ensure => present,
|
||||
require => Zulip::Sha256_Tarball_To[$title],
|
||||
before => Exec["Cleanup ${title}"],
|
||||
}
|
||||
file { $bin:
|
||||
ensure => file,
|
||||
require => [File[$path], Zulip::Sha256_Tarball_To[$title]],
|
||||
before => Exec["Cleanup ${title}"],
|
||||
mode => $mode,
|
||||
}
|
||||
}
|
||||
|
||||
exec { "Cleanup ${title}":
|
||||
refreshonly => true,
|
||||
provider => shell,
|
||||
onlyif => "ls -d /srv/zulip-${title}-* | grep -xv '${path}'",
|
||||
command => "ls -d /srv/zulip-${title}-* | grep -xv '${path}' | xargs rm -r",
|
||||
require => $cleanup_after,
|
||||
}
|
||||
}
|
||||
13
puppet/zulip/manifests/golang.pp
Normal file
13
puppet/zulip/manifests/golang.pp
Normal file
@@ -0,0 +1,13 @@
|
||||
# @summary go compiler and tools
|
||||
#
|
||||
class zulip::golang {
|
||||
$version = $zulip::common::versions['golang']['version']
|
||||
$dir = "/srv/zulip-golang-${version}"
|
||||
$bin = "${dir}/bin/go"
|
||||
|
||||
zulip::external_dep { 'golang':
|
||||
version => $version,
|
||||
url => "https://go.dev/dl/go${version}.linux-${zulip::common::goarch}.tar.gz",
|
||||
tarball_prefix => 'go',
|
||||
}
|
||||
}
|
||||
16
puppet/zulip/manifests/hooks/base.pp
Normal file
16
puppet/zulip/manifests/hooks/base.pp
Normal file
@@ -0,0 +1,16 @@
|
||||
# @summary Install sentry-cli binary and pre/post deploy hooks
|
||||
#
|
||||
class zulip::hooks::base {
|
||||
file { [
|
||||
'/etc/zulip/hooks',
|
||||
'/etc/zulip/hooks/common',
|
||||
'/etc/zulip/hooks/pre-deploy.d',
|
||||
'/etc/zulip/hooks/post-deploy.d',
|
||||
]:
|
||||
ensure => directory,
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
mode => '0755',
|
||||
tag => ['hooks'],
|
||||
}
|
||||
}
|
||||
14
puppet/zulip/manifests/hooks/file.pp
Normal file
14
puppet/zulip/manifests/hooks/file.pp
Normal file
@@ -0,0 +1,14 @@
|
||||
# @summary Install a static hook file
|
||||
#
|
||||
define zulip::hooks::file() {
|
||||
include zulip::hooks::base
|
||||
|
||||
file { "/etc/zulip/hooks/${title}":
|
||||
ensure => file,
|
||||
mode => '0755',
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
source => "puppet:///modules/zulip/hooks/${title}",
|
||||
tag => ['hooks'],
|
||||
}
|
||||
}
|
||||
9
puppet/zulip/manifests/hooks/push_git_ref.pp
Normal file
9
puppet/zulip/manifests/hooks/push_git_ref.pp
Normal file
@@ -0,0 +1,9 @@
|
||||
# @summary Push the merge_base to a git repo after deploy
|
||||
#
|
||||
class zulip::hooks::push_git_ref {
|
||||
include zulip::hooks::base
|
||||
|
||||
zulip::hooks::file { [
|
||||
'post-deploy.d/push_git_ref.hook',
|
||||
]: }
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
# @summary Send zuip update announcements after deploy
|
||||
#
|
||||
class zulip::hooks::send_zulip_update_announcements {
|
||||
include zulip::hooks::base
|
||||
|
||||
zulip::hooks::file { [
|
||||
'post-deploy.d/send_zulip_update_announcements.hook',
|
||||
]: }
|
||||
}
|
||||
12
puppet/zulip/manifests/hooks/sentry.pp
Normal file
12
puppet/zulip/manifests/hooks/sentry.pp
Normal file
@@ -0,0 +1,12 @@
|
||||
# @summary Install Sentry pre/post deploy hooks
|
||||
#
|
||||
class zulip::hooks::sentry {
|
||||
include zulip::hooks::base
|
||||
include zulip::sentry_cli
|
||||
|
||||
zulip::hooks::file { [
|
||||
'common/sentry.sh',
|
||||
'pre-deploy.d/sentry.hook',
|
||||
'post-deploy.d/sentry.hook',
|
||||
]: }
|
||||
}
|
||||
7
puppet/zulip/manifests/hooks/zulip_common.pp
Normal file
7
puppet/zulip/manifests/hooks/zulip_common.pp
Normal file
@@ -0,0 +1,7 @@
|
||||
# @summary zulip_notify common file
|
||||
#
|
||||
class zulip::hooks::zulip_common {
|
||||
include zulip::hooks::base
|
||||
|
||||
zulip::hooks::file { 'common/zulip_notify.sh': }
|
||||
}
|
||||
11
puppet/zulip/manifests/hooks/zulip_notify.pp
Normal file
11
puppet/zulip/manifests/hooks/zulip_notify.pp
Normal file
@@ -0,0 +1,11 @@
|
||||
# @summary Install hook that notifies when a deploy starts/stops
|
||||
#
|
||||
class zulip::hooks::zulip_notify {
|
||||
include zulip::hooks::base
|
||||
include zulip::hooks::zulip_common
|
||||
|
||||
zulip::hooks::file { [
|
||||
'pre-deploy.d/zulip_notify.hook',
|
||||
'post-deploy.d/zulip_notify.hook',
|
||||
]: }
|
||||
}
|
||||
34
puppet/zulip/manifests/local_mailserver.pp
Normal file
34
puppet/zulip/manifests/local_mailserver.pp
Normal file
@@ -0,0 +1,34 @@
|
||||
class zulip::local_mailserver {
|
||||
include zulip::snakeoil
|
||||
include zulip::certbot
|
||||
|
||||
if zulipconf('postfix', 'uninstall', true) {
|
||||
package { 'postfix':
|
||||
# TODO/compatibility: We can remove this when upgrading directly
|
||||
# from 10.x is no longer possible. We do not use "purged" here,
|
||||
# since that would remove config files, which users may have had
|
||||
# installed.
|
||||
ensure => absent,
|
||||
before => Service[$zulip::common::supervisor_service],
|
||||
}
|
||||
}
|
||||
$listen = zulipconf('email_gateway', 'listen', '')
|
||||
file { "${zulip::common::supervisor_conf_dir}/email-mirror.conf":
|
||||
ensure => file,
|
||||
require => [
|
||||
Package[supervisor],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/email-mirror.conf.template.erb'),
|
||||
notify => Service[$zulip::common::supervisor_service],
|
||||
}
|
||||
file { '/etc/letsencrypt/renewal-hooks/deploy/055-email-server.sh':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/letsencrypt/055-email-server.sh',
|
||||
}
|
||||
}
|
||||
16
puppet/zulip/manifests/localhost_camo.pp
Normal file
16
puppet/zulip/manifests/localhost_camo.pp
Normal file
@@ -0,0 +1,16 @@
|
||||
class zulip::localhost_camo {
|
||||
class { 'zulip::camo':
|
||||
listen_address => '127.0.0.1',
|
||||
}
|
||||
|
||||
# Install nginx configuration to run camo locally
|
||||
file { '/etc/nginx/zulip-include/app.d/camo.conf':
|
||||
ensure => file,
|
||||
require => Package['nginx-full'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-app.d/camo.conf',
|
||||
}
|
||||
}
|
||||
11
puppet/zulip/manifests/localhost_sso.pp
Normal file
11
puppet/zulip/manifests/localhost_sso.pp
Normal file
@@ -0,0 +1,11 @@
|
||||
class zulip::localhost_sso {
|
||||
file { '/etc/nginx/zulip-include/app.d/external-sso.conf':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-app.d/external-sso.conf',
|
||||
}
|
||||
}
|
||||
14
puppet/zulip/manifests/nagios_plugins.pp
Normal file
14
puppet/zulip/manifests/nagios_plugins.pp
Normal file
@@ -0,0 +1,14 @@
|
||||
# @summary Installs a subdirectory from puppet/zulip/files/nagios_plugins/
|
||||
define zulip::nagios_plugins () {
|
||||
include zulip::common
|
||||
|
||||
file { "${zulip::common::nagios_plugins_dir}/${name}":
|
||||
require => Package[$zulip::common::nagios_plugins],
|
||||
recurse => true,
|
||||
purge => true,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => "puppet:///modules/zulip/nagios_plugins/${name}",
|
||||
}
|
||||
}
|
||||
120
puppet/zulip/manifests/nginx.pp
Normal file
120
puppet/zulip/manifests/nginx.pp
Normal file
@@ -0,0 +1,120 @@
|
||||
class zulip::nginx {
|
||||
include zulip::certbot
|
||||
package { $zulip::common::nginx: ensure => installed }
|
||||
package { 'ca-certificates': ensure => latest }
|
||||
|
||||
if $facts['os']['family'] == 'RedHat' {
|
||||
file { '/etc/nginx/sites-available':
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
}
|
||||
file { '/etc/nginx/sites-enabled':
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
}
|
||||
}
|
||||
|
||||
file { '/etc/nginx/zulip-include/':
|
||||
require => Package[$zulip::common::nginx],
|
||||
recurse => true,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/nginx/zulip-include-common/',
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
file { '/etc/nginx/dhparam.pem':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
source => 'puppet:///modules/zulip/nginx/dhparam.pem',
|
||||
}
|
||||
|
||||
if $facts['os']['family'] == 'Debian' {
|
||||
$ca_crt = '/etc/ssl/certs/ca-certificates.crt'
|
||||
} else {
|
||||
$ca_crt = '/etc/pki/tls/certs/ca-bundle.crt'
|
||||
}
|
||||
$worker_processes = zulipconf('application_server', 'nginx_worker_processes', 'auto')
|
||||
$worker_connections = zulipconf('application_server', 'nginx_worker_connections', 10000)
|
||||
file { '/etc/nginx/nginx.conf':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx, 'ca-certificates'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
content => template('zulip/nginx.conf.template.erb'),
|
||||
}
|
||||
|
||||
$loadbalancers = split(zulipconf('loadbalancer', 'ips', ''), ',')
|
||||
$raw_true_client_header = zulipconf('loadbalancer', 'true_client_header', '')
|
||||
$true_client_header = regsubst(downcase($raw_true_client_header), '-', '_', 'G')
|
||||
$true_client_header_from = split(zulipconf('loadbalancer', 'true_client_header_from', ''), ',')
|
||||
$lb_rejects_http_requests = zulipconf('loadbalancer', 'rejects_http_requests', false)
|
||||
file { '/etc/nginx/zulip-include/trusted-ip':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
content => template('zulip/nginx/trusted-ip.template.erb'),
|
||||
}
|
||||
file { '/etc/nginx/zulip-include/trusted-proto':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
content => template('zulip/nginx/trusted-proto.template.erb'),
|
||||
}
|
||||
|
||||
file { '/etc/nginx/uwsgi_params':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
source => 'puppet:///modules/zulip/nginx/uwsgi_params',
|
||||
}
|
||||
|
||||
file { '/etc/nginx/sites-enabled/default':
|
||||
ensure => absent,
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
file { '/var/log/nginx':
|
||||
ensure => directory,
|
||||
owner => 'zulip',
|
||||
group => 'adm',
|
||||
mode => '0750',
|
||||
}
|
||||
$access_log_retention_days = zulipconf('application_server','access_log_retention_days', 14)
|
||||
file { '/etc/logrotate.d/nginx':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/logrotate/nginx.template.erb'),
|
||||
}
|
||||
file { ['/var/lib/zulip', '/var/lib/zulip/certbot-webroot']:
|
||||
ensure => directory,
|
||||
owner => 'zulip',
|
||||
group => 'adm',
|
||||
mode => '0770',
|
||||
}
|
||||
|
||||
service { 'nginx':
|
||||
ensure => running,
|
||||
}
|
||||
}
|
||||
47
puppet/zulip/manifests/postgresql_backups.pp
Normal file
47
puppet/zulip/manifests/postgresql_backups.pp
Normal file
@@ -0,0 +1,47 @@
|
||||
# @summary Use wal-g to take daily backups of PostgreSQL
|
||||
#
|
||||
class zulip::postgresql_backups {
|
||||
include zulip::postgresql_common
|
||||
include zulip::wal_g
|
||||
|
||||
file { '/var/log/pg_backup_and_purge.log':
|
||||
ensure => file,
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
mode => '0644',
|
||||
}
|
||||
file { '/usr/local/bin/pg_backup_and_purge':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'postgres',
|
||||
mode => '0754',
|
||||
source => 'puppet:///modules/zulip/postgresql/pg_backup_and_purge',
|
||||
require => [
|
||||
File['/usr/local/bin/env-wal-g'],
|
||||
Package[
|
||||
$zulip::postgresql_common::postgresql,
|
||||
],
|
||||
],
|
||||
}
|
||||
|
||||
zulip::cron { 'pg_backup_and_purge':
|
||||
hour => '2',
|
||||
minute => '0',
|
||||
command => '/usr/local/bin/pg_backup_and_purge >/var/log/pg_backup_and_purge.log 2>&1',
|
||||
user => 'postgres',
|
||||
require => [
|
||||
File['/var/log/pg_backup_and_purge.log'],
|
||||
File['/usr/local/bin/pg_backup_and_purge'],
|
||||
],
|
||||
}
|
||||
|
||||
$postgresql_backup_directory = zulipconf('postgresql', 'backups_directory', '')
|
||||
if $postgresql_backup_directory != '' {
|
||||
file { $postgresql_backup_directory:
|
||||
ensure => directory,
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
mode => '0600',
|
||||
}
|
||||
}
|
||||
}
|
||||
80
puppet/zulip/manifests/postgresql_base.pp
Normal file
80
puppet/zulip/manifests/postgresql_base.pp
Normal file
@@ -0,0 +1,80 @@
|
||||
# Minimal shared configuration needed to run a Zulip PostgreSQL database.
|
||||
class zulip::postgresql_base {
|
||||
include zulip::postgresql_common
|
||||
include zulip::process_fts_updates
|
||||
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$postgresql = "postgresql-${zulip::postgresql_common::version}"
|
||||
$postgresql_sharedir = "/usr/share/postgresql/${zulip::postgresql_common::version}"
|
||||
$postgresql_confdirs = [
|
||||
"/etc/postgresql/${zulip::postgresql_common::version}",
|
||||
"/etc/postgresql/${zulip::postgresql_common::version}/main",
|
||||
]
|
||||
$postgresql_confdir = $postgresql_confdirs[-1]
|
||||
$postgresql_datadir = "/var/lib/postgresql/${zulip::postgresql_common::version}/main"
|
||||
$tsearch_datadir = "${postgresql_sharedir}/tsearch_data"
|
||||
$pgroonga_setup_sql_path = "${postgresql_sharedir}/pgroonga_setup.sql"
|
||||
$setup_system_deps = 'setup_apt_repo'
|
||||
}
|
||||
'RedHat': {
|
||||
$postgresql = "postgresql${zulip::postgresql_common::version}"
|
||||
$postgresql_sharedir = "/usr/pgsql-${zulip::postgresql_common::version}/share"
|
||||
$postgresql_confdirs = [
|
||||
"/var/lib/pgsql/${zulip::postgresql_common::version}",
|
||||
"/var/lib/pgsql/${zulip::postgresql_common::version}/data",
|
||||
]
|
||||
$postgresql_confdir = $postgresql_confdirs[-1]
|
||||
$postgresql_datadir = "/var/lib/pgsql/${zulip::postgresql_common::version}/data"
|
||||
$tsearch_datadir = "${postgresql_sharedir}/tsearch_data/"
|
||||
$pgroonga_setup_sql_path = "${postgresql_sharedir}/pgroonga_setup.sql"
|
||||
$setup_system_deps = 'setup_yum_repo'
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
|
||||
file { "${tsearch_datadir}/zulip_english.stop":
|
||||
ensure => file,
|
||||
require => Package[$postgresql],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/postgresql/zulip_english.stop',
|
||||
tag => ['postgresql_upgrade'],
|
||||
}
|
||||
zulip::nagios_plugins { 'zulip_postgresql': }
|
||||
|
||||
$pgroonga = zulipconf('machine', 'pgroonga', false)
|
||||
if $pgroonga {
|
||||
# Needed for optional our full text search system
|
||||
package{"${postgresql}-pgdg-pgroonga":
|
||||
ensure => latest,
|
||||
require => [
|
||||
Package[$postgresql],
|
||||
Exec[$setup_system_deps]
|
||||
],
|
||||
tag => ['postgresql_upgrade'],
|
||||
}
|
||||
exec { 'pgroonga-config':
|
||||
require => Package["${postgresql}-pgdg-pgroonga"],
|
||||
unless => @("EOT"/$),
|
||||
test -f ${pgroonga_setup_sql_path}.applied &&
|
||||
test "$(dpkg-query --show --showformat='\${Version}' "${postgresql}-pgdg-pgroonga")" \
|
||||
= "$(cat ${pgroonga_setup_sql_path}.applied)"
|
||||
| EOT
|
||||
command => "${facts['zulip_scripts_path']}/setup/pgroonga-config ${postgresql_sharedir}",
|
||||
}
|
||||
}
|
||||
|
||||
$backups_s3_bucket = zulipsecret('secrets', 's3_backups_bucket', '')
|
||||
$backups_directory = zulipconf('postgresql', 'backups_directory', '')
|
||||
if $backups_s3_bucket != '' or $backups_directory != '' {
|
||||
include zulip::postgresql_backups
|
||||
} else {
|
||||
file { '/etc/cron.d/pg_backup_and_purge':
|
||||
ensure => absent,
|
||||
}
|
||||
}
|
||||
}
|
||||
12
puppet/zulip/manifests/postgresql_client.pp
Normal file
12
puppet/zulip/manifests/postgresql_client.pp
Normal file
@@ -0,0 +1,12 @@
|
||||
class zulip::postgresql_client {
|
||||
$version = zulipconf('postgresql', 'version', undef)
|
||||
if $version != undef {
|
||||
package { "postgresql-client-${version}":
|
||||
ensure => installed,
|
||||
}
|
||||
} else {
|
||||
package { 'postgresql-client':
|
||||
ensure => installed,
|
||||
}
|
||||
}
|
||||
}
|
||||
79
puppet/zulip/manifests/postgresql_common.pp
Normal file
79
puppet/zulip/manifests/postgresql_common.pp
Normal file
@@ -0,0 +1,79 @@
|
||||
class zulip::postgresql_common {
|
||||
include zulip::snakeoil
|
||||
$version = zulipconf('postgresql', 'version', undef)
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$postgresql = "postgresql-${version}"
|
||||
$postgresql_packages = [
|
||||
# The database itself
|
||||
$postgresql,
|
||||
# tools for database monitoring; formerly ptop
|
||||
'pgtop',
|
||||
# our dictionary
|
||||
'hunspell-en-us',
|
||||
# PostgreSQL Nagios check plugin
|
||||
'check-postgres',
|
||||
]
|
||||
$postgresql_user_reqs = [
|
||||
Package[$postgresql],
|
||||
Package['ssl-cert'],
|
||||
]
|
||||
}
|
||||
'RedHat': {
|
||||
$postgresql = "postgresql${version}"
|
||||
$postgresql_packages = [
|
||||
$postgresql,
|
||||
"${postgresql}-server",
|
||||
"${postgresql}-devel",
|
||||
'pg_top',
|
||||
'hunspell-en-US',
|
||||
# exists on CentOS 6 and Fedora 29 but not CentOS 7
|
||||
# see https://pkgs.org/download/check_postgres
|
||||
# alternatively, download directly from:
|
||||
# https://bucardo.org/check_postgres/
|
||||
# 'check-postgres', # TODO
|
||||
]
|
||||
group { 'ssl-cert':
|
||||
ensure => present,
|
||||
}
|
||||
# allows ssl-cert group to read /etc/pki/tls/private
|
||||
file { '/etc/pki/tls/private':
|
||||
ensure => directory,
|
||||
mode => '0750',
|
||||
owner => 'root',
|
||||
group => 'ssl-cert',
|
||||
}
|
||||
$postgresql_user_reqs = [
|
||||
Package[$postgresql],
|
||||
Group['ssl-cert'],
|
||||
]
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
|
||||
zulip::safepackage { $postgresql_packages:
|
||||
ensure => installed,
|
||||
require => Exec['generate-default-snakeoil'],
|
||||
tag => ['postgresql_upgrade'],
|
||||
}
|
||||
|
||||
if $facts['os']['family'] == 'Debian' {
|
||||
# The logrotate file only created in debian-based systems
|
||||
exec { 'disable_logrotate':
|
||||
# lint:ignore:140chars
|
||||
command => '/usr/bin/dpkg-divert --rename --divert /etc/logrotate.d/postgresql-common.disabled --add /etc/logrotate.d/postgresql-common',
|
||||
# lint:endignore
|
||||
creates => '/etc/logrotate.d/postgresql-common.disabled',
|
||||
}
|
||||
}
|
||||
|
||||
# Use arcane puppet virtual resources to add postgres user to zulip group
|
||||
@user { 'postgres':
|
||||
groups => ['ssl-cert'],
|
||||
membership => minimum,
|
||||
require => $postgresql_user_reqs,
|
||||
}
|
||||
User <| title == postgres |> { groups +> 'zulip' }
|
||||
}
|
||||
38
puppet/zulip/manifests/process_fts_updates.pp
Normal file
38
puppet/zulip/manifests/process_fts_updates.pp
Normal file
@@ -0,0 +1,38 @@
|
||||
class zulip::process_fts_updates {
|
||||
include zulip::supervisor
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$fts_updates_packages = [
|
||||
# Needed to run process_fts_updates
|
||||
'python3-psycopg2', # TODO: use a virtualenv instead
|
||||
]
|
||||
zulip::safepackage { $fts_updates_packages: ensure => installed }
|
||||
}
|
||||
'RedHat': {
|
||||
exec {'pip_process_fts_updates':
|
||||
command => 'python3 -m pip install psycopg2',
|
||||
}
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
|
||||
file { '/usr/local/bin/process_fts_updates':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/postgresql/process_fts_updates',
|
||||
}
|
||||
|
||||
file { "${zulip::common::supervisor_conf_dir}/zulip_db.conf":
|
||||
ensure => file,
|
||||
require => [Package[supervisor], Package['python3-psycopg2']],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/supervisor/conf.d/zulip_db.conf',
|
||||
notify => Service[$zulip::common::supervisor_service],
|
||||
}
|
||||
}
|
||||
65
puppet/zulip/manifests/profile/app_frontend.pp
Normal file
65
puppet/zulip/manifests/profile/app_frontend.pp
Normal file
@@ -0,0 +1,65 @@
|
||||
# Default configuration for a Zulip app frontend
|
||||
class zulip::profile::app_frontend {
|
||||
include zulip::profile::base
|
||||
include zulip::app_frontend_base
|
||||
include zulip::app_frontend_once
|
||||
|
||||
$nginx_http_only = zulipconf('application_server', 'http_only', false)
|
||||
if $nginx_http_only {
|
||||
$nginx_listen_port = zulipconf('application_server', 'nginx_listen_port', 80)
|
||||
} else {
|
||||
$nginx_listen_port = zulipconf('application_server', 'nginx_listen_port', 443)
|
||||
}
|
||||
$nginx_server_name = zulipconf('application_server', 'nginx_server_name', '')
|
||||
$ssl_dir = $facts['os']['family'] ? {
|
||||
'Debian' => '/etc/ssl',
|
||||
'RedHat' => '/etc/pki/tls',
|
||||
}
|
||||
file { '/etc/nginx/sites-available/zulip-enterprise':
|
||||
ensure => file,
|
||||
require => Package[$zulip::common::nginx],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/nginx/zulip-enterprise.template.erb'),
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
file { '/etc/nginx/sites-enabled/zulip-enterprise':
|
||||
ensure => link,
|
||||
require => Package[$zulip::common::nginx],
|
||||
target => '/etc/nginx/sites-available/zulip-enterprise',
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
|
||||
# Reload nginx after deploying a new cert.
|
||||
file { '/etc/letsencrypt/renewal-hooks/deploy/001-nginx.sh':
|
||||
# This was renumbered
|
||||
ensure => absent,
|
||||
}
|
||||
file { '/etc/letsencrypt/renewal-hooks/deploy/020-symlink.sh':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/letsencrypt/020-symlink.sh',
|
||||
require => [
|
||||
Package[certbot],
|
||||
File['/etc/letsencrypt/renewal-hooks/deploy'],
|
||||
]
|
||||
}
|
||||
file { '/etc/letsencrypt/renewal-hooks/deploy/050-nginx.sh':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/letsencrypt/050-nginx.sh',
|
||||
}
|
||||
|
||||
# Restart the server regularly to avoid potential memory leak problems.
|
||||
zulip::cron { 'restart-zulip':
|
||||
hour => '6',
|
||||
minute => '0',
|
||||
dow => '0',
|
||||
command => '/home/zulip/deployments/current/scripts/restart-server --fill-cache --skip-client-reloads',
|
||||
}
|
||||
}
|
||||
142
puppet/zulip/manifests/profile/base.pp
Normal file
142
puppet/zulip/manifests/profile/base.pp
Normal file
@@ -0,0 +1,142 @@
|
||||
# @summary Included only by classes that can be deployed.
|
||||
#
|
||||
# This class should only be included by classes that are intended to
|
||||
# be able to be deployed on their own host.
|
||||
class zulip::profile::base {
|
||||
include zulip::timesync
|
||||
include zulip::common
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
include zulip::apt_repository
|
||||
}
|
||||
'RedHat': {
|
||||
include zulip::yum_repository
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$base_packages = [
|
||||
# Basics
|
||||
'python3',
|
||||
'python3-yaml',
|
||||
'puppet',
|
||||
'git',
|
||||
'curl',
|
||||
'jq',
|
||||
'procps',
|
||||
# Used to read /etc/zulip/zulip.conf for `zulipconf` Puppet function
|
||||
'crudini',
|
||||
# Used for tools like sponge
|
||||
'moreutils',
|
||||
# Nagios monitoring plugins
|
||||
$zulip::common::nagios_plugins,
|
||||
# Required for using HTTPS in apt repositories.
|
||||
'apt-transport-https',
|
||||
# Needed for the cron jobs installed by Puppet
|
||||
'cron',
|
||||
# Applies log rotation config installed by Puppet
|
||||
'logrotate',
|
||||
]
|
||||
}
|
||||
'RedHat': {
|
||||
$base_packages = [
|
||||
'python3',
|
||||
'python3-pyyaml',
|
||||
'puppet',
|
||||
'git',
|
||||
'curl',
|
||||
'jq',
|
||||
'crudini',
|
||||
'moreutils',
|
||||
'nmap-ncat',
|
||||
'nagios-plugins', # there is no dummy package on CentOS 7
|
||||
'cronie',
|
||||
]
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
package { $base_packages: ensure => installed }
|
||||
|
||||
group { 'zulip':
|
||||
ensure => present,
|
||||
}
|
||||
|
||||
user { 'zulip':
|
||||
ensure => present,
|
||||
require => Group['zulip'],
|
||||
gid => 'zulip',
|
||||
shell => '/bin/bash',
|
||||
home => '/home/zulip',
|
||||
managehome => true,
|
||||
}
|
||||
|
||||
file { '/etc/zulip':
|
||||
ensure => directory,
|
||||
mode => '0755',
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
links => follow,
|
||||
}
|
||||
file { ['/etc/zulip/zulip.conf', '/etc/zulip/settings.py']:
|
||||
ensure => present,
|
||||
require => File['/etc/zulip'],
|
||||
mode => '0644',
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
}
|
||||
file { '/etc/zulip/zulip-secrets.conf':
|
||||
ensure => present,
|
||||
require => File['/etc/zulip'],
|
||||
mode => '0640',
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
}
|
||||
|
||||
file { '/etc/security/limits.d/zulip.conf':
|
||||
ensure => file,
|
||||
mode => '0640',
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
source => 'puppet:///modules/zulip/limits.d/zulip.conf',
|
||||
}
|
||||
file { '/etc/systemd/system.conf.d/':
|
||||
ensure => directory,
|
||||
mode => '0755',
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
}
|
||||
file { '/etc/systemd/system.conf.d/limits.conf':
|
||||
ensure => file,
|
||||
mode => '0644',
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
source => 'puppet:///modules/zulip/systemd/system.conf.d/limits.conf',
|
||||
}
|
||||
|
||||
service { 'puppet':
|
||||
ensure => stopped,
|
||||
enable => false,
|
||||
require => Package['puppet'],
|
||||
}
|
||||
|
||||
# This directory is written to by cron jobs for reading by Nagios
|
||||
file { '/var/lib/nagios_state/':
|
||||
ensure => directory,
|
||||
group => 'zulip',
|
||||
mode => '0775',
|
||||
}
|
||||
|
||||
file { '/var/log/zulip':
|
||||
ensure => directory,
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
mode => '0750',
|
||||
}
|
||||
|
||||
zulip::nagios_plugins { 'zulip_base': }
|
||||
}
|
||||
29
puppet/zulip/manifests/profile/docker.pp
Normal file
29
puppet/zulip/manifests/profile/docker.pp
Normal file
@@ -0,0 +1,29 @@
|
||||
# This class includes all the modules you need to install/run a Zulip installation
|
||||
# in a single container (without the database, memcached, Redis services).
|
||||
# The database, memcached, Redis services need to be run in separate containers.
|
||||
# Through this split of services, it is easier to scale the services to the needs.
|
||||
class zulip::profile::docker {
|
||||
include zulip::profile::base
|
||||
include zulip::profile::app_frontend
|
||||
include zulip::localhost_camo
|
||||
include zulip::local_mailserver
|
||||
include zulip::supervisor
|
||||
include zulip::process_fts_updates
|
||||
|
||||
file { "${zulip::common::supervisor_conf_dir}/cron.conf":
|
||||
ensure => file,
|
||||
require => Package[supervisor],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/supervisor/conf.d/cron.conf',
|
||||
}
|
||||
file { "${zulip::common::supervisor_conf_dir}/nginx.conf":
|
||||
ensure => file,
|
||||
require => Package[supervisor],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/supervisor/conf.d/nginx.conf',
|
||||
}
|
||||
}
|
||||
97
puppet/zulip/manifests/profile/memcached.pp
Normal file
97
puppet/zulip/manifests/profile/memcached.pp
Normal file
@@ -0,0 +1,97 @@
|
||||
class zulip::profile::memcached {
|
||||
include zulip::profile::base
|
||||
include zulip::sasl_modules
|
||||
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$memcached_packages = [ 'memcached', 'sasl2-bin' ]
|
||||
$memcached_user = 'memcache'
|
||||
}
|
||||
'RedHat': {
|
||||
$memcached_packages = [ 'memcached', 'cyrus-sasl' ]
|
||||
$memcached_user = 'memcached'
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
package { $memcached_packages: ensure => installed }
|
||||
|
||||
$memcached_max_item_size = zulipconf('memcached', 'max_item_size', '1m')
|
||||
$memcached_size_reporting = zulipconf('memcached', 'size_reporting', false)
|
||||
$memcached_memory = zulipconf('memcached', 'memory', $zulip::common::total_memory_mb / 8)
|
||||
file { '/etc/sasl2':
|
||||
ensure => directory,
|
||||
}
|
||||
file { '/etc/sasl2/memcached-zulip-password':
|
||||
# We cache the password in this file so we can check whether it
|
||||
# changed and avoid running saslpasswd2 if it didn't.
|
||||
require => File['/etc/sasl2'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0600',
|
||||
content => zulipsecret('secrets', 'memcached_password', ''),
|
||||
notify => Exec[generate_memcached_sasldb2],
|
||||
}
|
||||
file { '/var/lib/zulip/memcached-sasldb2.stamp':
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => '1',
|
||||
notify => Exec[generate_memcached_sasldb2],
|
||||
}
|
||||
exec { 'generate_memcached_sasldb2':
|
||||
require => [
|
||||
Package[$memcached_packages],
|
||||
Package[$zulip::sasl_modules::sasl_module_packages],
|
||||
],
|
||||
refreshonly => true,
|
||||
# Use localhost for the currently recommended MEMCACHED_USERNAME =
|
||||
# "zulip@localhost" and the hostname for compatibility with
|
||||
# MEMCACHED_USERNAME = "zulip".
|
||||
command => "bash -euc '
|
||||
rm -f /etc/sasl2/memcached-sasldb2
|
||||
saslpasswd2 -p -f /etc/sasl2/memcached-sasldb2 \
|
||||
-a memcached -u localhost zulip < /etc/sasl2/memcached-zulip-password
|
||||
saslpasswd2 -p -f /etc/sasl2/memcached-sasldb2 \
|
||||
-a memcached -u \"\$HOSTNAME\" zulip < /etc/sasl2/memcached-zulip-password
|
||||
'",
|
||||
}
|
||||
file { '/etc/sasl2/memcached-sasldb2':
|
||||
require => Exec[generate_memcached_sasldb2],
|
||||
owner => $memcached_user,
|
||||
group => $memcached_user,
|
||||
mode => '0600',
|
||||
}
|
||||
file { '/etc/sasl2/memcached.conf':
|
||||
require => File['/etc/sasl2'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/sasl2/memcached.conf',
|
||||
notify => Service[memcached],
|
||||
}
|
||||
file { '/etc/memcached.conf':
|
||||
ensure => file,
|
||||
require => [
|
||||
Package[$memcached_packages],
|
||||
Package[$zulip::sasl_modules::sasl_module_packages]
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/memcached.conf.template.erb'),
|
||||
}
|
||||
file { '/run/memcached':
|
||||
ensure => directory,
|
||||
owner => 'memcache',
|
||||
group => 'memcache',
|
||||
mode => '0755',
|
||||
require => Package[$memcached_packages],
|
||||
}
|
||||
service { 'memcached':
|
||||
ensure => running,
|
||||
subscribe => File['/etc/memcached.conf'],
|
||||
require => File['/run/memcached'],
|
||||
}
|
||||
}
|
||||
116
puppet/zulip/manifests/profile/postgresql.pp
Normal file
116
puppet/zulip/manifests/profile/postgresql.pp
Normal file
@@ -0,0 +1,116 @@
|
||||
# @summary Extends postgresql_base by tuning the configuration.
|
||||
class zulip::profile::postgresql(Boolean $start = true) {
|
||||
include zulip::profile::base
|
||||
include zulip::postgresql_base
|
||||
include zulip::systemd_daemon_reload
|
||||
|
||||
$version = $zulip::postgresql_common::version
|
||||
|
||||
if defined(Class['zulip::app_frontend_base']) {
|
||||
$total_postgres_memory_mb = zulipconf('postgresql', 'memory', $zulip::common::total_memory_mb / 2)
|
||||
} else {
|
||||
$total_postgres_memory_mb = zulipconf('postgresql', 'memory', $zulip::common::total_memory_mb)
|
||||
}
|
||||
$work_mem = zulipconf('postgresql', 'work_mem', sprintf('%dMB', $total_postgres_memory_mb / 256))
|
||||
$shared_buffers = zulipconf('postgresql', 'shared_buffers', sprintf('%dMB', $total_postgres_memory_mb / 4))
|
||||
$effective_cache_size = zulipconf('postgresql', 'effective_cache_size', sprintf('%dMB', $total_postgres_memory_mb * 3 / 4))
|
||||
$maintenance_work_mem = zulipconf('postgresql', 'maintenance_work_mem', sprintf('%dMB', min(2048, $total_postgres_memory_mb / 8)))
|
||||
|
||||
$max_worker_processes = zulipconf('postgresql', 'max_worker_processes', undef)
|
||||
$max_parallel_workers_per_gather = zulipconf('postgresql', 'max_parallel_workers_per_gather', undef)
|
||||
$max_parallel_workers = zulipconf('postgresql', 'max_parallel_workers', undef)
|
||||
$max_parallel_maintenance_workers = zulipconf('postgresql', 'max_parallel_maintenance_workers', undef)
|
||||
|
||||
$wal_buffers = zulipconf('postgresql', 'wal_buffers', undef)
|
||||
$min_wal_size = zulipconf('postgresql', 'min_wal_size', undef)
|
||||
$max_wal_size = zulipconf('postgresql', 'max_wal_size', undef)
|
||||
$random_page_cost = zulipconf('postgresql', 'random_page_cost', '1.1')
|
||||
$effective_io_concurrency = zulipconf('postgresql', 'effective_io_concurrency', undef)
|
||||
|
||||
$listen_addresses = zulipconf('postgresql', 'listen_addresses', undef)
|
||||
|
||||
$s3_backups_bucket = zulipsecret('secrets', 's3_backups_bucket', '')
|
||||
$replication_primary = zulipconf('postgresql', 'replication_primary', undef)
|
||||
$replication_user = zulipconf('postgresql', 'replication_user', undef)
|
||||
$replication_password = zulipsecret('secrets', 'postgresql_replication_password', '')
|
||||
|
||||
$ssl_cert_file = zulipconf('postgresql', 'ssl_cert_file', undef)
|
||||
$ssl_key_file = zulipconf('postgresql', 'ssl_key_file', undef)
|
||||
$ssl_ca_file = zulipconf('postgresql', 'ssl_ca_file', undef)
|
||||
$ssl_mode = zulipconf('postgresql', 'ssl_mode', undef)
|
||||
|
||||
file { $zulip::postgresql_base::postgresql_confdirs:
|
||||
ensure => directory,
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
}
|
||||
|
||||
if $version in ['14'] {
|
||||
$postgresql_conf_file = "${zulip::postgresql_base::postgresql_confdir}/postgresql.conf"
|
||||
file { $postgresql_conf_file:
|
||||
ensure => file,
|
||||
require => Package[$zulip::postgresql_base::postgresql],
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
mode => '0644',
|
||||
content => template("zulip/postgresql/${version}/postgresql.conf.template.erb"),
|
||||
}
|
||||
} elsif $version in ['15', '16', '17', '18'] {
|
||||
$postgresql_conf_file = "${zulip::postgresql_base::postgresql_confdir}/conf.d/zulip.conf"
|
||||
file { $postgresql_conf_file:
|
||||
ensure => file,
|
||||
require => Package[$zulip::postgresql_base::postgresql],
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
mode => '0644',
|
||||
content => template('zulip/postgresql/zulip.conf.template.erb'),
|
||||
}
|
||||
} else {
|
||||
fail("PostgreSQL ${version} not supported")
|
||||
}
|
||||
|
||||
# PostgreSQL 18's io_method = io_uring requires a larger
|
||||
# RLIMIT_MEMLOCK than systemd's default on Linux 6.14 and newer
|
||||
if $facts['os']['family'] == 'Debian' {
|
||||
file { '/etc/systemd/system/postgresql@.service.d':
|
||||
ensure => directory,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
}
|
||||
file { '/etc/systemd/system/postgresql@.service.d/zulip.conf':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/postgresql/postgresql@.service.d/zulip.conf',
|
||||
notify => [Exec['reload systemd'], Service['postgresql']],
|
||||
}
|
||||
}
|
||||
|
||||
if $replication_primary != undef and $replication_user != undef {
|
||||
# The presence of a standby.signal file triggers replication
|
||||
file { "${zulip::postgresql_base::postgresql_datadir}/standby.signal":
|
||||
ensure => file,
|
||||
require => Package[$zulip::postgresql_base::postgresql],
|
||||
before => Service['postgresql'],
|
||||
owner => 'postgres',
|
||||
group => 'postgres',
|
||||
mode => '0644',
|
||||
content => '',
|
||||
}
|
||||
}
|
||||
|
||||
$backups_s3_bucket = zulipsecret('secrets', 's3_backups_bucket', '')
|
||||
$backups_directory = zulipconf('postgresql', 'backups_directory', '')
|
||||
if $backups_s3_bucket != '' or $backups_directory != '' {
|
||||
$require = [File['/usr/local/bin/env-wal-g'], Package[$zulip::postgresql_base::postgresql]]
|
||||
} else {
|
||||
$require = [Package[$zulip::postgresql_base::postgresql]]
|
||||
}
|
||||
service { 'postgresql':
|
||||
ensure => $start,
|
||||
require => $require + [Exec['reload systemd']],
|
||||
subscribe => [ File[$postgresql_conf_file] ],
|
||||
}
|
||||
}
|
||||
95
puppet/zulip/manifests/profile/rabbitmq.pp
Normal file
95
puppet/zulip/manifests/profile/rabbitmq.pp
Normal file
@@ -0,0 +1,95 @@
|
||||
class zulip::profile::rabbitmq {
|
||||
include zulip::profile::base
|
||||
$erlang = $facts['os']['family'] ? {
|
||||
'Debian' => 'erlang-base',
|
||||
'RedHat' => 'erlang',
|
||||
}
|
||||
$rabbitmq_packages = [
|
||||
$erlang,
|
||||
'rabbitmq-server',
|
||||
]
|
||||
|
||||
group { 'rabbitmq':
|
||||
ensure => present,
|
||||
system => true,
|
||||
}
|
||||
user { 'rabbitmq':
|
||||
ensure => present,
|
||||
comment => 'RabbitMQ messaging server',
|
||||
gid => 'rabbitmq',
|
||||
home => '/var/lib/rabbitmq',
|
||||
shell => '/usr/sbin/nologin',
|
||||
system => true,
|
||||
require => Group['rabbitmq'],
|
||||
}
|
||||
file { '/etc/rabbitmq':
|
||||
ensure => directory,
|
||||
owner => 'rabbitmq',
|
||||
group => 'rabbitmq',
|
||||
mode => '0755',
|
||||
require => User['rabbitmq'],
|
||||
before => Package['rabbitmq-server'],
|
||||
}
|
||||
file { '/etc/rabbitmq/rabbitmq.config':
|
||||
ensure => file,
|
||||
owner => 'rabbitmq',
|
||||
group => 'rabbitmq',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/rabbitmq/rabbitmq.config',
|
||||
# This config file must be installed before the package, so that
|
||||
# port 25672 is not even briefly open to the Internet world, which
|
||||
# would be a security risk, due to insecure defaults in the
|
||||
# RabbitMQ package.
|
||||
before => Package['rabbitmq-server'],
|
||||
notify => Service['rabbitmq-server'],
|
||||
}
|
||||
exec { 'warn-rabbitmq-nodename-change':
|
||||
command => "${facts['zulip_scripts_path']}/lib/warn-rabbitmq-nodename-change",
|
||||
onlyif => '[ -f /etc/rabbitmq/rabbitmq-env.conf ] && ! grep -xq NODENAME=zulip@localhost /etc/rabbitmq/rabbitmq-env.conf',
|
||||
before => [
|
||||
File['/etc/rabbitmq/rabbitmq-env.conf'],
|
||||
Service['rabbitmq-server'],
|
||||
],
|
||||
logoutput => true,
|
||||
loglevel => warning,
|
||||
}
|
||||
file { '/etc/rabbitmq/rabbitmq-env.conf':
|
||||
ensure => file,
|
||||
owner => 'rabbitmq',
|
||||
group => 'rabbitmq',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/rabbitmq/rabbitmq-env.conf',
|
||||
before => Package['rabbitmq-server'],
|
||||
notify => [
|
||||
Service['rabbitmq-server'],
|
||||
Exec['configure-rabbitmq'],
|
||||
],
|
||||
}
|
||||
package { $rabbitmq_packages:
|
||||
ensure => installed,
|
||||
}
|
||||
# epmd doesn't have an init script, so we just check if it is
|
||||
# running, and if it isn't, start it. Even in case of a race, this
|
||||
# won't leak epmd processes, because epmd checks if one is already
|
||||
# running and exits if so.
|
||||
exec { 'epmd':
|
||||
command => 'epmd -daemon',
|
||||
unless => 'which pgrep && pgrep -x epmd >/dev/null',
|
||||
require => Package[$erlang],
|
||||
path => '/usr/bin/:/bin/',
|
||||
}
|
||||
|
||||
service { 'rabbitmq-server':
|
||||
ensure => running,
|
||||
require => [
|
||||
Exec['epmd'],
|
||||
Package['rabbitmq-server'],
|
||||
],
|
||||
}
|
||||
|
||||
exec { 'configure-rabbitmq':
|
||||
command => "${facts['zulip_scripts_path']}/setup/configure-rabbitmq",
|
||||
refreshonly => true,
|
||||
require => Service['rabbitmq-server'],
|
||||
}
|
||||
}
|
||||
71
puppet/zulip/manifests/profile/redis.pp
Normal file
71
puppet/zulip/manifests/profile/redis.pp
Normal file
@@ -0,0 +1,71 @@
|
||||
class zulip::profile::redis {
|
||||
include zulip::profile::base
|
||||
case $facts['os']['family'] {
|
||||
'Debian': {
|
||||
$redis = 'redis-server'
|
||||
$redis_dir = '/etc/redis'
|
||||
}
|
||||
'RedHat': {
|
||||
$redis = 'redis'
|
||||
$redis_dir = '/etc'
|
||||
}
|
||||
default: {
|
||||
fail('osfamily not supported')
|
||||
}
|
||||
}
|
||||
$redis_packages = [ # The server itself
|
||||
$redis,
|
||||
]
|
||||
|
||||
package { $redis_packages: ensure => installed }
|
||||
|
||||
$file = "${redis_dir}/redis.conf"
|
||||
$zulip_redisconf = "${redis_dir}/zulip-redis.conf"
|
||||
$line = "include ${zulip_redisconf}"
|
||||
exec { 'update-redis-conf':
|
||||
unless => "/bin/grep -Fxqe '${line}' '${file}'",
|
||||
path => '/bin',
|
||||
command => "bash -c \"(/bin/echo; /bin/echo '# Include Zulip-specific configuration'; /bin/echo '${line}') >> '${file}'\"",
|
||||
require => [
|
||||
Package[$redis],
|
||||
File[$zulip_redisconf],
|
||||
],
|
||||
}
|
||||
|
||||
$redis_password = zulipsecret('secrets', 'redis_password', '')
|
||||
file { $zulip_redisconf:
|
||||
ensure => file,
|
||||
require => Package[$redis],
|
||||
owner => 'redis',
|
||||
group => 'redis',
|
||||
mode => '0640',
|
||||
content => template('zulip/zulip-redis.template.erb'),
|
||||
}
|
||||
|
||||
# https://redis.io/docs/management/admin/#linux
|
||||
zulip::sysctl { 'redis-server':
|
||||
key => 'vm.overcommit_memory',
|
||||
value => '1',
|
||||
}
|
||||
package { 'sysfsutils': }
|
||||
file { '/etc/sysfs.d/40-disable-transpatent-hugepages.conf':
|
||||
require => Package['sysfsutils'],
|
||||
notify => Service['sysfsutils'],
|
||||
content => 'kernel/mm/transparent_hugepage/enabled = never',
|
||||
}
|
||||
service { 'sysfsutils':
|
||||
ensure => running,
|
||||
require => Package['sysfsutils'],
|
||||
}
|
||||
service { $redis:
|
||||
ensure => running,
|
||||
require => [
|
||||
Service['sysfsutils'],
|
||||
Package['redis-server'],
|
||||
],
|
||||
subscribe => [
|
||||
File[$zulip_redisconf],
|
||||
Exec['update-redis-conf'],
|
||||
],
|
||||
}
|
||||
}
|
||||
6
puppet/zulip/manifests/profile/smokescreen.pp
Normal file
6
puppet/zulip/manifests/profile/smokescreen.pp
Normal file
@@ -0,0 +1,6 @@
|
||||
# @summary Outgoing HTTP CONNECT proxy for HTTP/HTTPS on port 4750.
|
||||
#
|
||||
class zulip::profile::smokescreen {
|
||||
include zulip::profile::base
|
||||
include zulip::smokescreen
|
||||
}
|
||||
21
puppet/zulip/manifests/profile/standalone.pp
Normal file
21
puppet/zulip/manifests/profile/standalone.pp
Normal file
@@ -0,0 +1,21 @@
|
||||
# @summary Complete Zulip server on one server
|
||||
#
|
||||
# This class includes all the modules you need to run an entire Zulip
|
||||
# installation on a single server. If desired, you can split up the
|
||||
# different `zulip::profile::*` components of a Zulip installation
|
||||
# onto different servers:
|
||||
#
|
||||
# - zulip::profile::app_frontend
|
||||
# - zulip::profile::memcached
|
||||
# - zulip::profile::postgresql
|
||||
# - zulip::profile::rabbitmq
|
||||
# - zulip::profile::redis
|
||||
# - zulip::profile::smokescreen
|
||||
#
|
||||
# See the corresponding configuration in /etc/zulip/settings.py for
|
||||
# how to find the various services is also required to make this work.
|
||||
|
||||
class zulip::profile::standalone {
|
||||
include zulip::profile::standalone_nodb
|
||||
include zulip::profile::postgresql
|
||||
}
|
||||
16
puppet/zulip/manifests/profile/standalone_nodb.pp
Normal file
16
puppet/zulip/manifests/profile/standalone_nodb.pp
Normal file
@@ -0,0 +1,16 @@
|
||||
# @summary Complete Zulip server, except the database server.
|
||||
#
|
||||
# This includes all of the parts necessary to run an entire Zulip
|
||||
# installation on a single server, except the database. It is assumed
|
||||
# that the PostgreSQL database is either hosted on another server with
|
||||
# the `zulip::profile::postgresql` class applied, or a cloud-managed
|
||||
# database is used (e.g. AWS RDS).
|
||||
#
|
||||
# @see https://zulip.readthedocs.io/en/latest/production/postgresql.html
|
||||
class zulip::profile::standalone_nodb {
|
||||
include zulip::profile::app_frontend
|
||||
include zulip::profile::memcached
|
||||
include zulip::profile::rabbitmq
|
||||
include zulip::profile::redis
|
||||
include zulip::localhost_camo
|
||||
}
|
||||
5
puppet/zulip/manifests/safepackage.pp
Normal file
5
puppet/zulip/manifests/safepackage.pp
Normal file
@@ -0,0 +1,5 @@
|
||||
define zulip::safepackage ( $ensure = present ) {
|
||||
if !defined(Package[$title]) {
|
||||
package { $title: ensure => $ensure }
|
||||
}
|
||||
}
|
||||
7
puppet/zulip/manifests/sasl_modules.pp
Normal file
7
puppet/zulip/manifests/sasl_modules.pp
Normal file
@@ -0,0 +1,7 @@
|
||||
class zulip::sasl_modules {
|
||||
$sasl_module_packages = $facts['os']['family'] ? {
|
||||
'Debian' => [ 'libsasl2-modules' ],
|
||||
'RedHat' => [ 'cyrus-sasl-plain' ],
|
||||
}
|
||||
package { $sasl_module_packages: ensure => installed }
|
||||
}
|
||||
23
puppet/zulip/manifests/sentry_cli.pp
Normal file
23
puppet/zulip/manifests/sentry_cli.pp
Normal file
@@ -0,0 +1,23 @@
|
||||
# @summary Install sentry-cli binary
|
||||
#
|
||||
class zulip::sentry_cli {
|
||||
$version = $zulip::common::versions['sentry-cli']['version']
|
||||
$bin = "/srv/zulip-sentry-cli-${version}"
|
||||
|
||||
$arch = $facts['os']['architecture'] ? {
|
||||
'amd64' => 'x86_64',
|
||||
'aarch64' => 'aarch64',
|
||||
}
|
||||
|
||||
zulip::external_dep { 'sentry-cli':
|
||||
version => $version,
|
||||
url => "https://downloads.sentry-cdn.com/sentry-cli/${version}/sentry-cli-Linux-${arch}",
|
||||
}
|
||||
|
||||
file { '/usr/local/bin/sentry-cli':
|
||||
ensure => link,
|
||||
target => $bin,
|
||||
require => File[$bin],
|
||||
before => Exec['Cleanup sentry-cli'],
|
||||
}
|
||||
}
|
||||
13
puppet/zulip/manifests/sha256_file_to.pp
Normal file
13
puppet/zulip/manifests/sha256_file_to.pp
Normal file
@@ -0,0 +1,13 @@
|
||||
# @summary Downloads, verifies hash, and copies the one file out.
|
||||
#
|
||||
define zulip::sha256_file_to(
|
||||
String $sha256,
|
||||
String $url,
|
||||
String $install_to,
|
||||
) {
|
||||
exec { $url:
|
||||
command => "${facts['zulip_scripts_path']}/setup/sha256-file-to ${sha256} ${url} ${install_to}",
|
||||
creates => $install_to,
|
||||
timeout => 600,
|
||||
}
|
||||
}
|
||||
14
puppet/zulip/manifests/sha256_tarball_to.pp
Normal file
14
puppet/zulip/manifests/sha256_tarball_to.pp
Normal file
@@ -0,0 +1,14 @@
|
||||
# @summary Downloads, verifies hash, and copies files out.
|
||||
#
|
||||
define zulip::sha256_tarball_to(
|
||||
String $sha256,
|
||||
String $url,
|
||||
String $install_from,
|
||||
String $install_to,
|
||||
) {
|
||||
exec { $url:
|
||||
command => "${facts['zulip_scripts_path']}/setup/sha256-tarball-to ${sha256} ${url} ${install_from} ${install_to}",
|
||||
creates => $install_to,
|
||||
timeout => 600,
|
||||
}
|
||||
}
|
||||
65
puppet/zulip/manifests/smokescreen.pp
Normal file
65
puppet/zulip/manifests/smokescreen.pp
Normal file
@@ -0,0 +1,65 @@
|
||||
class zulip::smokescreen {
|
||||
include zulip::supervisor
|
||||
include zulip::golang
|
||||
|
||||
$version = $zulip::common::versions['smokescreen-src']['version']
|
||||
$dir = "/srv/zulip-smokescreen-src-${version}"
|
||||
$bin = "/usr/local/bin/smokescreen-${version}-go-${zulip::golang::version}"
|
||||
|
||||
zulip::external_dep { 'smokescreen-src':
|
||||
version => $version,
|
||||
url => "https://github.com/stripe/smokescreen/archive/${version}.tar.gz",
|
||||
tarball_prefix => "smokescreen-${version}",
|
||||
}
|
||||
|
||||
exec { 'compile smokescreen':
|
||||
command => "${zulip::golang::bin} build -o ${bin}",
|
||||
cwd => $dir,
|
||||
# GOCACHE is required; nothing is written to GOPATH, but it is required to be set
|
||||
environment => ['GOCACHE=/tmp/gocache', 'GOPATH=/root/go'],
|
||||
creates => $bin,
|
||||
require => [
|
||||
Zulip::External_Dep['golang'],
|
||||
Zulip::External_Dep['smokescreen-src'],
|
||||
],
|
||||
}
|
||||
# This resource is created by the 'compile smokescreen' step.
|
||||
file { $bin:
|
||||
ensure => file,
|
||||
require => Exec['compile smokescreen'],
|
||||
}
|
||||
exec { 'Cleanup smokescreen':
|
||||
refreshonly => true,
|
||||
provider => shell,
|
||||
onlyif => "ls /usr/local/bin/smokescreen-* | grep -xv '${bin}'",
|
||||
command => "ls /usr/local/bin/smokescreen-* | grep -xv '${bin}' | xargs rm -r",
|
||||
require => [File[$bin], Service[supervisor]],
|
||||
}
|
||||
|
||||
$listen_address = zulipconf('http_proxy', 'listen_address', '127.0.0.1')
|
||||
$allow_addresses = split(zulipconf('http_proxy', 'allow_addresses', ''), ',')
|
||||
$allow_ranges = split(zulipconf('http_proxy', 'allow_ranges', ''), ',')
|
||||
$deny_addresses = split(zulipconf('http_proxy', 'deny_addresses', ''), ',')
|
||||
$deny_ranges = split(zulipconf('http_proxy', 'deny_ranges', ''), ',')
|
||||
|
||||
file { "${zulip::common::supervisor_conf_dir}/smokescreen.conf":
|
||||
ensure => file,
|
||||
require => [
|
||||
Package[supervisor],
|
||||
Exec['compile smokescreen'],
|
||||
],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/smokescreen.conf.erb'),
|
||||
notify => Service[supervisor],
|
||||
}
|
||||
|
||||
file { '/etc/logrotate.d/smokescreen':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
source => 'puppet:///modules/zulip/logrotate/smokescreen',
|
||||
}
|
||||
}
|
||||
12
puppet/zulip/manifests/snakeoil.pp
Normal file
12
puppet/zulip/manifests/snakeoil.pp
Normal file
@@ -0,0 +1,12 @@
|
||||
class zulip::snakeoil {
|
||||
zulip::safepackage { 'ssl-cert': ensure => installed }
|
||||
|
||||
# We use the snakeoil certificate for PostgreSQL and SMTP; some VMs
|
||||
# install the `ssl-cert` package but (reasonably) don't build the
|
||||
# snakeoil certs into the image; build them as needed.
|
||||
exec { 'generate-default-snakeoil':
|
||||
require => Package['ssl-cert'],
|
||||
creates => '/etc/ssl/certs/ssl-cert-snakeoil.pem',
|
||||
command => '/usr/sbin/make-ssl-cert generate-default-snakeoil',
|
||||
}
|
||||
}
|
||||
101
puppet/zulip/manifests/supervisor.pp
Normal file
101
puppet/zulip/manifests/supervisor.pp
Normal file
@@ -0,0 +1,101 @@
|
||||
class zulip::supervisor {
|
||||
$supervisor_service = $zulip::common::supervisor_service
|
||||
|
||||
package { 'supervisor': ensure => installed }
|
||||
|
||||
$system_conf_dir = $zulip::common::supervisor_system_conf_dir
|
||||
file { $system_conf_dir:
|
||||
ensure => directory,
|
||||
require => Package['supervisor'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
}
|
||||
|
||||
$conf_dir = $zulip::common::supervisor_conf_dir
|
||||
file { $conf_dir:
|
||||
ensure => directory,
|
||||
require => Package['supervisor'],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
purge => true,
|
||||
recurse => true,
|
||||
notify => Service[$supervisor_service],
|
||||
}
|
||||
|
||||
# In the docker environment, we don't want/need supervisor to be
|
||||
# started/stopped /bin/true is used as a decoy command, to maintain
|
||||
# compatibility with other code using the supervisor service.
|
||||
$puppet_classes = zulipconf('machine', 'puppet_classes', undef)
|
||||
if 'docker' in $puppet_classes {
|
||||
service { $supervisor_service:
|
||||
ensure => running,
|
||||
require => [
|
||||
File['/var/log/zulip'],
|
||||
Package['supervisor'],
|
||||
],
|
||||
hasstatus => true,
|
||||
status => '/bin/true',
|
||||
hasrestart => true,
|
||||
restart => '/bin/true',
|
||||
}
|
||||
exec { 'supervisor-restart':
|
||||
refreshonly => true,
|
||||
command => '/bin/true',
|
||||
}
|
||||
} else {
|
||||
service { $supervisor_service:
|
||||
ensure => running,
|
||||
require => [
|
||||
File['/var/log/zulip'],
|
||||
Package['supervisor'],
|
||||
],
|
||||
hasstatus => true,
|
||||
status => $zulip::common::supervisor_status,
|
||||
# Restarting the whole supervisorctl on every update to its
|
||||
# configuration files has the unfortunate side-effect of
|
||||
# restarting all of the services it controls; this results in an
|
||||
# unduly large disruption. The better option is to tell
|
||||
# supervisord to reread its config via supervisorctl and then to
|
||||
# "update". You need to do both -- after a "reread", supervisor
|
||||
# won't actually take action based on the changed configuration
|
||||
# until you do an "update" (I assume this is so you can check if
|
||||
# your config file parses without doing anything, but it's
|
||||
# really confusing).
|
||||
#
|
||||
# If restarting supervisor itself is necessary, see
|
||||
# Exec['supervisor-restart']
|
||||
#
|
||||
# Also, to handle the case that supervisord wasn't running at
|
||||
# all, we check if it is not running and if so, start it.
|
||||
hasrestart => true,
|
||||
# lint:ignore:140chars
|
||||
restart => "bash -c 'if pgrep -x supervisord >/dev/null; then supervisorctl reread && supervisorctl update; else ${zulip::common::supervisor_start}; fi'",
|
||||
# lint:endignore
|
||||
}
|
||||
exec { 'supervisor-restart':
|
||||
refreshonly => true,
|
||||
provider => shell,
|
||||
command => $zulip::common::supervisor_reload,
|
||||
require => Service[$supervisor_service],
|
||||
}
|
||||
}
|
||||
|
||||
$file_descriptor_limit = zulipconf('application_server', 'service_file_descriptor_limit', 40000)
|
||||
file { $zulip::common::supervisor_conf_file:
|
||||
ensure => file,
|
||||
require => Package[supervisor],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/supervisor/supervisord.conf.erb'),
|
||||
notify => Exec['supervisor-restart'],
|
||||
}
|
||||
|
||||
file { '/usr/local/bin/secret-env-wrapper':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/secret-env-wrapper',
|
||||
}
|
||||
}
|
||||
31
puppet/zulip/manifests/sysctl.pp
Normal file
31
puppet/zulip/manifests/sysctl.pp
Normal file
@@ -0,0 +1,31 @@
|
||||
# @summary Adds a sysctl file, and immediately runs it.
|
||||
define zulip::sysctl (
|
||||
$key,
|
||||
$value,
|
||||
$order = 40,
|
||||
$comment = '',
|
||||
) {
|
||||
if $comment == '' {
|
||||
$content = "${key} = ${value}\n"
|
||||
} else {
|
||||
$content = "# ${comment}\n${key} = ${value}\n"
|
||||
}
|
||||
file { "/etc/sysctl.d/${order}-${name}.conf":
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => $content,
|
||||
}
|
||||
|
||||
# Try to touch the procfile before trying to adjust it -- if we're
|
||||
# in a containerized environment, failure to set this is not a fatal
|
||||
# exception.
|
||||
$procpath = regsubst($key, '\.', '/')
|
||||
exec { "sysctl_p_${name}":
|
||||
command => "/sbin/sysctl -p /etc/sysctl.d/${order}-${name}.conf",
|
||||
subscribe => File["/etc/sysctl.d/${order}-${name}.conf"],
|
||||
refreshonly => true,
|
||||
onlyif => "touch /proc/sys/${procpath}",
|
||||
}
|
||||
}
|
||||
9
puppet/zulip/manifests/systemd_daemon_reload.pp
Normal file
9
puppet/zulip/manifests/systemd_daemon_reload.pp
Normal file
@@ -0,0 +1,9 @@
|
||||
class zulip::systemd_daemon_reload {
|
||||
exec { 'reload systemd':
|
||||
# /run/systemd/system only exists if systemd is the running init
|
||||
# system (see sd_booted(3)), as opposed to merely installed, as may
|
||||
# be the case in containers.
|
||||
command => 'sh -c "! test -d /run/systemd/system || systemctl daemon-reload"',
|
||||
refreshonly => true,
|
||||
}
|
||||
}
|
||||
23
puppet/zulip/manifests/timesync.pp
Normal file
23
puppet/zulip/manifests/timesync.pp
Normal file
@@ -0,0 +1,23 @@
|
||||
# @summary Allows configuration of timesync tool.
|
||||
class zulip::timesync {
|
||||
$timesync = zulipconf('machine', 'timesync', 'chrony')
|
||||
|
||||
case $timesync {
|
||||
'chrony': {
|
||||
package { 'ntp': ensure => purged, before => Package['chrony'] }
|
||||
package { 'chrony': ensure => installed }
|
||||
service { 'chrony': require => Package['chrony'] }
|
||||
}
|
||||
'ntpd': {
|
||||
package { 'chrony': ensure => purged, before => Package['ntp'] }
|
||||
package { 'ntp': ensure => installed }
|
||||
service { 'ntp': require => Package['ntp'] }
|
||||
}
|
||||
'none': {
|
||||
package { ['ntp', 'chrony']: ensure => purged }
|
||||
}
|
||||
default: {
|
||||
fail('Unknown timesync tool: $timesync')
|
||||
}
|
||||
}
|
||||
}
|
||||
57
puppet/zulip/manifests/tornado_sharding.pp
Normal file
57
puppet/zulip/manifests/tornado_sharding.pp
Normal file
@@ -0,0 +1,57 @@
|
||||
class zulip::tornado_sharding {
|
||||
include zulip::nginx
|
||||
|
||||
# The file entries below serve only to initialize the sharding config files
|
||||
# with the correct default content for the "only one shard" setup. For this
|
||||
# reason they use "replace => false", because the files are managed by
|
||||
# the sharding script afterwards and Puppet shouldn't overwrite them.
|
||||
file { '/etc/zulip/nginx_sharding_map.conf':
|
||||
ensure => file,
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
mode => '0644',
|
||||
notify => Service['nginx'],
|
||||
content => @(EOT),
|
||||
map "" $tornado_server {
|
||||
default http://tornado;
|
||||
}
|
||||
| EOT
|
||||
replace => false,
|
||||
}
|
||||
file { '/etc/zulip/nginx_sharding.conf':
|
||||
ensure => absent,
|
||||
}
|
||||
file { '/etc/zulip/sharding.json':
|
||||
ensure => file,
|
||||
require => User['zulip'],
|
||||
owner => 'zulip',
|
||||
group => 'zulip',
|
||||
mode => '0644',
|
||||
content => "{}\n",
|
||||
replace => false,
|
||||
}
|
||||
|
||||
# This creates .tmp files which scripts/refresh-sharding-and-restart
|
||||
# moves into place
|
||||
exec { 'stage_updated_sharding':
|
||||
command => "${facts['zulip_scripts_path']}/lib/sharding.py",
|
||||
onlyif => "${facts['zulip_scripts_path']}/lib/sharding.py --errors-ok",
|
||||
require => [File['/etc/zulip/nginx_sharding_map.conf'], File['/etc/zulip/sharding.json']],
|
||||
logoutput => true,
|
||||
loglevel => warning,
|
||||
}
|
||||
|
||||
# The ports of Tornado processes to run on the server, computed from
|
||||
# the zulip.conf configuration. Default is just port 9800.
|
||||
$tornado_groups = zulipconf_keys('tornado_sharding').map |$key| { $key.regsubst(/_regex$/, '').split('_') }.unique
|
||||
$tornado_ports = $tornado_groups.flatten.unique
|
||||
|
||||
file { '/etc/nginx/zulip-include/tornado-upstreams':
|
||||
require => [Package[$zulip::common::nginx], Exec['stage_updated_sharding']],
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0644',
|
||||
content => template('zulip/nginx/tornado-upstreams.conf.template.erb'),
|
||||
notify => Service['nginx'],
|
||||
}
|
||||
}
|
||||
21
puppet/zulip/manifests/tusd.pp
Normal file
21
puppet/zulip/manifests/tusd.pp
Normal file
@@ -0,0 +1,21 @@
|
||||
# @summary Provide the tusd service binary
|
||||
#
|
||||
class zulip::tusd {
|
||||
$version = $zulip::common::versions['tusd']['version']
|
||||
$bin = "/srv/zulip-tusd-${version}/tusd"
|
||||
|
||||
# This tarball contains only a single file, which is extracted as $bin
|
||||
zulip::external_dep { 'tusd':
|
||||
version => $version,
|
||||
url => "https://github.com/tus/tusd/releases/download/v${version}/tusd_linux_${zulip::common::goarch}.tar.gz",
|
||||
tarball_prefix => "tusd_linux_${zulip::common::goarch}",
|
||||
bin => [$bin],
|
||||
cleanup_after => [Service[supervisor]],
|
||||
}
|
||||
file { '/usr/local/bin/tusd':
|
||||
ensure => link,
|
||||
target => $bin,
|
||||
require => File[$bin],
|
||||
before => Exec['Cleanup tusd'],
|
||||
}
|
||||
}
|
||||
40
puppet/zulip/manifests/wal_g.pp
Normal file
40
puppet/zulip/manifests/wal_g.pp
Normal file
@@ -0,0 +1,40 @@
|
||||
# @summary Provide the wal-g and env-wal-g binaries.
|
||||
#
|
||||
class zulip::wal_g {
|
||||
$wal_g_version = $zulip::common::versions['wal-g']['version']
|
||||
$bin = "/srv/zulip-wal-g-${wal_g_version}"
|
||||
|
||||
$package = "wal-g-pg-22.04-${zulip::common::goarch}"
|
||||
|
||||
# This tarball contains only a single file, which is extracted as $bin
|
||||
zulip::external_dep { 'wal-g':
|
||||
version => $wal_g_version,
|
||||
url => "https://github.com/wal-g/wal-g/releases/download/v${wal_g_version}/${package}.tar.gz",
|
||||
tarball_prefix => $package,
|
||||
}
|
||||
file { '/usr/local/bin/wal-g':
|
||||
ensure => link,
|
||||
target => $bin,
|
||||
require => File[$bin],
|
||||
before => Exec['Cleanup wal-g'],
|
||||
}
|
||||
# We used to install versions into /usr/local/bin/wal-g-VERSION,
|
||||
# until we moved to using Zulip::External_Dep which places them in
|
||||
# /srv/zulip-wal-g-VERSION. Tidy old versions.
|
||||
tidy { '/usr/local/bin/wal-g-*':
|
||||
recurse => 1,
|
||||
path => '/usr/local/bin/',
|
||||
matches => 'wal-g-*',
|
||||
}
|
||||
|
||||
file { '/usr/local/bin/env-wal-g':
|
||||
ensure => file,
|
||||
owner => 'root',
|
||||
group => 'root',
|
||||
mode => '0755',
|
||||
source => 'puppet:///modules/zulip/postgresql/env-wal-g',
|
||||
require => [
|
||||
File['/usr/local/bin/wal-g'],
|
||||
],
|
||||
}
|
||||
}
|
||||
6
puppet/zulip/manifests/yum_repository.pp
Normal file
6
puppet/zulip/manifests/yum_repository.pp
Normal file
@@ -0,0 +1,6 @@
|
||||
class zulip::yum_repository {
|
||||
$setup_yum_repo_file = "${facts['zulip_scripts_path']}/lib/setup-yum-repo"
|
||||
exec{'setup_yum_repo':
|
||||
command => "bash -c '${setup_yum_repo_file} --prod'",
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user