Added ability to specify compatibility in hotfix

This commit is contained in:
Chris 2016-12-02 15:23:03 +01:00
parent b5d3754b2f
commit 34f53c0e75
5 changed files with 115 additions and 1 deletions

View File

@ -17,6 +17,7 @@
"require": {
"symfony/console": "^3.0",
"symfony/yaml": "^3.0",
"noccylabs/downloader": "@dev"
"noccylabs/downloader": "@dev",
"symfony/expression-language": "^3.2"
}
}

29
docs/EXPRESSIONS.md Normal file
View File

@ -0,0 +1,29 @@
Matching Expressions
====================
Hotfixes can provide a `for` key with an array of supported systems. The
expressions are evaluated using Symfony's ExpressionLanguage and as such
can handle some pretty complex stuff.
For a hotfix to be considered supported, at least one of the expressions
must evaluate to true.
## Example:
for:
- lsb.id=='raspbian'
- lsb.id=='ubuntu' and lsb.release=>'16.04'
## System facts
### Distribution
Information is retrieved using `lsb_release` or the `/etc/os-release` file.
lsb.id Distribution ID (ex. ubuntu or raspbian)
lsb.description Pretty description
lsb.release Version number (ex. 16.04 or 8)
lsb.codename Release codename (ex. xenial, not always present)

View File

@ -10,7 +10,10 @@ use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
use Symfony\Component\Console\Question\ChoiceQuestion;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use NoccyLabs\Hotfix\Hotfix\Loader;
use NoccyLabs\Hotfix\System\Facts;
class ApplyCommand extends Command
{
@ -64,6 +67,28 @@ class ApplyCommand extends Command
} else {
$output->writeln("<fg=red;options=bold>Warning: Hotfix is not signed or signature not valid!</fg=red;options=bold>");
}
$requires = $hotfix->getRequirements();
if (count($requires)>0) {
$engine = new ExpressionLanguage();
$facts = Facts::getSystemFacts()->getFacts();
while (true) {
$expr = array_shift($requires);
$ret = $engine->evaluate($expr, $facts);
if ($ret) {
//$output->writeln("<fg=green;options=bold>Hotfix is compatible with the current distribution</>");
break;
}
if (count($requires)==0) {
$output->writeln("<error>Error: This hotfix it not compatible with the current distribution</>");
return false;
}
}
//} else {
//$output->writeln("<fg=green;options=bold>Hotfix indicates universal compatibility.</>");
}
$output->writeln("");
$output->writeln(" Hotfix: <fg=yellow;options=bold>".$hotfix->getName()."</fg=yellow;options=bold>");
$output->writeln(" Author: <comment>".$hotfix->getAuthor()."</comment>");

View File

@ -70,6 +70,14 @@ class Hotfix
unlink($tmpfile);
}
public function getRequirements()
{
if (!array_key_exists('for',$this->header)) {
return [];
}
return $this->header['for'];
}
public function getSignedBy()
{
if (!$this->signer) {

51
src/System/Facts.php Normal file
View File

@ -0,0 +1,51 @@
<?php
namespace NoccyLabs\Hotfix\System;
use Symfony\Component\Console\Application;
class Facts
{
private $facts;
public static function getSystemFacts()
{
static $facts;
if (!$facts) {
$facts = new self();
$facts->read();
}
return $facts;
}
public function read()
{
$facts = [];
$has_lsb_release = exec("which lsb_release");
if ($has_lsb_release) {
exec("lsb_release -idrcs", $output);
$facts['lsb'] = (object)[
'id' => strtolower($output[0]),
'description' => $output[1],
'release' => $output[2],
'codename' => $output[3]
];
} elseif (file_exists("/etc/os-release")) {
$ini = parse_ini_file("/etc/os-release");
$facts['lsb'] = (object)[
'id' => strtolower(@$ini['ID']),
'description' => @$ini['PRETTY_NAME'],
'release' => @$ini['VERSION_ID'],
'codename' => @$ini['VERSION_CODENAME']
];
}
$this->facts = $facts;
}
public function getFacts()
{
return $this->facts;
}
}