smeserver-manager/root/usr/share/smanager/lib/SrvMngr/Controller/Yum.pm

582 lines
11 KiB
Perl

package SrvMngr::Controller::Yum;
#----------------------------------------------------------------------
# heading : System
# description : Software installer
# navigation : 4000 300
#
# routes : end
#----------------------------------------------------------------------
use strict;
use warnings;
use Mojo::Base 'Mojolicious::Controller';
use Locale::gettext;
use SrvMngr::I18N;
use SrvMngr qw(theme_list init_session ip_number_or_blank);
use esmith::ConfigDB;
use esmith::util;
use File::Basename;
our $cdb = esmith::ConfigDB->open || die "Couldn't open config db";
my $dnf_status_file = '/var/cache/dnf/dnf.status';
#use File::stat;
our %dbs;
for ( qw(available installed updates) )
{
$dbs{$_} = esmith::ConfigDB->open_ro("dnf_$_") or
die "Couldn't open dnf_$_ DB\n";
}
for ( qw(repositories) )
{
$dbs{$_} = esmith::ConfigDB->open("yum_$_") or
die "Couldn't open yum_$_ DB\n";
}
sub main {
my $c = shift;
$c->app->log->info($c->log_req);
my %yum_datas = ();
my $title = $c->l('yum_FORM_TITLE');
my $dest = 'yum';
my $notif = '';
$yum_datas{'trt'} = 'STAT';
if ( $c->is_dnf_running()) {
$yum_datas{'trt'} = 'LOGF';
$dest = 'yumlogfile';
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
$yum_datas{'trt'} = 'PSTU';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
$dest = 'yumpostupg';
} else {
# normal other trt
}
$c->stash( title => $title, notif => $notif, yum_datas => \%yum_datas );
return $c->render( template => $dest );
}
sub do_display {
my $c = shift;
my $rt = $c->current_route;
my $trt = ($c->param('trt') || 'STAT');
my %yum_datas = ();
my $title = $c->l('yum_FORM_TITLE');
my ($notif, $dest) = '';
$yum_datas{'trt'} = $trt;
# force $trt if current logfile
if ( $c->is_dnf_running() ) {
$trt = 'LOGF';
} elsif ($cdb->get_prop('dnf', 'LogFile')) {
$trt = 'PSTU';
}
if ( $trt eq 'UPDT' ) {
$dest = 'yumupdate';
}
if ( $trt eq 'INST' ) {
$dest = 'yuminstall';
}
if ( $trt eq 'REMO' ) {
$dest = 'yumremove';
}
if ( $trt eq 'CONF' ) {
$dest = 'yumconfig';
}
if ( $trt eq 'LOGF' ) {
if ($c->is_dnf_running()) {
$dest = 'yumlogfile';
}
}
if ( $trt eq 'PSTU') {
if ($cdb->get_prop('dnf', 'LogFile')) {
$dest = 'yumpostupg';
$yum_datas{'reconf'} = $cdb->get_value('UnsavedChanges', 'yes');
}
}
if ( ! $dest ) { $dest = 'yum'; }
$c->stash( title => $title, notif => $notif, yum_datas => \%yum_datas );
return $c->render( template => $dest );
};
sub do_update {
my $c = shift;
$c->app->log->info($c->log_req);
my $rt = $c->current_route;
my $trt = $c->param('trt');
my %yum_datas = ();
$yum_datas{trt} = $trt;
my $title = $c->l('yum_FORM_TITLE');
my ($dest, $res, $result) = '';
if ( $trt eq 'UPDT' ) {
$dest = 'yumupdate';
if ( ! $result ) {
$res = $c->do_yum('update');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
#$result = $c->l('yum_SUCCESS');
}
}
}
if ( $trt eq 'INST' ) {
$dest = 'yuminstall';
if ( ! $result ) {
$res = $c->do_yum('install');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
#$result = $c->l('yum_SUCCESS');
}
}
}
if ( $trt eq 'REMO' ) {
$dest = 'yumremove';
if ( ! $result ) {
$res = $c->do_yum('remove');
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
#$result = $c->l('yum_SUCCESS');
}
}
}
if ( $trt eq 'CONF' ) {
$dest = 'yumconfig';
if ( ! $result ) {
$res = $c->change_settings();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
}
}
}
if ( $trt eq 'PSTU') {
my $reconf = $c->param('reconf') || 'yes';
$dest = 'yumpostupg';
# effective reconfigure and reboot required
if ( $reconf eq 'yes' ) {
$res = $c->post_upgrade_reboot();
$result .= $res unless $res eq 'OK';
if ( ! $result ) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SYSTEM_BEING_RECONFIGURED');
}
} else {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_UPDATE_SUCCESS');
}
}
if ( $trt eq 'LOGF' ) {
$dest = 'yumlogfile';
if ( ! $c->is_dnf_running()) {
$yum_datas{trt} = 'SUC';
$result = $c->l('yum_SUCCESS');
}
}
# do_yum ended (no message) --> forced to LOGFile
if ( ! $result ) {
$dest = 'yumlogfile';
$yum_datas{trt} = 'LOGF';
}
$c->stash( title => $title, notif => $result, yum_datas => \%yum_datas );
if ($yum_datas{trt} ne 'SUC') {
return $c->render(template => $dest);
}
my $message = "'Yum' $trt update DONE";
$c->app->log->info($message);
$c->flash(success => $result) if $result;
$c->redirect_to("/yum");
};
sub get_dnf_status {
#interrogate status file created and maintained by smeserver.py plugin for dnf.
my ($c) = @_;
my $file_name = $dnf_status_file;
my $content = "resolved";
if ( -e "$file_name") {
open my $fh, '<', $file_name or die "Can't open file: $!";
$content = <$fh>;
close $fh;
}
return $content;
}
sub is_dnf_running {
my ($c) = @_;
my $dnf_status = $c->get_dnf_status();
return $dnf_status ne "resolved" && $dnf_status ne "config" && $dnf_status ne "sack";
}
sub is_empty {
my ($c, $yumdb) = @_;
my $groups = $dbs{$yumdb}->get_all_by_prop(type => 'group') || 'none';
my $packages = $dbs{$yumdb}->get_all_by_prop(type => 'package') || 'none';
#Show no updates if both = none
return 1 if ($packages eq $groups);
#else return here
return;
}
sub non_empty {
my ($c, $yumdb, $type) = @_;
$type ||= 'both';
return 0 unless (exists $dbs{$yumdb});
my $groups = scalar $dbs{$yumdb}->get_all_by_prop(type => 'group');
return $groups if ($type eq 'group');
my $packages = scalar $dbs{$yumdb}->get_all_by_prop(type => 'package');
if ($type eq 'package')
{
return $c->package_functions_enabled ? $packages : 0;
}
return ($c->package_functions_enabled or $yumdb eq 'updates') ?
($groups || $packages) : $groups;
}
sub package_functions_enabled {
my ($c) = @_;
return ($cdb->get_prop("dnf", "PackageFunctions") eq "enabled");
}
sub get_status {
my ($c, $prop, $localise) = @_;
my $status = $cdb->get_prop("dnf", $prop) || 'disabled';
return $status unless $localise;
return $c->l($status eq 'enabled' ? 'ENABLED' : 'DISABLED');
}
sub get_options {
my ($c, $yumdb, $type) = @_;
my %options;
for ($dbs{$yumdb}->get_all_by_prop(type => $type))
{
$options{$_->key} = $_->key . " " . $_->prop("Version") . " - " .
$_->prop("Repo");
}
return \%options;
}
sub get_options2 {
my ($c, $yumdb, $type) = @_;
my @options;
for ($dbs{$yumdb}->get_all_by_prop(type => $type))
{
push @options, [ $_->key . " " . $_->prop("Version") . " - " .
$_->prop("Repo") => $_->key ];
}
return \@options;
}
sub get_names {
return [ keys %{get_options(@_)} ];
}
sub get_names2 {
my ($c, $yumdb, $type) = @_;
my @selected;
for ($dbs{$yumdb}->get_all_by_prop(type => $type)) {
push @selected, $_->key;
}
return \@selected;
# return [ values @{get_options2(@_)} ];
}
sub get_repository_options2 {
my $c = shift;
my @options;
foreach my $repos (
$dbs{repositories}->get_all_by_prop(type => "repository") )
{
next unless ($repos->prop('Visible') eq 'yes'
or $repos->prop('status') eq 'enabled');
push @options, [ $repos->prop('Name') => $repos->key ];
}
my @opts = sort { $a->[0] cmp $b->[0] } @options;
return \@opts;
}
sub get_repository_current_options
{
my $c = shift;
my @selected;
foreach my $repos (
$dbs{repositories}->get_all_by_prop( type => "repository" ) )
{
next unless ($repos->prop('Visible') eq 'yes'
or $repos->prop('status') eq 'enabled');
push @selected, $repos->key if ($repos->prop('status') eq 'enabled');
}
return \@selected;
}
sub get_avail2 {
my ($c, $yumdb, $type) = @_;
return $c->get_options2("available", "package");
}
sub get_check_freq_opt {
my ($c) = @_;
return [[ $c->l('DISABLED') => 'disabled'],
[ $c->l('yum_1DAILY') => 'daily'],
[ $c->l('yum_2WEEKLY') => 'weekly'],
[ $c->l('yum_3MONTHLY') => 'monthly']];
}
sub print_skip_header {
my ($c) = shift;
return "<INPUT TYPE=\"hidden\" NAME=\"skip_header\" VALUE=\"1\">\n";
}
sub change_settings {
my ($c) = @_;
for my $param ( qw(
PackageFunctions
) )
{
$cdb->set_prop("dnf", $param, $c->param("yum_$param"));
}
my $check4updates = $c->param("yum_check4updates");
my $status = 'disabled';
if ($check4updates ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop("dnf", 'check4updates', $check4updates);
my $deltarpm = $c->param("yum_DeltaRpmProcess");
$cdb->set_prop("dnf", 'DeltaRpmProcess', $deltarpm);
my $downloadonly = $c->param("yum_DownloadOnly");
if ($downloadonly ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop("dnf", 'DownloadOnly', $downloadonly);
my $AutoInstallUpdates = $c->param("yum_AutoInstallUpdates");
if ($AutoInstallUpdates ne 'disabled') { $status = 'enabled'; }
$cdb->set_prop("dnf", 'AutoInstallUpdates', $AutoInstallUpdates);
$cdb->set_prop("dnf", 'status', $status);
my %selected = map {$_ => 1} @{$c->every_param('SelectedRepositories')};
foreach my $repos (
$dbs{repositories}->get_all_by_prop(type => "repository") )
{
$repos->set_prop("status",
exists $selected{$repos->key} ? 'enabled' : 'disabled');
}
$dbs{repositories}->reload;
unless ( system( "/sbin/e-smith/signal-event", "dnf-modify" ) == 0 )
{
return $c->l('yum_ERROR_UPDATING_CONFIGURATION');
}
return 'OK';
}
sub do_yum {
my ($c, $function) = @_;
for ( qw(SelectedGroups SelectedPackages) )
{
$cdb->set_prop("dnf", $_, join(',', (@{$c->every_param($_)} )));
}
esmith::util::backgroundCommand(0,
"/sbin/e-smith/signal-event", "dnf-$function");
for ( qw(available installed updates) ) {
$dbs{$_}->reload;
}
return 'OK';
}
sub get_yum_status_page {
my ($c) = @_;
my $yum_status;
open(YUM_STATUS, "</var/run/yum.status");
$yum_status = <YUM_STATUS>;
close(YUM_STATUS);
return $yum_status;
}
sub format_yum_log {
my $c = shift;
$cdb->reload;
my $filepage = $cdb->get_prop('dnf', 'LogFile');
return '' unless $filepage and ( -e "$filepage" );
my $out = sprintf "<PRE>";
open (FILE, "$filepage");
while (<FILE>) {
$out .= sprintf("%s", $_);
}
close FILE;
$out .= sprintf "</PRE>";
undef $filepage;
return $out;
}
sub post_upgrade_reboot {
my $c = shift;
$cdb->get_prop_and_delete('dnf', 'LogFile');
$cdb->reload;
if (fork == 0) {
exec "/sbin/e-smith/signal-event post-upgrade; /sbin/e-smith/signal-event reboot";
die "Exec failed";
}
return 'OK'
}
sub show_yum_log {
my $c = shift;
my $out = $c->format_yum_log();
my $yum_log = $cdb->get_prop_and_delete('dnf', 'LogFile');
return $out;
}
1;