Skip to content

Commit

Permalink
Merge pull request #3353 from LibreSign/backport/3352/stable28
Browse files Browse the repository at this point in the history
[stable28] fix: setup at alpine
  • Loading branch information
vitormattos authored Jul 11, 2024
2 parents 1af6ffe + 9d42346 commit 4f15670
Show file tree
Hide file tree
Showing 3 changed files with 111 additions and 39 deletions.
9 changes: 8 additions & 1 deletion lib/Command/Install.php
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int
}
$all = $input->getOption('all');
if ($input->getOption('java') || $all) {
$this->installService->installJava();
if ($all) {
foreach (['linux', 'alpine-linux'] as $distro) {
$this->installService->setDistro($distro);
$this->installService->installJava();
}
} else {
$this->installService->installJava();
}
$ok = true;
}
if ($input->getOption('jsignpdf') || $all) {
Expand Down
72 changes: 64 additions & 8 deletions lib/Migration/DeleteOldBinaries.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,42 @@

namespace OCA\Libresign\Migration;

use OCA\Files\Command\ScanAppData;
use OCP\Files\AppData\IAppDataFactory;
use OCP\Files\Folder;
use OCP\Files\IAppData;
use OCP\Files\SimpleFS\ISimpleFolder;
use OCP\Migration\IOutput;
use OCP\Migration\IRepairStep;
use Symfony\Component\Console\Application;
use Symfony\Component\Console\Input\ArrayInput;

class DeleteOldBinaries implements IRepairStep {
protected IAppData $appData;
protected IOutput $output;
protected array $allowedFiles = [
'x86_64',
'aarch64',
'x86_64' => [
'alpine-linux' => [
'java',
],
'linux' => [
'java',
],
'cfssl',
'jsignpdf',
'pdftk',
],
'aarch64' => [
'alpine-linux' => [
'java',
],
'linux' => [
'java',
],
'cfssl',
'jsignpdf',
'pdftk',
],
'openssl_config',
'cfssl_config',
'unauthenticated',
Expand All @@ -35,19 +59,51 @@ public function getName(): string {
}

public function run(IOutput $output): void {
$output->warning('Run the follow command first: files:scan-app-data libresign');
$this->scan();
$this->output = $output;
$folder = $this->appData->getFolder('/');

$list = $this->getDirectoryListing($folder);
foreach ($list as $file) {
if (!in_array($file->getName(), $this->allowedFiles)) {
$file->delete();
$this->deleteFolder($folder, $this->allowedFiles);
}

private function scan(): void {
$application = \OCP\Server::get(Application::class);
$input = new ArrayInput([
'command' => 'files:scan-app-data',
'folder' => 'libresign',
]);
$application->add(\OC::$server->get(ScanAppData::class));
$application->setAutoExit(false);
$application->run($input);
}

private function deleteFolder(ISimpleFolder $folder, array $allowedFiles): void {
$list = $this->getSimpleFolderList($folder);
foreach ($list as $node) {
if (!in_array($node->getName(), $allowedFiles)) {
if (in_array($node->getName(), array_keys($allowedFiles))) {
$this->deleteRecursive($node, $allowedFiles[$node->getName()]);
continue;
}
$node->delete();
}
}
}

private function deleteRecursive(Folder $folder, array $allowedFiles): void {
$list = $folder->getDirectoryListing();
foreach ($list as $node) {
if (!in_array($node->getName(), $allowedFiles)) {
if (in_array($node->getName(), array_keys($allowedFiles))) {
$this->deleteRecursive($node, $allowedFiles[$node->getName()]);
continue;
}
$node->delete();
}
}
}

private function getDirectoryListing(ISimpleFolder $node): array {
private function getSimpleFolderList(ISimpleFolder $node): array {
$reflection = new \ReflectionClass($node);
$reflectionProperty = $reflection->getProperty('folder');
$reflectionProperty->setAccessible(true);
Expand Down
69 changes: 39 additions & 30 deletions lib/Service/Install/InstallService.php
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class InstallService {
'pdftk',
'cfssl'
];
private string $distro = '';
private string $architecture;
private bool $willUseLocalCert = false;

Expand Down Expand Up @@ -386,7 +387,11 @@ public function installJava(?bool $async = false): void {
$this->runAsync();
return;
}
$extractDir = $this->getFullPath() . '/' . $this->resource;
if (PHP_OS_FAMILY !== 'Linux') {
throw new RuntimeException(sprintf('OS_FAMILY %s is incompatible with LibreSign.', PHP_OS_FAMILY));
}
$linuxDistribution = $this->getLinuxDistributionToDownloadJava();
$extractDir = $this->getFullPath() . '/' . $linuxDistribution . '/' . $this->resource;

if ($this->isDownloadedFilesOk()) {
$folder = $this->getFolder($this->resource);
Expand All @@ -400,19 +405,14 @@ public function installJava(?bool $async = false): void {
* URL used to get the MD5 and URL to download:
* https://jdk.java.net/java-se-ri/8-MR3
*/
if (PHP_OS_FAMILY === 'Linux') {
$linuxDistribution = $this->getLinuxDistributionToDownloadJava();
if ($this->architecture === 'x86_64') {
$compressedFileName = 'OpenJDK21U-jre_x64_' . $linuxDistribution . '_hotspot_' . self::JAVA_PARTIAL_VERSION . '.tar.gz';
$url = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-' . self::JAVA_URL_PATH_NAME . '/' . $compressedFileName;
} elseif ($this->architecture === 'aarch64') {
$compressedFileName = 'OpenJDK21U-jre_aarch64_' . $linuxDistribution . '_hotspot_' . self::JAVA_PARTIAL_VERSION . '.tar.gz';
$url = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-' . self::JAVA_URL_PATH_NAME . '/' . $compressedFileName;
}
$class = TAR::class;
} else {
throw new RuntimeException(sprintf('OS_FAMILY %s is incompatible with LibreSign.', PHP_OS_FAMILY));
if ($this->architecture === 'x86_64') {
$compressedFileName = 'OpenJDK21U-jre_x64_' . $linuxDistribution . '_hotspot_' . self::JAVA_PARTIAL_VERSION . '.tar.gz';
$url = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-' . self::JAVA_URL_PATH_NAME . '/' . $compressedFileName;
} elseif ($this->architecture === 'aarch64') {
$compressedFileName = 'OpenJDK21U-jre_aarch64_' . $linuxDistribution . '_hotspot_' . self::JAVA_PARTIAL_VERSION . '.tar.gz';
$url = 'https://github.com/adoptium/temurin21-binaries/releases/download/jdk-' . self::JAVA_URL_PATH_NAME . '/' . $compressedFileName;
}
$class = TAR::class;
$checksumUrl = $url . '.sha256.txt';
$hash = $this->getHash($compressedFileName, $checksumUrl);
try {
Expand All @@ -422,7 +422,8 @@ public function installJava(?bool $async = false): void {
}
$comporessedInternalFileName = $this->getDataDir() . '/' . $this->getInternalPathOfFile($compressedFile);

$this->download($url, 'java', $comporessedInternalFileName, $hash, 'sha256');
$dependencyName = 'java ' . $this->architecture . ' '. $linuxDistribution;
$this->download($url, $dependencyName, $comporessedInternalFileName, $hash, 'sha256');

$extractor = new $class($comporessedInternalFileName);
$extractor->extract($extractDir);
Expand All @@ -434,10 +435,17 @@ public function installJava(?bool $async = false): void {
$this->removeDownloadProgress();
}

public function setDistro(string $distro): void {
$this->distro = $distro;
}

/**
* Return linux or alpine-linux
*/
private function getLinuxDistributionToDownloadJava(): string {
if ($this->distro) {
return $this->distro;
}
$distribution = shell_exec('cat /etc/*-release');
preg_match('/^ID=(?<version>.*)$/m', $distribution, $matches);
if (isset($matches['version']) && strtolower($matches['version']) === 'alpine') {
Expand Down Expand Up @@ -577,18 +585,18 @@ public function installCfssl(?bool $async = false): void {
$this->removeDownloadProgress();
}

private function installCfsslByArchitecture(string $arcitecture): void {
private function installCfsslByArchitecture(string $architecture): void {
if ($this->isDownloadedFilesOk()) {
$folder = $this->getFolder($this->resource);
} else {
$folder = $this->getEmptyFolder($this->resource);
$downloads = [
[
'file' => 'cfssl_' . self::CFSSL_VERSION . '_linux_' . $arcitecture,
'file' => 'cfssl_' . self::CFSSL_VERSION . '_linux_' . $architecture,
'destination' => 'cfssl',
],
[
'file' => 'cfssljson_' . self::CFSSL_VERSION . '_linux_' . $arcitecture,
'file' => 'cfssljson_' . self::CFSSL_VERSION . '_linux_' . $architecture,
'destination' => 'cfssljson',
],
];
Expand All @@ -600,7 +608,8 @@ private function installCfsslByArchitecture(string $arcitecture): void {
$file = $folder->newFile($download['destination']);
$fullPath = $this->getDataDir() . '/' . $this->getInternalPathOfFile($file);

$this->download($baseUrl . $download['file'], $download['destination'], $fullPath, $hash, 'sha256');
$dependencyName = $download['destination'] . ' ' . $architecture;
$this->download($baseUrl . $download['file'], $dependencyName, $fullPath, $hash, 'sha256');

chmod($fullPath, 0700);
}
Expand Down Expand Up @@ -633,15 +642,15 @@ public function isCfsslBinInstalled(): bool {
return false;
}

protected function download(string $url, string $filename, string $path, ?string $hash = '', ?string $hash_algo = 'md5'): void {
protected function download(string $url, string $dependencyName, string $path, ?string $hash = '', ?string $hash_algo = 'md5'): void {
if (file_exists($path)) {
$this->progressToDatabase((int) filesize($path), 0);
if (hash_file($hash_algo, $path) === $hash) {
return;
}
}
if (php_sapi_name() === 'cli' && $this->output instanceof OutputInterface) {
$this->downloadCli($url, $filename, $path, $hash, $hash_algo);
$this->downloadCli($url, $dependencyName, $path, $hash, $hash_algo);
return;
}
$client = $this->clientService->newClient();
Expand All @@ -654,17 +663,17 @@ protected function download(string $url, string $filename, string $path, ?string
},
]);
} catch (\Exception $e) {
throw new LibresignException('Failure on download ' . $filename . " try again.\n" . $e->getMessage());
throw new LibresignException('Failure on download ' . $dependencyName . " try again.\n" . $e->getMessage());
}
if ($hash && file_exists($path) && hash_file($hash_algo, $path) !== $hash) {
throw new LibresignException('Failure on download ' . $filename . ' try again. Invalid ' . $hash_algo . '.');
throw new LibresignException('Failure on download ' . $dependencyName . ' try again. Invalid ' . $hash_algo . '.');
}
}

protected function downloadCli(string $url, string $filename, string $path, ?string $hash = '', ?string $hash_algo = 'md5'): void {
protected function downloadCli(string $url, string $dependencyName, string $path, ?string $hash = '', ?string $hash_algo = 'md5'): void {
$client = $this->clientService->newClient();
$progressBar = new ProgressBar($this->output);
$this->output->writeln('Downloading ' . $filename . '...');
$this->output->writeln('Downloading ' . $dependencyName . '...');
$progressBar->start();
try {
$client->get($url, [
Expand All @@ -679,21 +688,21 @@ protected function downloadCli(string $url, string $filename, string $path, ?str
} catch (\Exception $e) {
$progressBar->finish();
$this->output->writeln('');
$this->output->writeln('<error>Failure on download ' . $filename . ' try again.</error>');
$this->output->writeln('<error>Failure on download ' . $dependencyName . ' try again.</error>');
$this->output->writeln('<error>' . $e->getMessage() . '</error>');
$this->logger->error('Failure on download ' . $filename . '. ' . $e->getMessage());
$this->logger->error('Failure on download ' . $dependencyName . '. ' . $e->getMessage());
} finally {
$progressBar->finish();
$this->output->writeln('');
}
if ($hash && file_exists($path) && hash_file($hash_algo, $path) !== $hash) {
$this->output->writeln('<error>Failure on download ' . $filename . ' try again</error>');
$this->output->writeln('<error>Failure on download ' . $dependencyName . ' try again</error>');
$this->output->writeln('<error>Invalid ' . $hash_algo . '</error>');
$this->logger->error('Failure on download ' . $filename . '. Invalid ' . $hash_algo . '.');
$this->logger->error('Failure on download ' . $dependencyName . '. Invalid ' . $hash_algo . '.');
}
if (!file_exists($path)) {
$this->output->writeln('<error>Failure on download ' . $filename . ', empty file, try again</error>');
$this->logger->error('Failure on download ' . $filename . ', empty file.');
$this->output->writeln('<error>Failure on download ' . $dependencyName . ', empty file, try again</error>');
$this->logger->error('Failure on download ' . $dependencyName . ', empty file.');
}
}

Expand Down

0 comments on commit 4f15670

Please sign in to comment.