1{ pkgs, ... }:
2{
3 name = "uwsgi";
4 meta = with pkgs.lib.maintainers; {
5 maintainers = [ lnl7 ];
6 };
7
8 nodes.machine =
9 { pkgs, ... }:
10 {
11 users.users.hello = {
12 isSystemUser = true;
13 group = "hello";
14 };
15 users.groups.hello = { };
16
17 services.uwsgi = {
18 enable = true;
19 plugins = [
20 "python3"
21 "php"
22 ];
23 capabilities = [ "CAP_NET_BIND_SERVICE" ];
24 instance.type = "emperor";
25
26 instance.vassals.hello = {
27 type = "normal";
28 immediate-uid = "hello";
29 immediate-gid = "hello";
30 module = "wsgi:application";
31 http = ":80";
32 cap = "net_bind_service";
33 pythonPackages = self: [ self.flask ];
34 chdir = pkgs.writeTextDir "wsgi.py" ''
35 from flask import Flask
36 import subprocess
37 application = Flask(__name__)
38
39 @application.route("/")
40 def hello():
41 return "Hello, World!"
42
43 @application.route("/whoami")
44 def whoami():
45 whoami = "${pkgs.coreutils}/bin/whoami"
46 proc = subprocess.run(whoami, capture_output=True)
47 return proc.stdout.decode().strip()
48 '';
49 };
50
51 instance.vassals.php = {
52 type = "normal";
53 master = true;
54 workers = 2;
55 http-socket = ":8000";
56 http-socket-modifier1 = 14;
57 php-index = "index.php";
58 php-docroot = pkgs.writeTextDir "index.php" ''
59 <?php echo "Hello World\n"; ?>
60 '';
61 };
62 };
63 };
64
65 testScript = ''
66 machine.wait_for_unit("multi-user.target")
67 machine.wait_for_unit("uwsgi.service")
68
69 with subtest("uWSGI has started"):
70 machine.wait_for_unit("uwsgi.service")
71
72 with subtest("Vassal can bind on port <1024"):
73 machine.wait_for_open_port(80)
74 hello = machine.succeed("curl -f http://machine").strip()
75 assert "Hello, World!" in hello, f"Excepted 'Hello, World!', got '{hello}'"
76
77 with subtest("Vassal is running as dedicated user"):
78 username = machine.succeed("curl -f http://machine/whoami").strip()
79 assert username == "hello", f"Excepted 'hello', got '{username}'"
80
81 with subtest("PHP plugin is working"):
82 machine.wait_for_open_port(8000)
83 assert "Hello World" in machine.succeed("curl -fv http://machine:8000")
84 '';
85}