def main():

  # Initialize, 3 attempts
  for i in range(3):
    try:
      answers = getConfigParameters()
      deviceShadow = setClient(answers)
    except OSError as os_error:
      print(os_error)
    else:
      break
    
  unit = Unit(b'polkadot-validator.service')
  unit.load()
  status = 'unknown'

  # To stop running this script, press Ctrl+C.
  while True:
    prev_status = status
    status = unit.Unit.ActiveState.decode('utf-8')
    
    try:
      if prev_status != status:
        msg = '{"state":{"reported":{"status":"%(data)s"}}}' % { 'data' : status}
        deviceShadow.shadowUpdate(msg, myShadowUpdateCallback, 5)
      else:
        msg = '{"state":{"desired":{"status":"%(data)s"}}}' % { 'data' : prev_status}
        # Uncomment next line if you want to send AWS IOT desired status to enable deltas.
        #deviceShadow.shadowUpdate(msg, myShadowUpdateCallback, 5) 
    except:
      break

    # Polling wait time [sec]
    time.sleep(.5)
Example #2
0
 def using_systemd(self):
     if not PYSTEMD_AVAIL:
         return False
     if self._systemd is not None:
         return self._systemd
     self._unit = Unit(b"opensight.service", _autoload=True)
     self._systemd = self._unit.Unit.ActiveState == b"active"
     return self._systemd
Example #3
0
    def __init__(self):
        self.indicator = appindicator.Indicator.new(
            APPINDICATOR_ID, get_icon_path("lightgreen"),
            appindicator.IndicatorCategory.SYSTEM_SERVICES)
        self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE)
        self.indicator.set_label("", "0!")
        self.menu = gtk.Menu()

        self.item_systemd_status = gtk.MenuItem.new_with_label("???")
        self.item_systemd_status.set_sensitive(False)
        self.menu.append(self.item_systemd_status)

        self.item_healthchecks_status = gtk.MenuItem.new_with_label("???")
        self.item_healthchecks_status.set_sensitive(False)
        self.menu.append(self.item_healthchecks_status)

        self.item_journalctl_tail = gtk.MenuItem.new_with_label("???")
        self.item_journalctl_tail.set_sensitive(False)
        # self.item_journalctl_tail.get_child().set_line_wrap(True)
        # self.item_journalctl_tail.get_child().set_max_width_chars(75)
        self.submenu_log_item = gtk.MenuItem.new_with_label("Log")
        self.menu.append(self.submenu_log_item)
        self.submenu_log = gtk.Menu()
        self.submenu_log_item.set_submenu(self.submenu_log)
        self.submenu_log.append(self.item_journalctl_tail)

        self.menu.append(gtk.SeparatorMenuItem())

        self.item_goto_healthchecks = gtk.MenuItem.new_with_label(
            "Go to Healthchecks")
        self.item_goto_healthchecks.connect("activate", self.goto_healthchecks)
        self.menu.append(self.item_goto_healthchecks)

        self.item_show_log = gtk.MenuItem.new_with_label("Show Log")
        self.item_show_log.connect("activate", self.show_log)
        self.menu.append(self.item_show_log)

        self.item_show_status = gtk.MenuItem.new_with_label("Show Status")
        self.item_show_status.connect("activate", self.show_status)
        self.menu.append(self.item_show_status)

        self.item_start_borgmatic = gtk.MenuItem.new_with_label("Start Backup")
        self.item_start_borgmatic.connect("activate", self.start_service)
        self.menu.append(self.item_start_borgmatic)

        self.menu.show_all()
        self.indicator.set_menu(self.menu)

        # self.notification = notify.Notification.new("<b>Borgmatic</b>", "", "drive-harddisk-symbolic")

        self.borgmatic_unit = Unit(b'borgmatic.service')
        self.checks = []
        self.journal = []

        self.running = Event()
        self.update_now = Event()
Example #4
0
def checkFSstate(op):
   fs = Unit(b'freeswitch.service')
   fs.load()
   if op == 'start':
       if fs.Unit.ActiveState.decode() not in {'active'}:
    #       print("need to start")
           fsStartStop('start')
   elif op == 'stop':
       if fs.Unit.ActiveState.decode() not in {'inactive', 'failed'}:
   #        print("need to stop")
           fsStartStop('stop')
Example #5
0
def get_unit(instance: str) -> Unit:
    """Return the systemd Unit name of the Instance.

    Args:
        instance (str): The name of the instance.

    Returns:
        Unit: The systemd service Unit.
    """
    unit = Unit(f"{UNIT_NAME}@{instance}.service")
    unit.load()
    return unit
Example #6
0
def fsStartStop(op):
   wait_flag = 1
   fs = Unit(b'freeswitch.service')
   fs.load()
   if op == 'stop':
       #print("FreeSwitch before stop state:",fs.Unit.ActiveState)
       while wait_flag:
           fs.Unit.Stop('replace')
           time.sleep(time_stop)
           wait_flag = 0
       if fs.Unit.ActiveState.decode() in {'inactive', 'failed'}:
           message = '{scream} {fire} Local DB on {local_serv} is not responding. DB at {remote_serv} is not
Example #7
0
def restart_nginx():
    try:
        spinner.start("Restarting Nginx service...")
        unit = Unit(b"nginx")
        unit.load()
        unit.Unit.Start(b"replace")
        time.sleep(5)
        unit.Unit.Stop(b"replace")
        spinner.stop()
    except pystemd.dbusexc.DBusInvalidArgsError:
        spinner.fail(
            "Unable to restart nginx due to some error. You would have to restart it manually."
        )
Example #8
0
def restart_services():
    hostapd = Unit(b'hostapd.service')
    hostapd.load()
    hostapd.Unit.Restart(b'replace')
    dnsmasq = Unit(b'dnsmasq.service')
    dnsmasq.load()
    dnsmasq.Unit.Restart(b'replace')
Example #9
0
 def __init__(self, parameters):
     self.services = parameters
     print('Services collector. Loading services status:')
     for idx, service in enumerate(self.services):
         print('  - Loading ' + service)
         self.services_status.append(Unit(service, _autoload=True))
         print(self.services_status)
Example #10
0
def start_transient_unit(cmd='/bin/sleep 15'):
    a_cmd = [c.encode() for c in shlex.split(cmd)]
    random_unit_name = 'myservice.{r}.{t}.service'.format(
        r=random.randint(0, 100), t=time.time()).encode()

    unit = {
        b'Description': b'Example of transient unit',
        b'ExecStart': [(a_cmd[0], a_cmd, False)],
        b'RemainAfterExit': True}

    with Manager() as manager:
        manager.Manager.StartTransientUnit(
            random_unit_name, b'fail', unit)

    with Unit(random_unit_name) as unit:
        while True:
            print(
                'service `{cmd}` (name={random_unit_name}) has MainPID '
                '{unit.Service.MainPID}'.format(**locals()))
            if unit.Service.MainPID == 0:
                print(
                    'service finished with '
                    '{unit.Service.ExecMainStatus}/{unit.Service.Result} '
                    'will stop it and then... bye'.format(**locals()))
                unit.Unit.Stop(b'replace')
                break
            print('service still runing, sleeping by 5 seconds')
            time.sleep(5)
Example #11
0
def get_magma_services_status():
    """ Get health for all the running services """
    # DBus Unit objects: https://www.freedesktop.org/wiki/Software/systemd/dbus/
    chan = ServiceRegistry.get_rpc_channel('magmad', ServiceRegistry.LOCAL)
    client = MagmadStub(chan)

    configs = client.GetConfigs(common_pb2.Void())
    services_health_summary = []

    for service_name in configs.configs_by_key:
        unit = Unit('magma@{}.service'.format(service_name), _autoload=True)
        active_state = ActiveState.dbus2state[unit.Unit.ActiveState]
        sub_state = str(unit.Unit.SubState, 'utf-8')
        if active_state == ActiveState.ACTIVE:
            pid = unit.Service.MainPID
            process = subprocess.Popen(
                'ps -o etime= -p {}'.format(pid).split(),
                stdout=subprocess.PIPE)

            time_running, error = process.communicate()
        else:
            time_running = b'00'

        services_health_summary.append(
            ServiceHealth(service_name=service_name,
                          active_state=active_state,
                          sub_state=sub_state,
                          time_running=str(time_running, 'utf-8').strip()))
    return services_health_summary
 def read_services_dbus(self):
     services = {}
     with Manager() as manager:
         for _unit in manager.Manager.ListUnits():
             idx = _unit[0].find(b"maverick-")
             if idx == -1:
                 continue
             service_name = _unit[0][9:-8].decode()
             category = None
             if "@" in service_name:
                 category = service_name.split("@")[-1].strip()
             unit = Unit(_unit[0])
             services[unit.path] = {
                 "unit": unit,
                 "path": unit.path,
                 "category_name": category,
                 "category_display_name": category,
                 "command": _unit[0][0:-8].decode(),
                 "service_name": _unit[0][9:-8].decode(),
                 "service_display_name": _unit[1].decode(),
                 "last_update": int(time.time()),
                 "enabled": None,
                 "running": True if _unit[4] == b"running" else False,
             }
     for service in services:
         application_log.debug(f"Adding service: {services[service]}")
     return services
def start_transient_unit(cmd="/bin/sleep 15"):
    a_cmd = [c.encode() for c in shlex.split(cmd)]
    random_unit_name = "myservice.{r}.{t}.service".format(
        r=random.randint(0, 100), t=time.time()).encode()

    unit = {
        b"Description": b"Example of transient unit",
        b"ExecStart": [(a_cmd[0], a_cmd, False)],
        b"RemainAfterExit": True,
    }
    # if we need interactive prompts for passwords, we can create our own DBus object.
    # if we dont need interactive, we would just do `with Manager() as manager:`.
    with DBus(interactive=True) as bus, Manager(bus=bus) as manager:
        manager.Manager.StartTransientUnit(random_unit_name, b"fail", unit)

        with Unit(random_unit_name, bus=bus) as unit:
            while True:
                print("service `{cmd}` (name={random_unit_name}) has MainPID "
                      "{unit.Service.MainPID}".format(**locals()))
                if unit.Service.MainPID == 0:
                    print(
                        "service finished with "
                        "{unit.Service.ExecMainStatus}/{unit.Service.Result} "
                        "will stop it and then... bye".format(**locals()))
                    unit.Unit.Stop(b"replace")
                    break
                print("service still running, sleeping by 5 seconds")
                time.sleep(5)
Example #14
0
def start_transient_unit(cmd="/bin/sleep 15"):
    a_cmd = [c.encode() for c in shlex.split(cmd)]
    random_unit_name = "myservice.{r}.{t}.service".format(
        r=random.randint(0, 100), t=time.time()).encode()

    unit = {
        b"Description": b"Example of transient unit",
        b"ExecStart": [(a_cmd[0], a_cmd, False)],
        b"RemainAfterExit": True,
    }

    with Manager() as manager:
        manager.Manager.StartTransientUnit(random_unit_name, b"fail", unit)

    with Unit(random_unit_name) as unit:
        while True:
            print("service `{cmd}` (name={random_unit_name}) has MainPID "
                  "{unit.Service.MainPID}".format(**locals()))
            if unit.Service.MainPID == 0:
                print("service finished with "
                      "{unit.Service.ExecMainStatus}/{unit.Service.Result} "
                      "will stop it and then... bye".format(**locals()))
                unit.Unit.Stop(b"replace")
                break
            print("service still runing, sleeping by 5 seconds")
            time.sleep(5)
Example #15
0
def is_bird_active():
    with Unit(b'bird.service') as bird_unit:
        bird_unit.load()
        if bird_unit.Unit.ActiveState == b'active':
            return True, "bird is active"
        else:
            return False, "bird is not active"
Example #16
0
    def discover_units(cls):
        # factory function that queries systemd files and returns a list
        # of McUints (1 systemd unit per Minecraft installation)
        mc_installs = list(Config.mc_root.glob("*"))
        mc_names = [
            str(mc.name) for mc in mc_installs
            if not str(mc.name).startswith(".")
        ]
        units = []

        for i, mc_name in enumerate(mc_names):
            unit_name = Config.unit_name_format.format(mc_name)
            unit = Unit(unit_name.encode("utf8"), bus=cls.dbus)
            unit.load()
            units.append(McUnit(mc_name, unit, unit_name, i))

        return units
Example #17
0
def register_gunicorn_service(nginx_answers):
    service_registered = False
    try:
        if os.path.exists("/etc/systemd/system/"):
            spinner.succeed("systemd folder found!")
            shutil.copyfile(
                "deploy_it/gunicorn.service", "/etc/systemd/system/gunicorn.service"
            )
            spinner.succeed("Gunicorn service file copied to systemd")
            service_registered = True
        else:
            spinner.fail(
                "systemd folder was not found! Couldn't copy gunicorn.service file."
            )
    except PermissionError:
        spinner.fail(
            "The script does not has the permission to copy files /etc/systemd/system/ folder."
        )
        spinner.info(
            "You have to manually copy the gunicorn.service file to /etc/systemd/system/ folder."
        )

    if service_registered:

        # Loading the Unit file and starting systemd service
        unit = Unit(b"gunicorn.service")
        unit.load()
        unit.Unit.Start(b"replace")
        spinner.info("Sleeping for 7 seconds and waiting for gunicorn to start")
        time.sleep(7)

        # If gunicorn has started, we should see a project_name.sock file
        if os.path.exists(
            nginx_answers["working_directory"]
            + "/"
            + nginx_answers["django_project_name"]
            + ".sock"
        ):
            spinner.succeed("Socket file found. Gunicorn has started.")
        else:
            spinner.fail(
                "gunicorn.sock file not found. Maybe gunicorn wasn't able to start :("
            )
Example #18
0
    def boot(self, **kwargs):
        import json
        import logging
        import pystemd.journal
        from pathlib import Path
        from pystemd.systemd1 import Unit

        CONFIG = '/opt/photobooth/conf/custom/trigger.json'
        unit = Unit(b'graphical.target')
        unit.load()
        config = Path(CONFIG)
        color = 'black'
        brightness = 0

        status = (unit.Unit.ActiveState).decode()
        while status != 'active':
            pystemd.journal.sendv(f'PRIORITY={logging.INFO}',
                                  MESSAGE=f'Graphical target: {status}',
                                  SYSLOG_IDENTIFIER='ledpanel')
            self.pulsate('blue', start_brightness=0.1)
            status = (unit.Unit.ActiveState).decode()
        pystemd.journal.sendv(f'PRIORITY={logging.INFO}',
                              MESSAGE=f'Graphical target: {status}',
                              SYSLOG_IDENTIFIER='ledpanel')

        self.clear()
        default_set = False
        if config.exists():
            with config.open() as fin:
                for action in json.load(fin)['actions']:
                    if action['trigger'] == 'default' and not default_set:
                        for sub in action['ledpanel']:
                            if sub['name'] == 'default' and not default_set:
                                for slot in sub['slots']:
                                    self.setPanelColor(slot['color'])
                                    self.setBrightness(
                                        float(slot['brightness']))
                                    default_set = True
        if not default_set:
            self.setPanelColor(color)
            self.setBrightness(brightness)
    def is_server_running(self) -> bool:
        with DBus(user_mode=True) as bus, \
            Unit(self.__config.get_system_service_unit_name(), \
            bus=bus, _autoload=True) as service:
    
            if service.Unit.ActiveState == b'active':
                return True

            return False

        print('Can\t read server state via Dbus!')
        return False
    def stop_server(self) -> bool:
        with DBus(user_mode=True) as bus, \
            Unit(self.__config.get_system_service_unit_name(), \
            bus=bus, _autoload=True) as service:
    
            try:
                service.Unit.Stop(b"replace")
            except Exception as e:
                print(f"Can't stop server: {e}")
                return False

            return True

        print('Can\t read server state via Dbus!')
        return False
Example #21
0
def monitor(name):

    unit = Unit(name)

    with DBus() as bus:

        bus.match_signal(
            unit.destination,
            unit.path,
            b"org.freedesktop.DBus.Properties",
            b"PropertiesChanged",
            process,  # callback for this message
            STATE,  # maybe pass custom python objects as userdata?
        )
        fd = bus.get_fd()

        while not STATE.EXIT:
            select.select([fd], [], [])  # wait for message
            bus.process()  # execute all methods (driver)
Example #22
0
def full_example():
    with Unit(b"postfix.service") as sd_unit:
        print("ConditionTimestamp", sd_unit.Unit.ConditionTimestamp)
        print("StopWhenUnneeded", sd_unit.Unit.StopWhenUnneeded)
        print("StartLimitAction", sd_unit.Unit.StartLimitAction)
        print("StartLimitBurst", sd_unit.Unit.StartLimitBurst)
        print("StartupBlockIOWeight", sd_unit.Service.StartupBlockIOWeight)
        print("SyslogPriority", sd_unit.Service.SyslogPriority)
        print("SyslogFacility", sd_unit.Service.SyslogFacility)
        print("SyslogLevelPrefix", sd_unit.Service.SyslogLevelPrefix)
        print("After", sd_unit.Unit.After)
        print("Conditions", sd_unit.Unit.Conditions)
        print("Job", sd_unit.Unit.Job)
        print("InvocationID", sd_unit.Unit.InvocationID)
        print("ExecStart", sd_unit.Service.ExecStart)

        # next one require sudo powers!
        if os.geteuid() == 0:
            print(".GetProcesses", sd_unit.Service.GetProcesses())
            print(".Start(b'replace')", sd_unit.Unit.Start(b"replace"))
        else:
            print("no root user, no complex method for you!")

        print(sd_unit.Service._methods_xml["GetProcesses"].toxml())
Example #23
0
except ImportError:
    if distro.name() == 'Fedora':
        system("pip install python3-dnf")
        import dnf

### install dev packages
try:
    from pystemd.systemd1 import Unit
except ImportError:
    if distro.name() == 'Fedora':
        system("dnf install python3-devel")
        system("dnf install systemd-libs")
        system("dnf install python3-pystemd")
        from pystemd.systemd1 import Unit

docker_service = Unit(b'docker.service')
docker_service.load()
if docker_service.ActiveState == b'inactive':
    docker_service.Start(b'docker.service')

### variavel global para usar o docker
client = docker.from_env()


### Gera o hash que serĂ¡ usado como senha no db
def HashGen():
    STAGING_KEY = "RANDOM"
    set_chars = string.ascii_letters + string.digits + string.punctuation
    STAGING_KEY = ''.join(
        [random.SystemRandom().choice(set_chars) for _ in range(128)])
    hash = hashlib.md5(STAGING_KEY.encode("UTF-8")).hexdigest()
Example #24
0
 def check_control_request(self):
     try:
         if not self.api_token:
             print('PhotomateurAPI ERROR: api_token missing')
         else:
             response = self.post('device/control/status')
             response_msg = response.get('message', None)
             if response_msg != None:
                 pass
                 # print(f'Control request response: {response_msg}')
             else:
                 print(f'PhotomateurAPI ERROR - control: {response}')
             unit = Unit(b'ngrok@ssh\\x20http.service')
             unit.load()
             status = (unit.Unit.ActiveState).decode()
             if response_msg == 1 and status != 'active':
                 print('Initiating remote control...')
                 cmd = 'systemctl start ngrok@"ssh\\x20http".service'
                 run_command(cmd)
                 retries = 10
                 while status != 'active' and retries > 0:
                     time.sleep(1)
                     retries -= 1
                     status = (unit.Unit.ActiveState).decode()
                 if status == 'active':
                     tunnels_detailed = requests.get(
                         'http://127.0.0.1:4040/api/tunnels').json(
                         )['tunnels']
                     tunnels = dict([(t['public_url'].split(":")[0],
                                      t['public_url'])
                                     for t in tunnels_detailed])
                     self.post('device/control/callback', {
                         'status': 'up',
                         'tunnels': json.dumps(tunnels)
                     })
                 else:
                     self.post('device/control/callback', {
                         'status': 'error',
                         'tunnels': json.dumps({})
                     })
             elif response_msg == 1 and status == 'active':
                 tunnels_detailed = requests.get(
                     'http://127.0.0.1:4040/api/tunnels').json()['tunnels']
                 tunnels = dict([(t['public_url'].split(":")[0],
                                  t['public_url'])
                                 for t in tunnels_detailed])
                 self.post('device/control/callback', {
                     'status': 'up',
                     'tunnels': json.dumps(tunnels)
                 })
             elif response_msg == 0 and status == 'active':
                 print('Exiting remote control...')
                 cmd = 'systemctl stop ngrok@"ssh\\x20http".service'
                 run_command(cmd)
                 self.post('device/control/callback', {
                     'status': 'down',
                     'tunnels': json.dumps({})
                 })
             elif response_msg == 0 and status != 'active':
                 pass
     except Exception as err:
         print(f'PhotomateurAPI ERROR: {err}')
Example #25
0
from pystemd.systemd1 import Unit
import time

unit_local = Unit(b'pulseaudio-linein-local.service')
unit_local.load()

unit_stream = Unit(b'pulseaudio-linein-stream.service')
unit_stream.load()

print(unit_local.ActiveState)
print(unit_stream.ActiveState)

if (unit_local.ActiveState == b'active'):
    print('Stopping local...')
    unit_local.Stop(b'replace')
    print('Starting stream...')
    unit_stream.Start(b'replace')
elif (unit_stream.ActiveState == b'active'):
    print('Stopping stream...')
    unit_stream.Stop(b'replace')
    print('Starting local...')
    unit_local.Start(b'replace')
else:
    unit_stream.Start(b'replace')

print(unit_local.ActiveState)
print(unit_stream.ActiveState)
Example #26
0
 def _get_systemd_unit(self):
     unit = Unit(self._get_systemd_unit_name())
     unit.load()
     return unit
Example #27
0
def run(
    cmd,
    address=None,
    service_type=None,
    name=None,
    user=None,
    user_mode=os.getuid() != 0,
    nice=None,
    runtime_max_sec=None,
    env=None,
    extra=None,
    cwd=None,
    machine=None,
    wait=False,
    remain_after_exit=False,
    collect=False,
    raise_on_fail=False,
    pty=None,
    pty_master=None,
    pty_path=None,
    stdin=None,
    stdout=None,
    stderr=None,
    _wait_polling=None,
    slice_=None,
    stop_cmd=None,
    stop_post_cmd=None,
    start_pre_cmd=None,
    start_post_cmd=None,
):
    """
    pystemd.run imitates systemd-run, but with a pythonic feel to it.

    Options:

        cmd: Array with the command to execute (absolute path only)
        stop_cmd: Array with the command to execute on stop (absolute path only)
        stop_post_cmd: Array with the command to execute after stop (absolute path only)
        start_pre_cmd: Array with the command to execute on pre start (absolute path only)
        start_post_cmd: Array with the command to execute on on post start (absolute path only)
        address: A custom dbus socket address
        service_type: Set the unit type, e.g. notify, oneshot. If you dont give a
            value, the unit type will be whatever systemd thinks is the default.
        name: Name of the unit. If not provided, it will be autogenerated.
        user: Username to execute the command, defaults to current user.
        user_mode: Equivalent to running `systemd-run --user`. Defaults to True
            if current user id not root (uid = 0).
        nice: Nice level to run the command.
        runtime_max_sec: Set seconds before sending a sigterm to the process, if
           the service does not die nicely, it will send a sigkill.
        env: A dict with environment variables.
        extra: If you know what you are doing, you can pass extra configuration
            settings to the start_transient_unit method.
        machine: Machine name to execute the command, by default we connect to
            the host's dbus.
        wait: Wait for command completion before returning control, defaults
            to False.
        remain_after_exit: If True, the transient unit will remain after cmd
            has finished, also if true, this methods will return
            pystemd.systemd1.Unit object. defaults to False and this method
            returns None and the unit will be gone as soon as is done.
        collect: Unload unit after it ran, even when failed.
        raise_on_fail: Will raise a PystemdRunError is cmd exit with non 0
            status code, it won't take affect unless you set wait=True,
            defaults to False.
        pty: Set this variable to True if you want a pty to be created. if you
            pass a `machine`, the pty will be created in the machine. Setting
            this value will ignore whatever you set in pty_master and pty_path.
        pty_master: It has only meaning if you pass a pty_path also, this file
            descriptor will be used to forward redirection to `stdin` and `stdout`
            if no `stdin` or `stdout` is present, then this value does nothing.
        pty_path: Setting this value will pass this pty_path to the created
            process and will connect the process stdin, stdout and stderr to this
            pty. by itself it only ensure that your process has a real pty that
            can have ioctl operation over it. if you also pass a `pty_master`,
            `stdin` and `stdout` the pty forwars is handle for you.
        stdin: Specify a file descriptor for stdin. By default this is `None`
            and your unit will not have a stdin. If you set pty = True, or set a
            `pty_master` then that pty will be read and forwarded to this file
            descriptor.
        stdout: Specify a file descriptor for stdout. By default this is `None`
            and your unit will not have a stdout. If you set pty = True, or set a
            `pty_master` then that pty will be read and forwarded to this file
            descriptor.
        stderr: Specify a file descriptor for stderr. By default this is `None`
            and your unit will not have a stderr.
        slice_: the slice under you want to run the unit.

    More info and examples in:
    https://github.com/facebookincubator/pystemd/blob/master/_docs/pystemd.run.md

    """

    def bus_factory():
        if address:
            return DBusAddress(x2char_star(address))
        elif machine:
            return DBusMachine(x2char_star(machine))
        else:
            return DBus(user_mode=user_mode)

    name = x2char_star(name or "pystemd{}.service".format(uuid.uuid4().hex))
    runtime_max_usec = (runtime_max_sec or 0) * 10**6 or runtime_max_sec

    stdin, stdout, stderr = get_fno(stdin), get_fno(stdout), get_fno(stderr)
    env = env or {}
    unit_properties = {}
    selectors = []

    extra = extra or {}
    start_cmd = x2cmdlist(cmd, False) + extra.pop(b"ExecStart", [])
    stop_cmd = x2cmdlist(stop_cmd, False) + extra.pop(b"ExecStop", [])
    stop_post_cmd = x2cmdlist(stop_post_cmd, False) + extra.pop(b"ExecStopPost", [])
    start_pre_cmd = x2cmdlist(start_pre_cmd, False) + extra.pop(b"ExecStartPre", [])
    start_post_cmd = x2cmdlist(start_post_cmd, False) + extra.pop(b"ExecStartPost", [])

    if user_mode:
        _wait_polling = _wait_polling or 0.5

    with CExit() as ctexit, bus_factory() as bus, SDManager(bus=bus) as manager:

        if pty:
            if machine:
                with pystemd.machine1.Machine(machine) as m:
                    pty_master, pty_path = m.Machine.OpenPTY()
            else:
                pty_master, pty_follower = ptylib.openpty()
                pty_path = os.ttyname(pty_follower).encode()
                ctexit.register(os.close, pty_master)

        if slice_:
            unit_properties[b"Slice"] = x2char_star(slice_)

        if pty_path:
            unit_properties.update(
                {
                    b"StandardInput": b"tty",
                    b"StandardOutput": b"tty",
                    b"StandardError": b"tty",
                    b"TTYPath": pty_path,
                }
            )

            if None not in (stdin, pty_master):
                # lets set raw mode for stdin so we can forward input without
                # waiting for a new line, but lets also make sure we return the
                # attributes as they where after this method is done
                stdin_attrs = tty.tcgetattr(stdin)
                tty.setraw(stdin)
                ctexit.register(tty.tcsetattr, stdin, tty.TCSAFLUSH, stdin_attrs)
                selectors.append(stdin)

            if None not in (stdout, pty_master):
                if os.getenv("TERM"):
                    env[b"TERM"] = env.get(b"TERM", os.getenv("TERM").encode())

                selectors.append(pty_master)
                # lets be a friend and set the size of the pty.
                winsize = fcntl.ioctl(
                    stdout, termios.TIOCGWINSZ, struct.pack("HHHH", 0, 0, 0, 0)
                )
                fcntl.ioctl(pty_master, termios.TIOCSWINSZ, winsize)
        else:
            unit_properties.update(
                {
                    b"StandardInputFileDescriptor": get_fno(stdin) if stdin else stdin,
                    b"StandardOutputFileDescriptor": get_fno(stdout)
                    if stdout
                    else stdout,
                    b"StandardErrorFileDescriptor": get_fno(stderr)
                    if stderr
                    else stderr,
                }
            )

        unit_properties.update(
            {
                b"Type": service_type,
                b"Description": b"pystemd: " + name,
                b"ExecStartPre": start_pre_cmd or None,
                b"ExecStart": start_cmd,
                b"ExecStartPost": start_post_cmd or None,
                b"ExecStop": stop_cmd or None,
                b"ExecStopPost": stop_post_cmd or None,
                b"RemainAfterExit": remain_after_exit,
                b"CollectMode": b"inactive-or-failed" if collect else None,
                b"WorkingDirectory": cwd,
                b"User": user,
                b"Nice": nice,
                b"RuntimeMaxUSec": runtime_max_usec,
                b"Environment": [
                    b"%s=%s" % (x2char_star(key), x2char_star(value))
                    for key, value in env.items()
                ]
                or None,
            }
        )

        unit_properties.update(extra)
        unit_properties = {k: v for k, v in unit_properties.items() if v is not None}

        unit = Unit(name, bus=bus, _autoload=True)
        if wait:
            mstr = (
                (
                    "type='signal',"
                    "sender='org.freedesktop.systemd1',"
                    "path='{}',"
                    "interface='org.freedesktop.DBus.Properties',"
                    "member='PropertiesChanged'"
                )
                .format(unit.path.decode())
                .encode()
            )

            monbus = bus_factory()
            monbus.open()
            ctexit.register(monbus.close)

            monitor = pystemd.DBus.Manager(bus=monbus, _autoload=True)
            monitor.Monitoring.BecomeMonitor([mstr], 0)

            monitor_fd = monbus.get_fd()
            selectors.append(monitor_fd)

        # start the process
        unit_start_job = manager.Manager.StartTransientUnit(
            name, b"fail", unit_properties
        )

        while wait:
            _in, _, _ = select.select(selectors, [], [], _wait_polling)

            if stdin in _in:
                data = os.read(stdin, 1024)
                os.write(pty_master, data)

            if pty_master in _in:

                try:
                    data = os.read(pty_master, 1024)
                except OSError:
                    selectors.remove(pty_master)
                else:
                    os.write(stdout, data)

            if monitor_fd in _in:
                m = monbus.process()
                if m.is_empty():
                    continue

                m.process_reply(False)
                if (
                    m.get_path() == unit.path
                    and m.body[0] == b"org.freedesktop.systemd1.Unit"
                ):
                    _, message_job_path = m.body[1].get(b"Job", (0, b"/"))

                    if (
                        message_job_path != unit_start_job
                        and m.body[1].get(b"SubState") in EXIT_SUBSTATES
                    ):
                        break

            if _wait_polling and not _in and unit.Service.MainPID == 0:
                # on usermode the subscribe to events does not work that well
                # this is a temporary hack. you can always not wait on usermode.
                break

        if raise_on_fail:
            if unit.Service.ExecMainStatus:
                raise PystemdRunError(
                    "cmd {} exited with status {}".format(
                        cmd, unit.Service.ExecMainStatus
                    )
                )

        unit.load()
        unit.bus_context = bus_factory
        return unit
 def _get_systemd_unit(self):
     unit = Unit(f"{self.systemd_unit}.service".encode())
     unit.load()
     return unit
Example #29
0
def test_docker_deamon_is_running():
    unit = Unit(b'docker.service')
    unit.load()
    assert unit.Unit.ActiveState == b'active', "Docker deamon is not running"
Example #30
0
def reload_ats_unit(unit_name=b'trafficserver-tls.service'):
    ats_unit = Unit(unit_name)
    ats_unit.load()
    if ats_unit.Unit.ActiveState == b'active':
        ats_unit.Unit.Reload(b'replace')