odoo: fix websocket support for real-time connections (#513980)

This commit is contained in:
xanderio 2026-05-07 07:21:41 +00:00 committed by GitHub
commit 623d10aa7a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 102 additions and 11 deletions

View file

@ -46,7 +46,24 @@ in
};
settings = lib.mkOption {
type = format.type;
type = lib.types.submodule {
options = {
options = {
workers = lib.mkOption {
type = lib.types.ints.unsigned;
default = 0;
description = "Values above 0 will enable the multi-processing HTTP server, this should be set for production setups. This needs to be set to >0 for real-time connections in the discuss app. For configuration recommendations see <https://www.odoo.com/documentation/19.0/administration/on_premise/deploy.html#builtin-server>";
};
proxy_mode = lib.mkOption {
type = lib.types.bool;
default = cfg.domain != null;
defaultText = "services.odoo.domain != null";
description = "Enables the use of X-Forwarded-* headers through Werkzeugs proxy support. Must be enabled if reverse proxy is used.";
};
};
};
freeformType = format.type;
};
default = { };
description = ''
Odoo configuration settings. For more details see <https://www.odoo.com/documentation/15.0/administration/install/deploy.html>
@ -96,7 +113,7 @@ in
'';
locations = {
"/longpolling" = {
"/websocket" = {
proxyPass = "http://odoochat";
};
@ -127,7 +144,6 @@ in
);
settings.options = {
data_dir = "/var/lib/private/odoo/data";
proxy_mode = cfg.domain != null;
# Disable the database manager by default
# https://www.odoo.com/documentation/master/administration/on_premise/deploy.html#database-manager-security
list_db = lib.mkDefault false;

View file

@ -1177,15 +1177,27 @@ in
octoprint = runTest ./octoprint.nix;
oddjobd = handleTestOn [ "x86_64-linux" "aarch64-linux" ] ./oddjobd.nix { };
odoo17 = runTest {
imports = [ ./odoo.nix ];
imports = [ ./odoo/single-process.nix ];
_module.args.package = pkgs.odoo17;
};
odoo17-multiprocess = runTest {
imports = [ ./odoo/multi-process.nix ];
_module.args.package = pkgs.odoo17;
};
odoo18 = runTest {
imports = [ ./odoo.nix ];
imports = [ ./odoo/single-process.nix ];
_module.args.package = pkgs.odoo18;
};
odoo18-multiprocess = runTest {
imports = [ ./odoo/multi-process.nix ];
_module.args.package = pkgs.odoo18;
};
odoo19 = runTest {
imports = [ ./odoo.nix ];
imports = [ ./odoo/single-process.nix ];
_module.args.package = pkgs.odoo19;
};
odoo19-multiprocess = runTest {
imports = [ ./odoo/multi-process.nix ];
_module.args.package = pkgs.odoo19;
};
oh-my-zsh = runTest ./oh-my-zsh.nix;

View file

@ -0,0 +1,39 @@
{
package,
lib,
...
}:
{
name = "odoo-multi-process";
meta.maintainers = with lib.maintainers; [
mkg20001
xanderio
];
nodes.server = {
services.nginx = {
enable = true;
recommendedProxySettings = true;
};
services.odoo = {
enable = true;
package = package;
autoInit = true;
autoInitExtraFlags = [ "--without-demo=all" ];
domain = "localhost";
settings.options.workers = 2;
};
};
testScript = # python
''
server.wait_for_unit("odoo.service")
server.wait_until_succeeds(
"test $(journalctl -u odoo | grep -o 'Worker WorkerHTTP ([[:digit:]]*) alive' | wc -l) = 2"
)
server.wait_until_succeeds("curl -s http://localhost:8069/web/database/selector | grep '<title>Odoo</title>'")
server.succeed("curl -s http://localhost/web/database/selector | grep '<title>Odoo</title>'")
server.succeed("curl http://localhost/web/database/manager | grep 'database manager has been disabled'")
'';
}

View file

@ -4,8 +4,11 @@
...
}:
{
name = "odoo";
meta.maintainers = with lib.maintainers; [ mkg20001 ];
name = "odoo-single-process";
meta.maintainers = with lib.maintainers; [
mkg20001
xanderio
];
nodes.server = {
services.nginx = {

View file

@ -55,6 +55,13 @@ python.pkgs.buildPythonApplication rec {
}"
];
postPatch = ''
# hardcode the location of the unwrapped python scrip, otherwise the websocket
# server (called longpoll in codebase) will fail to start.
substituteInPlace odoo/service/server.py \
--replace-fail 'sys.argv[0]' "'${placeholder "out"}/bin/.odoo-wrapped'"
'';
build-system = with python.pkgs; [
setuptools
];
@ -111,7 +118,7 @@ python.pkgs.buildPythonApplication rec {
passthru = {
updateScript = ./update.sh;
tests = {
inherit (nixosTests) odoo17;
inherit (nixosTests) odoo17 odoo17-multiprocess;
};
};

View file

@ -26,6 +26,13 @@ python.pkgs.buildPythonApplication rec {
hash = "sha256-rNG0He+51DnRT5g1SovGZ9uiE1HWXtcmAybcadBMjY4="; # odoo
};
postPatch = ''
# hardcode the location of the unwrapped python scrip, otherwise the websocket
# server (called longpoll in codebase) will fail to start.
substituteInPlace odoo/service/server.py \
--replace-fail 'sys.argv[0]' "'${placeholder "out"}/bin/.odoo-wrapped'"
'';
makeWrapperArgs = [
"--prefix PATH : ${
lib.makeBinPath [
@ -97,7 +104,7 @@ python.pkgs.buildPythonApplication rec {
passthru = {
updateScript = ./update.sh;
tests = {
inherit (nixosTests) odoo18;
inherit (nixosTests) odoo18 odoo18-multiprocess;
};
};

View file

@ -26,6 +26,13 @@ python.pkgs.buildPythonApplication rec {
hash = "sha256-JsbJ39zPZm4eyRTXkvdCMHwYaA08yUxZXcLglRn3kWs="; # odoo
};
postPatch = ''
# hardcode the location of the unwrapped python scrip, otherwise the websocket
# server (called longpoll in codebase) will fail to start.
substituteInPlace odoo/service/server.py \
--replace-fail 'sys.argv[0]' "'${placeholder "out"}/bin/.odoo-wrapped'"
'';
makeWrapperArgs = [
"--prefix PATH : ${
lib.makeBinPath [
@ -92,7 +99,7 @@ python.pkgs.buildPythonApplication rec {
passthru = {
updateScript = ./update.sh;
tests = {
inherit (nixosTests) odoo19;
inherit (nixosTests) odoo19 odoo19-multiprocess;
};
};