Skip to content

Commit 6e2fa88

Browse files
fix: improve file cleanup when the package is deleted
Before, we were neglecting to cleanup some dynamic files like forms, endpoints, caches and schemas. This change includes de-install tasks to handle cleanup of these files. This also improves the order of de-installation tasks to avoid package de-install warnings about missing files due to improper removal order.
1 parent 5e4429f commit 6e2fa88

File tree

3 files changed

+113
-28
lines changed

3 files changed

+113
-28
lines changed
Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,23 @@
11
#!/bin/sh
22

3-
if [ "${2}" != "DEINSTALL" ]; then
4-
exit 0
5-
fi
3+
if [ "${2}" == "DEINSTALL" ]; then
4+
# Remove forms and dispatcher schedules
5+
/usr/local/bin/php -f /usr/local/pkg/RESTAPI/.resources/scripts/manage.php removeforms
6+
/usr/local/bin/php -f /usr/local/pkg/RESTAPI/.resources/scripts/manage.php unscheduledispatchers
67

7-
# Unlink this package from pfSense
8-
/usr/local/bin/php -f /etc/rc.packages %%PORTNAME%% POST-DEINSTALL
8+
# Unlink this package from pfSense
9+
/usr/local/bin/php -f /etc/rc.packages %%PORTNAME%% POST-DEINSTALL
910

10-
# Remove the pfsense-RESTAPI command line tool
11-
/bin/rm /usr/local/bin/pfsense-restapi
11+
# Remove the pfsense-RESTAPI command line tool
12+
/bin/rm /usr/local/bin/pfsense-restapi
13+
fi
1214

13-
# Remove Endpoints
14-
rm -rf /usr/local/www/api/v2 2>/dev/null
15+
if [ "${2}" == "POST-DEINSTALL" ]; then
16+
# Remove other files and directories generated by the package
17+
printf "Removing endpoints, schemas, and caches..."
18+
find /usr/local/www/api/v2/ -depth 1 -not -name documentation -not -name schema -exec rm -rf {} +
19+
rm -rf /usr/local/www/api/v2/schema/*
20+
rm /usr/local/pkg/RESTAPI/.resources/cache/*
21+
rm /usr/local/pkg/RESTAPI/.resources/schemas/*
22+
printf " done.\n"
23+
fi

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/.resources/scripts/manage.php

Lines changed: 78 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,31 @@ function build_forms(): void {
8282
build_privs();
8383
}
8484

85+
/**
86+
* Removes Forms (UI pages) built by the REST API package.
87+
*/
88+
function remove_forms(): void {
89+
# Print that we are starting to remove forms
90+
print 'Removing forms... ';
91+
92+
# Import each form class
93+
foreach (glob('/usr/local/pkg/RESTAPI/Forms/*.inc') as $file) {
94+
# Import classes files and create object
95+
require_once $file;
96+
$form_class = '\\RESTAPI\\Forms\\' . str_replace('.inc', '', basename($file));
97+
$form_obj = new $form_class();
98+
99+
# Remove the form URL
100+
if (!$form_obj->delete_form_url()) {
101+
print "failed! ($form_obj->url)";
102+
exit(1);
103+
}
104+
}
105+
106+
# Print that the removal is done if we made it through the loop
107+
print 'done.' . PHP_EOL;
108+
}
109+
85110
/**
86111
* Automatically creates pfSense privileges for each Endpoint class defined in \RESTAPI\Endpoints and each Form class
87112
* defined in \RESTAPI\Forms.
@@ -181,6 +206,30 @@ function schedule_dispatchers(): void {
181206
}
182207
}
183208

209+
/**
210+
* Removes the cron jobs for all Dispatcher classes in \RESTAPI\Dispatchers and all Cache classes in \RESTAPI\Caches
211+
* with configured schedules.
212+
*/
213+
function unschedule_dispatchers(): void {
214+
# Variables
215+
$dispatchers = get_classes_from_namespace('\\RESTAPI\\Dispatchers\\');
216+
$caches = get_classes_from_namespace('\\RESTAPI\\Caches\\');
217+
218+
# Include both Dispatcher classes and Cache classes. Cache classes inherit from the Dispatcher class.
219+
$classes = array_merge($dispatchers, $caches);
220+
221+
# Loop through each defined Dispatcher class and remove the cron jobs for dispatchers with schedules
222+
foreach ($classes as $class) {
223+
$dispatcher = new $class();
224+
if ($dispatcher->schedule) {
225+
# Start removing the schedules
226+
echo "Removing schedule for $class... ";
227+
$dispatcher->remove_schedule();
228+
echo 'done.' . PHP_EOL;
229+
}
230+
}
231+
}
232+
184233
/**
185234
* Refreshes the cache file by obtaining new day for a given Cache object.
186235
* @param string|null $cache_name The shortname of the Cache class that should have its cache file refreshed.
@@ -367,7 +416,7 @@ function revert(string $tag): void {
367416
/**
368417
* Delete the REST API package and restart the webConfigurator to remove nginx changes.
369418
*/
370-
function delete() {
419+
function delete(): void {
371420
echo shell_exec('/usr/local/sbin/pkg-static delete -y pfSense-pkg-RESTAPI');
372421
echo shell_exec('/etc/rc.restart_webgui');
373422
}
@@ -400,31 +449,37 @@ function help(): void {
400449
echo 'SYNTAX:' . PHP_EOL;
401450
echo ' pfsense-restapi <command> <args>' . PHP_EOL;
402451
echo 'COMMANDS:' . PHP_EOL;
403-
echo ' version : Display the current package version and build information' . PHP_EOL;
404-
echo ' help : Display the help page (this page)' . PHP_EOL;
405-
echo ' buildendpoints : Build all REST API Endpoints included in this package' . PHP_EOL;
406-
echo ' buildforms : Build all REST API Forms included in this package' . PHP_EOL;
407-
echo ' buildprivs : Build all REST API privileges included in this package' . PHP_EOL;
408-
echo ' buildschemas : Build all Schema/documentation files' . PHP_EOL;
409-
echo ' notifydispatcher : Start a dispatcher process' . PHP_EOL;
410-
echo ' scheduledispatchers : Sets up cron jobs for dispatchers and caches on a schedule.' . PHP_EOL;
411-
echo ' refreshcache : Refresh the cache file for a given cache class.' . PHP_EOL;
412-
echo ' runtests : Run all REST API unit Tests. Warning: this may be disruptive!' . PHP_EOL;
413-
echo ' restartwebgui : Restart the webConfigurator in the background' . PHP_EOL;
414-
echo ' update : Update package to the latest stable version available' . PHP_EOL;
415-
echo ' revert : Revert package to a specified version' . PHP_EOL;
416-
echo ' delete : Delete package from this system' . PHP_EOL;
417-
echo ' rotateserverkey : Rotate the REST API server key and remove all existing tokens' . PHP_EOL;
418-
echo ' backup : Create a backup of the REST API configuration' . PHP_EOL;
419-
echo ' restore : Restore the REST API configuration from the latest backup' . PHP_EOL;
420-
echo " sync : Sync this system's REST API configuration to configured HA nodes" . PHP_EOL;
452+
echo ' version : Display the current package version and build information' . PHP_EOL;
453+
echo ' help : Display the help page (this page)' . PHP_EOL;
454+
echo ' buildendpoints : Build all REST API Endpoints included in this package' . PHP_EOL;
455+
echo ' buildforms : Build all REST API Forms included in this package' . PHP_EOL;
456+
echo ' removeforms : Remove all REST API Forms included in this package' . PHP_EOL;
457+
echo ' buildprivs : Build all REST API privileges included in this package' . PHP_EOL;
458+
echo ' buildschemas : Build all Schema/documentation files' . PHP_EOL;
459+
echo ' notifydispatcher : Start a dispatcher process' . PHP_EOL;
460+
echo ' scheduledispatchers : Sets up cron jobs for dispatchers and caches on a schedule.' . PHP_EOL;
461+
echo ' unscheduledispatchers : Removes cron jobs for dispatchers and caches on a schedule.' . PHP_EOL;
462+
echo ' refreshcache : Refresh the cache file for a given cache class.' . PHP_EOL;
463+
echo ' runtests : Run all REST API unit Tests. Warning: this may be disruptive!' . PHP_EOL;
464+
echo ' restartwebgui : Restart the webConfigurator in the background' . PHP_EOL;
465+
echo ' update : Update package to the latest stable version available' . PHP_EOL;
466+
echo ' revert : Revert package to a specified version' . PHP_EOL;
467+
echo ' delete : Delete package from this system' . PHP_EOL;
468+
echo ' rotateserverkey : Rotate the REST API server key and remove all existing tokens' . PHP_EOL;
469+
echo ' backup : Create a backup of the REST API configuration' . PHP_EOL;
470+
echo ' restore : Restore the REST API configuration from the latest backup' . PHP_EOL;
471+
echo " sync : Sync this system's REST API configuration to configured HA nodes" . PHP_EOL;
421472
echo PHP_EOL;
422473
}
423474

424475
# BUILD_FORMS COMMAND
425476
if ($argv[1] == 'buildforms') {
426477
build_forms();
427478
}
479+
# REMOVE_FORMS COMMAND
480+
elseif ($argv[1] == 'removeforms') {
481+
remove_forms();
482+
}
428483
# BUILDENDPOINTS COMMAND
429484
elseif ($argv[1] == 'buildendpoints') {
430485
build_endpoints();
@@ -447,6 +502,10 @@ function help(): void {
447502
elseif ($argv[1] == 'scheduledispatchers') {
448503
schedule_dispatchers();
449504
}
505+
# UNSCHEDULE_DISPATCHER COMMAND
506+
elseif ($argv[1] == 'unscheduledispatchers') {
507+
unschedule_dispatchers();
508+
}
450509
# REFRESH_CACHE COMMAND
451510
elseif ($argv[1] == 'refreshcache') {
452511
refresh_cache(cache_name: $argv[2]);

pfSense-pkg-RESTAPI/files/usr/local/pkg/RESTAPI/Core/Form.inc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -562,4 +562,21 @@ class Form {
562562
}
563563
return false;
564564
}
565+
566+
/**
567+
* Deletes the Form's endpoint file from the pfSense webroot.
568+
* @returns bool Returns true if the file was successfully deleted, otherwise false.
569+
*/
570+
public function delete_form_url(): bool {
571+
# Assign the absolute path to the file. Assume index.php filename if not specified.
572+
$filename = "/usr/local/www/$this->url";
573+
$filename = str_ends_with($filename, '.php') ? $filename : "$filename/index.php";
574+
$content = file_get_contents($filename);
575+
576+
# Delete the file and return true if it was successfully deleted
577+
if (is_file($filename) and str_contains($content, 'RESTAPI/Forms') and unlink($filename)) {
578+
return true;
579+
}
580+
return false;
581+
}
565582
}

0 commit comments

Comments
 (0)