Merge branch 'master' of github.com:webmin/webmin
Some checks failed
Tests / prove (push) Has been cancelled
Package and upload artifacts / build (push) Has been cancelled

This commit is contained in:
Jamie Cameron
2026-08-17 21:26:37 -07:00
4 changed files with 100 additions and 32 deletions

View File

@@ -1,16 +1,24 @@
## Changelog
#### 2.654 (August, 2026)
* Add incremental ban time options to the Fail2Ban module
* Add Btrfs subvolume quota management to the Disk Quotas module, with full and simple accounting modes
#### 2.660 (August 17, 2026)
* Add support for creating `vfsv1` Linux quota files for limits above 4 TiB, while preserving existing quota file formats
* Add Btrfs subvolume quota management to the Disk Quotas module, with full and simple accounting modes
* Add support for openSUSE 16 vendor and local Logrotate configuration overlays [#2682](https://github.com/webmin/webmin/issues/2682)
* Fix to ignore failures when adding IPv6 link-local (fe80::) addresses that may already be configured automatically
* Add support for applying multiple patches at once with the `patch` sub-command
* Add APT package hold management to the Package Updates module
* Add incremental ban time options to the Fail2Ban module
* Fix Webmin server connections that open but never send a request, preventing them from waiting indefinitely [#2815](https://github.com/webmin/webmin/pull/2815)
* Fix to ignore failures when adding IPv6 link-local (fe80\:\:) addresses that may already be configured automatically
* Fixed creation of permissions new log files in the System Logs module (thanks to Kevin Carter)
* Fix Fail2Ban jail editor to correctly separate actions when one has no parameters [#2718](https://github.com/webmin/webmin/issues/2718)
* Update the Authentic theme to the latest version with various improvements:
- Fix change detection and submission for forms using grouped bottom action buttons
- Fix login page front side clipping and flip animation for long welcome messages
- Fix opening the wrong directory in Terminal for domain owners in File Manager
- Fix disallowed entry handling in File Manager [forum.virtualmin.com/t/137654](https://forum.virtualmin.com/t/extra-admin-file-manager-permissions/137654?u=ilia)
- Fix File Manager errors for Webmin-only users
- Fix File Manager opening the wrong directory in Terminal for domain owners
- Fix support for navigation detection for the upcoming Virtualmin Podman plugin
- Fix inline images not displaying when printing emails in Usermin
- Fix navigation detection for the new Virtualmin Podman plugin
- Fix bottom page action buttons wrapping and alignment
- Fix errors for Webmin-only users in File Manager
#### 2.653 (July 26, 2026)
* Fix to include missing `xmlrpc-lib.pl` file in the package

View File

@@ -1,5 +1,6 @@
#!/usr/bin/env perl
# patch - Apply a patch to Webmin core or its modules from GitHub or a local file
# patch - Apply one or more patches to Webmin core or its modules from
# GitHub or a local file
use strict;
use warnings;
@@ -49,20 +50,56 @@ if (!has_command('patch')) {
}
}
# Get patch URL or file
my $patch = $ARGV[0];
# Get patch URLs or files
my @patches = @ARGV;
# Params check
if (!$patch) {
if (!@patches) {
pod2usage(0);
exit 1;
}
# Apply all patches in the given order, stopping at the first failure
my $orig_cwd = cwd();
my $applied = 0;
my $failed = 0;
foreach my $patch (@patches) {
# Show which patch is being applied if there are multiple
print "Applying $patch ..\n" if (@patches > 1);
# Always start from the original directory, as applying a patch
# may change it
chdir($orig_cwd);
if (!apply_patch($patch)) {
$failed = 1;
last;
}
$applied++;
}
# Restart Webmin once, if any patches were applied, so that changes to
# any file, including miniserv.pl itself, take effect
restart_miniserv() if ($applied);
# Report if some patches were not applied
if ($failed) {
print "Stopped: $applied of ".scalar(@patches)." patches applied\n"
if (@patches > 1);
exit 1;
}
exit 0;
# apply_patch(patch)
# Apply a single patch given as URL or local file, printing the outcome
# and returning 1 on success or 0 on failure
sub apply_patch
{
my ($patch) = @_;
# Patch check
if ($patch !~ /^https?:\/\//) {
if (!-r $patch) {
print "Patch file $patch doesn't exist\n";
exit 1;
return 0;
}
}
elsif ($patch =~ /^https?:\/\/(github|gitlab)\.com/ &&
@@ -101,9 +138,9 @@ if ($patch =~ m{
# Check if module exists
if (!-d "$path/$module") {
print "Module '$module' doesn't exist\n";
exit 1;
}
print "Module '$module' doesn't exist\n";
return 0;
}
# Prepare patch command
my $cmd;
@@ -128,7 +165,7 @@ if ($patch =~ m{^https?://raw\.githubusercontent\.com/} ||
}
else {
print "Patch failed: Can't parse file name from URL\n";
exit 1;
return 0;
}
my $cd = "$path/$module/$dir";
$cd =~ s|/+|/|g;
@@ -149,26 +186,34 @@ else {
if ($direct) {
$output = `$cmd 2>&1`;
if ($output != 200) {
print "Patch failed: Cannot download '$filename'. HTTP status code: $output\n";
exit 1;
}
print "Patch failed: Cannot download '$filename'. HTTP status code: $output\n";
return 0;
}
}
# Apply patch using patch command
elsif (has_command('patch')) {
$output = `$cmd 2>&1 | patch -p1 --verbose 2>&1`;
# Do not leave .orig backups behind when hunks apply with fuzz or offset
$output = `$cmd 2>&1 | patch -p1 --verbose --no-backup-if-mismatch 2>&1`;
if ($output !~ /succeeded/i) {
print "Patch failed: $output\n";
exit 1;
return 0;
}
}
# Apply patch using git command
else {
$output = `$cmd 2>&1 | git apply --reject --verbose --whitespace=fix 2>&1`;
# If the current directory is inside some git repository (e.g. Webmin
# root tracked with git), git would treat patch paths as relative to
# that repository root and silently skip them, so stop repository
# discovery at the parent directory to always apply patch paths
# relative to the current directory
local $ENV{'GIT_CEILING_DIRECTORIES'} = dirname(cwd());
# Allow reduced context, similar to the default fuzz used by patch
$output = `$cmd 2>&1 | git apply --reject --verbose -C1 --whitespace=fix 2>&1`;
if ($output !~ /applied patch.*?cleanly/i) {
print "Patch failed: $output\n";
exit 1;
return 0;
}
}
}
# Print results
if ($direct) {
@@ -183,11 +228,10 @@ if ($direct) {
else {
print "Patch applied successfully to:\n";
print " $1\n" while $output =~ /^(?|Applied patch\s+(\S+)|patching file\s+(\S+))/mg;
}
return 1;
}
# Reload Webmin
reload_miniserv();
=pod
=head1 NAME
@@ -199,9 +243,13 @@ patch
Apply a patch to Webmin core or its modules from GitHub/GitLab, a local
file, or by downloading and replacing the entire file from a raw URL.
Multiple patches can be given at once and are applied in the given order,
stopping at the first failure. Webmin is restarted only once after all
patches are applied.
=head1 SYNOPSIS
webmin patch patch-url/file
webmin patch patch-url/file [patch-url/file ...]
=head1 OPTIONS
@@ -229,6 +277,11 @@ Examples of usage:
- cd /usr/libexec/webmin/virtual-server/pro &&
webmin patch /root/virtualmin-pro/patches/patch-1.patch
Apply multiple patches at once.
- webmin patch https://github.com/webmin/webmin/commit/e6a2bb15b0 \
https://github.com/virtualmin/virtualmin-gpl/commit/f4433153d
=back
=head1 LICENSE AND COPYRIGHT

View File

@@ -210,7 +210,7 @@ my @w;
my $v = $dir->{'value'};
$v =~ s/\n/ /g;
while($v =~ /\S/) {
if ($v =~ /^([^\[]+\[[^\]]+\])\s*(.*)/) {
if ($v =~ /^\s*([^\s\[]+\[[^\]]*\])\s*(.*)/) {
push(@w, $1);
$v = $2;
}
@@ -408,7 +408,9 @@ my @rv;
my @v = ref($dir->{'value'}) eq 'ARRAY' ? @{$dir->{'value'}}
: split(/\n/, $dir->{'value'});
push(@rv, $dir->{'name'}." = ".shift(@v));
push(@rv, map { " ".$_ } @v); # Continuation
# Indent continuation lines to align with the first value
my $indent = " " x (length($dir->{'name'}) + 3);
push(@rv, map { $indent.$_ } @v);
return @rv;
}

View File

@@ -73,8 +73,13 @@ elsif ($in{'now'}) {
print $text{'force_doingone'},"\n";
($ex, $out) = &rotate_log_now($log);
print "<pre>$out</pre>";
if ($?) {
if ($out =~ /\S/) {
print "<pre>",&html_escape($out),"</pre>";
}
else {
print "<br>\n";
}
if ($ex) {
print $text{'force_failed'},"<br>\n";
}
else {