From 425085f018709913b2ff7c73f51fac38ec0a28f5 Mon Sep 17 00:00:00 2001 From: shuki Date: Wed, 4 Mar 2026 04:30:42 +0200 Subject: [PATCH] Add Run Now button to schedules page Adds a "Run Now" button in each schedule's Actions column that triggers the backup in the background, logging to the same cron log file. Forks the process and redirects immediately. Co-Authored-By: Claude Opus 4.6 --- whm/gniza-whm/schedules.cgi | 83 ++++++++++++++++++++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/whm/gniza-whm/schedules.cgi b/whm/gniza-whm/schedules.cgi index d3d8285..592b7eb 100644 --- a/whm/gniza-whm/schedules.cgi +++ b/whm/gniza-whm/schedules.cgi @@ -22,6 +22,7 @@ if ($action eq 'add') { handle_add() } elsif ($action eq 'edit') { handle_edit() } elsif ($action eq 'delete') { handle_delete() } elsif ($action eq 'toggle_cron') { handle_toggle_cron() } +elsif ($action eq 'run_now') { handle_run_now() } else { handle_list() } exit; @@ -66,13 +67,21 @@ sub handle_list { print qq{}; print qq{}; print qq{}; - print qq{Edit }; + print qq{
}; + print qq{
}; + print qq{}; + print qq{}; + print GnizaWHM::UI::csrf_hidden_field(); + print qq{}; + print qq{
}; + print qq{Edit}; print qq{
}; print qq{}; print qq{}; print GnizaWHM::UI::csrf_hidden_field(); print qq{}; print qq{
}; + print qq{
}; print qq{}; print qq{\n}; } @@ -322,6 +331,78 @@ sub handle_delete { exit; } +# ── Run Now ────────────────────────────────────────────────── + +sub handle_run_now { + if ($method ne 'POST') { + print "Status: 302 Found\r\n"; + print "Location: schedules.cgi\r\n\r\n"; + exit; + } + + unless (GnizaWHM::UI::verify_csrf_token($form->{'gniza_csrf'})) { + GnizaWHM::UI::set_flash('error', 'Invalid or expired form token.'); + print "Status: 302 Found\r\n"; + print "Location: schedules.cgi\r\n\r\n"; + exit; + } + + my $name = $form->{'name'} // ''; + my $name_err = GnizaWHM::Validator::validate_schedule_name($name); + if ($name_err) { + GnizaWHM::UI::set_flash('error', 'Invalid schedule name.'); + print "Status: 302 Found\r\n"; + print "Location: schedules.cgi\r\n\r\n"; + exit; + } + + my $conf_path = GnizaWHM::UI::schedule_conf_path($name); + unless (-f $conf_path) { + GnizaWHM::UI::set_flash('error', "Schedule '$name' not found."); + print "Status: 302 Found\r\n"; + print "Location: schedules.cgi\r\n\r\n"; + exit; + } + + my $conf = GnizaWHM::Config::parse($conf_path, 'schedule'); + my $remotes = $conf->{REMOTES} // ''; + $remotes =~ s/^\s+|\s+$//g; + + # Build command + my @cmd = ('/usr/local/bin/gniza', 'backup'); + if ($remotes ne '') { + push @cmd, "--remote=$remotes"; + } + + my $log_file = "/var/log/gniza/cron-${name}.log"; + + # Fork to background + my $pid = fork(); + if (!defined $pid) { + GnizaWHM::UI::set_flash('error', "Failed to fork backup process: $!"); + print "Status: 302 Found\r\n"; + print "Location: schedules.cgi\r\n\r\n"; + exit; + } + + if ($pid == 0) { + # Child: detach and exec + close STDIN; + close STDOUT; + close STDERR; + open STDOUT, '>>', $log_file; + open STDERR, '>&', \*STDOUT; + exec @cmd; + exit 1; + } + + # Parent: don't wait, redirect immediately + GnizaWHM::UI::set_flash('success', "Backup started for schedule '$name'. Check Logs for progress."); + print "Status: 302 Found\r\n"; + print "Location: schedules.cgi\r\n\r\n"; + exit; +} + # ── Toggle Cron ────────────────────────────────────────────── sub handle_toggle_cron {