This commit is contained in:
2024-10-14 00:08:40 +02:00
parent dbfba56f66
commit 1462d52e13
4572 changed files with 2658864 additions and 0 deletions

View File

@@ -0,0 +1,104 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::Export;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::System::Main',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Export the contents of an OTRS package to a directory.');
$Self->AddOption(
Name => 'target-directory',
Description => "Export contents of the package to the specified directory.",
Required => 1,
HasValue => 1,
ValueRegex => qr/.*/smx,
);
$Self->AddArgument(
Name => 'source-path',
Description => "Specify the path to an OTRS package (opm) file that should be exported.",
Required => 1,
ValueRegex => qr/.*/smx,
);
return;
}
sub PreRun {
my ( $Self, %Param ) = @_;
my $SourcePath = $Self->GetArgument('source-path');
if ( $SourcePath && !-r $SourcePath ) {
die "File $SourcePath does not exist / can not be read.\n";
}
my $TargetDirectory = $Self->GetOption('target-directory');
if ( $TargetDirectory && !-d $TargetDirectory ) {
die "Directory $TargetDirectory does not exist.\n";
}
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Exporting package contents...</yellow>\n");
my $SourcePath = $Self->GetArgument('source-path');
my $FileString;
my $ContentRef = $Kernel::OM->Get('Kernel::System::Main')->FileRead(
Location => $SourcePath,
Mode => 'utf8', # optional - binmode|utf8
Result => 'SCALAR', # optional - SCALAR|ARRAY
);
if ( !$ContentRef || ref $ContentRef ne 'SCALAR' ) {
$Self->PrintError("File $SourcePath is empty / could not be read.");
return $Self->ExitCodeError();
}
$FileString = ${$ContentRef};
my %Structure = $Kernel::OM->Get('Kernel::System::Package')->PackageParse(
String => $FileString,
);
# just export files if PackageIsDownloadable flag is enable
if (
defined $Structure{PackageIsDownloadable}
&& !$Structure{PackageIsDownloadable}->{Content}
)
{
$Self->PrintError("Files cannot be exported.\n");
return $Self->ExitCodeError();
}
my $TargetDirectory = $Self->GetOption('target-directory');
my $Success = $Kernel::OM->Get('Kernel::System::Package')->PackageExport(
String => $FileString,
Home => $TargetDirectory,
);
if ($Success) {
$Self->Print("<green>Exported files of package $SourcePath to $TargetDirectory.</green>\n");
return $Self->ExitCodeOk();
}
}
1;

View File

@@ -0,0 +1,78 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::FileSearch;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Find a file in an installed OTRS package.');
$Self->AddArgument(
Name => 'search-path',
Description => "Filename or path to search for.",
Required => 1,
ValueRegex => qr/.*/smx,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Searching in installed OTRS packages...</yellow>\n");
my $Hit = 0;
my $Filepath = $Self->GetArgument('search-path');
PACKAGE:
for my $Package ( $Kernel::OM->Get('Kernel::System::Package')->RepositoryList() ) {
# Just show if PackageIsVisible flag is enabled.
if (
defined $Package->{PackageIsVisible}
&& !$Package->{PackageIsVisible}->{Content}
)
{
next PACKAGE;
}
for my $File ( @{ $Package->{Filelist} } ) {
if ( $File->{Location} =~ m{\Q$Filepath\E}smx ) {
print
"+----------------------------------------------------------------------------+\n";
print "| File: $File->{Location}\n";
print "| Name: $Package->{Name}->{Content}\n";
print "| Version: $Package->{Version}->{Content}\n";
print "| Vendor: $Package->{Vendor}->{Content}\n";
print "| URL: $Package->{URL}->{Content}\n";
print "| License: $Package->{License}->{Content}\n";
print
"+----------------------------------------------------------------------------+\n";
$Hit++;
}
}
}
if ($Hit) {
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
$Self->PrintError("File $Filepath was not found in an installed OTRS package.\n");
return $Self->ExitCodeError();
}
1;

View File

@@ -0,0 +1,143 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::Install;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand Kernel::System::Console::Command::Admin::Package::List);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Cache',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Install an OTRS package.');
$Self->AddOption(
Name => 'force',
Description => 'Force package installation even if validation fails.',
Required => 0,
HasValue => 0,
);
$Self->AddArgument(
Name => 'location',
Description =>
"Specify a file path, a remote repository (http://ftp.otrs.org/pub/otrs/packages/:Package-1.0.0.opm) or just any online repository (online:Package).",
Required => 1,
ValueRegex => qr/.*/smx,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Installing package...</yellow>\n");
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Enable in-memory cache to improve SysConfig performance, which is normally disabled for commands.
$CacheObject->Configure(
CacheInMemory => 1,
);
my $FileString = $Self->_PackageContentGet( Location => $Self->GetArgument('location') );
return $Self->ExitCodeError() if !$FileString;
my $PackageObject = $Kernel::OM->Get('Kernel::System::Package');
# Parse package.
my %Structure = $PackageObject->PackageParse(
String => $FileString,
);
my $Verified = $PackageObject->PackageVerify(
Package => $FileString,
Structure => \%Structure,
) || 'verified';
my %VerifyInfo = $PackageObject->PackageVerifyInfo();
# Check if installation of packages, which are not verified by us, is possible.
my $PackageAllowNotVerifiedPackages = $Kernel::OM->Get('Kernel::Config')->Get('Package::AllowNotVerifiedPackages');
if ( $Verified ne 'verified' ) {
if ( !$PackageAllowNotVerifiedPackages ) {
$Self->PrintError(
"$Structure{Name}->{Content}-$Structure{Version}->{Content} is not verified by the OTRS Group!\n\nThe installation of packages which are not verified by the OTRS Group is not possible by default."
);
return $Self->ExitCodeError();
}
else {
$Self->Print(
"<yellow>Package $Structure{Name}->{Content}-$Structure{Version}->{Content} not verified by the OTRS Group! It is recommended not to use this package.</yellow>\n"
);
}
}
# intro screen
if ( $Structure{IntroInstall} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroInstall},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'pre',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# install
my $Success = $PackageObject->PackageInstall(
String => $FileString,
Force => $Self->GetOption('force'),
);
if ( !$Success ) {
$Self->PrintError("Package installation failed.");
return $Self->ExitCodeError();
}
# intro screen
if ( $Structure{IntroInstall} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroInstall},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'post',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# Disable in memory cache.
$CacheObject->Configure(
CacheInMemory => 0,
);
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,364 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::List;
use strict;
use utf8;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Cache',
'Kernel::System::Main',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('List all installed OTRS packages.');
$Self->AddOption(
Name => 'package-name',
Description => '(Part of) package name to filter for. Omit to show all installed packages.',
Required => 0,
HasValue => 1,
ValueRegex => qr/.*/,
);
$Self->AddOption(
Name => 'show-deployment-info',
Description => 'Show package and files status (package deployment info).',
Required => 0,
HasValue => 0,
);
$Self->AddOption(
Name => 'show-verification-info',
Description => 'Show package OTRS Verify™ status.',
Required => 0,
HasValue => 0,
);
$Self->AddOption(
Name => 'delete-verification-cache',
Description => 'Delete OTRS Verify™ cache, so verification info is fetch again from OTRS group servers.',
Required => 0,
HasValue => 0,
);
return;
}
sub PreRun {
my ( $Self, %Param ) = @_;
my $ShowVerificationInfoOption = $Self->GetOption('show-verification-info');
my $DeleteVerificationCacheOption = $Self->GetOption('delete-verification-cache');
if ( $DeleteVerificationCacheOption && !$ShowVerificationInfoOption ) {
die "--delete-verification-cache requires --show-verification-info";
}
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Listing all installed packages...</yellow>\n");
my @Packages = $Kernel::OM->Get('Kernel::System::Package')->RepositoryList();
if ( !@Packages ) {
$Self->Print("<green>There are no packages installed.</green>\n");
return $Self->ExitCodeOk();
}
my $PackageNameOption = $Self->GetOption('package-name');
my $ShowDeploymentInfoOption = $Self->GetOption('show-deployment-info');
my $ShowVerificationInfoOption = $Self->GetOption('show-verification-info');
my $DeleteVerificationCacheOption = $Self->GetOption('delete-verification-cache');
my $CloudServicesDisabled = $Kernel::OM->Get('Kernel::Config')->Get('CloudServices::Disabled') || 0;
# Do not show verification status is cloud services are disabled.
if ( $CloudServicesDisabled && $ShowVerificationInfoOption ) {
$ShowVerificationInfoOption = 0;
$Self->Print("<red>Cloud Services are disabled OTRS Verify information can not be retrieved</red>\n");
}
# Get package object
my $PackageObject = $Kernel::OM->Get('Kernel::System::Package');
my %VerificationInfo;
PACKAGE:
for my $Package (@Packages) {
# Just show if PackageIsVisible flag is enabled.
if (
defined $Package->{PackageIsVisible}
&& !$Package->{PackageIsVisible}->{Content}
)
{
next PACKAGE;
}
if ( defined $PackageNameOption && length $PackageNameOption ) {
my $PackageString = $Package->{Name}->{Content} . '-' . $Package->{Version}->{Content};
next PACKAGE if $PackageString !~ m{$PackageNameOption}i;
}
my %Data = $Self->_PackageMetadataGet(
Tag => $Package->{Description},
StripHTML => 0,
);
$Self->Print("+----------------------------------------------------------------------------+\n");
$Self->Print("| <yellow>Name:</yellow> $Package->{Name}->{Content}\n");
$Self->Print("| <yellow>Version:</yellow> $Package->{Version}->{Content}\n");
$Self->Print("| <yellow>Vendor:</yellow> $Package->{Vendor}->{Content}\n");
$Self->Print("| <yellow>URL:</yellow> $Package->{URL}->{Content}\n");
$Self->Print("| <yellow>License:</yellow> $Package->{License}->{Content}\n");
$Self->Print("| <yellow>Description:</yellow> $Data{Description}\n");
if ($ShowDeploymentInfoOption) {
my $PackageDeploymentOK = $PackageObject->DeployCheck(
Name => $Package->{Name}->{Content},
Version => $Package->{Version}->{Content},
Log => 0,
);
my %PackageDeploymentInfo = $PackageObject->DeployCheckInfo();
if ( defined $PackageDeploymentInfo{File} && %{ $PackageDeploymentInfo{File} } ) {
$Self->Print(
'| <red>Deployment:</red> ' . ( $PackageDeploymentOK ? 'OK' : 'Not OK' ) . "\n"
);
for my $File ( sort keys %{ $PackageDeploymentInfo{File} } ) {
my $FileMessage = $PackageDeploymentInfo{File}->{$File};
$Self->Print("| <red>File Status:</red> $File => $FileMessage\n");
}
}
else {
$Self->Print(
'| <yellow>Pck. Status:</yellow> ' . ( $PackageDeploymentOK ? 'OK' : 'Not OK' ) . "\n"
);
}
}
if ($ShowVerificationInfoOption) {
if ( !%VerificationInfo ) {
# Clear the package verification cache to get fresh results.
if ($DeleteVerificationCacheOption) {
$Kernel::OM->Get('Kernel::System::Cache')->CleanUp(
Type => 'PackageVerification',
);
}
# Get verification info for all packages (this will create the cache again).
%VerificationInfo = $PackageObject->PackageVerifyAll();
}
if (
!defined $VerificationInfo{ $Package->{Name}->{Content} }
|| $VerificationInfo{ $Package->{Name}->{Content} } ne 'verified'
)
{
$Self->Print("| <red>OTRS Verify:</red> Not Verified\n");
}
else {
$Self->Print("| <yellow>OTRS Verify:</yellow> Verified\n");
}
}
}
$Self->Print("+----------------------------------------------------------------------------+\n");
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
# =item _PackageMetadataGet()
#
# locates information in tags that are language specific.
# First, 'en' is looked for, if that is not present, the first found language will be used.
#
# my %Data = $CommandObject->_PackageMetadataGet(
# Tag => $Package->{Description},
# StripHTML => 1, # optional, perform HTML->ASCII conversion (default 1)
# );
#
# my %Data = $Self->_PackageMetadataGet(
# Tag => $Structure{IntroInstallPost},
# AttributeFilterKey => 'Type',
# AttributeFilterValue => 'pre',
# );
#
# Returns the content and the title of the tag in a hash:
#
# my %Result = (
# Description => '...', # tag content
# Title => '...', # tag title
# );
#
# =cut
sub _PackageMetadataGet {
my ( $Self, %Param ) = @_;
return if !ref $Param{Tag};
my $AttributeFilterKey = $Param{AttributeFilterKey};
my $AttributeFilterValue = $Param{AttributeFilterValue};
my $Title = '';
my $Description = '';
TAG:
for my $Tag ( @{ $Param{Tag} } ) {
if ($AttributeFilterKey) {
if ( lc $Tag->{$AttributeFilterKey} ne lc $AttributeFilterValue ) {
next TAG;
}
}
if ( !$Description && $Tag->{Lang} eq 'en' ) {
$Description = $Tag->{Content} || '';
$Title = $Tag->{Title} || '';
}
}
if ( !$Description ) {
TAG:
for my $Tag ( @{ $Param{Tag} } ) {
if ($AttributeFilterKey) {
if ( lc $Tag->{$AttributeFilterKey} ne lc $AttributeFilterValue ) {
next TAG;
}
}
if ( !$Description ) {
$Description = $Tag->{Content} || '';
$Title = $Tag->{Title} || '';
}
}
}
if ( !defined $Param{StripHTML} || $Param{StripHTML} ) {
$Title =~ s/(.{4,78})(?:\s|\z)/| $1\n/gm;
$Description =~ s/^\s*//mg;
$Description =~ s/\n/ /gs;
$Description =~ s/\r/ /gs;
$Description =~ s/\<style.+?\>.*\<\/style\>//gsi;
$Description =~ s/\<br(\/|)\>/\n/gsi;
$Description =~ s/\<(hr|hr.+?)\>/\n\n/gsi;
$Description =~ s/\<(\/|)(pre|pre.+?|p|p.+?|table|table.+?|code|code.+?)\>/\n\n/gsi;
$Description =~ s/\<(tr|tr.+?|th|th.+?)\>/\n\n/gsi;
$Description =~ s/\.+?<\/(td|td.+?)\>/ /gsi;
$Description =~ s/\<.+?\>//gs;
$Description =~ s/ / /mg;
$Description =~ s/&amp;/&/g;
$Description =~ s/&lt;/</g;
$Description =~ s/&gt;/>/g;
$Description =~ s/&quot;/"/g;
$Description =~ s/&nbsp;/ /g;
$Description =~ s/^\s*\n\s*\n/\n/mg;
$Description =~ s/(.{4,78})(?:\s|\z)/| $1\n/gm;
}
return (
Description => $Description,
Title => $Title,
);
}
sub _PackageContentGet {
my ( $Self, %Param ) = @_;
my $FileString;
if ( -e $Param{Location} ) {
my $ContentRef = $Kernel::OM->Get('Kernel::System::Main')->FileRead(
Location => $Param{Location},
Mode => 'utf8', # optional - binmode|utf8
Result => 'SCALAR', # optional - SCALAR|ARRAY
);
if ($ContentRef) {
$FileString = ${$ContentRef};
}
else {
$Self->PrintError("Can't open: $Param{Location}: $!");
return;
}
}
elsif ( $Param{Location} =~ /^(online|.*):(.+?)$/ ) {
my $URL = $1;
my $PackageName = $2;
if ( $URL eq 'online' ) {
my %List = %{ $Kernel::OM->Get('Kernel::Config')->Get('Package::RepositoryList') };
%List = (
%List,
$Kernel::OM->Get('Kernel::System::Package')->PackageOnlineRepositories()
);
for ( sort keys %List ) {
if ( $List{$_} =~ /^\[-Master-\]/ ) {
$URL = $_;
}
}
}
if ( $PackageName !~ /^.+?.opm$/ ) {
my @Packages = $Kernel::OM->Get('Kernel::System::Package')->PackageOnlineList(
URL => $URL,
Lang => $Kernel::OM->Get('Kernel::Config')->Get('DefaultLanguage'),
);
PACKAGE:
for my $Package (@Packages) {
if ( $Package->{Name} eq $PackageName ) {
$PackageName = $Package->{File};
last PACKAGE;
}
}
}
$FileString = $Kernel::OM->Get('Kernel::System::Package')->PackageOnlineGet(
Source => $URL,
File => $PackageName,
);
if ( !$FileString ) {
$Self->PrintError("No such file '$Param{Location}' in $URL!");
return;
}
}
else {
if ( $Param{Location} =~ /^(.*)\-(\d{1,4}\.\d{1,4}\.\d{1,4})$/ ) {
$FileString = $Kernel::OM->Get('Kernel::System::Package')->RepositoryGet(
Name => $1,
Version => $2,
);
}
else {
PACKAGE:
for my $Package ( $Kernel::OM->Get('Kernel::System::Package')->RepositoryList() ) {
if ( $Param{Location} eq $Package->{Name}->{Content} ) {
$FileString = $Kernel::OM->Get('Kernel::System::Package')->RepositoryGet(
Name => $Package->{Name}->{Content},
Version => $Package->{Version}->{Content},
);
last PACKAGE;
}
}
}
if ( !$FileString ) {
$Self->PrintError("No such file '$Param{Location}' or invalid 'package-version'!");
return;
}
}
return $FileString;
}
1;

View File

@@ -0,0 +1,58 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::ListInstalledFiles;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Main',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('List all installed OTRS package files.');
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Listing all installed package files...</yellow>\n");
my @Packages = $Kernel::OM->Get('Kernel::System::Package')->RepositoryList();
PACKAGE:
for my $Package (@Packages) {
# Just show if PackageIsVisible flag is enabled.
if (
defined $Package->{PackageIsVisible}
&& !$Package->{PackageIsVisible}->{Content}
)
{
next PACKAGE;
}
for my $File ( @{ $Package->{Filelist} } ) {
$Self->Print(" $Package->{Name}->{Content}: $File->{Location}\n");
}
}
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,114 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::Reinstall;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand Kernel::System::Console::Command::Admin::Package::List);
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Reinstall an OTRS package.');
$Self->AddOption(
Name => 'force',
Description => 'Force package reinstallation even if validation fails.',
Required => 0,
HasValue => 0,
);
$Self->AddArgument(
Name => 'location',
Description =>
"Specify a file path, a remote repository (http://ftp.otrs.org/pub/otrs/packages/:Package-1.0.0.opm) or just any online repository (online:Package).",
Required => 1,
ValueRegex => qr/.*/smx,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Reinstalling package...</yellow>\n");
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Enable in-memory cache to improve SysConfig performance, which is normally disabled for commands.
$CacheObject->Configure(
CacheInMemory => 1,
);
my $FileString = $Self->_PackageContentGet( Location => $Self->GetArgument('location') );
return $Self->ExitCodeError() if !$FileString;
# parse package
my %Structure = $Kernel::OM->Get('Kernel::System::Package')->PackageParse(
String => $FileString,
);
# intro screen
if ( $Structure{IntroReinstall} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroReinstall},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'pre',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# install
my $Success = $Kernel::OM->Get('Kernel::System::Package')->PackageReinstall(
String => $FileString,
Force => $Self->GetOption('force'),
);
if ( !$Success ) {
$Self->PrintError("Package reinstallation failed.");
return $Self->ExitCodeError();
}
# intro screen
if ( $Structure{IntroReinstall} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroReinstall},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'post',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# Disable in memory cache.
$CacheObject->Configure(
CacheInMemory => 0,
);
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,104 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::ReinstallAll;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Reinstall all OTRS packages that are not correctly deployed.');
$Self->AddOption(
Name => 'force',
Description => 'Force package reinstallation even if validation fails.',
Required => 0,
HasValue => 0,
);
$Self->AddOption(
Name => 'hide-deployment-info',
Description => 'Hide package and files status (package deployment info).',
Required => 0,
HasValue => 0,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
my $HideDeploymentInfoOption = $Self->GetOption('hide-deployment-info') || 0;
$Self->Print("<yellow>Reinstalling all OTRS packages that are not correctly deployed...</yellow>\n");
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Enable in-memory cache to improve SysConfig performance, which is normally disabled for commands.
$CacheObject->Configure(
CacheInMemory => 1,
);
my @ReinstalledPackages;
# loop all locally installed packages
for my $Package ( $Kernel::OM->Get('Kernel::System::Package')->RepositoryList() ) {
# do a deploy check to see if reinstallation is needed
my $CorrectlyDeployed = $Kernel::OM->Get('Kernel::System::Package')->DeployCheck(
Name => $Package->{Name}->{Content},
Version => $Package->{Version}->{Content},
Log => $HideDeploymentInfoOption ? 0 : 1,
);
if ( !$CorrectlyDeployed ) {
push @ReinstalledPackages, $Package->{Name}->{Content};
my $FileString = $Kernel::OM->Get('Kernel::System::Package')->RepositoryGet(
Name => $Package->{Name}->{Content},
Version => $Package->{Version}->{Content},
);
my $Success = $Kernel::OM->Get('Kernel::System::Package')->PackageReinstall(
String => $FileString,
Force => $Self->GetOption('force'),
);
if ( !$Success ) {
$Self->PrintError("Package $Package->{Name}->{Content} could not be reinstalled.\n");
return $Self->ExitCodeError();
}
}
}
if (@ReinstalledPackages) {
$Self->Print( "<green>" . scalar(@ReinstalledPackages) . " package(s) reinstalled.</green>\n" );
}
else {
$Self->Print("<green>No packages needed reinstallation.</green>\n");
}
# Disable in memory cache.
$CacheObject->Configure(
CacheInMemory => 0,
);
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,97 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::RepositoryList;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('List all known OTRS package repsitories.');
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Listing OTRS package repositories...</yellow>\n");
my $Count = 0;
my %List;
if ( $Kernel::OM->Get('Kernel::Config')->Get('Package::RepositoryList') ) {
%List = %{ $Kernel::OM->Get('Kernel::Config')->Get('Package::RepositoryList') };
}
%List = ( %List, $Kernel::OM->Get('Kernel::System::Package')->PackageOnlineRepositories() );
if ( !%List ) {
$Self->PrintError("No package repositories configured.");
return $Self->ExitCodeError();
}
for my $URL ( sort { $List{$a} cmp $List{$b} } keys %List ) {
$Count++;
print "+----------------------------------------------------------------------------+\n";
print "| $Count) Name: $List{$URL}\n";
print "| URL: $URL\n";
}
print "+----------------------------------------------------------------------------+\n";
print "\n";
$Self->Print("<yellow>Listing OTRS package repository contents...</yellow>\n");
for my $URL ( sort { $List{$a} cmp $List{$b} } keys %List ) {
print
"+----------------------------------------------------------------------------+\n";
print "| Package Overview for Repository $List{$URL}:\n";
my @Packages = $Kernel::OM->Get('Kernel::System::Package')->PackageOnlineList(
URL => $URL,
Lang => $Kernel::OM->Get('Kernel::Config')->Get('DefaultLanguage'),
);
my $PackageCount = 0;
PACKAGE:
for my $Package (@Packages) {
# Just show if PackageIsVisible flag is enabled.
if (
defined $Package->{PackageIsVisible}
&& !$Package->{PackageIsVisible}->{Content}
)
{
next PACKAGE;
}
$PackageCount++;
print
"+----------------------------------------------------------------------------+\n";
print "| $PackageCount) Name: $Package->{Name}\n";
print "| Version: $Package->{Version}\n";
print "| Vendor: $Package->{Vendor}\n";
print "| URL: $Package->{URL}\n";
print "| License: $Package->{License}\n";
print "| Description: $Package->{Description}\n";
print "| Install: $URL:$Package->{File}\n";
}
print
"+----------------------------------------------------------------------------+\n";
print "\n";
}
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,135 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::Uninstall;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand Kernel::System::Console::Command::Admin::Package::List);
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Package',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Uninstall an OTRS package.');
$Self->AddOption(
Name => 'force',
Description => 'Force package uninstallation even if validation fails.',
Required => 0,
HasValue => 0,
);
$Self->AddArgument(
Name => 'location',
Description =>
"Specify a file path, a remote repository (http://ftp.otrs.org/pub/otrs/packages/:Package-1.0.0.opm) or just any online repository (online:Package).",
Required => 1,
ValueRegex => qr/.*/smx,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Uninstalling package...</yellow>\n");
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Enable in-memory cache to improve SysConfig performance, which is normally disabled for commands.
$CacheObject->Configure(
CacheInMemory => 1,
);
my $FileString = $Self->_PackageContentGet( Location => $Self->GetArgument('location') );
return $Self->ExitCodeError() if !$FileString;
# get package file from db
# parse package
my %Structure = $Kernel::OM->Get('Kernel::System::Package')->PackageParse(
String => $FileString,
);
# just un-install it if PackageIsRemovable flag is enable
if (
defined $Structure{PackageIsRemovable}
&& !$Structure{PackageIsRemovable}->{Content}
)
{
my $Error = "Not possible to remove this package!\n";
# exchange message if package should not be visible
if (
defined $Structure{PackageIsVisible}
&& !$Structure{PackageIsVisible}->{Content}
)
{
$Error = "No such package!\n";
}
$Self->PrintError($Error);
return $Self->ExitCodeError();
}
# intro screen
if ( $Structure{IntroUninstall} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroUninstall},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'pre',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# Uninstall
my $Success = $Kernel::OM->Get('Kernel::System::Package')->PackageUninstall(
String => $FileString,
Force => $Self->GetOption('force'),
);
if ( !$Success ) {
$Self->PrintError("Package uninstallation failed.");
return $Self->ExitCodeError();
}
# intro screen
if ( $Structure{IntroUninstallPost} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroUninstall},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'post',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# Disable in memory cache.
$CacheObject->Configure(
CacheInMemory => 0,
);
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,143 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::Upgrade;
use strict;
use warnings;
use parent qw(Kernel::System::Console::BaseCommand Kernel::System::Console::Command::Admin::Package::List);
our @ObjectDependencies = (
'Kernel::System::Cache',
'Kernel::System::Package',
'Kernel::Config',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Upgrade an OTRS package.');
$Self->AddOption(
Name => 'force',
Description => 'Force package upgrade even if validation fails.',
Required => 0,
HasValue => 0,
);
$Self->AddArgument(
Name => 'location',
Description =>
"Specify a file path, a remote repository (http://ftp.otrs.org/pub/otrs/packages/:Package-1.0.0.opm) or just any online repository (online:Package).",
Required => 1,
ValueRegex => qr/.*/smx,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
$Self->Print("<yellow>Upgrading package...</yellow>\n");
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Enable in-memory cache to improve SysConfig performance, which is normally disabled for commands.
$CacheObject->Configure(
CacheInMemory => 1,
);
my $FileString = $Self->_PackageContentGet( Location => $Self->GetArgument('location') );
return $Self->ExitCodeError() if !$FileString;
my $PackageObject = $Kernel::OM->Get('Kernel::System::Package');
# Parse package.
my %Structure = $PackageObject->PackageParse(
String => $FileString,
);
my $Verified = $PackageObject->PackageVerify(
Package => $FileString,
Structure => \%Structure,
) || 'verified';
my %VerifyInfo = $PackageObject->PackageVerifyInfo();
# Check if installation of packages, which are not verified by us, is possible.
my $PackageAllowNotVerifiedPackages = $Kernel::OM->Get('Kernel::Config')->Get('Package::AllowNotVerifiedPackages');
if ( $Verified ne 'verified' ) {
if ( !$PackageAllowNotVerifiedPackages ) {
$Self->PrintError(
"$Structure{Name}->{Content}-$Structure{Version}->{Content} is not verified by the OTRS Group!\n\nThe installation of packages which are not verified by the OTRS Group is not possible by default."
);
return $Self->ExitCodeError();
}
else {
$Self->Print(
"<yellow>Package $Structure{Name}->{Content}-$Structure{Version}->{Content} not verified by the OTRS Group! It is recommended not to use this package.</yellow>\n"
);
}
}
# Intro screen.
if ( $Structure{IntroUpgrade} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroUpgrade},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'pre',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# Upgrade.
my $Success = $Kernel::OM->Get('Kernel::System::Package')->PackageUpgrade(
String => $FileString,
Force => $Self->GetOption('force'),
);
if ( !$Success ) {
$Self->PrintError("Package upgrade failed.");
return $Self->ExitCodeError();
}
# Intro screen.
if ( $Structure{IntroUpgrade} ) {
my %Data = $Self->_PackageMetadataGet(
Tag => $Structure{IntroUpgrade},
AttributeFilterKey => 'Type',
AttributeFilterValue => 'post',
);
if ( $Data{Description} ) {
print "+----------------------------------------------------------------------------+\n";
print "| $Structure{Name}->{Content}-$Structure{Version}->{Content}\n";
print "$Data{Title}";
print "$Data{Description}";
print "+----------------------------------------------------------------------------+\n";
}
}
# Disable in memory cache.
$CacheObject->Configure(
CacheInMemory => 0,
);
$Self->Print("<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;

View File

@@ -0,0 +1,226 @@
# --
# Copyright (C) 2001-2019 OTRS AG, https://otrs.com/
# --
# This software comes with ABSOLUTELY NO WARRANTY. For details, see
# the enclosed file COPYING for license information (GPL). If you
# did not receive this file, see https://www.gnu.org/licenses/gpl-3.0.txt.
# --
package Kernel::System::Console::Command::Admin::Package::UpgradeAll;
use strict;
use warnings;
use utf8;
use Kernel::System::VariableCheck qw(:all);
use parent qw(Kernel::System::Console::BaseCommand);
our @ObjectDependencies = (
'Kernel::Config',
'Kernel::System::Cache',
'Kernel::System::Package',
'Kernel::System::SystemData',
);
sub Configure {
my ( $Self, %Param ) = @_;
$Self->Description('Upgrade all OTRS packages to the latest versions from the on-line repositories.');
$Self->AddOption(
Name => 'force',
Description => 'Force package upgrade/installation even if validation fails.',
Required => 0,
HasValue => 0,
);
return;
}
sub Run {
my ( $Self, %Param ) = @_;
my $CacheObject = $Kernel::OM->Get('Kernel::System::Cache');
# Enable in-memory cache to improve SysConfig performance, which is normally disabled for commands.
$CacheObject->Configure(
CacheInMemory => 1,
);
my $PackageObject = $Kernel::OM->Get('Kernel::System::Package');
my %IsRunningResult = $PackageObject->PackageUpgradeAllIsRunning();
if ( $IsRunningResult{IsRunning} ) {
$Self->Print("\nThere is another package upgrade process running\n");
$Self->Print("\n<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
my @List = $PackageObject->RepositoryList(
Result => 'short',
);
if ( !@List ) {
$Self->Print("\nThere are no installed packages\n");
$Self->Print("\n<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
my %RepositoryList = $PackageObject->_ConfiguredRepositoryDefinitionGet();
# Show cloud repositories if system is registered.
my $RepositoryCloudList;
my $RegistrationState = $Kernel::OM->Get('Kernel::System::SystemData')->SystemDataGet(
Key => 'Registration::State',
) || '';
if (
$RegistrationState eq 'registered'
&& !$Kernel::OM->Get('Kernel::Config')->Get('CloudServices::Disabled')
)
{
$Self->Print("<yellow>Getting cloud repositories information...</yellow>\n");
$RepositoryCloudList = $PackageObject->RepositoryCloudList( NoCache => 1 );
$Self->Print(" Cloud repositories... <green>Done</green>\n\n");
}
my %RepositoryListAll = ( %RepositoryList, %{ $RepositoryCloudList || {} } );
my @PackageOnlineList;
my %PackageSoruceLookup;
$Self->Print("<yellow>Fetching on-line repositories...</yellow>\n");
URL:
for my $URL ( sort keys %RepositoryListAll ) {
$Self->Print(" $RepositoryListAll{$URL}... ");
my $FromCloud = 0;
if ( $RepositoryCloudList->{$URL} ) {
$FromCloud = 1;
}
my @OnlineList = $PackageObject->PackageOnlineList(
URL => $URL,
Lang => 'en',
Cache => 1,
FromCloud => $FromCloud,
);
$Self->Print("<green>Done</green>\n");
}
# Check again after repository refresh
%IsRunningResult = $PackageObject->PackageUpgradeAllIsRunning();
if ( $IsRunningResult{IsRunning} ) {
$Self->Print("\nThere is another package upgrade process running\n");
$Self->Print("\n<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
$Self->Print("\n<yellow>Upgrading installed packages...</yellow>\n");
my $ErrorMessage;
my %Result;
eval {
# Localize the standard error, everything will be restored after the eval block.
# Package installation or upgrades always produce messages in STDERR for files and directories.
local *STDERR;
# Redirect the standard error to a variable.
open STDERR, ">>", \$ErrorMessage;
%Result = $PackageObject->PackageUpgradeAll(
Force => $Self->GetOption('force'),
);
};
# Remove package upgrade data from the DB, so the GUI will not show the finished notification.
$PackageObject->PackageUpgradeAllDataDelete();
# Be sure to print any error messages in case of a failure.
if ( IsHashRefWithData( $Result{Failed} ) ) {
print STDERR $ErrorMessage if $ErrorMessage;
}
if (
!IsHashRefWithData( $Result{Updated} )
&& !IsHashRefWithData( $Result{Installed} )
&& !IsHashRefWithData( $Result{Undeployed} )
&& !IsHashRefWithData( $Result{Failed} )
)
{
$Self->Print(" All installed packages are already at their latest versions.\n");
$Self->Print("\n<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
my %SuccessMessages = (
Updated => 'updated',
Installed => 'installed',
AlreadyUpdated => 'already up-to-date',
Undeployed => 'already up-to-date but <red>not deployed correctly</red>',
);
for my $ResultPart (qw(AlreadyUpdated Undeployed Updated Installed)) {
if ( IsHashRefWithData( $Result{$ResultPart} ) ) {
$Self->Print( ' The following packages were ' . $SuccessMessages{$ResultPart} . "...\n" );
my $Color = 'green';
if ( $ResultPart eq 'Installed' || $ResultPart eq 'Undeployed' ) {
$Color = 'yellow';
}
for my $PackageName ( sort keys %{ $Result{$ResultPart} } ) {
$Self->Print(" <$Color>$PackageName</$Color>\n");
}
}
}
my %FailedMessages = (
UpdateError => 'could not be upgraded...',
InstallError => 'could not be installed...',
Cyclic => 'had cyclic dependencies...',
NotFound => 'could not be found in the on-line repositories...',
WrongVersion => 'require a version higher than the one found in the on-line repositories...',
DependencyFail => 'fail to upgrade/install their package dependencies...'
);
if ( IsHashRefWithData( $Result{Failed} ) ) {
for my $FailedPart (qw(UpdateError InstallError DependencyFail Cyclic NotFound WrongVersion)) {
if ( IsHashRefWithData( $Result{Failed}->{$FailedPart} ) ) {
$Self->Print(" The following packages $FailedMessages{$FailedPart}\n");
for my $PackageName ( sort keys %{ $Result{Failed}->{$FailedPart} } ) {
$Self->Print(" <red>$PackageName</red>\n");
}
}
}
}
if ( !$Result{Success} ) {
$Self->Print("\n<red>Fail.</red>\n");
return $Self->ExitCodeError();
}
if ( IsHashRefWithData( $Result{Undeployed} ) ) {
my $Message = "\nPlease reinstall not correctly deployed packages using"
. " <yellow>Admin::Package::Reinstall</yellow>"
. " or <yellow>Admin::Package::ReinstallAll</yellow> console commands.\n";
$Self->Print($Message);
}
# Disable in memory cache.
$CacheObject->Configure(
CacheInMemory => 0,
);
$Self->Print("\n<green>Done.</green>\n");
return $Self->ExitCodeOk();
}
1;