Fossil Forum

"after-receive" hook not running automatically
Login

"after-receive" hook not running automatically

"after-receive" hook not running automatically

(1) By Jesper Høy (jesperhoy) on 2022-08-01 18:33:54 [link] [source]

Hi Fossil community.

Having trouble getting the "after-receive" hook to run automatically after pushing new commits to server.

The hook works fine if I run "fossil backoffice" manually on the server after the commit.

The problem seems to be that "backoffice" never runs automatically. From the docs I think this is supposed to run after each web request - possibly limited to once per minute.

Some parts of the docs seem to suggest that "backoffice" is only used for sending emails. Does email sending have to be setup for "backoffice" to run automatically - and thus for hooks to run?

I tried enabling "backoffice-logfile" to confirm this - and it only writes the log when I manually do "fossil backoffice".

The server OS is Windows Server 2022 Standard.

Thanks,

Jesper

(2) By Jesper Høy (jesperhoy) on 2022-08-01 18:53:28 in reply to 1 [link] [source]

Same problem in current version (2.19). I was using 2.15 when first reported.

Thanks,

Jesper

(3) By Richard Hipp (drh) on 2022-08-01 18:59:58 in reply to 2 [link] [source]

Yeah - I was never able to get backoffice to run automatically on Windows or OpenBSD. If you have any ideas on how to fix that, please submit patches.

I recommend that you use the "fossil backoffice --poll 60".

(4) By Jesper Høy (jesperhoy) on 2022-08-01 19:07:04 in reply to 3 [link] [source]

I wish I could help - this is a fantastic project. But unfortunately no C++ skills here.

What does "fossil backoffice --poll 60" actually do?

Does it keep running in the background?

Do I need to run it every time the server starts - or periodically?

Thanks

(5) By Jesper Høy (jesperhoy) on 2022-08-01 19:09:50 in reply to 4 [link] [source]

I mean is there any difference between running "fossil backoffice --poll 60" - or just setting up task scheduler to run "fossil backoffice" every 60 seconds?

(6) By Richard Hipp (drh) on 2022-08-01 19:38:44 in reply to 5 [link] [source]

The "fossil backoffice --poll 60" command runs in the foreground, sitting idle mostly. But every 60 seconds, it checks to see if the repository database has been modified, and if it has, an instance of backoffice is run as a subprocess.

You have to keep the command running yourself. That's trivial on unix, but I don't know how to do that on Windows. But there are others on this forum that probably know how.

(7) By Jesper Høy (jesperhoy) on 2022-08-01 20:01:35 in reply to 6 [link] [source]

Thanks again for your fast response :-)

I ran some tests, and this doesn't seem to work either. Even with --debug - it just says "SLEEP: 60000 - SLEEP: 60000...", but doesn't appear to notice pushes to the repository, or to ever kick off backoffice.

I guess I'll just run "fossil backoffice" on a schedule instead.

Instead of using this "backoffice" thing - wouldn't it be simpler to just kick of a subprocess to run the "after-receive" hook(s) directly after each receive?

Perhaps as an option?

This would be really nice to for CI/CD.

Sincerely,

Jesper

(8) By Richard Hipp (drh) on 2022-08-01 22:00:45 in reply to 7 [link] [source]

Instead of using this "backoffice" thing - wouldn't it be simpler to just kick of a subprocess to run the "after-receive" hook(s) directly after each receive?

That's what it normally does, yes. But those subprocesses don't like to run on Windows or OpenBSD, for some reason. Probably because the parent process needs to immediately terminate in order to finish sending the HTTP reply. Or something. I forget the details since I haven't looked at it in a few years. I just remember that it worked fine on Linux, but gave trouble on Windows and OpenBSD, and I never quite figured out exactly why.

(9) By anonymous on 2022-08-05 02:01:53 in reply to 8 [source]

Hi,

I am posting anonymously because I cannot find my password for the forums. My user name is thebondo.

I use fossil on windows (although not as a server) so I thought I would give this a look. Hopefully this will be helpful. The changes below have only been tested on windows.

After rummaging around the fossil source code and tracing what happens for running the backoffice in windows, the primary cause appears to be in main.c in the function cmd_http. Here is a unified diff with a proposed fix for getting the backoffice to run.

  --- src/main.c
  +++ src/main.c
  @@ -2756,10 +2756,10 @@
     if( zInFile ){
  -    backoffice_disable();
  +//  backoffice_disable();
       g.httpIn = fossil_fopen(zInFile, "rb");
       if( g.httpIn==0 ) fossil_fatal("cannot open \"%s\" for reading", zInFile);
     }else{
       g.httpIn = stdin;
   #if defined(_WIN32)
      _setmode(_fileno(stdin), _O_BINARY);
   #endif
     }

The function win32_http_request from winhttp.c handles requests for the windows server (either running in a command prompt or running as a service). This function serves the request by running a child process for a "fossil http" command using fossil_system. The options used for this command always use --in and --out. So when cmd_http is called from "fossil server" on windows, zInFile is always set, which means the line backoffice_disable() is always executed. This effectively stops the backoffice from running. On Linux this is not an issue because fossil server handles requests by forking and ultimately calling process_one_web_page from the child process (I think).

Initially, I tried just this fix. However, I happened to be working in a path with spaces (C:fossil test), which caused a separate issue that also prevented the backoffice from running as expected.

After some more exploring, I found that the important block is in the function backoffice_run_if_needed from backoffice.c (shown below with a diff for a proposed fix). By tracing the execution, I found that _wspawnv splits the elements of the third argument on unquoted spaces. It does not split the second argument on unquoted spaces. So "C:fossil testfossil.exe" was getting executed, but it was being given an argument list of "C:fossil" "testfossil.exe" "backoffice" "-R" "C:fossil" "testserver.fossil". Just fixing the quoting of g.nameOfExe was not sufficient. Then, the backoffice would run, but it would silently fail because it would not find either "C:fossil" or "testserver.fossil" as repositories.

  --- src/backoffice.c
  +++ src/backoffice.c
  @@ -822,20 +822,23 @@
   #if defined(_WIN32)
     {
       int i;
       intptr_t x;
  -    char *argv[4];
  -    wchar_t *ax[5];
  +    char *argv[5];
  +    wchar_t *ax[6];
       argv[0] = g.nameOfExe;
  -    argv[1] = "backoffice";
  -    argv[2] = "-R";
  -    argv[3] = backofficeDb;
  -    ax[4] = 0;
  -    for(i=0; i<=3; i++) ax[i] = fossil_utf8_to_unicode(argv[i]);
  -    x = _wspawnv(_P_NOWAIT, ax[0], (const wchar_t * const *)ax);
  -    for(i=0; i<=3; i++) fossil_unicode_free(ax[i]);
  +    argv[1] = mprintf("%$", g.nameOfExe);
  +    argv[2] = "backoffice";
  +    argv[3] = "-R";
  +    argv[4] = mprintf("%$", backofficeDb);
  +    ax[5] = 0;
  +    for(i=0; i<=4; i++) ax[i] = fossil_utf8_to_unicode(argv[i]);
  +    x = _wspawnv(_P_NOWAIT, ax[0], (const wchar_t * const *)(ax+1));
  +    for(i=0; i<=4; i++) fossil_unicode_free(ax[i]);
  +    fossil_free(argv[1]);
  +    fossil_free(argv[4]);
       backofficeTrace(
         "/***** Subprocess %d creates backoffice child %lu *****/\n",
         GETPID(), GetProcessId((HANDLE)x));
       if( x>=0 ) return;
     }
   #else /* unix */

The preceding diff fixes the issue with spaces by

  1. inserting a new argv[1] item with a quoted version of g.nameOfExe
  2. quoting backofficeDb for argv[4]
  3. Updateing _wspawnv to use ax[1..5] instead of ax[0..4]
  4. Updating the loop limits
  5. Adding code to free argv[1] and argv[4]

I did a global code search to see where else "--in" might be used internally, and I did not find any uses in src that looked like there would be issues. However, it does look like tests might be affected. My guess is that the line in main.c was originally added so that test_fossil_http from testtester.tcl would not try to invoke the backoffice. Perhaps a separate flag could be added to fossil http to prevent the backoffice from running when needed?

(10) By Stephan Beal (stephan) on 2022-08-05 07:04:55 in reply to 9 [link] [source]

I am posting anonymously because I cannot find my password for the forums. My user name is thebondo.

If you will send me an email from the address associated with that account i will reset your password.