Assisted-by: GLM 5.3 Flash
This commit is contained in:
@@ -90,7 +90,7 @@ a change would do without doing it.
|
|||||||
| `network-diag.pl` | 2.0.0 | Network latency, DNS, MTU, packet loss and dual-stack on Linux and FreeBSD |
|
| `network-diag.pl` | 2.0.0 | Network latency, DNS, MTU, packet loss and dual-stack on Linux and FreeBSD |
|
||||||
| `system-diag.pl` | 2.0.0 | System health with a grade from A to F. Linux only |
|
| `system-diag.pl` | 2.0.0 | System health with a grade from A to F. Linux only |
|
||||||
| `security-audit.pl` | 2.0.0 | Security posture with a grade from A to F and an exit code for cron. Linux only |
|
| `security-audit.pl` | 2.0.0 | Security posture with a grade from A to F and an exit code for cron. Linux only |
|
||||||
| `server-setup.pl` | 2.0.0 | Server initial setup for Fedora, CentOS Stream and openEuler |
|
| `server-setup.pl` | 2.1.0 | Server initial setup for Fedora, CentOS Stream and openEuler |
|
||||||
| `workstation-setup.pl` | 2.0.0 | Fedora desktop setup |
|
| `workstation-setup.pl` | 2.0.0 | Fedora desktop setup |
|
||||||
| `sglang-deploy.pl` | 2.1.0 | SGLang inference server on an AMD GPU, behind Caddy with HTTPS |
|
| `sglang-deploy.pl` | 2.1.0 | SGLang inference server on an AMD GPU, behind Caddy with HTTPS |
|
||||||
| `system-optimise.pl` | 2.0.0 | System cleanup; refuses rpm-ostree systems |
|
| `system-optimise.pl` | 2.0.0 | System cleanup; refuses rpm-ostree systems |
|
||||||
|
|||||||
+43
-10
@@ -44,7 +44,7 @@
|
|||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
|
|
||||||
my $VERSION = '2.0.0';
|
my $VERSION = '2.1.0';
|
||||||
|
|
||||||
my $BOLD = "\033[1m";
|
my $BOLD = "\033[1m";
|
||||||
my $RED = "\033[31m";
|
my $RED = "\033[31m";
|
||||||
@@ -67,16 +67,39 @@ my %SUPPORTED_OS = (
|
|||||||
);
|
);
|
||||||
|
|
||||||
# Base packages installed on Fedora, CentOS Stream and openEuler alike.
|
# Base packages installed on Fedora, CentOS Stream and openEuler alike.
|
||||||
|
# caddy is the reverse proxy the deploy scripts serve the endpoints through;
|
||||||
|
# openEuler ships no package for it, and install_packages says so and leaves
|
||||||
|
# it to the script that needs it.
|
||||||
my @BASE_PACKAGES = qw(
|
my @BASE_PACKAGES = qw(
|
||||||
nano curl wget htop tmux rsync nginx openssl jq fastfetch
|
nano curl wget htop tmux rsync caddy openssl jq fastfetch
|
||||||
);
|
);
|
||||||
|
|
||||||
# Services to open in firewalld by default. ssh is mandatory: losing it means
|
# Services to open in firewalld by default. ssh is mandatory: losing it means
|
||||||
# locking out remote administration.
|
# locking out remote administration.
|
||||||
my @FIREWALL_SERVICES = ('ssh');
|
my @FIREWALL_SERVICES = ('ssh');
|
||||||
|
|
||||||
# Opened in firewalld only when nginx is installed, which it is by default.
|
# Opened in firewalld only when caddy is installed, which it is by default
|
||||||
my @NGINX_FIREWALL_SERVICES = ('http', 'https');
|
# wherever the package exists.
|
||||||
|
my @CADDY_FIREWALL_SERVICES = ('http', 'https');
|
||||||
|
|
||||||
|
# The one base package a distribution's repositories do not carry, with the
|
||||||
|
# reason and who provides it instead.
|
||||||
|
my %UNPACKAGED = (
|
||||||
|
openeuler => {
|
||||||
|
caddy => 'openEuler ships no caddy package; the scripts that need the '
|
||||||
|
. 'proxy install the release binary themselves',
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
# Test-visible accessors: the catalogue is lexical to this file, so the checks
|
||||||
|
# under tests/ read the base package list and the unpackaged map through these.
|
||||||
|
sub base_packages { return @BASE_PACKAGES; }
|
||||||
|
|
||||||
|
sub unpackaged_for {
|
||||||
|
my ($os_id) = @_;
|
||||||
|
return () unless exists $UNPACKAGED{$os_id};
|
||||||
|
return %{ $UNPACKAGED{$os_id} };
|
||||||
|
}
|
||||||
|
|
||||||
# dnf-automatic configuration file. dnf 4 ships it with defaults; dnf 5 reads host
|
# dnf-automatic configuration file. dnf 4 ships it with defaults; dnf 5 reads host
|
||||||
# overrides from this path (its own defaults live in /usr/share/dnf5).
|
# overrides from this path (its own defaults live in /usr/share/dnf5).
|
||||||
@@ -565,19 +588,29 @@ sub ensure_epel {
|
|||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
sub install_packages {
|
sub install_packages {
|
||||||
my ($dry_run) = @_;
|
my ($os_id, $dry_run) = @_;
|
||||||
my (@installed, @skipped, @failed, @to_install);
|
my (@installed, @skipped, @failed, @to_install, @unpackaged);
|
||||||
|
|
||||||
_status('Checking base packages');
|
_status('Checking base packages');
|
||||||
for my $pkg (@BASE_PACKAGES) {
|
for my $pkg (@BASE_PACKAGES) {
|
||||||
|
# exists and not a bare lookup: descending into a missing os key
|
||||||
|
# would autovivify it.
|
||||||
|
if (exists $UNPACKAGED{$os_id} && exists $UNPACKAGED{$os_id}{$pkg}) {
|
||||||
|
push @unpackaged, [$pkg, $UNPACKAGED{$os_id}{$pkg}];
|
||||||
|
next;
|
||||||
|
}
|
||||||
if (rpm_installed($pkg)) { push @skipped, $pkg }
|
if (rpm_installed($pkg)) { push @skipped, $pkg }
|
||||||
else { push @to_install, $pkg }
|
else { push @to_install, $pkg }
|
||||||
}
|
}
|
||||||
|
|
||||||
my $already = scalar @skipped;
|
my $already = scalar @skipped;
|
||||||
my $missing = scalar @to_install;
|
my $missing = scalar @to_install;
|
||||||
my $total = scalar @BASE_PACKAGES;
|
my $total = scalar @BASE_PACKAGES - scalar @unpackaged;
|
||||||
_status_done("$already/$total already installed");
|
_status_done("$already/$total already installed");
|
||||||
|
for my $entry (@unpackaged) {
|
||||||
|
my ($pkg, $reason) = @$entry;
|
||||||
|
_info("$pkg is not packaged on this distribution: $reason");
|
||||||
|
}
|
||||||
|
|
||||||
if (!@to_install) {
|
if (!@to_install) {
|
||||||
_ok('All base packages already present');
|
_ok('All base packages already present');
|
||||||
@@ -663,9 +696,9 @@ sub setup_firewall {
|
|||||||
$info{installed} = 1;
|
$info{installed} = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# ssh is mandatory; http and https only when nginx is present.
|
# ssh is mandatory; http and https only when caddy is present.
|
||||||
my @services = @FIREWALL_SERVICES;
|
my @services = @FIREWALL_SERVICES;
|
||||||
push @services, @NGINX_FIREWALL_SERVICES if rpm_installed('nginx');
|
push @services, @CADDY_FIREWALL_SERVICES if rpm_installed('caddy');
|
||||||
|
|
||||||
# --- Permanent rules first, through the offline client, which needs no daemon
|
# --- Permanent rules first, through the offline client, which needs no daemon
|
||||||
my $permanent_changed = 0;
|
my $permanent_changed = 0;
|
||||||
@@ -1776,7 +1809,7 @@ sub main {
|
|||||||
# 3. Base packages
|
# 3. Base packages
|
||||||
print STDERR "\n${BOLD}── Base Packages ──$RESET\n";
|
print STDERR "\n${BOLD}── Base Packages ──$RESET\n";
|
||||||
if (!$opt{skip_packages}) {
|
if (!$opt{skip_packages}) {
|
||||||
$results{packages} = install_packages($opt{dry_run});
|
$results{packages} = install_packages($os_id, $opt{dry_run});
|
||||||
if (@{ $results{packages}{failed} }) {
|
if (@{ $results{packages}{failed} }) {
|
||||||
push @warnings, 'Some packages failed to install: '
|
push @warnings, 'Some packages failed to install: '
|
||||||
. join(', ', @{ $results{packages}{failed} });
|
. join(', ', @{ $results{packages}{failed} });
|
||||||
|
|||||||
@@ -124,6 +124,25 @@ my %defaults = parse_args();
|
|||||||
is($defaults{dry_run}, 0, 'args: dry run is off by default');
|
is($defaults{dry_run}, 0, 'args: dry run is off by default');
|
||||||
@ARGV = @saved;
|
@ARGV = @saved;
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# The base package catalogue
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# The proxy of the collection is caddy everywhere; nginx left the baseline when
|
||||||
|
# sglang-deploy.pl moved to Caddy, and the name survives only in its own legacy
|
||||||
|
# clean-up.
|
||||||
|
check((grep { $_ eq 'caddy' } base_packages()) == 1, 'packages: caddy is a base package');
|
||||||
|
check((grep { $_ eq 'nginx' } base_packages()) == 0, 'packages: nginx is not');
|
||||||
|
is(join('|', base_packages()),
|
||||||
|
'nano|curl|wget|htop|tmux|rsync|caddy|openssl|jq|fastfetch',
|
||||||
|
'packages: the whole list, in order');
|
||||||
|
my %openeuler_gaps = unpackaged_for('openeuler');
|
||||||
|
is(exists $openeuler_gaps{caddy} ? 'yes' : 'no', 'yes',
|
||||||
|
'packages: the openEuler gap is named in the unpackaged map');
|
||||||
|
is(scalar(unpackaged_for('fedora')) // 0, 0, 'packages: Fedora has no unpackaged entry');
|
||||||
|
is(scalar(unpackaged_for('centos')) // 0, 0,
|
||||||
|
'packages: CentOS Stream has no unpackaged entry, EPEL carries caddy');
|
||||||
|
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
# The command runner
|
# The command runner
|
||||||
# ---------------------------------------------------------------------------
|
# ---------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user