diff options
author | Christian Poessinger <christian@poessinger.com> | 2018-08-17 15:52:32 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-08-17 15:52:32 +0200 |
commit | f6836850812eb7826c40c866eb61a03e36f431ab (patch) | |
tree | 3373698e2dba150f2f7b305cb1512fa8c045d6c1 | |
parent | bb1f7d0cfd6b7ba96eb049e47e857fb92f6c09e5 (diff) | |
parent | 86088fa6e0816cb7e79ce497a89df2d004bc4764 (diff) | |
download | vyos-1x-f6836850812eb7826c40c866eb61a03e36f431ab.tar.gz vyos-1x-f6836850812eb7826c40c866eb61a03e36f431ab.zip |
Merge pull request #29 from runborg/current
T689: Rewritten poweroff/reboot script to use systemd-shutdownd service
-rw-r--r-- | op-mode-definitions/poweroff.xml | 38 | ||||
-rw-r--r-- | op-mode-definitions/reboot.xml | 38 | ||||
-rwxr-xr-x | src/op_mode/powerctrl.py | 142 |
3 files changed, 198 insertions, 20 deletions
diff --git a/op-mode-definitions/poweroff.xml b/op-mode-definitions/poweroff.xml index 07cea7927..ff27f4f4d 100644 --- a/op-mode-definitions/poweroff.xml +++ b/op-mode-definitions/poweroff.xml @@ -4,35 +4,53 @@ <properties> <help>Poweroff the system</help> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff</command> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --poweroff now</command> + <children> <leafNode name="now"> <properties> <help>Poweroff the system without confirmation</help> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff --now</command> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff now</command> </leafNode> - + <leafNode name="cancel"> <properties> <help>Cancel a pending poweroff</help> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff_cancel</command> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --cancel</command> </leafNode> + <tagNode name="in"> + <properties> + <help>Poweroff in X minutes</help> + <completionHelp> + <list><Minutes></list> + </completionHelp> + </properties> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3 $4</command> + + </tagNode> <tagNode name="at"> <properties> <help>Poweroff at a specific time</help> <completionHelp> - <list>HH:MM</list> - <list>MMDDYY</list> - <list>midnight</list> - <list>noon</list> + <list><HH:MM></list> </completionHelp> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff_at --at_time '$3'</command> - + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3</command> + <children> + <tagNode name="date"> + <properties> + <help>Poweroff at a specific date</help> + <completionHelp> + <list><DDMMYYYY> <DD/MM/YYYY> <DD.MM.YYYY> <DD:MM:YYYY></list> + </completionHelp> + </properties> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --poweroff $3 $5</command> + </tagNode> + </children> </tagNode> </children> diff --git a/op-mode-definitions/reboot.xml b/op-mode-definitions/reboot.xml index 2c5a85d95..340c8ca82 100644 --- a/op-mode-definitions/reboot.xml +++ b/op-mode-definitions/reboot.xml @@ -4,35 +4,53 @@ <properties> <help>Reboot the system</help> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-reboot.pl --action reboot</command> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --reboot now</command> + <children> <leafNode name="now"> <properties> <help>Reboot the system without confirmation</help> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-reboot.pl --action reboot --now</command> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot now</command> </leafNode> - + <leafNode name="cancel"> <properties> <help>Cancel a pending reboot</help> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-reboot.pl --action reboot_cancel</command> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --cancel</command> </leafNode> + <tagNode name="in"> + <properties> + <help>Reboot in X minutes</help> + <completionHelp> + <list><Minutes></list> + </completionHelp> + </properties> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3 $4</command> + + </tagNode> <tagNode name="at"> <properties> <help>Reboot at a specific time</help> <completionHelp> - <list>HH:MM</list> - <list>MMDDYY</list> - <list>midnight</list> - <list>noon</list> + <list><HH:MM></list> </completionHelp> </properties> - <command>/opt/vyatta/bin/sudo-users/vyatta-reboot.pl --action reboot_at --at_time '$3'</command> - + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3</command> + <children> + <tagNode name="date"> + <properties> + <help>Reboot at a specific date</help> + <completionHelp> + <list><DDMMYYYY> <DD/MM/YYYY> <DD.MM.YYYY> <DD:MM:YYYY></list> + </completionHelp> + </properties> + <command>sudo ${vyos_op_scripts_dir}/powerctrl.py --yes --reboot $3 $5</command> + </tagNode> + </children> </tagNode> </children> diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py new file mode 100755 index 000000000..f73d6c005 --- /dev/null +++ b/src/op_mode/powerctrl.py @@ -0,0 +1,142 @@ +#!/usr/bin/env python3 +import os +import sys +import argparse +from datetime import datetime, timedelta, time as type_time, date as type_date +from subprocess import check_output,CalledProcessError,STDOUT +import re + +def yn(msg, default=False): + default_msg = "[Y/n]" if default else "[y/N]" + while True: + sys.stdout.write("%s %s " % (msg,default_msg)) + c = input().lower() + if c == '': + return default + elif c in ("y", "ye","yes"): + return True + elif c in ("n", "no"): + return False + else: + sys.stdout.write("Please respond with yes/y or no/n\n") + + +def valid_time(s): + try: + return datetime.strptime(s, "%H:%M").time() + except ValueError: + return None + + +def valid_date(s): + try: + return datetime.strptime(s, "%d%m%Y").date() + except ValueError: + try: + return datetime.strptime(s, "%d/%m/%Y").date() + except ValueError: + try: + return datetime.strptime(s, "%d.%m.%Y").date() + except ValueError: + try: + return datetime.strptime(s, "%d:%m:%Y").date() + except ValueError: + return None + + +def check_shutdown(): + try: + cmd = check_output(["/bin/systemctl","status","systemd-shutdownd.service"]) + #Shutodwn is scheduled + r = re.findall(r'Status: \"(.*)\"\n', cmd.decode())[0] + print(r) + except CalledProcessError as e: + #Shutdown is not scheduled + print("Shutdown is not scheduled") + +def cancel_shutdown(): + try: + cmd = check_output(["/sbin/shutdown","-c"]) + except CalledProcessError as e: + sys.exit("Error aborting shutdown: %s" % e) + +def execute_shutdown(time, reboot = True, ask=True): + if not ask: + action = "reboot" if reboot else "poweroff" + if not yn("Are you sure you want to %s this system?" % action): + sys.exit(0) + + action = "-r" if reboot else "-P" + + if len(time) == 0: + cmd = check_output(["/sbin/shutdown",action,"now"],stderr=STDOUT) + print(cmd.decode().split(",",1)[0]) + return + + # Try to extract date from the first argument + if len(time) == 1: + time = time[0].split(" ",1) + + if len(time) == 1: + ts=valid_time(time[0]) + if time[0].isdigit() or valid_time(time[0]): + cmd = check_output(["/sbin/shutdown",action,time[0]],stderr=STDOUT) + else: + sys.exit("Timestamp needs to be in format of 12:34") + + elif len(time) == 2: + ts = valid_time(time[0]) + ds = valid_date(time[1]) + if ts and ds: + t = datetime.combine(ds, ts) + td = t-datetime.now() + t2 = 1+int(td.total_seconds())//60 # Get total minutes + cmd = check_output(["/sbin/shutdown",action,str(t2)],stderr=STDOUT) + else: + sys.exit("Timestamp needs to be in format of 12:34\nDatestamp in the format of DD.MM.YY") + else: + sys.exit("Could not decode time and date") + + print(cmd.decode().split(",",1)[0]) + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument("--yes", "-y", + help="dont as for shutdown", + action="store_true", + dest="yes") + action = parser.add_mutually_exclusive_group(required=True) + action.add_argument("--reboot", "-r", + help="Reboot the system", + nargs="*", + metavar="Minutes|HH:MM") + + action.add_argument("--poweroff", "-p", + help="Poweroff the system", + nargs="*", + metavar="Minutes|HH:MM") + + action.add_argument("--cancel", "-c", + help="Cancel pending shutdown", + action="store_true") + + action.add_argument("--check", + help="Check pending chutdown", + action="store_true") + args = parser.parse_args() + + try: + if args.reboot: + execute_shutdown(args.reboot, reboot=True, ask=args.yes) + if args.poweroff: + execute_shutdown(args.poweroff, reboot=False,ask=args.yes) + if args.cancel: + cancel_shutdown() + if args.check: + check_shutdown() + except KeyboardInterrupt: + sys.exit("Interrupted") + + +if __name__ == "__main__": + main() |