Reload config(via USR1) has no effect after upgrading(via USR2)


(chuang.he) #1

I am trying the upgrading feature, then I found that pkill -usr1 caddy has no effect after caddy is upgraded.

caddy version:

 ./caddy -version|head

Caddy 0.11.0 (+1f7b5ab Thu Jul 26 10:48:36 UTC 2018) (unofficial)

first , start caddy with an empty Caddyfile and with -log parameter

./caddy -log nohup.out 

Activating privacy features… done.
http://:2015

in the second console, run:

pkill -usr1 caddy

in the third console, it shows:

tail -f nohup.out


2018/07/26 18:54:31 [INFO] SIGUSR1: Reloading
2018/07/26 18:54:31 [INFO] Reloading
2018/07/26 18:54:31 [INFO] Reloading complete

that’s all right, every thing goes as expected.

then run:

pkill -usr2 caddy

the log thows:


2018/07/26 18:55:08 [INFO] SIGUSR2: Upgrading
2018/07/26 18:55:08 [INFO] Upgrading
2018/07/26 18:55:08 http://:2015
2018/07/26 18:55:08 [INFO] Upgrade finished
this goes normal, the upgrade is OK

but… NOW, you pkill -usr1 caddy again, you will found log int the third console :


2018/07/26 18:55:33 [INFO] SIGUSR1: Reloading
2018/07/26 18:55:33 [ERROR] SIGUSR1: no Caddyfile loader with which to reload Caddyfile

I dig a little into the source code, it seems that before upgrade, the caddy use Caddyfile to trigger reload action, however, in the upgrading process, the caddy config will be piped(via pipe()) to the child(in the memory), then the Caddyfile is useless after that.(the loaderUsed.loader is not take effect for every)


(Matt Holt) #2

This could be a bug – would you mind filing an issue on GitHub? :slight_smile:

I don’t know a good solution yet but somehow we need to keep the Caddyfile around for when a USR1 happens after a USR2 (which, as you noticed, pipes in the configuration, which pipe is ephemeral, unlike a file on disk).


(chuang.he) #3

Maybe we can transfer the full path of Caddyfile to the child process instead of it’s content?
Then the child process can do a reload action as it received the path of config file.
This policy will insure always to use the Caddyfile as current configure.
If this is OK, maybe I can have a try. the race condition have to be concerned in the child reload progress, is this what you worry about?


(Matthew Fay) #4

A problem then occurs when the current Caddy has a Caddyfile in memory that is no longer accessible on disk (storage failure, file deletion, etc.). We could see current Caddy process pass off the file path, peace out, and leave the updated Caddy with nothing but pockets full of mom’s spaghetti while the sysadmin has to then troubleshoot the storage problem during their website outage.

The most robust approach would be to pass both the in-memory Caddyfile and the file path so that the updated Caddy can fall back in case of such a problem.


(chuang.he) #6

Yes, I agree.
the path as well as it’s content. path for next reload, content for current configure.


(chuang.he) #7

issue on github:

By the way, is there any chance for our plugins to transfer something to the child when upgrading?

eg. there are some features running in memory, which cannot be upgraded, I want to transfer there contexts to the child, so that it can revive in the child.


(Matthew Fay) #8

I don’t think Caddy provides any structure for an in-memory transfer of plugin state to the upgraded process.

Easiest way for your plugin to do this would be to save state to disk and reload it as part of its setup function.