unit icon indicating copy to clipboard operation
unit copied to clipboard

Query control API to show the loaded modules

Open lcrilly opened this issue 1 year ago • 8 comments

This feature extends the /status Control API endpoint to include the currently loaded modules.

Currently, the available modules are loaded by the discovery process at startup and logged to the Unit log file.

2024/06/26 09:36:16 [info] 55991#2488927 discovery started
2024/06/26 09:36:16 [notice] 55991#2488927 module: php 8.3.4 "/var/lib/unit/modules/php.unit.so"
2024/06/26 09:36:16 [notice] 55991#2488927 module: python 3.12.2 "/var/lib/unit/modules/python3.unit.so"
2024/06/26 09:36:16 [notice] 55991#2488927 module: wasm-wasi-component 0.1 "/var/lib/unit/modules/wasm_wasi_component.unit.so"
2024/06/26 09:36:17 [info] 55990#2488925 controller started

This information is already transferred to the Control API because attempts to configure an application with an unloaded "type" fails with a suitable error, e.g.

$ echo '{"bogus":{"type":"cobol"}}' | unitc /config/applications
{
  "error": "Invalid configuration.",
  "detail": "The module to run \"cobol\" is not found among the available application modules."
}

It would be much more convenient if the loaded modules information was also queryable at runtime. So the /status endpoint would return something like:

{
  "modules": [
    "php 8.3.4",
    "python 3.12.2",
    "wasm-wasi-component 0.1"
  ],
  "connections": { … },
  "requests": { … },
  "applications": { … }
}

This would provide a more convenient way of checking what language modules are loaded. It would also benefit command line tools that auto-configure Unit to serve applications.

lcrilly avatar Jun 26 '24 15:06 lcrilly

The language modules and versions are handily stored in the languages array member of the nxt_runtime_t structure...

We have access to the following information

typedef struct {                                                                
    nxt_app_type_t            type;                                             
    u_char                    *version;                                         
    char                      *file;                                            
    nxt_app_module_t          *module;                                          
    nxt_array_t               *mounts;    /* of nxt_fs_mount_t */               
} nxt_app_lang_module_t;

Would showing the path (e.g /opt/unit/modules/python.unit.so) to the module be useful? Might be handy for debugging to make sure it's loading the modules you expect it to...

ac000 avatar Jun 26 '24 16:06 ac000

Would showing the path (e.g /opt/unit/modules/python.unit.so) to the module be useful?

I have wished for this information several times in fact! :) I think having this will better enable our users to roll their own docker images and to compile Unit for themselves.

avahahn avatar Jun 26 '24 19:06 avahahn

Given that we have the type and version as separate entities in the struct, it makes sense to have an array of objects instead of the simple naive array I was envisaging.

I wasn't sure about the information disclosure of the path. And I didn't have a use case for it. But now I think about it, knowing exactly which module is loaded seems like a good idea.

lcrilly avatar Jun 26 '24 23:06 lcrilly

I have an initial version that will return something like

{
    "modules": {
        "python": {
            "version": "3.12.2",
            "lib": "/opt/unit/modules/python.unit.so"
        },
        "wasm": {
            "version": "0.1",
            "lib": "/opt/unit/modules/wasm.unit.so"
        },
        "wasm-wasi-component": {
            "version": "0.1",
            "lib": "/opt/unit/modules/wasm_wasi_component.unit.so"
        }
    },
...
}

ac000 avatar Jun 28 '24 16:06 ac000

I look forward to trying it :)

I suggested an array of objects because we may find multiple versions of the same language module installed (especially for PHP and Python).

lcrilly avatar Jul 01 '24 10:07 lcrilly

Are you saying you want the JSON formatted differently?

Currently it's modelled on the "applications" section

	"applications": {
		"luw-echo-request": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"luw-upload-reflector": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"echo-request-raw": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"rust-echo-request": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"rust-upload-reflector": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"rust-hello-world": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"sc-test": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"large-upload": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		},

		"rust-large-upload": {
			"processes": {
				"running": 1,
				"starting": 0,
				"idle": 1
			},

			"requests": {
				"active": 0
			}
		}
	}

ac000 avatar Jul 01 '24 14:07 ac000

I think Liam probably means:

{
    "modules": {
        "python": [
            {
                "version": "3.12.2",
                "lib": "/opt/unit/modules/python3.12.unit.so"
            },
            {
                "version": "3.11.0",
                "lib": "/opt/unit/modules/python3.11.unit.so"
            }
        ],
        "wasm": [ ... ]
}

callahad avatar Jul 01 '24 16:07 callahad

I actually meant something different but then realised that it's not possible to have ambiguous module names.

So @ac000 's original example looks ideal.

lcrilly avatar Jul 01 '24 17:07 lcrilly

Excellent! Well done @ac000

lcrilly avatar Jul 12 '24 17:07 lcrilly