Allow housekeeping task creation, also fix double unix task entries

This commit is contained in:
deajan 2024-08-26 22:15:32 +02:00
parent eb71a8d2a8
commit 59c69a9b0a
5 changed files with 79 additions and 25 deletions

View file

@ -280,11 +280,18 @@ This is free software, and you are welcome to redistribute it under certain cond
help="Create a new encryption key, requires a file path",
)
parser.add_argument(
"--create-scheduled-task",
"--create-backup-scheduled-task",
type=str,
default=None,
required=False,
help="Create a scheduled task, specify an argument interval via interval=minutes, or hour=hour,minute=minute for a daily task",
help="Create a scheduled backup task, specify an argument interval via interval=minutes, or hour=hour,minute=minute for a daily task",
)
parser.add_argument(
"--create-housekeeping-scheduled-task",
type=str,
default=None,
required=False,
help="Create a scheduled housekeeping task, specify hour=hour,minute=minute for a daily task",
)
args = parser.parse_args()
@ -354,22 +361,26 @@ This is free software, and you are welcome to redistribute it under certain cond
json_error_logging(False, msg, "critical")
sys.exit(71)
if args.create_scheduled_task:
if args.create_backup_scheduled_task or args.create_housekeeping_scheduled_task:
try:
if "interval" in args.create_scheduled_task:
interval = args.create_scheduled_task.split("=")[1].strip()
result = create_scheduled_task(
config_file, interval_minutes=int(interval)
config_file, type="backup", interval_minutes=int(interval)
)
elif (
"hour" in args.create_scheduled_task
and "minute" in args.create_scheduled_task
):
if args.create_backup_scheduled_task:
type = "backup"
if args.create_housekeeping_scheduled_task:
type = "housekeeping"
hours, minutes = args.create_scheduled_task.split(",")
hour = hours.split("=")[1].strip()
minute = minutes.split("=")[1].strip()
result = create_scheduled_task(
config_file, hour=int(hour), minute=int(minute)
config_file, type=type, hour=int(hour), minute=int(minute)
)
if not result:
msg = "Scheduled task creation failed"

View file

@ -1921,18 +1921,29 @@ Google Cloud storage: GOOGLE_PROJECT_ID GOOGLE_APPLICATION_CREDENTIALS\n\
)
],
[
sg.Text(_t("config_gui.create_scheduled_task_every"), size=(40, 1)),
sg.Text(_t("config_gui.create_backup_scheduled_task_every"), size=(40, 1)),
sg.Input(key="scheduled_task_interval", size=(4, 1)),
sg.Text(_t("generic.minutes"), size=(10, 1)),
sg.Button(_t("generic.create"), key="create_interval_task"),
sg.Button(_t("generic.create"), key="create_backup_interval_task"),
],
[
sg.Text(_t("config_gui.create_scheduled_task_at"), size=(40, 1)),
sg.Text(_t("config_gui.create_backup_scheduled_task_at"), size=(40, 1)),
sg.Input(key="scheduled_task_hour", size=(4, 1)),
sg.Text(_t("generic.hours"), size=(10, 1)),
sg.Input(key="scheduled_task_minute", size=(4, 1)),
sg.Text(_t("generic.minutes"), size=(10, 1)),
sg.Button(_t("generic.create"), key="create_daily_task"),
sg.Button(_t("generic.create"), key="create_backup_daily_task"),
],
[
sg.HorizontalSeparator(),
],
[
sg.Text(_t("config_gui.create_housekeeping_scheduled_task_at"), size=(40, 1)),
sg.Input(key="scheduled_task_hour", size=(4, 1)),
sg.Text(_t("generic.hours"), size=(10, 1)),
sg.Input(key="scheduled_task_minute", size=(4, 1)),
sg.Text(_t("generic.minutes"), size=(10, 1)),
sg.Button(_t("generic.create"), key="create_housekeeping_daily_task"),
],
]
@ -2255,10 +2266,15 @@ Google Cloud storage: GOOGLE_PROJECT_ID GOOGLE_APPLICATION_CREDENTIALS\n\
)
update_global_gui(full_config, unencrypted=True)
continue
if event in ("create_interval_task", "create_daily_task"):
if event in ("create_backup_interval_task", "create_backup_daily_task", "create_housekeeping_daily_task"):
try:
if event == "create_housekeeping_daily_task":
type = "housekeeping"
else:
type = "backup"
result = create_scheduled_task(
config_file,
type=type,
values["scheduled_task_interval"],
values["scheduled_task_hour"],
values["scheduled_task_minute"],

View file

@ -7,7 +7,7 @@ __intname__ = "npbackup.task"
__author__ = "Orsiris de Jong"
__copyright__ = "Copyright (C) 2022-2024 NetInvent"
__license__ = "GPL-3.0-only"
__build__ = "2024081901"
__build__ = "2024082601"
import sys
@ -24,7 +24,7 @@ logger = getLogger()
def create_scheduled_task(
config_file: str, interval_minutes: int = None, hour: int = None, minute: int = None
config_file: str, type: str, interval_minutes: int = None, hour: int = None, minute: int = None
):
"""
Creates a scheduled task for NPBackup
@ -41,6 +41,10 @@ def create_scheduled_task(
except ValueError:
logger.error("Bogus interval given")
return False
if type not in ("backup", "housekeeping"):
logger.error("Undefined task type")
return False
if isinstance(interval_minutes, int) and interval_minutes < 1:
logger.error("Bogus interval given")
@ -59,16 +63,17 @@ def create_scheduled_task(
if os.name == "nt":
return create_scheduled_task_windows(
config_file, CURRENT_EXECUTABLE, interval_minutes, hour, minute
config_file, type, CURRENT_EXECUTABLE, interval_minutes, hour, minute
)
else:
return create_scheduled_task_unix(
config_file, CURRENT_EXECUTABLE, interval_minutes, hour, minute
config_file, type, CURRENT_EXECUTABLE, interval_minutes, hour, minute
)
def create_scheduled_task_unix(
config_file,
type,
cli_executable_path,
interval_minutes: int = None,
hour: int = None,
@ -80,11 +85,12 @@ def create_scheduled_task_unix(
else:
cli_executable_path = f'"{cli_executable_path}"'
cron_file = "/etc/cron.d/npbackup"
if interval_minutes is not None:
TASK_ARGS = f'-c "{config_file}" --backup --run-as-cli'
TASK_ARGS = f'-c "{config_file}" --{type} --run-as-cli'
trigger = f"*/{interval_minutes} * * * *"
elif hour is not None and minute is not None:
TASK_ARGS = f'-c "{config_file}" --backup --force --run-as-cli'
TASK_ARGS = f'-c "{config_file}" --{type} --force --run-as-cli'
trigger = f"{minute} {hour} * * * root"
else:
raise ValueError("Bogus trigger given")
@ -92,9 +98,24 @@ def create_scheduled_task_unix(
crontab_entry = (
f'{trigger} cd "{executable_dir}" && {cli_executable_path} {TASK_ARGS}\n'
)
crontab_file = []
try:
with open(cron_file, "r", encoding="utf-8") as file_handle:
current_crontab = file_handle.readlines()
for line in current_crontab:
if "--{type}" in line:
logger.info("Replacing existing task")
crontab_file.append(crontab_entry)
else:
crontab_file.append(line)
except OSError as exc:
crontab_file.append(crontab_entry)
try:
with open(cron_file, "w", encoding="utf-8") as file_handle:
file_handle.write(crontab_entry)
file_handle.writelines(crontab_file)
except OSError as exc:
logger.error("Could not write to file {}: {}".format(cron_file, exc))
return False
@ -104,6 +125,7 @@ def create_scheduled_task_unix(
def create_scheduled_task_windows(
config_file,
type,
cli_executable_path,
interval_minutes: int = None,
hour: int = None,
@ -117,8 +139,11 @@ def create_scheduled_task_windows(
runner = cli_executable_path
task_args = ""
temp_task_file = os.path.join(tempfile.gettempdir(), "backup_task.xml")
task_name = f"{PROGRAM_NAME} {type}"
if interval_minutes is not None:
task_args = f'{task_args}-c "{config_file}" --backup --run-as-cli'
task_args = f'{task_args}-c "{config_file}" --{type} --run-as-cli'
start_date = datetime.datetime.now().replace(microsecond=0).isoformat()
trigger = f"""<TimeTrigger>
<Repetition>
@ -205,15 +230,15 @@ def create_scheduled_task_windows(
# Setup task
command_runner(
'schtasks /DELETE /TN "{}" /F'.format(PROGRAM_NAME),
'schtasks /DELETE /TN "{}" /F'.format(task_name),
valid_exit_codes=[0, 1],
windows_no_window=True,
encoding="cp437",
)
logger.info("Creating scheduled task {}".format(PROGRAM_NAME))
logger.info("Creating scheduled task {}".format(task_name))
exit_code, output = command_runner(
'schtasks /CREATE /TN "{}" /XML "{}" /RU System /F'.format(
PROGRAM_NAME, temp_task_file
task_name, temp_task_file
),
windows_no_window=True,
encoding="cp437",

View file

@ -78,8 +78,9 @@ en:
auto_upgrade_failed: Auto upgrade procedure failed, see logs for further details
auto_upgrade_disabled: Auto upgrade is disabled or server is not reachable
create_scheduled_task_every: Create scheduled task every
create_scheduled_task_at: Create scheduled task at
create_backup_scheduled_task_every: Create scheduled backup task every
create_bakcup_scheduled_task_at: Create scheduled backup task every day at
create_housekeeping_schedule_task_at: Create housekeeping scheduled every day at
scheduled_task_explanation: Task can run at a given time to run a backup which is great to make server backups, or run every x minutes, but only run actual backup when more than maximum_backup_age minutes was reached, which is the best way to backup laptops which have flexible power on hours.
scheduled_task_creation_success: Scheduled task created successfuly
scheduled_task_creation_failure: Scheduled task could not be created. See logs for further info

View file

@ -79,8 +79,9 @@ fr:
auto_upgrade_failed: Procédure de mise à niveau échouée, veuillez consulter les journaux pour plus de détails
auto_upgrade_disabled: Mise à niveau automatique désactivée ou serveur injoignable
create_scheduled_task_every: Créer une tâche planifiée toutes les
create_scheduled_task_at: Créer une tâche planifiée à
create_backup_scheduled_task_every: Créer une tâche planifiée de sauvegarde toutes les
create_backup_scheduled_task_at: Créer une tâche planifiée de sauvegarde tous les jours à
create_housekeeping_schedule_task_at: Créer une tpache planifiée de maintenance tous les jours à
scheduled_task_explanation: Les tâches planifiées peuvent être crées à heure fixe pour réaliser des sauvegardes serveur, ou toutes les x minutes, auquel cas la sauvegarde aura lieue uniquement si le temps minimal entre deux sauvegardes est dépassé, ce qui est adapté aux ordinateurs portables qui ont des heures de travail flexibles.
scheduled_task_creation_success: Tâche planifiée crée avec succès
scheduled_task_creation_failure: Impossible de créer la tâche planifiée. Veuillez consulter les journaux pour plus de détails