summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am1
-rwxr-xr-xscripts/vyatta-poweroff.pl189
-rw-r--r--templates/poweroff/at/node.tag/node.def7
-rw-r--r--templates/poweroff/cancel/node.def2
-rw-r--r--templates/poweroff/node.def9
-rw-r--r--templates/poweroff/now/node.def5
6 files changed, 196 insertions, 17 deletions
diff --git a/Makefile.am b/Makefile.am
index d32cc56..410c419 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -60,6 +60,7 @@ sbin_SCRIPTS += scripts/vyatta-regen-unpriv-commands.sh
bin_sudo_users_SCRIPTS = scripts/vyatta-identify-interface.pl
bin_sudo_users_SCRIPTS += scripts/vyatta-delete-log-file.sh
bin_sudo_users_SCRIPTS += scripts/vyatta-reboot.pl
+bin_sudo_users_SCRIPTS += scripts/vyatta-poweroff.pl
bin_sudo_users_SCRIPTS += scripts/vyatta-op-dns-forwarding.pl
bin_sudo_users_SCRIPTS += scripts/vyatta-op-dynamic-dns.pl
bin_sudo_users_SCRIPTS += scripts/vyatta-clear-conntrack
diff --git a/scripts/vyatta-poweroff.pl b/scripts/vyatta-poweroff.pl
new file mode 100755
index 0000000..9103900
--- /dev/null
+++ b/scripts/vyatta-poweroff.pl
@@ -0,0 +1,189 @@
+#!/usr/bin/perl
+#
+# Module: vyatta-poweroff.pl
+#
+# **** License ****
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# This code was originally developed by Vyatta, Inc.
+# Portions created by Vyatta are Copyright (C) 2007 Vyatta, Inc.
+# All Rights Reserved.
+#
+# Based on the original vyatta-reboot script by Stig Thormodsrud
+#
+# Author: Alex Harpin
+# Date: Jan 2015
+# Description: Script to shutdown or schedule a shutdown
+#
+# **** End License ****
+#
+
+use lib "/opt/vyatta/share/perl5/";
+use Getopt::Long;
+use POSIX;
+use IO::Prompt;
+use Sys::Syslog qw(:standard :macros);
+
+use strict;
+use warnings;
+
+my $poweroff_job_file = '/var/run/poweroff.job';
+
+sub parse_at_output {
+ my @lines = @_;
+
+ foreach my $line (@lines) {
+ if ($line =~ /error/) {
+ return (1, '', '');
+ } elsif ($line =~ /job (\d+) (.*)$/) {
+ return (0, $1, $2);
+ }
+ }
+ return (1, '', '');
+}
+
+sub is_poweroff_pending {
+ if ( ! -f $poweroff_job_file) {
+ return (0, '');
+ }
+ my $job = `cat $poweroff_job_file`;
+ chomp $job;
+ my $line = `atq $job`;
+ if ($line =~ /\d+\s+(.*)\sa root$/) {
+ return (1, $1);
+ } else {
+ return (0, '');
+ }
+}
+
+sub do_poweroff {
+ my $login = shift;
+
+ syslog("warning", "Poweroff now requested by $login");
+ if (!system("sudo /sbin/shutdown -h now")) {
+ exec("sudo /usr/bin/killall sshd");
+ }
+}
+
+sub cancel_poweroff {
+ my ($login, $time) = @_;
+
+ my $job = `cat $poweroff_job_file`;
+ chomp $job;
+ system("atrm $job");
+ system("rm $poweroff_job_file");
+ syslog("warning", "Poweroff scheduled for [$time] - CANCELED by $login");
+}
+
+my ($action, $at_time, $now);
+GetOptions("action=s" => \$action,
+ "at_time=s" => \$at_time,
+ "now!" => \$now,
+);
+
+if (! defined $action) {
+ die "no action specified";
+}
+
+openlog($0, "", LOG_USER);
+my $login = getlogin() || getpwuid($<) || "unknown";
+
+if ($action eq "poweroff") {
+
+ my ($rc, $time) = is_poweroff_pending();
+ if ($rc) {
+ if (defined $now) {
+ cancel_poweroff($login, $time);
+ do_poweroff($login);
+ } else {
+ print "Poweroff already scheduled for [$time]\n";
+ exit 1;
+ }
+ }
+
+ if (defined $now) {
+ do_poweroff($login);
+ } else {
+ if (prompt("Proceed with poweroff? (Yes/No) [No] ", -ynd=>"n")) {
+ do_poweroff($login);
+ } else {
+ print "Poweroff canceled\n";
+ exit 1;
+ }
+ }
+}
+
+if ($action eq "poweroff_at") {
+ if (! -f '/usr/bin/at') {
+ die "Package [at] not installed";
+ }
+
+ if (! defined $at_time) {
+ die "no at_time specified";
+ }
+
+ my ($rc, $rtime) = is_poweroff_pending();
+ if ($rc) {
+ print "Poweroff already scheduled for [$rtime]\n";
+ exit 1;
+ }
+
+ my @lines = `echo true | at $at_time 2>&1`;
+ my ($err, $job, $time) = parse_at_output(@lines);
+ if ($err) {
+ print "Invalid time format [$at_time]\n";
+ exit 1;
+ }
+ system("atrm $job");
+
+ print "\nPoweroff scheduled for $time\n\n";
+ if (!prompt("Proceed with poweroff schedule? [confirm] ", -y1d=>"y")) {
+ print "Poweroff canceled\n";
+ exit 1;
+ }
+
+ @lines = `echo "sudo /sbin/shutdown -h now && sudo /usr/bin/killall sshd" | at $at_time 2>&1`;
+ ($err, $job, $time) = parse_at_output(@lines);
+ if ($err) {
+ print "Error: unable to schedule poweroff\n";
+ exit 1;
+ }
+ system("echo $job > $poweroff_job_file");
+ print "\nPoweroff scheduled for $time\n";
+ syslog("warning", "Poweroff scheduled for [$time] by $login");
+
+ exit 0;
+}
+
+if ($action eq "poweroff_cancel") {
+
+ my ($rc, $time) = is_poweroff_pending();
+ if (! $rc) {
+ print "No poweroff currently scheduled\n";
+ exit 1;
+ }
+ cancel_poweroff($login, $time);
+ print "Poweroff canceled\n";
+ exit 0;
+}
+
+if ($action eq "show_poweroff") {
+
+ my ($rc, $time) = is_poweroff_pending();
+ if ($rc) {
+ print "Poweroff scheduled for [$time]\n";
+ exit 0;
+ } else {
+ print "No poweroff currently scheduled\n";
+ }
+ exit 1;
+}
+
+exit 1;
diff --git a/templates/poweroff/at/node.tag/node.def b/templates/poweroff/at/node.tag/node.def
index ccc3b5b..932e04b 100644
--- a/templates/poweroff/at/node.tag/node.def
+++ b/templates/poweroff/at/node.tag/node.def
@@ -1,6 +1,3 @@
help: Poweroff the system at a future time
-allowed: echo -n '<HH:MM>' '<MMDDYY>' '+MM'
-run: if /opt/vyatta/bin/vyatta-gettime.pl $3 >/tmp/shutdown.at
- then (sudo /sbin/shutdown -h $3 &
- disown %?sudo ) >/dev/null 2>&1
- fi
+allowed: echo -n '<HH:MM>' '<MMDDYY>' '<midnight>' '<noon>'
+run: sudo /opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff_at --at_time "$3"
diff --git a/templates/poweroff/cancel/node.def b/templates/poweroff/cancel/node.def
index c08a72d..c45f17a 100644
--- a/templates/poweroff/cancel/node.def
+++ b/templates/poweroff/cancel/node.def
@@ -1,2 +1,2 @@
help: Cancel a pending poweroff
-run: sudo /sbin/shutdown -c
+run: sudo /opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff_cancel
diff --git a/templates/poweroff/node.def b/templates/poweroff/node.def
index 44b8301..ccb7338 100644
--- a/templates/poweroff/node.def
+++ b/templates/poweroff/node.def
@@ -1,9 +1,2 @@
help: Poweroff the system
-run: if [ "$VYATTA_PROCESS_CLIENT" == "gui2_rest" ]
- then
- sudo /sbin/shutdown -h now && sudo /usr/bin/killall sshd
- else
- ${vyatta_bindir}/yesno -n "Proceed with poweroff? (Yes/No) [No] " \
- && sudo /sbin/shutdown -h now && sudo /usr/bin/killall sshd
- fi
-
+run: sudo /opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff
diff --git a/templates/poweroff/now/node.def b/templates/poweroff/now/node.def
index d9902cb..6b67572 100644
--- a/templates/poweroff/now/node.def
+++ b/templates/poweroff/now/node.def
@@ -1,3 +1,2 @@
-help: Poweroff the system now [disruptive]
-run: sudo /sbin/shutdown -h now && sudo /usr/bin/killall sshd
-
+help: Poweroff the system without confirmation
+run: sudo /opt/vyatta/bin/sudo-users/vyatta-poweroff.pl --action poweroff --now