File: systemd.py

package info (click to toggle)
libcgroup 3.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 6,764 kB
  • sloc: ansic: 14,997; cpp: 9,957; python: 8,340; sh: 5,194; yacc: 470; makefile: 400; lex: 38
file content (76 lines) | stat: -rw-r--r-- 2,685 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
# SPDX-License-Identifier: LGPL-2.1-only
#
# Systemd class for the libcgroup functional tests
#
# Copyright (c) 2022 Oracle and/or its affiliates.
# Author: Tom Hromatka <tom.hromatka@oracle.com>
#

from run import Run, RunError
from cgroup import Cgroup
import os


class Systemd(object):
    @staticmethod
    def is_delegated(config, scope_name):
        cmd = ['systemctl', 'show', '-P', 'Delegate', scope_name]
        try:
            out = Run.run(cmd, shell_bool=True)

            if out == 'yes':
                return True
            else:
                return False
        except RunError as re:
            if re.stderr.find('invalid option') >= 0:
                # This version of systemd is too old for the '-P' flag.  At this time, I don't
                # think there's a way to verify the scope is delegated.  Lie and return true
                # until we figure out something better :(
                return True
            raise re

    # This function creates a task and writes its pid into systemd
    # configuration file, that gets passed to the cgconfigparser tool to
    # create systemd slice/scope.
    @staticmethod
    def write_config_with_pid(config, config_fname, _slice, scope, setdefault="yes"):
        pid = config.process.create_process(config)
        config_file = '''systemd {{
            slice = {};
            scope = {};
            setdefault = {};
            pid = {};
        }}'''.format(_slice, scope, setdefault, pid)

        f = open(config_fname, 'w')
        f.write(config_file)
        f.close()

        return pid

    # Stopping the systemd scope, will kill the default task in the scope
    # and remove scope cgroup but will not remove the slice, that needs to
    # removed manually.
    @staticmethod
    def remove_scope_slice_conf(config, _slice, scope, controller, config_fname=None):
        if config_fname:
            os.remove(config_fname)

        try:
            if config.args.container:
                config.container.run(['systemctl', 'stop', '{}'.format(scope)],
                                     shell_bool=True)
            else:
                Run.run(['sudo', 'systemctl', 'stop', '{}'.format(scope)], shell_bool=True)
        except RunError as re:
            if 'scope not loaded' in re.stderr:
                raise re

        # In case the error occurs before the creation of slice/scope and
        # we may very well be on the teardown path, ignore the exception
        try:
            Cgroup.delete(config, controller, cgname=_slice, ignore_systemd=True)
        except RunError as re:
            if 'No such file or directory' not in re.stderr:
                raise re