summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Poessinger <christian@poessinger.com>2018-08-17 15:52:32 +0200
committerGitHub <noreply@github.com>2018-08-17 15:52:32 +0200
commitf6836850812eb7826c40c866eb61a03e36f431ab (patch)
tree3373698e2dba150f2f7b305cb1512fa8c045d6c1
parentbb1f7d0cfd6b7ba96eb049e47e857fb92f6c09e5 (diff)
parent86088fa6e0816cb7e79ce497a89df2d004bc4764 (diff)
downloadvyos-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.xml38
-rw-r--r--op-mode-definitions/reboot.xml38
-rwxr-xr-xsrc/op_mode/powerctrl.py142
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>&lt;Minutes&gt;</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>&lt;HH:MM&gt;</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>&lt;DDMMYYYY&gt; &lt;DD/MM/YYYY&gt; &lt;DD.MM.YYYY&gt; &lt;DD:MM:YYYY&gt;</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>&lt;Minutes&gt;</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>&lt;HH:MM&gt;</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>&lt;DDMMYYYY&gt; &lt;DD/MM/YYYY&gt; &lt;DD.MM.YYYY&gt; &lt;DD:MM:YYYY&gt;</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()