I might of mentioned this before but having an app catalogue would improve community engagement, even if just for people to browse.
The mandatory tags could be:
Core
Approved
Pending Approval
Experimental
Paid
Free
Paid plugins could be made made approved 3rd and the rules are they must be push via the Virtualmin Reps so they can be controlled. They could be cryptographically signed by the VM team and if not they will not install (not sure how the GPL would like this though)
Webmin requires knowledge of perl this rather limits the amount of plugins that are written and or maintained. You mentioned some time ago there should be some wrapper to allow plugins to be coded in any language which may promote new plugins/addons. Just look at the dates of some of the plugins/modules. Some of them are near pensionable age since their last update
I ve looked at the code and have used php from it’s onset don’t see much resemblance between the 2 languages in fact i would think perl has a greater resemblance to other languages than php
Anything that helps to bring new blood into programming cannot be a bad thing. old programmers never die they just wither away and forget to update their code.
PHP like Perl like Cobol like Dos all make good starting points in code.
PHP had quite a few syntax and conventions borrowed from Perl. But, the two languages have diverged a lot over the years, mostly for the better in both cases. It’s not hard to go from PHP to Perl or vice-versa, though, though I like Perl better, and it lends itself to more concise code.
But, you don’t have to code in Perl to write tools to work with Webmin/Virtualmin. There are APIs, key=value config files, a CLI (for both Webmin and Virtualmin), etc. There are many ways to interact with Webmin and Virtualmin that doesn’t require writing it in Perl, though for something integrated as a plugin it does need at least a glue layer in Perl so it can participate in the plugin system.
Maybe a skeleton module with a glue layer (not looked at the examples) which can be used to access other languages. But I think the APIs are very powerful and can easily be interacted with by PHP.
This is another good reason for the app catalogue , you can see how someone else has done a plugin or solved a certain problem.
Ok first perl script, which works, If you get a second have a look and see if I have missed anything, however it appears to work ok
#!/usr/bin/env perl
use strict;
use warnings;
use POSIX qw(getuid);
use File::Basename;
use Cwd qw();
use constant INTERVAL => 5; # read in seconds
my $processUser = (getpwuid($<))[0] || $ENV{LOGNAME} || $ENV{USER};
if (!is_root()) {
print "This Must Be Run as ROOT\n";
if (is_sudo($processUser)) {
print "however you can run this script via the sudo command\n";
} else {
print "You can not run this script, contact your system administrator\n";
}
exit;
}
start();
sub runIt {
# function to run every n seconds
my $working_directory = Cwd::cwd();
system("php $working_directory/run-units"); # runs all known filters
}
sub checkForStopFlag {
# Return TRUE to stop.
return 0;
}
sub start {
my $active = 1;
my $nextTime = time() + INTERVAL; # Set initial delay
# mix this up a bit to allow different intervals
while ($active) {
select(undef, undef, undef, 0.001); # optional, if you want to be considerate
if (time() >= $nextTime) {
runIt();
$nextTime = time() + INTERVAL;
}
# Do other stuff (you can have as many other timers as you want)
$active = !checkForStopFlag();
}
}
sub is_root {
# checks for root user not sudo user
return getuid() == 0;
}
sub is_sudo {
my ($user) = @_;
$user = trim($user);
return $user eq 'root' if $user eq 'root';
my $j = `getent group sudo | cut -d: -f4`; # perl may do this better
chomp($j);
return index($j, $user) != -1;
}
sub trim {
my ($string) = @_;
$string =~ s/^\s+|\s+$//g;
return $string;
}
It’s not a secret, and it’s not very complicated. We don’t have any examples of writing plugins in other languages because all of our plugins are in Perl; it’s just the simplest way to do it absent some compelling reason to use another language.
That’s way too verbose to be Perlish. I wouldn’t make anything that can be a one-liner into a function (runIt, is_root, is_sudo, trim, are all one-liners, and checkForStopFlag doesn’t make sense). It’s so long as to obscure what it does.
Also, is_root and is_sudo are dupes. You don’t need to check for both.
e.g.
print "UID: ", (getpwuid($<))[2], "\n";
Returns 0 if the user is root or is running under sudo. If you’re parsing files for this, or spinning up a shell for this, you’re working too hard.
Avoiding variables is also a good way to avoid many classes of error (trim is egregious here, but since you only use trim in a function you also don’t need, you can just kill all that code and remove all those potential future bugs). Code that doesn’t exist can’t have bugs.
#!/usr/bin/env perl
use strict;
use warnings;
use POSIX qw(getuid);
use File::Basename;
use Cwd qw();
use feature 'say';
use IPC::System::Simple qw(system);
use constant INTERVAL => 5; # read in seconds
if ((getpwuid($<))[2] != 0) {
say "You can not run this script, contact your system administrator or run as sudo user";
exit;
}
start();
sub start {
my $active = 1;
my $nextTime = time() + INTERVAL; # Set initial delay
while ($active) {
select(undef, undef, undef, 0.001); # optional, if you want to be considerate
if (time() >= $nextTime) {
my $working_directory = Cwd::cwd(); # gets the current directory
my $exit_status = system("php $working_directory/run-units"); # runs the php script
$nextTime = time() + INTERVAL;
}
# Do other stuff (you can have as many other timers as you want)
$active = !checkForStopFlag();
}
}
sub checkForStopFlag {
# completely optional
# Logic to check for a program-exit flag
# Could be via socket or file etc.
# Return TRUE to stop.
# I haven't worked this bit out yet in perl
return 0;
}
Instead of use feature 'say'; you can use v5.16.0; which gets you all the features that arrived in 5.16 and every version before it, including say.
I suggest 5.16, as it’s the version found in RHEL 7, and what our new development currently uses if it uses new features (though Jamie doesn’t use new features, most of his code still runs on 5.10 or even earlier). You can probably even move on to 5.26 (I think that’s the version in RHEL8), since RHEL 7 is now EOL. We tend to move to a new version a year or two after EOL for whatever support distro has the oldest Perl version…which has been 5.16 for a few years. 5.20, I think, gets signatures (though still behind an experimental flag until 5.36), which is a nice feature and the Perl implementation is very nice (it better be, since it took decades to arrive).