initial commit of file from CVS for e-smith-base on Thu 26 Oct 11:24:52 BST 2023

This commit is contained in:
2023-10-26 11:24:52 +01:00
parent bbc22988a8
commit 9510d1a360
678 changed files with 22721 additions and 2 deletions

View File

@@ -0,0 +1,126 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# add_drive_to_raid: Add spare disk to existing raid arrays
#----------------------------------------------------------------------
# Copyright (C) 2005 Gordon Rowell <gordonr@gormand.com.au>
# Copyright (C) 2006 Shad L. Lords <slords@mail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------
use strict;
use warnings;
use Getopt::Long;
use Data::Dumper;
my %options = ();
GetOptions(\%options, 'f', 'force');
my $force = $options{f} || $options{force};
my $newdev = $ARGV[0] || die "usage:\n\n\tadd_drive_to_raid [-f] dev\n\n";
my $target_drive = "/dev/$newdev";
my $raid = require "/sbin/e-smith/console-menu-items/manageRAID.pl";
# Log STDOUT from this point on and return STDERR back to the console
my $pid = open(STDOUT, "|-");
die gettext("Can't fork"), ": $!\n" unless defined $pid;
unless ($pid)
{
exec qw(/usr/bin/logger -p local1.info -t add_drive_to_raid);
}
# Get dictionary of active md devices and sort by size
my %devices = $raid->get_raid_details();
my @devices = sort { $devices{$a}{DeviceSize} <=> $devices{$b}{DeviceSize} } keys %devices;
die "There are no RAID devices configured\n" unless $#devices >= 0;
# Get dictionary of all partitions from /proc/partitions
my %partitions = $raid->get_partitions();
my @partitions;
die "$target_drive is not a block special device\n" unless -b $target_drive;
# Calculate min size of new disk to accomodate active md devices
my $minsize = 0;
for my $dev (@devices)
{
die "$target_drive is already in use\n" if grep m#^$newdev$#, @{$devices{$dev}{UsedDisks}};
$minsize += $devices{$dev}{DeviceSize} + 65;
}
die "$target_drive is not large enough\n" unless $partitions{$newdev}{blocks} >= $minsize;
die "$target_drive already contains partitions\n" unless $force or ! grep m#^$newdev.+$#, keys %partitions;
# Find a healthy drive hosting our /boot partition to use as our template
my @srcdrives = qx(df /boot --output=source | grep /dev/ | xargs -r lsblk -lnsp | grep disk);
die "Unable to identify existing boot device - manual intervention required\n" unless (scalar @srcdrives) >= 1;
my ($source_drive) = $srcdrives[0] =~ /(\S+)/;
print "Using $source_drive as source partition template.\n";
# Check if it's MBR or GPT
my $pttype = qx(blkid -o value -s PTTYPE $source_drive);
chomp $pttype;
die "Unable to identify source partition table type for $source_drive\n" unless $pttype;
print "$source_drive partition table type is $pttype\n";
# Clear disk in preparation
print "Wiping $target_drive...\n";
system("wipefs", "-a", $target_drive) == 0
or die "Error clearing existing partition table on $target_drive\n";
# Copy new partition layout
print "Copying partition table from $source_drive to $target_drive...\n";
if ($pttype eq 'dos') {
system("sfdisk -d $source_drive | sfdisk -qf --no-reread $target_drive") == 0
or die "Error copying MBR partition table to $target_drive\n";
} elsif ($pttype eq 'gpt') {
system("sgdisk", "-R", $target_drive, $source_drive) == 0
or die "Error copying GPT partition table to $target_drive\n";
system("sgdisk", "-G", $target_drive) == 0
or die "Error randomising GUID on $target_drive\n";
} else {
die "Couldn't interpret partition table type '$pttype' on $source_drive\n";
}
# Pause to sync
sleep(3);
# Install GRUB
print "Installing GRUB on $target_drive...\n";
system("grub2-install", "--recheck", $target_drive) == 0
or warn "Warning - error installing GRUB to $target_drive\n";
# Loop through RAID devices and add the corresponding new partitions
my @srcparts;
my $srcpart;
my $tgtpart;
foreach my $part (0..$#devices)
{
# Find the matching source drive partition and substitute the name
@srcparts = qx(mdadm -v --detail --scan $devices[$part]);
foreach my $s (@srcparts) {($srcpart) = $s =~ /devices=(\Q$source_drive\E\d+)/};
$tgtpart = $srcpart =~ s/\Q$source_drive/$target_drive/r;
print "Adding $tgtpart to $devices[$part]\n";
system("/sbin/mdadm", $devices[$part], "--add", $tgtpart) == 0
or die "Error adding $tgtpart to $devices[$part]";
}
# Finished
print "Successfully added $target_drive to RAID!\n";

View File

@@ -0,0 +1,56 @@
#!/usr/bin/perl -wT
#----------------------------------------------------------------------
# copyright (C) 1999-2006 Mitel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------
package esmith::console;
use strict;
use Locale::gettext;
use esmith::ConfigDB::unsaved;
use esmith::console;
my $console = esmith::console->new();
my $db = esmith::ConfigDB::unsaved->open;
my $termType = $db->get_prop('serial-console', 'Terminal') || '';
$ENV{TERM} = $termType if($termType);
use esmith::console::backup_running;
esmith::console::backup_running->new->doit($console, $db);
use esmith::console::perform_restore;
esmith::console::perform_restore->new(bootstrap => 1)->doit($console, $db);
use esmith::console::system_password;
esmith::console::system_password->new->doit($console, $db);
if ($db->get_prop('bootstrap-console', 'Run') eq 'yes')
{
use esmith::console::configure;
esmith::console::configure->new(bootstrap => 1)->doit($console, $db);
use esmith::console::save_config;
esmith::console::save_config->new->doit($console, $db);
}
system("/usr/bin/tput", "clear");
exit (0);

View File

@@ -0,0 +1,43 @@
#!/usr/bin/perl -wT
#----------------------------------------------------------------------
# copyright (C) 1999-2006 Mitel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------
package esmith::console;
use strict;
use Locale::gettext;
use esmith::ConfigDB::unsaved;
use esmith::console;
my $console = esmith::console->new();
my $db = esmith::ConfigDB::unsaved->open;
my $termType = $db->get_prop('serial-console', 'Terminal') || '';
$ENV{TERM} = $termType if($termType);
$ARGV[0] = 'tty';
$console = esmith::console->new();
use esmith::console::startup;
esmith::console::startup->new->doit($console,$db);
system("/usr/bin/tput", "clear");
exit (0);

View File

@@ -0,0 +1,3 @@
package esmith::console::configure;
use esmith::console::configure;
return new esmith::console::configure;

View File

@@ -0,0 +1,303 @@
package esmith::console::manageDiskRedundancy;
use strict;
use warnings;
use esmith::console;
use Locale::gettext;
use Taint::Util;
use Data::Dumper;
use constant DEBUG_MANAGE_RAID => 0;
sub new
{
my $class = shift;
my $self = {
name => gettext("Manage disk redundancy"),
order => 45,
};
bless $self, $class;
return $self;
}
sub name
{
return $_[0]->{name};
}
sub order
{
return $_[0]->{order};
}
sub doit
{
my ($self, $console, $db) = @_;
my ($rc, $choice);
use POSIX qw(strftime);
SCAN:
my $today = strftime "%A %B %e, %Y %H:%M:%S", localtime;
my $title = gettext("Disk redundancy status as of") . " " . $today,
my $text = gettext("Current RAID status:") . "\n\n" .
join("", get_raid_status()) . "\n\n";
my %devices = get_raid_details();
warn $text if DEBUG_MANAGE_RAID;
warn "devices: " . Dumper(\%devices) . "\n" if DEBUG_MANAGE_RAID;
unless (scalar %devices)
{
$text = gettext("There are no RAID devices configured");
($rc, $choice) = $console->message_page(title => $title, text => $text);
return;
}
# Determine the status of each array
my @unclean = ();
my @recovering = ();
my @failed = ();
my %used_disks = ();
for my $dev (keys %devices)
{
$used_disks{$_}++ for (@{$devices{$dev}{UsedDisks}});
if ($devices{$dev}{FailedDevices} > 0) {
push @failed, "$dev => " . $devices{$dev}{FailedDevices};
}
if ($devices{$dev}{State} =~ /recovering|resync/) {
push @recovering, "$dev => " . $devices{$dev}{State};
next;
}
next if ($devices{$dev}{State} =~ /^(clean|active)\s*$/);
push @unclean, "$dev => " . $devices{$dev}{State};
}
warn "unclean: @unclean\n" if DEBUG_MANAGE_RAID;
warn "recovering: @recovering\n" if DEBUG_MANAGE_RAID;
warn "failed: @failed\n" if DEBUG_MANAGE_RAID;
warn "used_disks: " . Dumper(\%used_disks) . "\n" if DEBUG_MANAGE_RAID;
# Check for any spare disks we could add
my %free_disks = map {$_ => 1} get_disks();
delete $free_disks{$_} for keys %used_disks;
warn "free_disks: " . Dumper(\%free_disks) . "\n" if DEBUG_MANAGE_RAID;
# Report status and return if recovering
if (scalar @recovering)
{
$text .= gettext("A RAID resynchronization is in progress.");
($rc, $choice) = $console->message_page(title => $title, text => $text);
return;
}
# Report status and return if arrays are inconsistent
if ((scalar @unclean && scalar @unclean != scalar keys %devices) || (scalar @failed && scalar @failed != scalar keys %devices))
{
$text .= gettext("Only some of the RAID devices are unclean or contain failed disks.") .
"\n\n" .
gettext("Manual intervention may be required.") . "\n\n";
($rc, $choice) = $console->message_page(title => $title, text => $text);
return;
}
# Report status if arrays are clean and continue if a spare disk is available or there's only one disk in the system
unless (scalar @unclean || scalar @failed)
{
$text .= gettext("All RAID devices are in a clean state.");
($rc, $choice) = $console->message_page(title => $title, text => $text);
return unless scalar keys %free_disks > 0 || scalar keys %used_disks == 1;
}
# Report status if all arrays are dirty and continue
if ((scalar @unclean && scalar @unclean == scalar keys %devices) || (scalar @failed && scalar @failed == scalar keys %devices))
{
$text .= gettext("All RAID devices are in an unclean state or contain failed disks.");
($rc, $choice) = $console->message_page(title => $title, text => $text);
}
# Summarise disk assignments
my $disk_status = gettext("Current disk status:") . "\n\n";
$disk_status .= gettext("Installed disks") . ": " .
join(" ", get_disks()) . "\n";
$disk_status .= gettext("Used disks") . ": " .
join(" ", keys %used_disks) . "\n";
$disk_status .= gettext("Free disks") . ": " .
join(" ", keys %free_disks) . "\n";
# Spare disk scenarios
# Scenario 1 - single disk or degraded array with no spare - warn
if ((scalar @unclean || scalar @failed || scalar keys %used_disks == 1) && scalar keys %free_disks == 0)
{
$text = $disk_status .
"\n\n" .
gettext("To ensure continued redundancy, please shut down, install another drive of the same capacity and then return to this screen.");
($rc, $choice) = $console->message_page(title => $title, text => $text);
return;
}
# Scenario 2 - no spares and not degraded so something has gone wrong
if (scalar keys %free_disks == 0)
{
$text = $disk_status .
"\n\n" .
gettext("Your RAID devices are in an inconsistent state, and no spare drives were detected. You may need to manually remove a failed drive from your arrays using mdadm.");
($rc, $choice) = $console->message_page(title => $title, text => $text);
return;
}
# Scenario 3 - multiple spares
if (scalar keys %free_disks > 1)
{
$text = $disk_status .
"\n\n" .
gettext("Multiple spare drives have been detected. This utility can only add one drive at a time. Please either shut down and remove all but one of your spare drives, or configure your array manually.");
($rc, $choice) = $console->message_page(title => $title, text => $text);
return;
}
# Scenario 4 - single spare ready to add
$text = $disk_status .
"\n\n" .
gettext("There is an unused disk drive in your system. Do you want to add it to the existing RAID array(s)?") .
"\n\n" .
gettext("WARNING: ALL DATA ON THE NEW DISK WILL BE DESTROYED!") .
"\n";
($rc, $choice) = $console->yesno_page(title => $title, text => $text, defaultno => 1);
return unless ($rc == 0);
my @cmd = ("/sbin/e-smith/add_drive_to_raid", "-f", join("", keys %free_disks));
my $cmd_out = qx( @cmd 2>&1 );
untaint $cmd_out;
if ($? == 0) {
$text = "\nSuccessfully added /dev/" . join("", keys %free_disks) . " to RAID!";
} else {
$text = gettext("The command failed:") . " @cmd" .
"\n\n" . $cmd_out . "\n\n";
}
($rc, $choice) = $console->message_page(title => $title, text => $text);
goto SCAN;
}
sub get_raid_status
{
die gettext("Couldn't open") . " /proc/mdstat:$!\n"
unless (open(MDSTAT, "/proc/mdstat"));
my @mdstat;
while (<MDSTAT>)
{
push @mdstat, "$1\n" if (/(.*\w.*)/);
}
close MDSTAT;
return @mdstat;
}
sub get_raid_details
{
my @devices = ();
die gettext("Couldn't call") . " mdadm: $!\n"
unless open(MDADM, "/sbin/mdadm --detail --scan|");
while (<MDADM>)
{
push @devices, $1 if ( m:ARRAY (/dev/md/\w+): )
}
close MDADM;
my %devices;
for my $dev (@devices)
{
die gettext("Couldn't call") . " mdadm --detail $dev: $!\n"
unless open(MDADM, "/sbin/mdadm --detail $dev|");
while ( <MDADM> )
{
if ( /\s*(.*)\s+:\s+(\d+)\s+\(.*\)\s*/ )
{
my ($key, $value) = ($1, $2);
$key =~ s/\s//g;
# Allow for different mdadm output formats for DeviceSize
$key =~ s/UsedDevSize/DeviceSize/;
$devices{$dev}{$key} = $value;
}
elsif ( /\s*(.*)\s+:\s+(.*)\s*/ )
{
my ($key, $value) = ($1, $2);
$key =~ s/\s//g;
$devices{$dev}{$key} = $value;
}
if ( m:\s+(\d+)\s+(\d+)\s+(\d+).*/dev/([\w\/]+): )
{
$devices{$dev}{$1} = $_;
my $used_disk = $4;
if (/(rd|ida|cciss|i2o)\//) {
$used_disk =~ s/p\d+$//;
} else {
$used_disk =~ s/\d+//;
}
push (@{$devices{$dev}{UsedDisks}}, $used_disk);
}
}
close MDADM;
}
return %devices;
}
sub get_partitions
{
die gettext("Couldn't read") . " /proc/partitions: $!\n"
unless open (PARTITIONS, "/proc/partitions");
my %parts;
while (<PARTITIONS>)
{
if ( /\s+(\d+)\s+(\d+)\s+(\d+)\s+([\w\/]+)\s+/ )
{
my $name = $4;
$parts{$name}{major} = $1;
$parts{$name}{minor} = $2;
$parts{$name}{blocks} = $3;
}
}
close PARTITIONS;
return %parts;
}
sub get_disks
{
my %parts = get_partitions();
my @disks;
for (keys %parts)
{
push @disks, $_ unless (/[0-9]$/);
push @disks, $_ if (/(rd|ida|cciss|i2o)\// && ! /p\d+$/);
}
return @disks;
}
return new esmith::console::manageDiskRedundancy;

View File

@@ -0,0 +1,80 @@
package esmith::console::reboot;
use strict;
use warnings;
use esmith::console;
use Locale::gettext;
sub new
{
my $class = shift;
my $self = {
name => gettext("Reboot, reconfigure or shut down this server"),
order => 40,
};
bless $self, $class;
return $self;
}
sub name
{
return $_[0]->{name};
}
sub order
{
return $_[0]->{order};
}
sub doit
{
#------------------------------------------------------------
# REBOOT_SHUTDOWN:
#------------------------------------------------------------
my ($self, $console, $db) = @_;
my @args =
(
gettext("Reboot"), gettext("Reboot this server"),
gettext("Reconfigure"), gettext("Reconfigure this server"),
gettext("Shutdown"), gettext("Shutdown this server"),
);
my ($rc, $choice) = $console->menu_page
(
title => gettext("Reboot, reconfigure or shutdown this server"),
text =>
gettext("Please select whether you wish to reboot, reconfigure or shutdown. The process will start as soon as you make your selection.") .
"\n\n" .
gettext("If you have an older computer without power management, the shutdown process will perform a clean halt of all system services, but will not actually power off your computer. In this case, wait for the power down message and then shut off the power manually.") .
"\n\n" .
gettext("If you have changed your mind and do not want to reboot or shutdown, use the Tab key to select Cancel, then press Enter."),
argsref => \@args,
left => gettext("Cancel"),
right => gettext("OK"),
);
return unless ($rc == 0);
if ($choice eq gettext('Shutdown'))
{
system("/usr/bin/tput", "clear");
system("/sbin/e-smith/signal-event", "halt");
}
elsif ($choice eq gettext('Reboot'))
{
system("/usr/bin/tput", "clear");
system("/sbin/e-smith/signal-event", "reboot");
}
elsif ($choice eq gettext('Reconfigure'))
{
system("/usr/bin/tput", "clear");
system("/sbin/e-smith/signal-event", "post-upgrade");
system("/sbin/e-smith/signal-event", "reboot");
}
# A bit of a hack to avoid the console restarting before the
# reboot takes effect.
sleep(600);
}
return new esmith::console::reboot;

View File

@@ -0,0 +1,60 @@
package esmith::console::serverManager;
use strict;
use warnings;
use esmith::console;
use Locale::gettext;
sub new
{
my $class = shift;
my $self = {
name => gettext("Access server manager"),
order => 50,
};
bless $self, $class;
return $self;
}
sub name
{
return $_[0]->{name};
}
sub order
{
return $_[0]->{order};
}
sub doit
{
my ($self, $console, $db) = @_;
#------------------------------------------------------------
# MANAGER:
#------------------------------------------------------------
my $SystemName = $db->get_value('SystemName');
my ($rc, $choice) = $console->yesno_page
(
title => gettext("Access server manager"),
text =>
gettext("This option will start a text-mode browser to access the server manager from this console. Normally you would access the server manager from a web browser at the following url:") .
"\n\n" .
"http://${SystemName}/server-manager/" .
"\n\n" .
gettext("You should only proceed if you are comfortable using a text-mode browser. Note that you will be prompted for the administrator password in order to access the server manager.") .
"\n\n" .
gettext("NOTE: The 'q' key is used to quit from the text-mode browser.") .
"\n\n" .
gettext("Do you wish to proceed?"),
);
if ($rc == 0)
{
system(
"/usr/bin/links",
"http://localhost/server-manager"
);
}
$db->reload;
}
return new esmith::console::serverManager;

View File

@@ -0,0 +1,70 @@
package esmith::console::status;
use strict;
use warnings;
use esmith::console;
use Locale::gettext;
sub new
{
my $class = shift;
my $self = {
name => gettext("Check status of this server"),
order => 10,
};
bless $self, $class;
return $self;
}
sub name
{
return $_[0]->{name};
}
sub order
{
return $_[0]->{order};
}
sub doit
{
#------------------------------------------------------------
# STATUS:
#------------------------------------------------------------
my ($self, $console, $db) = @_;
use POSIX qw(strftime);
my $today = strftime "%A %B %e, %Y", localtime;
unless (open(UPTIME, "</proc/uptime"))
{
warn("Could not open /proc/uptime: $!");
return;
}
my $seconds = <UPTIME>;
close UPTIME or warn("Could not close /proc/uptime: $!");
# Select and untaint seconds
$seconds =~ /(\d+)/;
$seconds = $1;
my $days = int ($seconds / 86400);
$seconds = $seconds % 86400;
my $hours = int ($seconds / 3600);
$seconds = $seconds % 3600;
my $minutes = int ($seconds / 60);
$seconds = $seconds % 60;
my ($rc, $choice) = $console->screen
(
"--title", gettext("Status of this server as of") . " " . $today,
"--msgbox", gettext("This server has been running for") . " " .
$days . " " . gettext("days") . ", " .
$hours . " " . gettext("hours") . ", " .
$minutes . " " . gettext("minutes"),
7, esmith::console::SCREEN_COLUMNS
);
}
return new esmith::console::status;

View File

@@ -0,0 +1,107 @@
#!/usr/bin/perl -wT
#----------------------------------------------------------------------
# copyright (C) 1999-2006 Mitel Corporation
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------
package esmith::console;
use strict;
use Locale::gettext;
use esmith::ConfigDB::unsaved;
use esmith::console;
use esmith::console::quitConsole;
my $console = esmith::console->new();
my $db = esmith::ConfigDB::unsaved->open;
my $termType = $db->get_prop('serial-console', 'Terminal') || '';
my $SystemName = $db->get_value('SystemName');
my $DomainName = $db->get_value('DomainName');
$ENV{TERM} = $termType if($termType);
system '/bin/sh', '/etc/profile.d/lang.sh';
my %menu2object = ();
my @args = ();
my @items = ();
my $menu_dir = '/sbin/e-smith/console-menu-items';
opendir ITEMS, $menu_dir;
while (defined (my $item = readdir ITEMS ))
{
next unless -f "$menu_dir/$item";
if ($item =~ /([\w\.]+)/)
{
$item = $1;
}
else
{
warn "Don't know what to do with $menu_dir/$item\n";
next;
}
my $obj = require "$menu_dir/$item";
push @items, $obj;
}
close ITEMS;
my $number = 1;
foreach my $item (sort { $a->order <=> $b->order } @items)
{
next if ($item->order < 0);
push @args, $number . '.', gettext($item->name);
$menu2object{$number++ . '.'} = $item;
}
my $quit = esmith::console::quitConsole->new;
while (1)
{
#----------------------------------------
# Reload the configuration from file
#----------------------------------------
$db->reload;
my $title = gettext('Server console');
$title .= " (${SystemName}.${DomainName}) ";
$title .= gettext('** unsaved changes **')
if ( $db->get_value('UnsavedChanges') eq 'yes' );
my ($rc, $choice) = $console->menu_page
(
title => $title,
text =>
gettext('Welcome to the server console!') .
"\n\n" .
gettext('Use the Arrow and Tab keys to make your selection, then press Enter.'),
argsref => \@args,
left => gettext('Exit'),
);
$choice = ($rc == 0) ? $menu2object{$choice} : $quit;
$choice->doit($console, $db);
}

View File

@@ -0,0 +1,125 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
#
# generate-subjectaltnames
#
# This script returns a list of hostnames and IP addresses that
# can be used to construct the list of subjectAltName entries
# for a web server certificate.
#
# Usage: generate-subjectaltnames
#
# Copyright 1999-2003 Mitel Networks Corporation
# This program is free software; you can redistribute it and/or
# modify it under the same terms as Perl itself.
#
#----------------------------------------------------------------------
use esmith::ConfigDB;
use esmith::HostsDB;
my $configuration = esmith::ConfigDB->open_ro('configuration')
or die "Couldn't open configuration DB\n";
my $domains = esmith::ConfigDB->open_ro('domains')
or die "Couldn't open domains DB\n";
my $hosts = esmith::HostsDB->open_ro()
or die "Couldn't open domains DB\n";
my %results_dict = ();
#----------------------------------------------------------------------
# Add FQDN, system name and the domain name.
#----------------------------------------------------------------------
$SystemName = $configuration->get('SystemName')->value;
$DomainName = $configuration->get('DomainName')->value;
$results_dict{$SystemName . '.' . $DomainName} = 1;
$results_dict{$SystemName} = 1;
$results_dict{$DomainName} = 1;
#----------------------------------------------------------------------
# Add a wildcard entry for domain name.
#----------------------------------------------------------------------
$results_dict{'*.' . $DomainName} = 1;
#----------------------------------------------------------------------
# Add IP addresses for the various interfaces.
#----------------------------------------------------------------------
foreach $Interface ('InternalInterface',
'ExternalInterface',
'ExternalInterface2')
{
$Interface_Record = $configuration->get($Interface);
if ($Interface_Record)
{
if (defined $Interface_Record->prop('Configuration') and $Interface_Record->prop('Configuration') eq 'static')
{
if ($Interface_Record->prop('IPAddress'))
{
$results_dict{$Interface_Record->prop('IPAddress')} = 1;
}
}
}
}
#----------------------------------------------------------------------
# Add all domains defined
#----------------------------------------------------------------------
my $modSSL = $configuration->get('modSSL');
my $AddDomains = $modSSL->prop('AddDomains') || "enabled";
if ( $AddDomains eq "enabled" )
{
foreach my $domain ( $domains->get_all_by_prop(type => 'domain') )
{
$results_dict{$domain->key} = 1;
}
}
#----------------------------------------------------------------------
# Add all hosts per domains defined
#----------------------------------------------------------------------
my $AddHosts = $modSSL->prop('AddHosts') || "enabled";
if ( $AddHosts eq "enabled" )
{
foreach my $domain ($domains->get_all_by_prop(type => 'domain')) #ignore domain-remote
{
foreach my $host ( $hosts->get_hosts_by_domain($domain->key) )
{
next unless (($host->prop('HostType')||'undef') eq 'Self'); #only define self host
$results_dict{$host->key} = 1;
}
}
}
#----------------------------------------------------------------------
# Add any alternate names specified in the modSSL config DB.
#----------------------------------------------------------------------
if ($modSSL)
{
$AlternateNames = $modSSL->prop('AlternateNames');
if ($AlternateNames)
{
foreach $AlternateName (split(',', $AlternateNames))
{
$AlternateName =~ s/\s//g;
$results_dict{$AlternateName} = 1;
}
}
}
#----------------------------------------------------------------------
# Output the sorted list of entries.
#----------------------------------------------------------------------
foreach (sort keys %results_dict)
{
print "$_\n";
}
exit(0);

68
root/sbin/e-smith/mdevent Normal file
View File

@@ -0,0 +1,68 @@
#!/usr/bin/perl -w
#----------------------------------------------------------------------
# mdevent: Handle events from mdadm --monitor
#----------------------------------------------------------------------
# Copyright (C) 2006 Shad L. Lords <slords@mail.com>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#----------------------------------------------------------------------
package esmith;
use strict;
use esmith::ConfigDB;
use esmith::util;
use esmith::db;
use Text::Template;
my $conf = esmith::ConfigDB->open_ro;
my $event = $ARGV [0];
my $device = $ARGV [1];
my $member = $ARGV [2] || '';
print "Event: $event, Device: $device, Member: $member\n";
if ($event =~ m#^Rebuild# && system( "ps -C raid-check" ) == 0 ) {
exit 0;
}
if ($event =~ m#^Rebuild|^Fail|^Degraded|^SpareActive#) {
my $domain = $conf->get_value("DomainName") || 'localhost';
my $user = "admin_raidreport\@$domain";
my $templates = '/etc/e-smith/templates';
my $source = '/usr/lib/e-smith-mdevent/mdEvent.tmpl';
-f "${templates}-custom${source}" and $templates .= "-custom";
my $t = new Text::Template(TYPE => 'FILE',
SOURCE => "${templates}${source}");
open(QMAIL, "|/var/qmail/bin/qmail-inject -froot\@$domain $user")
|| die "Could not send mail via qmail-inject!\n";
print QMAIL $t->fill_in( HASH => {
conf => \$conf,
user => $user,
event => $event,
device => $device,
member => $member,
});
close QMAIL;
}

57
root/sbin/e-smith/service Executable file
View File

@@ -0,0 +1,57 @@
#! /bin/sh
# prevent initscript to use systemctl
export SYSTEMCTL_SKIP_REDIRECT=1
. /etc/rc.d/init.d/functions
# what is our current runlevel
runlevel=$(systemctl get-default)
SERVICE=$1
USAGE="Usage: service SERVICENAME [ACTION]"
#if no servicename is provided return usage
if [[ "${SERVICE}" == "" ]]
then
echo ${USAGE} >&2
exit
fi
if [ "$runlevel" = "multi-user.target" ] || [ "$runlevel" = "sme-server.target" ]
then
if ls /etc/rc7.d/S??$1 >/dev/null 2>/dev/null
then
script=$(ls /etc/rc7.d/S??$1 | head -1)
exec $script $2
elif ls /usr/lib/systemd/system/${SERVICE}.service >/dev/null 2>/dev/null || ls /etc/systemd/system/${SERVICE}.service >/dev/null 2>/dev/null
then
if [[ "$2" == "" ]] ; then
echo "'$1' requires an action" 1>&2
echo ${USAGE} >&2
exit
elif [[ $2 == "status" ]] ; then
exec /bin/systemctl status -n0 ${SERVICE}
exit
elif [[ $2 == "start" ]] ; then
echo -n "Starting ${SERVICE}" 2>/dev/null
elif [[ $2 == "stop" ]] ; then
echo -n "Stopping ${SERVICE}" 2>/dev/null
elif [[ $2 == "restart" ]] ; then
echo -n "Restarting ${SERVICE}" 2>/dev/null
else
echo -n "Sending $2 signal to ${SERVICE}" 2>/dev/null
fi
/bin/systemctl $2 ${SERVICE}.service> /dev/null
if [ $? -ne 0 ]; then
echo_failure
else
echo_success
fi
echo
exit
fi
echo "'$1' is not a valid service name" 1>&2
exit 1
else
exec /sbin/service "$@"
fi

View File

@@ -0,0 +1,30 @@
#! /bin/sh
SERVICE=$1
USAGE="Usage: service-status SERVICENAME"
#if no servicename is provided return usage
if [[ "${SERVICE}" == "" ]]
then
echo ${USAGE} >&2
exit 1
fi
TYPE=$(/sbin/e-smith/db configuration gettype "$SERVICE" || echo none)
if [[ "$TYPE" != 'service' ]]
then
echo "$SERVICE is not a service"
exit 9
fi
STATUS=$(/sbin/e-smith/db configuration getprop "$SERVICE" status || echo disabled)
if [[ "$STATUS" != 'enabled' ]]
then
echo "$SERVICE status not enabled in configuration db."
exit 0
# change this one to 5 if you want systemd to fail on ExecStartPre
fi
exit 0

180
root/sbin/e-smith/systemctl Normal file
View File

@@ -0,0 +1,180 @@
#!/bin/bash
#systemctl wrapper fo Koozali SME Server
allargs=$@
opts=();
syscommand="";
sysunit=""
debug=$(/sbin/e-smith/config get debug || echo "false")
if [ "$debug" != "true" ]; then debug=false;fi
# short OPTIONS we must pay attention as they have more arguments
#-t, --type=
#-s, --signal=
#-p, --property=
#-o, --output=
#-n, --lines=
#-H, --host=
#-M, --machine=
#commands we should return directly to systemd
#list-units,list-sockets,list-timers,is-active,is-failed,status,show,cat,set-property,help,reset-failed,list-dependencies,
#list-unit-files,is-enabled,get-default,set-default
#list-machines
#list-jobs
#snapshot,delete
#show-environment,set-environment,unset-environment,import-environment
#daemon-reload,daemon-reexec
#is-system-running,default,rescue,emergency,halt,poweroff,reboot,kexec,switch-root,suspend,hibernate,hybrid-sleep
# This is a list of commands :
# -we want to handle ourself or
# -we need to translate for systemd or
# -we do not want admin uses against the SME Server
#
# commands we handle: start,stop,reload,restart,try-restart,reload-or-restart,reload-or-try-restart,isolate,kill
# enable,disable,reenable,preset,preset-all,mask,unmask,link,add-wants,edit
# commands we deactivate/hide : mask,unmask,link,add-wants,edit set-default
# not systemd but we might use them : adjust sigterm sighup sigusr1 sigusr2
filteredcommands=(start stop reload restart try-restart reload-or-restart reload-or-try-restart isolate kill enable disable reenable preset preset-all adjust sigterm sighup sigusr1 sigusr2 mask unmask link add-wants add-requires edit set-default );
# fucntion to check if this is a command we want
contains2 () {
local seeking=$1
local in=0
for element in "${filteredcommands[@]}"; do
if [[ $element == "$seeking" ]]; then
in=1
break
fi
done
return $in
}
# if no args we return to systemcl
if [ $# -eq 0 ]; then
echo "we return to systemctl"
/usr/bin/systemctl
exit
fi
#parse args
while [ "$#" -gt 0 ]; do
case "$1" in
-p|-t|-s|-o|-n|H|-M) temp=$1; shift ; opts+=("$temp $1"); ;;
--*) opts+=("$1") ;;
-*) opts+=("$1") ;;
*) if [[ "$syscommand" == "" ]]; then syscommand="$1" ; else sysunit="$1"; fi ;;
esac
shift
done
servicename=${sysunit%".service"}
#we return to systemd systemctl command unless this is one of the command we want to handle
if ( contains2 "$syscommand" ) ; then
($debug) && echo "we return to /usr/bin/systemctl ${allargs[*]}"
/usr/bin/systemctl ${allargs[*]}
exit
fi
# here we convert sig* to kill -s=SIG* or SME commant to ones systemd recognize
case "$syscommand" in
adjust|sighup|sigusr1|sigusr2)
$syscommand="reload-or-restart";
;;
sigterm)
$syscommand="restart";
;;
esac
# catch here non unit signals, or ones we would like to do something different
#enable disable reenable preset preset-all
#mask unmask link add-wants edit
case "$syscommand" in
preset-all)
($debug) && echo "We do /etc/e-smith/events/actions/systemd-default"
/etc/e-smith/events/actions/systemd-default
exit
;;
preset)
# TODO looking if we could use /etc/e-smith/events/actions/systemd-default none $servicename
($debug) && echo "We do /etc/e-smith/events/actions/systemd-default"
/etc/e-smith/events/actions/systemd-default
exit
;;
enable|disable|reenable)
# looking if we could use
newstatus="enabled"
todo="enable"
if [ $syscommand == "disable" ]; then newstatus="disabled";todo="disable" ; fi
/sbin/e-smith/config setprop $servicename status $newstatus
#/etc/e-smith/events/actions/systemd-default none $servicename
# TODO looking if we could do it only for the service would be great!
($debug) && echo "We do /etc/e-smith/events/actions/systemd-default"
($debug) && echo "/usr/bin/systemctl $todo $sysunit ${opts[*]}"
/etc/e-smith/events/actions/systemd-default
/usr/bin/systemctl $todo $sysunit ${opts[*]}
exit
;;
set-default |isolate)
echo "We only $syscommand against sme-server.target"
($debug) && echo "/etc/e-smith/events/actions/systemd-default"
($debug) && echo "/etc/e-smith/events/actions/systemd-isolate"
/etc/e-smith/events/actions/systemd-default
/etc/e-smith/events/actions/systemd-isolate
;;
link|mask|unmask|add-wants|add-requires|edit)
echo "Please, do not use $syscommand for Koozali SME Server"
exit
;;
esac
#check the unit exist or fails : we do not care systemctl will do this...
# here we check if in db and if enabled or disabled
# if not or not service = return to systemctl directly
stype=$(/sbin/e-smith/db configuration gettype $servicename || echo "none")
sstatus=$(/sbin/e-smith/db configuration getprop $servicename status || echo "disabled")
if [ $stype == "none" ] ; then
# not defined in db, we redirect
echo "Information: $sysunit is not defined in configuration DB."
($debug) && echo "/usr/bin/systemctl ${allargs[*]}"
/usr/bin/systemctl ${allargs[*]}
exit
elif [ $stype != "service" ] ; then
echo "Information: $sysunit is not defined as a service in configuration DB but $type"
($debug) && echo "/usr/bin/systemctl ${allargs[*]}"
/usr/bin/systemctl ${allargs[*]}
exit
elif [ $sstatus == "disabled" ]; then
echo "Information: $sysunit is $sstatus in configuration DB."
# we might want to simply stop
#/usr/bin/systemctl stop $sysunit
# but we will do what we were asked for
($debug) && echo "/usr/bin/systemctl ${allargs[*]}"
/usr/bin/systemctl ${allargs[*]}
exit
elif [ $sstatus == "enabled" ]; then
#echo "$sstatus"
# starting in case
#systemctl is-active -q $sysunit will return zero if active; non zero if not
#/usr/bin/systemctl is-active -q $sysunit || /usr/bin/systemctl start $sysunit
# now executing the command
($debug) && echo "/usr/bin/systemctl $syscommand $sysunit ${opts[*]}"
/usr/bin/systemctl $syscommand $sysunit ${opts[*]}
exit
fi
echo "if you see that, we missed something, report the command to https://bugs.koozali.org"
echo "options : " ${opts[*]};
echo "command : " $syscommand;
echo "unit :" $sysunit;
echo $@

View File

@@ -0,0 +1,10 @@
#!/bin/sh
count=$(sed -n '/[0-9]\s\+[^ ]\+[^0-9]$/p;/[0-9]\s\+\(rd\|ida\|cciss\|i2o\)\/[^ ]\+[^0-9p][0-9]\+$/p' /proc/partitions | wc -l)
if [ $count -ge 2 ]
then
exit 0
else
echo "Only $count drive(s) in this system - disabling raid monitoring"
exit 1
fi

View File

@@ -0,0 +1,16 @@
#!/bin/bash
# before 10.1 rsyslog was listening to /dev/log
# we want systemd-journald listen to that now
# and rsyslog to /run/systemd/journal/syslog
# will not be needed in SME 11
if [[ ! -S /dev/log ]]; then
#echo "no /dev/log"
/usr/bin/systemctl restart systemd-journald.socket
/usr/bin/systemctl restart systemd-journald.service
fi
# we can now keep going with rsyslog startup
# /etc/rsyslog.conf will define the use of /run/systemd/journal/syslog