Skip to content

Commit

Permalink
Merge pull request #362 from cPholloway/RE-71
Browse files Browse the repository at this point in the history
Add blocker for start mode if backup or upcp is currently executing
  • Loading branch information
toddr authored Jan 29, 2024
2 parents b4df54f + c7cf2f1 commit 154c62b
Show file tree
Hide file tree
Showing 10 changed files with 177 additions and 27 deletions.
9 changes: 9 additions & 0 deletions docs-website-src/content/blockers.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,15 @@ The following conditions are assumed to be in place any time you run this script
* You have cPanel version 102 or greater installed.
* You are logged in as **root**.

## Conflicting Processes

The following processes are known to conflict with this script and cannot be executed simulaneously.

* `/usr/local/cpanel/scripts/upcp`
* `/usr/local/cpanel/bin/backup`

**NOTE** These checks are only enforced when the script is executed in start mode

## Disk space

At any given time, the upgrade process may use at or more than 5 GB. If you have a complex mount system, we have determined that the following areas may require disk space for a period of time:
Expand Down
60 changes: 51 additions & 9 deletions elevate-cpanel
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ BEGIN { # Suppress load of all of these at earliest point.
}

my $blocker = cpev::Blocker->new( id => $caller_id, msg => $msg, %others );
die $blocker if $self->cpev->_abort_on_first_blocker;
die $blocker if $self->blockers->abort_on_first_blocker();

if ( !$others{'quiet'} ) {
WARN( <<~"EOS");
Expand Down Expand Up @@ -215,6 +215,7 @@ BEGIN { # Suppress load of all of these at earliest point.
cpev
check_mode
blockers
abort_on_first_blocker
);

# use Log::Log4perl qw(:easy);
Expand Down Expand Up @@ -293,8 +294,8 @@ BEGIN { # Suppress load of all of these at earliest point.
return 666;
}

$_CHECK_MODE = !!$check_mode; # running with --check
$self->cpev->{_abort_on_first_blocker} = !$_CHECK_MODE; # abort on first blocker
$_CHECK_MODE = !!$check_mode; # running with --check
$self->abort_on_first_blocker( !$_CHECK_MODE );

my $ok = eval { $self->_check_all_blockers; 1; };

Expand Down Expand Up @@ -1931,10 +1932,12 @@ EOS
use Elevate::Constants ();
use Elevate::Notify ();

use Cpanel::Version::Tiny ();
use Cpanel::Update::Tiers ();
use Cpanel::License ();
use Cpanel::Pkgr ();
use Cpanel::Backup::Sync ();
use Cpanel::Version::Tiny ();
use Cpanel::Update::Tiers ();
use Cpanel::License ();
use Cpanel::Pkgr ();
use Cpanel::Unix::PID::Tiny ();

# use Elevate::Blockers::Base();
our @ISA;
Expand All @@ -1943,6 +1946,10 @@ EOS
# use Log::Log4perl qw(:easy);
INIT { Log::Log4perl->import(qw{:easy}); }

use constant BACKUP_ID => Cpanel::Backup::Sync::BACKUP_TYPE_NEW;
use constant BACKUP_LOGDIR => '/usr/local/cpanel/logs/cpbackup';
use constant UPCP_PIDFILE => '/var/run/upcp.pid';

sub check ($self) {

my $ok = 1;
Expand All @@ -1953,6 +1960,8 @@ EOS
$ok = 0 unless $self->_blocker_cpanel_needs_license;
$ok = 0 unless $self->_blocker_cpanel_needs_update;
$ok = 0 unless $self->_blocker_is_sandbox;
$ok = 0 unless $self->_blocker_is_upcp_running;
$ok = 0 unless $self->_blocker_is_cpanel_backup_running;
$ok = 0 unless $self->_blocker_is_calendar_installed;

return $ok;
Expand Down Expand Up @@ -2061,6 +2070,41 @@ EOS
return 0;
}

sub _blocker_is_upcp_running ($self) {
return 0 unless $self->getopt('start');

my $upid = Cpanel::Unix::PID::Tiny->new();

my $upcp_pid = $upid->get_pid_from_pidfile(UPCP_PIDFILE);

if ($upcp_pid) {

$self->blockers->abort_on_first_blocker(1);

return $self->has_blocker( <<~"EOS");
cPanel Update (upcp) is currently running. Please wait for the upcp (PID $upcp_pid) to complete, then try again.
You can use the command 'ps --pid $upcp_pid' to check if the process is running.
EOS
}

return 0;
}

sub _blocker_is_cpanel_backup_running ($self) {
return 0 unless $self->getopt('start');

if ( !Cpanel::Backup::Sync::handle_already_running( BACKUP_ID, BACKUP_LOGDIR, Log::Log4perl->get_logger(__PACKAGE__) ) ) {

$self->blockers->abort_on_first_blocker(1);

return $self->has_blocker( <<~'EOS');
A cPanel backup is currently running. Please wait for the cPanel backup to complete, then try again.
EOS
}

return 0;
}

1;

} # --- END lib/Elevate/Blockers/WHM.pm
Expand Down Expand Up @@ -5066,8 +5110,6 @@ use Simple::Accessor qw{
service
script
blockers
_abort_on_first_blocker
};

# after Simple::Accessor
Expand Down
5 changes: 3 additions & 2 deletions lib/Elevate/Blockers.pm
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ use Simple::Accessor qw(
cpev
check_mode
blockers
abort_on_first_blocker
);

use Log::Log4perl qw(:easy);
Expand Down Expand Up @@ -119,8 +120,8 @@ sub _has_blockers ( $self, $check_mode = 0 ) {
return 666;
}

$_CHECK_MODE = !!$check_mode; # running with --check
$self->cpev->{_abort_on_first_blocker} = !$_CHECK_MODE; # abort on first blocker
$_CHECK_MODE = !!$check_mode; # running with --check
$self->abort_on_first_blocker( !$_CHECK_MODE );

my $ok = eval { $self->_check_all_blockers; 1; };

Expand Down
2 changes: 1 addition & 1 deletion lib/Elevate/Blockers/Base.pm
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ sub has_blocker ( $self, $msg, %others ) {
}

my $blocker = cpev::Blocker->new( id => $caller_id, msg => $msg, %others );
die $blocker if $self->cpev->_abort_on_first_blocker;
die $blocker if $self->blockers->abort_on_first_blocker();

if ( !$others{'quiet'} ) {
WARN( <<~"EOS");
Expand Down
53 changes: 49 additions & 4 deletions lib/Elevate/Blockers/WHM.pm
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,21 @@ use cPstrict;
use Elevate::Constants ();
use Elevate::Notify ();

use Cpanel::Version::Tiny ();
use Cpanel::Update::Tiers ();
use Cpanel::License ();
use Cpanel::Pkgr ();
use Cpanel::Backup::Sync ();
use Cpanel::Version::Tiny ();
use Cpanel::Update::Tiers ();
use Cpanel::License ();
use Cpanel::Pkgr ();
use Cpanel::Unix::PID::Tiny ();

use parent qw{Elevate::Blockers::Base};

use Log::Log4perl qw(:easy);

use constant BACKUP_ID => Cpanel::Backup::Sync::BACKUP_TYPE_NEW;
use constant BACKUP_LOGDIR => '/usr/local/cpanel/logs/cpbackup';
use constant UPCP_PIDFILE => '/var/run/upcp.pid';

sub check ($self) {

my $ok = 1;
Expand All @@ -34,6 +40,8 @@ sub check ($self) {
$ok = 0 unless $self->_blocker_cpanel_needs_license;
$ok = 0 unless $self->_blocker_cpanel_needs_update;
$ok = 0 unless $self->_blocker_is_sandbox;
$ok = 0 unless $self->_blocker_is_upcp_running;
$ok = 0 unless $self->_blocker_is_cpanel_backup_running;
$ok = 0 unless $self->_blocker_is_calendar_installed;

return $ok;
Expand Down Expand Up @@ -142,4 +150,41 @@ sub _blocker_is_calendar_installed ($self) {
return 0;
}

sub _blocker_is_upcp_running ($self) {
return 0 unless $self->getopt('start');

my $upid = Cpanel::Unix::PID::Tiny->new();

my $upcp_pid = $upid->get_pid_from_pidfile(UPCP_PIDFILE);

if ($upcp_pid) {

$self->blockers->abort_on_first_blocker(1);

return $self->has_blocker( <<~"EOS");
cPanel Update (upcp) is currently running. Please wait for the upcp (PID $upcp_pid) to complete, then try again.
You can use the command 'ps --pid $upcp_pid' to check if the process is running.
EOS
}

return 0;
}

sub _blocker_is_cpanel_backup_running ($self) {
return 0 unless $self->getopt('start');

if ( !Cpanel::Backup::Sync::handle_already_running( BACKUP_ID, BACKUP_LOGDIR, Log::Log4perl->get_logger(__PACKAGE__) ) ) {

$self->blockers->abort_on_first_blocker(1);

# Cpanel::Backup::Sync::handle_already_running will log the PID and log file location for the backup
# so there is no need for us to do that in the blocker message
return $self->has_blocker( <<~'EOS');
A cPanel backup is currently running. Please wait for the cPanel backup to complete, then try again.
EOS
}

return 0;
}

1;
2 changes: 0 additions & 2 deletions script/elevate-cpanel.PL
Original file line number Diff line number Diff line change
Expand Up @@ -330,8 +330,6 @@ use Simple::Accessor qw{
service
script
blockers
_abort_on_first_blocker
};

# after Simple::Accessor
Expand Down
2 changes: 1 addition & 1 deletion t/blocker-DiskSpace.t
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ is $check, 0, "_disk_space_check failure - /usr/local/cpanel 1.4 G";
);

$mock_ds->redefine( _disk_space_check => 1 );
ok( check_blocker( _abort_on_first_blocker => 1 ), 'System is up to date' );
ok( check_blocker(), 'System is up to date' );
}

undef $mock_saferun;
Expand Down
3 changes: 1 addition & 2 deletions t/blocker-IsContainer.t
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,7 @@ my $mock = Test::MockModule->new('Elevate::Blockers::IsContainer');

$mock->redefine( '_is_container_envtype' => 1 );

#my $cpev = bless { _abort_on_first_blocker => 1 }, 'cpev';
my $cpev = cpev->new( _abort_on_first_blocker => 1 );
my $cpev = cpev->new();
my $msg = <<~'EOS';
cPanel thinks that this is a container-like environment.
This cannot be upgraded by the native leapp tool.
Expand Down
6 changes: 0 additions & 6 deletions t/blocker-Python.t
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@ use Test::MockModule qw{strict};

use Elevate::Blockers::Python ();

{

package bogus::cpev;
sub _abort_on_first_blocker { return 0 }
}

my %mocks = map { $_ => Test::MockModule->new($_); } qw{
Cpanel::Pkgr
Elevate::Blockers
Expand Down
62 changes: 62 additions & 0 deletions t/blocker-whm.t
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,68 @@ my $whm = $cpev->get_blocker('WHM');
is( $whm->_blocker_is_sandbox(), 0, "if not dev_sandbox, we're ok" );
}

{
note 'UPCP is running';

is( $whm->_blocker_is_upcp_running(), 0, 'should return 0 if not in start mode' );

local $cpev->{_getopt} = { start => 1 };

my $mock_cpanel_unix_pid_tiny = Test::MockModule->new('Cpanel::Unix::PID::Tiny');
$mock_cpanel_unix_pid_tiny->redefine(
get_pid_from_pidfile => sub { return; },
);

is( $whm->_blocker_is_upcp_running(), 0, 'should return 0 if upcp is not running and it is in start mode' );

$mock_cpanel_unix_pid_tiny->redefine(
get_pid_from_pidfile => sub { return 42; },
);

like(
dies { $whm->_blocker_is_upcp_running() },
{
id => q[Elevate::Blockers::WHM::_blocker_is_upcp_running],
msg => qr{cPanel Update \(upcp\) is currently running}m,
},
'should block when upcp is running and it is in start mode'
);

# Reset this
$whm->blockers->abort_on_first_blocker(0);
}

{
note 'bin/backup is running';

is( $whm->_blocker_is_cpanel_backup_running(), 0, 'should return 0 if not in start mode' );

local $cpev->{_getopt} = { start => 1 };

my $mock_cpanel_backup_sync = Test::MockModule->new('Cpanel::Backup::Sync');
$mock_cpanel_backup_sync->redefine(
handle_already_running => 1,
);

is( $whm->_blocker_is_cpanel_backup_running(), 0, 'should return 0 if backup is not running and it is in start mode' );

$mock_cpanel_backup_sync->redefine(
handle_already_running => 0,
);

like(
dies { $whm->_blocker_is_cpanel_backup_running() },
{
id => q[Elevate::Blockers::WHM::_blocker_is_cpanel_backup_running],
msg => qr{A cPanel backup is currently running}m,
},
'should block when backup is running and it is in start mode'
);

# Reset this
$whm->blockers->abort_on_first_blocker(0);
}

{
note "CCS CalendarServer";

Expand Down

0 comments on commit 154c62b

Please sign in to comment.