diff --git a/client/node.go b/client/node.go index 455f448fb..d96ff4ae1 100644 --- a/client/node.go +++ b/client/node.go @@ -259,6 +259,20 @@ func (n *NodeClient) NetworkListInterfaces(ctx context.Context) (result map[stri return } +// AdminRebootNode return all physical devices on a node +func (n *NodeClient) AdminRebootNode(ctx context.Context) error { + const cmd = "zos.admin.reboot" + + return n.bus.Call(ctx, n.nodeTwin, cmd, nil, nil) +} + +// AdminRestartService return all physical devices on a node +func (n *NodeClient) AdminRestartService(ctx context.Context, service string) error { + const cmd = "zos.admin.restart" + + return n.bus.Call(ctx, n.nodeTwin, cmd, service, nil) +} + // NetworkListAllInterfaces return all physical devices on a node func (n *NodeClient) NetworkListAllInterfaces(ctx context.Context) (result map[string]Interface, err error) { const cmd = "zos.network.admin.interfaces" diff --git a/docs/manual/api.md b/docs/manual/api.md index 250eb00f2..9a9c5ef15 100644 --- a/docs/manual/api.md +++ b/docs/manual/api.md @@ -153,6 +153,22 @@ it means it can act like an access node to user private networks The next set of commands are ONLY possible to be called by the `farmer` only. +### Reboot Node + +| command |body| return| +|---|---|---| +| `zos.admin.reboot` | - | - | + +Stops all services then reboot the node + +### Restart Service + +| command |body| return| +|---|---|---| +| `zos.admin.reboot` | string | - | + +Restarts a service running on the node + ### List Physical Interfaces | command |body| return| diff --git a/pkg/zos_api/admin.go b/pkg/zos_api/admin.go index 4b53237e6..2474e6b0e 100644 --- a/pkg/zos_api/admin.go +++ b/pkg/zos_api/admin.go @@ -4,8 +4,31 @@ import ( "context" "encoding/json" "fmt" + + "github.com/threefoldtech/zos/pkg/zinit" ) +func (g *ZosAPI) adminRestartHandler(ctx context.Context, payload []byte) (interface{}, error) { + var service string + if err := json.Unmarshal(payload, &service); err != nil { + return nil, fmt.Errorf("failed to decode input, expecting string: %w", err) + } + + zinit := zinit.Default() + + if err := zinit.Stop(service); err != nil { + return nil, err + } + + return nil, zinit.Start(service) +} + +func (g *ZosAPI) adminRebootHandler(ctx context.Context, payload []byte) (interface{}, error) { + zinit := zinit.Default() + + return nil, zinit.Reboot() +} + func (g *ZosAPI) adminInterfacesHandler(ctx context.Context, payload []byte) (interface{}, error) { // list all interfaces on node type Interface struct { diff --git a/pkg/zos_api/routes.go b/pkg/zos_api/routes.go index 8006f23b7..dd9aa06f3 100644 --- a/pkg/zos_api/routes.go +++ b/pkg/zos_api/routes.go @@ -45,6 +45,8 @@ func (g *ZosAPI) SetupRoutes(router *peer.Router) { admin := root.SubRoute("admin") admin.Use(g.authorized) + admin.WithHandler("reboot", g.adminRebootHandler) + admin.WithHandler("restart", g.adminRestartHandler) admin.WithHandler("interfaces", g.adminInterfacesHandler) admin.WithHandler("set_public_nic", g.adminSetPublicNICHandler) admin.WithHandler("get_public_nic", g.adminGetPublicNICHandler)