Skip to content

Commit

Permalink
incusd/scriptlet: Add useful QMP functions
Browse files Browse the repository at this point in the history
Signed-off-by: Benjamin Somers <benjamin.somers@imt-atlantique.fr>
  • Loading branch information
bensmrs committed Oct 28, 2024
1 parent fbba738 commit bb39fa8
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 4 deletions.
9 changes: 9 additions & 0 deletions internal/server/scriptlet/load/load.go
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,15 @@ func QEMUCompile(name string, src string) (*starlark.Program, error) {
"log_warn",
"log_error",
"run_qmp",
"device_del",
"netdev_del",
"object_del",
"qom_get",
"qom_list",
"qom_set",
"quit",
"set_link",
"system_reset",
})
}

Expand Down
63 changes: 59 additions & 4 deletions internal/server/scriptlet/qemu.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,68 @@ func QEMURun(l logger.Logger, m *qmp.Monitor, instance string, stage string) err
return rv, nil
}

makeQOM := func(funName string, parameters ...string) *starlark.Builtin {
fun := func(thread *starlark.Thread, b *starlark.Builtin, args starlark.Tuple, kwargs []starlark.Tuple) (starlark.Value, error) {
// Construct the key-value parameter array
pairs := make([]any, len(parameters)*2)
values := make([]starlark.Value, len(parameters))
for i, parameter := range parameters {
pairs[i*2] = parameter
pairs[i*2+1] = &values[i]
}

err := starlark.UnpackArgs(b.Name(), args, kwargs, pairs...)
if err != nil {
return nil, err
}

qmpArgs := make(map[string]any)
for i, parameter := range parameters {
value, err := StarlarkUnmarshal(values[i])
if err != nil {
return nil, err
}

qmpArgs[parameter] = value
}

var resp struct {
Return any
}

err = m.Run(funName, qmpArgs, &resp)
if err != nil {
return nil, err
}

// Extract the return value
rv, err := StarlarkMarshal(resp.Return)
if err != nil {
return nil, fmt.Errorf("Marshalling QMP response failed: %w", err)
}

return rv, nil
}

return starlark.NewBuiltin(funName, fun)
}

// Remember to match the entries in scriptletLoad.QEMUCompile() with this list so Starlark can
// perform compile time validation of functions used.
env := starlark.StringDict{
"log_info": starlark.NewBuiltin("log_info", logFunc),
"log_warn": starlark.NewBuiltin("log_warn", logFunc),
"log_error": starlark.NewBuiltin("log_error", logFunc),
"run_qmp": starlark.NewBuiltin("run_qmp", runQMPFunc),
"log_info": starlark.NewBuiltin("log_info", logFunc),
"log_warn": starlark.NewBuiltin("log_warn", logFunc),
"log_error": starlark.NewBuiltin("log_error", logFunc),
"run_qmp": starlark.NewBuiltin("run_qmp", runQMPFunc),
"device_del": makeQOM("device_del", "id"),
"netdev_del": makeQOM("netdev_del", "id"),
"object_del": makeQOM("object-del", "id"),
"qom_get": makeQOM("qom-get", "path", "property"),
"qom_list": makeQOM("qom-list", "path"),
"qom_set": makeQOM("qom-set", "path", "property", "value"),
"quit": makeQOM("quit"),
"set_link": makeQOM("set_link", "name", "up"),
"system_reset": makeQOM("system_reset"),
}

prog, thread, err := scriptletLoad.QEMUProgram(instance)
Expand Down

0 comments on commit bb39fa8

Please sign in to comment.