Files
pxe_boot_alma/work/KickStart/cfg/config.cgi
T
andersenandClaude Fable 5 6d398b826a refactor: move tree under homelab/, add alma10 hardening and kickstart docs
- restructure boot/kickstarts/scripts/docs into homelab/
- docs: alma9->10 breaking changes, CIS hardening, kickstart changes
- add find_cron_entries.sh helper and codex running memory notes

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-07-06 22:35:07 -04:00

358 lines
11 KiB
Perl
Executable File

#!/usr/bin/perl
my $KSDIR = "/home/KickStart/cfg";
my $KSCONFIG = "$KSDIR/ks.config";
my $CONFIGD = "$KSDIR/config.d";
my $ACTIVED = "$KSDIR/ks.d";
my @HDTYPES = ( "prompt", "sd", "hd", "hdc" );
my @FWTYPES = ( "disable", "medium", "high" );
my @SELINUX = ( "disabled", "permissive", "enforcing" );
my @SETYPES = ( "targeted", "strict" );
my @TZONES = ( "US/Arizona", "US/Eastern", "US/Hawaii", "US/Pacific", "US/Central", "US/East-Indiana", "US/Indiana-Starke", "US/Mountain" );
my $DISCOLS = 3;
my $STAGES;
$STAGES->{1}->{suffix} = "P";
$STAGES->{1}->{desc} = "Pre";
$STAGES->{2}->{suffix} = "S";
$STAGES->{2}->{desc} = "Post (chroot)";
$STAGES->{3}->{suffix} = "N";
$STAGES->{3}->{desc} = "Post (No chroot)";
my $ks;
my $cnt;
my $run;
print "Content-type: text/html\n\n";
print "<html>\n";
print "<head>\n";
print " <title> iGlass KickStart Config </title>\n";
print "</head>\n";
print "<body>\n";
print "<h3>iGlass KickStart Config</h3>\n";
# Make changes if any
my @stdin = <STDIN>;
if ( @stdin ) {
my $rlst;
my $clst;
print "<pre>\n" if $DEBUG;
foreach my $line ( @stdin ) {
foreach my $pair ( split(/\&/,$line) ) {
$pair = URLDecode($pair);
if ( $pair =~ /^CF\+(\S+)=(.+)$/ ) {
print "file $1 = $2\n" if $DEBUG;
$rlst->{$1} = $2;
} elsif ( $pair =~ /^(\S+)=(.+)$/ ) {
print "config $1=$2\n" if $DEBUG;
$clst->{$1} = $2;
}
}
}
if ( open(RC, "$KSCONFIG") ) {
my @configs = <RC>;
close RC;
system("cp", "-a", "$KSCONFIG.2", "$KSCONFIG.3");
system("cp", "-a", "$KSCONFIG.1", "$KSCONFIG.2");
system("cp", "-a", "$KSCONFIG", "$KSCONFIG.1");
if ( open(WC, ">$KSCONFIG") ) {
foreach ( @configs ) {
if ( /^(\w+)\=(.+)$/ ) {
if ( exists $clst->{$1} ) {
print WC "$1=$clst->{$1}\n";
delete $clst->{$1};
} else {
print WC "$1=$2\n";
}
} else {
print WC "$_";
}
}
foreach $new ( keys %{$clst} ) {
print WC "$new=$clst->{$new}\n";
}
} else {
print "Erorr: Could not open $KSCONFIG for read\n";
}
close WC;
} else {
print "Erorr: Could not open $KSCONFIG for write\n";
}
if ( opendir(CD, "$CONFIGD") ) {
my @fileList = grep(!/^\./, readdir(CD));
close CD;
foreach my $file ( @fileList ) {
if ( $file =~ /^(\w)(\d+.+)$/ ) {
print "$file: " if $DEBUG;
if ( -e "$ACTIVED/$file" ) {
if ( exists $rlst->{$file} ) {
print " Is turned on and should be turned on\n" if $DEBUG;
} else {
print " Is turned on and should be turned off\n" if $DEBUG;
unlink("$ACTIVED/$file");
}
} else {
if ( exists $rlst->{$file} ) {
print " Is turned off and should be turned on\n" if $DEBUG;
symlink("$CONFIGD/$file", "$ACTIVED/$file");
} else {
print " Is turned off and should be turned off\n" if $DEBUG;
}
}
} elsif ( $file =! /^HEADER/ ) {
} else {
print "<h3>Warning: What is this file $CONFIGD/$file</h3>\n";
}
}
} else {
print "<h3>Erorr: Could not open directory $CONFIGD</h3>\n";
}
print "</pre>\n" if $DEBUG;
}
# Get current setup
if ( open(C, "$KSCONFIG") ) {
print "<pre>\n" if $DEBUG;
while ( <C> ) {
if ( (/^\s*$/) || (/^\s*#/) ) {
next;
} elsif ( /^(\w+)\=(.+)$/ ) {
$ks->{$1} = $2;
print "$1 == $ks->{$1}\n" if $DEBUG;
}
}
print "</pre>\n" if $DEBUG;
close C;
} else {
print "Erorr: Could not open $KSCONFIG\n";
}
if ( opendir(CD, "$CONFIGD") ) {
foreach my $file ( grep(!/^\./, readdir(CD)) ) {
if ( $file =~ /^([PSN])(\d+)(.+)$/ ) {
my $act = $1;
$run->{$act}->{$file}->{num} = $2;
$run->{$act}->{$file}->{name} = $3;
$run->{$act}->{$file}->{run} = '';
if (exists $cnt->{$act}) {
++$cnt->{$act};
} else {
$cnt->{$act} = 1;
}
if ( open(F, "$CONFIGD/$file") ) {
while ( <F> ) {
if ( /^#\s+description:\s*(.+)/ ) {
$run->{$act}->{$file}->{desc} = $1;
last;
}
}
close F;
} else {
print "<h3>Warning: Could not read file $CONFIGD/$file</h3>\n";
}
} elsif ( $file =! /^HEADER/ ) {
} else {
print "<h3>Warning: What is this file $CONFIGD/$file</h3>\n";
}
}
close CD;
} else {
print "<h3>Erorr: Could not open directory $CONFIGD</h3>\n";
}
if ( opendir(AD, "$ACTIVED") ) {
foreach my $file ( grep(!/^\./, readdir(AD)) ) {
if ( ($file =~ /^([PSN])\d+.+$/) && (exists $run->{$1}->{$file}) ) {
$run->{$1}->{$file}->{run} = 'checked';
} elsif ( $file =! /^HEADER/ ) {
} else {
print "<h3>Warning: What is this file $ACTIVED/$file</h3>\n";
}
}
close AD;
} else {
print "<h3>Erorr: Could not open directory $ACTIVED</h3>\n";
}
# Start the form
print "<form method=POST action=\"/KickStart/cfg/config.cgi\">\n";
print "<table width=\"100%\"><tr><td valign=\"top\">\n";
print "Disk device type: ";
foreach my $type ( @HDTYPES ) {
my $checked;
if ( $type eq $ks->{DISKTYPE} ) {
$checked = "checked";
}
print "<input type=\"radio\" name=\"DISKTYPE\" value=\"$type\" $checked> $type \n";
}
print "<p>\n";
print "Time Zone: <select name=\"TZ\">";
foreach my $type ( @TZONES ) {
my $checked;
if ( "$type" eq "$ks->{TZ}" ) {
$checked = "selected=\"selected\"";
}
print "<option value=\"$type\" $checked> $type \n";
}
print "</select>\n";
print "<p>\n";
print "Firewall setting: ";
foreach my $type ( @FWTYPES ) {
my $checked;
if ( $type eq $ks->{FIREWALL} ) {
$checked = "checked";
}
print "<input type=\"radio\" name=\"FIREWALL\" value=\"$type\" $checked> $type \n";
}
print "<p>\n";
print "SELinux setting: ";
foreach my $type ( @SELINUX ) {
my $checked;
if ( $type eq $ks->{SELINUX} ) {
$checked = "checked";
}
print "<input type=\"radio\" name=\"SELINUX\" value=\"$type\" $checked> $type \n";
}
print "<p>\n";
{ # password
print "Grub and root MD5 password hash: <input type=\"text\" size=\"45\" name=\"MD5PASS\" value=\"$ks->{MD5PASS}\">\n";
}
print "<p>\n";
{ # interactive
print "Prompt for settings? ";
if ( $ks->{INTERACTIVE} =~ /^y/ ) {
print "<input type=\"radio\" name=\"INTERACTIVE\" value=\"y\" checked> Yes\n";
print "<input type=\"radio\" name=\"INTERACTIVE\" value=\"n\"> No\n";
} else {
print "<input type=\"radio\" name=\"INTERACTIVE\" value=\"y\"> Yes\n";
print "<input type=\"radio\" name=\"INTERACTIVE\" value=\"n\" checked> No\n";
}
}
print "<p>\n";
{ # reboot
print "Reboot when done? ";
if ( $ks->{REBOOT} =~ /^y/ ) {
print "<input type=\"radio\" name=\"REBOOT\" value=\"y\" checked> Yes";
print "<input type=\"radio\" name=\"REBOOT\" value=\"n\"> No\n";
} else {
print "<input type=\"radio\" name=\"REBOOT\" value=\"y\"> Yes";
print "<input type=\"radio\" name=\"REBOOT\" value=\"n\" checked> No\n";
}
}
print "<p>\n";
{ # pre-scripts
print "Run Pre-scripts? ";
if ( $ks->{PRE} =~ /^y/ ) {
print "<input type=\"radio\" name=\"PRE\" value=\"y\" checked> Yes";
print "<input type=\"radio\" name=\"PRE\" value=\"n\"> No\n";
} else {
print "<input type=\"radio\" name=\"PRE\" value=\"y\"> Yes";
print "<input type=\"radio\" name=\"PRE\" value=\"n\" checked> No\n";
}
}
print "<p>\n";
{ # post-scripts
print "Run Post-scripts? ";
if ( $ks->{POST} =~ /^y/ ) {
print "<input type=\"radio\" name=\"POST\" value=\"y\" checked> Yes";
print "<input type=\"radio\" name=\"POST\" value=\"n\"> No\n";
} else {
print "<input type=\"radio\" name=\"POST\" value=\"y\"> Yes";
print "<input type=\"radio\" name=\"POST\" value=\"n\" checked> No\n";
}
}
print "<p>\n";
{ # post-nochroot-scripts
print "Run Post-nochroot-scripts? ";
if ( $ks->{POSTNR} =~ /^y/ ) {
print "<input type=\"radio\" name=\"POSTNR\" value=\"y\" checked> Yes";
print "<input type=\"radio\" name=\"POSTNR\" value=\"n\"> No\n";
} else {
print "<input type=\"radio\" name=\"POSTNR\" value=\"y\"> Yes";
print "<input type=\"radio\" name=\"POSTNR\" value=\"n\" checked> No\n";
}
}
print "</td><td valign=\"top\" align=\"right\">\n";
print "<input type=\"submit\" value=\"Save\">";
print "<input type=\"reset\" value=\"Cancel\"><br>";
print "<p align=\"right\"><a href=\"/KickStart/cfg/probe-config.cgi\"><small>Add/Del Probe Config</small></a></p>\n";
print "</td></tr></table>\n";
print "<p><hr>\n";
foreach $stage ( sort keys %{$STAGES} ) {
print "<table width=\"100%\">\n";
print "<tr><td colspan=\"$DISCOLS\" align=\"center\"> <b>$STAGES->{$stage}->{desc}</b> </td></tr>\n";
print "<tr><td valign=\"top\"><table>";
my $i;
foreach my $file ( sort keys %{$run->{$STAGES->{$stage}->{suffix}}} ) {
if ( defined $i ) {
if ( $i > ($cnt->{$STAGES->{$stage}->{suffix}}/$DISCOLS) ) {
print "</table></td><td valign=\"top\"><table>";
$i = 1;
} else {
++$i;
}
} else {
$i = 1;
}
my $pdesc;
if ( defined $run->{$STAGES->{$stage}->{suffix}}->{$file}->{desc} ) {
$pdesc = $run->{$STAGES->{$stage}->{suffix}}->{$file}->{desc};
} else {
$pdesc = $run->{$STAGES->{$stage}->{suffix}}->{$file}->{name};
}
print "<tr><td> <input type=checkbox name=\"CF+$file\" $run->{$STAGES->{$stage}->{suffix}}->{$file}->{run} /> </td><td> <a href=\"/KickStart/cfg/config.d/$file\">$run->{$STAGES->{$stage}->{suffix}}->{$file}->{num}</a> </td><td> - </td><td> $pdesc </td></tr>\n";
}
print "</table></td></tr>";
print "</table>\n";
print "<p><hr>\n";
}
print "</form>\n";
print "<p align=\"right\"><a href=\"/KickStart/cfg/ks.cgi\"><small>View ks.cfg</small></a></p>\n";
print "</body>\n";
sub URLDecode {
my $url = shift;
$url =~ tr/+/ /;
$url =~ s/%([a-fA-F0-9]{2,2})/chr(hex($1))/eg;
$url =~ s/<!--(.|\n)*-->//g;
return $url;
}
sub URLEncode {
my $url = shift;
my $MetaChars = quotemeta( ';,/?\|=+)(*&^%$#@!~`:');
$url =~ s/([$MetaChars\"\'\x80-\xFF])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
$url =~ s/ /\+/g;
return $theURL;
}