1 # Copyright (C) The Arvados Authors. All rights reserved.
3 # SPDX-License-Identifier: AGPL-3.0
5 # When updating this, please make the same changes in
6 # apps/workbench/config/initializers/reload_config.rb as well.
8 def start_reload_thread
10 lockfile = Rails.root.join('tmp', 'reload_config.lock')
11 File.open(lockfile, File::WRONLY|File::CREAT, 0600) do |f|
12 # Note we don't use LOCK_NB here. If we did, each time passenger
13 # kills the lock-holder process, we would be left with nobody
14 # checking for updates until passenger starts a new worker,
15 # which could be a long time.
16 Rails.logger.debug("reload_config: waiting for lock on #{lockfile}")
17 f.flock(File::LOCK_EX)
19 t_lastload = Rails.configuration.SourceTimestamp
20 hash_lastload = Rails.configuration.SourceSHA256
21 conffile = ENV['ARVADOS_CONFIG'] || "/etc/arvados/config.yml"
22 Rails.logger.info("reload_config: polling for updated mtime on #{conffile} with threshold #{t_lastload}")
25 t = File.mtime(conffile)
26 # If the file is newer than 5s, re-read it even if the
27 # timestamp matches the previously loaded file. This enables
28 # us to detect changes even if the filesystem's timestamp
29 # precision cannot represent multiple updates per second.
30 if t.to_f != t_lastload.to_f || Time.now.to_f - t.to_f < 5
31 Open3.popen2("arvados-server", "config-dump", "-skip-legacy") do |stdin, stdout, status_thread|
32 confs = YAML.load(stdout, deserialize_symbols: false)
33 hash = confs["SourceSHA256"]
35 Rails.logger.info("reload_config: config file updated but could not be loaded: #{e}")
39 if hash == hash_lastload
40 # If we reloaded a new or updated file, but the content is
41 # identical, keep polling instead of restarting.
46 restartfile = Rails.root.join('tmp', 'restart.txt')
48 Rails.logger.info("reload_config: mtime on #{conffile} changed to #{t}, touching #{restartfile} to #{touchtime}")
50 File.utime(touchtime, touchtime, restartfile)
52 # remove + re-create works even if the existing file is
53 # owned by root, provided the tempdir is writable.
54 File.unlink(restartfile) rescue nil
55 File.open(restartfile, 'w') {}
57 # Even if passenger doesn't notice that we hit restart.txt
58 # and kill our process, there's no point waiting around to
67 if !File.owned?(Rails.root.join('tmp'))
68 Rails.logger.debug("reload_config: not owner of #{Rails.root}/tmp, skipping")
69 elsif ENV["ARVADOS_CONFIG"] == "none"
70 Rails.logger.debug("reload_config: no config in use, skipping")
71 elsif defined?(PhusionPassenger)
72 PhusionPassenger.on_event(:starting_worker_process) do |forked|