puppet: Generate sharding in puppet, then refresh-sharding-and-restart.

This supports running puppet to pick up new sharding changes, which
will warn of the need to finalize them via
`refresh-sharding-and-restart`, or simply running that directly.
This commit is contained in:
Alex Vandiver 2020-09-08 16:35:13 -07:00 committed by Tim Abbott
parent 0de356c2df
commit 8adf530400
3 changed files with 54 additions and 3 deletions

View File

@ -7,13 +7,17 @@ class zulip::tornado_sharding {
# with the correct default content for the "only one shard" setup. For this # with the correct default content for the "only one shard" setup. For this
# reason they use "replace => false", because the files are managed by # reason they use "replace => false", because the files are managed by
# the sharding script afterwards and puppet shouldn't overwrite them. # the sharding script afterwards and puppet shouldn't overwrite them.
# The sha256 of the empty hash, used to fingerprint the configs as
# having been generated with a null sharding configuration.
$empty_sha256 = sha256('')
file { '/etc/zulip/nginx_sharding.conf': file { '/etc/zulip/nginx_sharding.conf':
ensure => file, ensure => file,
owner => 'root', owner => 'root',
group => 'root', group => 'root',
mode => '0644', mode => '0644',
notify => Service['nginx'], notify => Service['nginx'],
content => "set \$tornado_server http://tornado;\n", content => "# Configuration hash: ${empty_sha256}\nset \$tornado_server http://tornado;\n",
replace => false, replace => false,
} }
file { '/etc/zulip/sharding.json': file { '/etc/zulip/sharding.json':
@ -26,6 +30,14 @@ class zulip::tornado_sharding {
replace => false, replace => false,
} }
exec { 'write_updated_sharding':
command => "${::zulip_scripts_path}/lib/sharding.py",
unless => "${::zulip_scripts_path}/lib/sharding.py --verify",
require => [File['/etc/zulip/nginx_sharding.conf']],
logoutput => true,
loglevel => 'warning',
}
# The number of Tornado processes to run on the server; this # The number of Tornado processes to run on the server; this
# defaults to 1, since Tornado sharding is currently only at the # defaults to 1, since Tornado sharding is currently only at the
# Realm level. # Realm level.

View File

@ -1,4 +1,6 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import argparse
import hashlib
import json import json
import os import os
import subprocess import subprocess
@ -19,6 +21,15 @@ def write_realm_nginx_config_line(f: Any, host: str, port: str) -> None:
set $tornado_server http://tornado{port}; set $tornado_server http://tornado{port};
}}\n""") }}\n""")
def hash_sharding_config() -> str:
config_file = get_config_file()
if not config_file.has_section("tornado_sharding"):
return hashlib.sha256(b'').hexdigest()
contents = subprocess.check_output([
"crudini", "--get", "--format=lines", "/etc/zulip/zulip.conf", "tornado_sharding",
])
return hashlib.sha256(contents).hexdigest()
# Basic system to do Tornado sharding. Writes two output .tmp files that need # Basic system to do Tornado sharding. Writes two output .tmp files that need
# to be renamed to the following files to finalize the changes: # to be renamed to the following files to finalize the changes:
# * /etc/zulip/nginx_sharding.conf; nginx needs to be reloaded after changing. # * /etc/zulip/nginx_sharding.conf; nginx needs to be reloaded after changing.
@ -26,8 +37,28 @@ def write_realm_nginx_config_line(f: Any, host: str, port: str) -> None:
# after changing. TODO: We can probably make this live-reload by statting the file. # after changing. TODO: We can probably make this live-reload by statting the file.
# #
# TODO: Restructure this to automatically generate a sharding layout. # TODO: Restructure this to automatically generate a sharding layout.
parser = argparse.ArgumentParser(description="Adjust Tornado sharding configuration")
parser.add_argument("--verify", action='store_true',
help="Exits 0 with no action if no changes are required; exits 1 if changes would be made.")
options = parser.parse_args()
new_hash = hash_sharding_config()
if os.path.exists('/etc/zulip/nginx_sharding.conf') and os.path.exists('/etc/zulip/sharding.json'):
with open('/etc/zulip/nginx_sharding.conf') as old_file:
if new_hash in old_file.read():
sys.exit(0)
if options.verify:
sys.exit(1)
if "SUPPRESS_SHARDING_NOTICE" not in os.environ:
print("** Updated sharding; scripts/refresh-sharding-and-restart required")
with open('/etc/zulip/nginx_sharding.conf.tmp', 'w') as nginx_sharding_conf_f, \ with open('/etc/zulip/nginx_sharding.conf.tmp', 'w') as nginx_sharding_conf_f, \
open('/etc/zulip/sharding.json.tmp', 'w') as sharding_json_f: open('/etc/zulip/sharding.json.tmp', 'w') as sharding_json_f:
# Puppet uses this to know if it needs to rewrite the files
nginx_sharding_conf_f.write(f"# Configuration hash: {new_hash}\n")
config_file = get_config_file() config_file = get_config_file()
if not config_file.has_section("tornado_sharding"): if not config_file.has_section("tornado_sharding"):

View File

@ -2,8 +2,16 @@
set -e set -e
"$(dirname "$0")/zulip-puppet-apply" -f # Stand up the new zulip-tornado supervisor instances, and write out
# The step above should have generated the config files, now we need to move them into place: # the newly generated config files, with .tmp suffix
SUPPRESS_SHARDING_NOTICE=1 "$(dirname "$0")/zulip-puppet-apply" -f
# Verify, before we move them into place
if ! [ -e /etc/zulip/nginx_sharding.conf.tmp ] || ! [ -e /etc/zulip/sharding.json.tmp ]; then
echo "No sharding updates found to apply."
exit 1
fi
chown root:root /etc/zulip/nginx_sharding.conf.tmp chown root:root /etc/zulip/nginx_sharding.conf.tmp
chmod 644 /etc/zulip/nginx_sharding.conf.tmp chmod 644 /etc/zulip/nginx_sharding.conf.tmp
chown zulip:zulip /etc/zulip/sharding.json.tmp chown zulip:zulip /etc/zulip/sharding.json.tmp