Skip to content

Commit

Permalink
Add a new service plugin
Browse files Browse the repository at this point in the history
Signed-off-by: Ronan Abhamon <[email protected]>
  • Loading branch information
Wescoeur committed Feb 19, 2025
1 parent 9e6280e commit 878dbb0
Show file tree
Hide file tree
Showing 3 changed files with 120 additions and 0 deletions.
36 changes: 36 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,42 @@ $ xe host-call-plugin host-uuid=<uuid> plugin=ipmitool.py fn=get_ipmi_lan
```

## Service

A xapi plugin that uses `systemctl` to manage services.

### `start_service`

Start a service if it is not already running.

```
$ xe host-call-plugin host-uuid<uuid> plugin=service.py fn=start_service args:service=<service>
```

### `stop_service`

Stop a service if it is currently running.

```
$ xe host-call-plugin host-uuid<uuid> plugin=service.py fn=stop_service args:service=<service>
```

### `restart_service`

Stop a service if it is running and then start it.

```
$ xe host-call-plugin host-uuid<uuid> plugin=service.py fn=restart_service args:service=<service>
```

### `try_restart_service`

Restart a service only if it is already running.

```
$ xe host-call-plugin host-uuid<uuid> plugin=service.py fn=try_restart_service args:service=<service>
```

## Tests

To run the plugins' unit tests you'll need to install `pytest`, `pyfakefs` and `mock`.
Expand Down
41 changes: 41 additions & 0 deletions SOURCES/etc/xapi.d/plugins/service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import json
import sys
import XenAPIPlugin

sys.path.append('.')
from xcpngutils import configure_logging, run_command, error_wrapped

def run_service_command(cmd_name, args):
service = args.get('service')
if not service:
raise Exception('Missing or empty argument `service`')
run_command(['systemctl', cmd_name, service])
return json.dumps(True)

@error_wrapped
def start_service(session, args):
return run_service_command('start', args)

@error_wrapped
def stop_service(session, args):
return run_service_command('stop', args)

@error_wrapped
def restart_service(session, args):
return run_service_command('restart', args)

@error_wrapped
def try_restart_service(session, args):
return run_service_command('try-restart', args)

_LOGGER = configure_logging('service')
if __name__ == "__main__":
XenAPIPlugin.dispatch({
'start_service': start_service,
'stop_service': stop_service,
'restart_service': restart_service,
'try_restart_service': try_restart_service
})
43 changes: 43 additions & 0 deletions tests/test_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import mock
import pytest
import XenAPIPlugin

from service import start_service, stop_service, restart_service, try_restart_service

@mock.patch("service.run_command", autospec=True)
class TestService:
SERVICE = 'linstor-satellite'

def _test_command(self, cmd, cmd_name, run_command):
cmd(mock.MagicMock(), {'service': self.SERVICE})
run_command.assert_called_once_with(['systemctl', cmd_name, self.SERVICE])

def _test_command_without_service(self, cmd):
with pytest.raises(XenAPIPlugin.Failure) as e:
start_service(mock.MagicMock(), {})
assert e.value.params[0] == '-1'
assert e.value.params[1] == 'Missing or empty argument `service`'

def test_start(self, run_command):
self._test_command(start_service, 'start', run_command)

def test_stop(self, run_command):
self._test_command(stop_service, 'stop', run_command)

def test_restart(self, run_command):
self._test_command(restart_service, 'restart', run_command)

def test_try_restart(self, run_command):
self._test_command(try_restart_service, 'try-restart', run_command)

def test_start_without_service(self, run_command):
self._test_command_without_service(start_service)

def test_stop_without_service(self, run_command):
self._test_command_without_service(stop_service)

def test_restart_without_service(self, run_command):
self._test_command_without_service(restart_service)

def test_try_restart_without_service(self, run_command):
self._test_command_without_service(try_restart_service)

0 comments on commit 878dbb0

Please sign in to comment.