Example #1
0
def create_service_template(args):
    here = os.path.abspath(".")
    fname, extra_args = args.fname_or_cmd.split()[0], " ".join(
        args.fname_or_cmd.split()[1:])
    binary, cmd = get_cmd_from_filename(fname)
    service_name = fname + "_" + here.split("/")[-1] if binary else fname
    service_name = to_sn(service_name)
    fname = fname + " "
    # other binary
    if binary:
        fname = ""
    if args.notify_cmd != "-1":
        on_failure = "OnFailure={}-onfailure@%i.service".format(
            args.notify_cmd)
    else:
        on_failure = ""
    timer = run_quiet("systemd-analyze calendar '{}'".format(args.timer))
    if bool(timer):
        service_type = "oneshot"
        restart = ""
        part_of = ""
    else:
        service_type = "simple"
        restart = "Restart=always\nRestartSec={delay}".format(delay=args.delay)
        part_of = "PartOf={service_name}_monitor.service".format(
            service_name=service_name)
    service = ("""
    [Unit]
    Description={service_name} service (generated by sysdm)
    After=network-online.target
    {part_of}
    {on_failure}

    [Service]
    {user_and_group}
    Type={service_type}
    {restart}
    ExecStart={cmd} {fname} {extra_args}
    WorkingDirectory={here}

    [Install]
    WantedBy=multi-user.target
    """.replace("\n    ", "\n").format(
        service_name=service_name,
        cmd=cmd,
        fname=fname,
        extra_args=extra_args,
        here=here,
        restart=restart,
        part_of=part_of,
        on_failure=on_failure,
        service_type=service_type,
        user_and_group=user_and_group_if_sudo(args),
    ).strip())
    return service_name, service
Example #2
0
    def view(self, unit: str):
        """
        Monitor a unit

        :param unit: File/cmd/unit to observe. Dots will be replaced with _ automatically
        """
        service_name = to_sn(unit)
        if not os.path.exists(self.systempath + "/" + service_name +
                              ".service"):
            print(
                "Service file does not exist. You can start by running:\n\n    sysdm create {}\n\nto create a service or run:\n\n    sysdm ls\n\nto see the services already created by sysdm."
                .format(unit))
            sys.exit(1)
        monitor(service_name, self.systempath)
Example #3
0
def create_service_template(fname_or_cmd,
                            notifier,
                            timer,
                            delay,
                            root,
                            killaftertimeout,
                            restart,
                            workdir: str = "",
                            env_vars=[]):
    here = workdir or os.path.abspath(".")
    fname, extra_args = fname_or_cmd.split()[0], " ".join(
        fname_or_cmd.split()[1:])
    binary, cmd = get_cmd_from_filename(fname)
    service_name = get_service_name(fname_or_cmd) + "_" + here.split(
        "/")[-1] if binary else fname
    service_name = to_sn(service_name)
    fname = fname + " "
    start_info = ""
    # other binary
    if binary:
        fname = ""
    if notifier is not None:
        on_failure = "OnFailure={}-onfailure@%i.service".format(notifier)
    else:
        on_failure = ""
    if timer is not None:
        timer = run_quiet("systemd-analyze calendar '{}'".format(timer))
    if bool(timer):
        service_type = "oneshot"
        restart = ""
        part_of = ""
    else:
        service_type = "simple"
        start_info = "StartLimitBurst=2\nStartLimitIntervalSec=15s" if restart else ""
        restart = "Restart=always\nRestartSec={delay}".format(
            delay=delay) if restart else ""
        part_of = "PartOf={service_name}_monitor.service".format(
            service_name=service_name)
    user_and_group = user_and_group_if_sudo(root)
    if timer:
        install = ""
    else:
        wanted_by = "multi-user.target" if user_and_group.strip(
        ) else "default.target"
        wanted_by += " " + service_name + "_monitor.service"
        install = "[Install]\nWantedBy={wanted_by}".format(wanted_by=wanted_by)
    env_var_section = "\n".join([
        f'Environment={x if "=" in x else x + "=" + os.environ[x]}'
        for x in env_vars
    ])
    service = ("""
    [Unit]
    Description={service_name} service (generated by sysdm)
    After=network-online.target
    {part_of}
    {on_failure}
    {start_info}

    [Service]
    {user_and_group}
    Type={service_type}
    {restart}
    TimeoutStopSec={killaftertimeout}
    ExecStart={cmd} {fname} {extra_args}
    WorkingDirectory={here}
    Environment=PYTHONUNBUFFERED=1
    {env_var_section}

    {install}
    """.replace("\n    ", "\n").format(**locals()).strip())
    return service_name, service
Example #4
0
def create_service_template(fname_or_cmd, notify_cmd, timer, delay, root,
                            killaftertimeout):
    here = os.path.abspath(".")
    fname, extra_args = fname_or_cmd.split()[0], " ".join(
        fname_or_cmd.split()[1:])
    binary, cmd = get_cmd_from_filename(fname)
    service_name = fname + "_" + here.split("/")[-1] if binary else fname
    service_name = to_sn(service_name)
    fname = fname + " "
    # other binary
    if binary:
        fname = ""
    if notify_cmd != "-1":
        on_failure = "OnFailure={}-onfailure@%i.service".format(notify_cmd)
    else:
        on_failure = ""
    if timer is not None:
        timer = run_quiet("systemd-analyze calendar '{}'".format(timer))
    if bool(timer):
        service_type = "oneshot"
        restart = ""
        part_of = ""
    else:
        service_type = "simple"
        restart = "Restart=always\nRestartSec={delay}".format(delay=delay)
        part_of = "PartOf={service_name}_monitor.service".format(
            service_name=service_name)
    user_and_group = user_and_group_if_sudo(root)
    if timer:
        install = ""
    else:
        wanted_by = "multi-user.target" if user_and_group.strip(
        ) else "default.target"
        wanted_by += " " + service_name + "_monitor.service"
        install = "[Install]\nWantedBy={wanted_by}".format(wanted_by=wanted_by)
    service = ("""
    [Unit]
    Description={service_name} service (generated by sysdm)
    After=network-online.target
    {part_of}
    {on_failure}

    [Service]
    {user_and_group}
    Type={service_type}
    {restart}
    TimeoutStopSec={killaftertimeout}
    ExecStart={cmd} {fname} {extra_args}
    WorkingDirectory={here}

    {install}
    """.replace("\n    ", "\n").format(
        service_name=service_name,
        cmd=cmd,
        fname=fname,
        extra_args=extra_args,
        here=here,
        restart=restart,
        part_of=part_of,
        on_failure=on_failure,
        service_type=service_type,
        user_and_group=user_and_group,
        install=install,
        killaftertimeout=killaftertimeout,
    ).strip())
    return service_name, service
Example #5
0
def _main():
    parser, args = get_argparser()
    try:
        if args.systempath is None:
            args.systempath = "/etc/systemd/system" if IS_SUDO else "~/.config/systemd/user"
        args.systempath = os.path.expanduser(args.systempath)
        args.systempath = args.systempath.rstrip("/")
        try:
            os.makedirs(args.systempath)
        except FileExistsError:
            pass
    except AttributeError:
        # most commands have it, but not all
        pass
    if args.command == "create":
        print("Creating systemd unit...")
        service_name = install(args)
        print("Done")
        if not args.nolist:
            monitor(service_name, args.systempath)
    elif args.command == "view":
        service_name = to_sn(args.unit)
        if not os.path.exists(args.systempath + "/" + service_name +
                              ".service"):
            print(
                "Service file does not exist. You can start by running:\n\n    sysdm create {}\n\nto create a service or run:\n\n    sysdm ls\n\nto see the services already created by sysdm."
                .format(args.unit))
            sys.exit(1)
        monitor(service_name, args.systempath)
    elif args.command == "run":
        if args.unit is None:
            units = ls(args)
            unit = choose_unit(args.systempath, units)
            if unit is None:
                sys.exit()
        else:
            unit = args.unit
        with open(args.systempath + "/" + unit + ".service") as f:
            for line in f:
                line = line.strip()
                if line.startswith("ExecStart="):
                    cmd = line.split("ExecStart=")[1]
                    if args.debug:
                        cmd = cmd.replace("python3 -u", "python3 -u -m pdb")
                        cmd = cmd.replace("python -u", "python -u -m pdb")
                elif line.startswith("WorkingDirectory="):
                    cwd = line.split("WorkingDirectory=")[1]
            os.system("cd {!r} && {}".format(cwd, cmd))
    elif args.command == "show_unit":
        show(args)
    elif args.command == "reload":
        systemctl("daemon-reload")
    elif args.command == "watch":
        watch(args)
    elif args.command == "delete":
        if args.unit is None:
            units = ls(args)
            unit = choose_unit(args.systempath, units)
            if unit is None:
                sys.exit()
            inp = input(
                "Are you sure you want to delete '{}'? [y/N]: ".format(unit))
            if inp.lower().strip() != "y":
                print("Aborting")
                return
        else:
            unit = args.unit
        delete(unit, args.systempath)
    elif args.command == "edit":
        if args.unit is None:
            units = ls(args)
            unit = choose_unit(args.systempath, units)
            if unit is None:
                sys.exit()
        else:
            unit = args.unit
        unit = unit if unit.endswith(".service") else unit + ".service"
        os.system("$EDITOR {}/{}".format(args.systempath, unit))
    elif args.command == "ls":
        while True:
            units = ls(args)
            if units:
                unit = choose_unit(args.systempath, units)
                if unit is None:
                    sys.exit()
                monitor(unit, args.systempath)
            else:
                print(
                    "sysdm knows of no units. Why don't you make one? `sysdm create file_i_want_as_service.py`"
                )
                break
    else:
        parser.print_help(sys.stderr)
        sys.exit(1)