summaryrefslogtreecommitdiff
path: root/src/op_mode
diff options
context:
space:
mode:
authorDaniil Baturin <daniil@baturin.org>2019-12-09 23:14:55 +0100
committerDaniil Baturin <daniil@baturin.org>2019-12-09 23:14:55 +0100
commit7d8d04ae2fcdb6346029b9e4be2fefb2f0d2b309 (patch)
treedd24ece3d35fe3ccf5f50fa3f7660eeed1311e8d /src/op_mode
parent4d9e51a00545278a3390938b9c20eef3e5133862 (diff)
downloadvyos-1x-7d8d04ae2fcdb6346029b9e4be2fefb2f0d2b309.tar.gz
vyos-1x-7d8d04ae2fcdb6346029b9e4be2fefb2f0d2b309.zip
T1855, T1826: clean up the reboot/shutdown script.
Diffstat (limited to 'src/op_mode')
-rwxr-xr-xsrc/op_mode/powerctrl.py119
1 files changed, 58 insertions, 61 deletions
diff --git a/src/op_mode/powerctrl.py b/src/op_mode/powerctrl.py
index 2f6112fb7..8de25d752 100755
--- a/src/op_mode/powerctrl.py
+++ b/src/op_mode/powerctrl.py
@@ -22,65 +22,63 @@ import re
from datetime import datetime, timedelta, time as type_time, date as type_date
from subprocess import check_output, CalledProcessError, STDOUT
-
-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")
+from vyos.util import ask_yes_no
-def valid_time(s):
+def parse_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:
+def parse_date(s):
+ for fmt in ["%d%m%Y", "%d/%m/%Y", "%d.%m.%Y", "%d:%m:%Y", "%Y-%m-%d"]:
try:
- return datetime.strptime(s, "%d/%m/%Y").date()
+ return datetime.strptime(s, fmt).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
+ continue
+ # If nothing matched...
+ return None
+def get_shutdown_status():
+ try:
+ output = check_output(["/bin/systemctl", "status", "systemd-shutdownd.service"]).decode()
+ return output
+ except CalledProcessError:
+ 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")
+ output = get_shutdown_status()
+ if output:
+ r = re.findall(r'Status: \"(.*)\"\n', output)
+ if r:
+ # When available, that line is like
+ # Status: "Shutting down at Thu 1970-01-01 00:00:00 UTC (poweroff)..."
+ print(r[0])
+ else:
+ # Sometimes status string is not available immediately
+ # after service startup
+ print("Poweroff or reboot is scheduled")
+ else:
+ print("Poweroff or reboot is not scheduled")
def cancel_shutdown():
- try:
- cmd = check_output(["/sbin/shutdown","-c"])
- except CalledProcessError as e:
- sys.exit("Error aborting shutdown: %s" % e)
+ output = get_shutdown_status()
+ if output:
+ try:
+ timenow = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
+ cmd = check_output(["/sbin/shutdown","-c","--no-wall"])
+ message = "Scheduled reboot or poweroff has been cancelled %s" % timenow
+ os.system("wall %s" % message)
+ except CalledProcessError as e:
+ sys.exit("Could not cancel a reboot or poweroff: %s" % e)
+ else:
+ print("Reboot or poweroff is not scheduled")
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):
+ if not ask_yes_no("Are you sure you want to %s this system?" % action):
sys.exit(0)
action = "-r" if reboot else "-P"
@@ -93,32 +91,30 @@ def execute_shutdown(time, reboot = True, ask=True):
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)
+ elif len(time) == 1:
+ # Assume the argument is just time
+ ts = parse_time(time[0])
+ if ts:
+ cmd = check_output(["/sbin/shutdown", action, time[0]], stderr=STDOUT)
else:
- sys.exit("Timestamp needs to be in format of 12:34")
-
+ sys.exit("Invalid time \"{0}\". The valid format is HH:MM".format(time[0]))
elif len(time) == 2:
- ts = valid_time(time[0])
- ds = valid_date(time[1])
+ # Assume it's date and time
+ ts = parse_time(time[0])
+ ds = parse_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)
+ 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")
+ if not ts:
+ sys.exit("Invalid time \"{0}\". The valid format is HH:MM".format(time[0]))
+ else:
+ sys.exit("Invalid time \"{0}\". A valid format is YYYY-MM-DD [HH:MM]".format(time[1]))
else:
- sys.exit("Could not decode time and date")
-
- print(cmd.decode().split(",",1)[0])
+ sys.exit("Could not decode date and time. Valids formats are HH:MM or YYYY-MM-DD HH:MM")
+ check_shutdown()
def chk_vyatta_based_reboots():
### T870 commit-confirm is still using the vyatta code base, once gone, the code below can be removed
@@ -126,7 +122,7 @@ def chk_vyatta_based_reboots():
### name is the node of scheduled the job, commit-confirm checks for that
f = r'/var/run/confirm.job'
- if os .path.exists(f):
+ if os.path.exists(f):
jid = open(f).read().strip()
if jid != 0:
subprocess.call(['sudo', 'atrm', jid])
@@ -135,7 +131,7 @@ def chk_vyatta_based_reboots():
def main():
parser = argparse.ArgumentParser()
parser.add_argument("--yes", "-y",
- help="dont as for shutdown",
+ help="Do not ask for confirmation",
action="store_true",
dest="yes")
action = parser.add_mutually_exclusive_group(required=True)
@@ -173,3 +169,4 @@ def main():
if __name__ == "__main__":
main()
+