* executor basics added to repo

This commit is contained in:
Dávid Danyi 2017-03-17 16:30:19 +01:00
parent 2814f4f98e
commit 8bd0b827bf
14 changed files with 1537 additions and 3 deletions

View File

@ -16,7 +16,10 @@
"zendframework/zend-hydrator": "2.2.1", "zendframework/zend-hydrator": "2.2.1",
"zendframework/zend-filter": "2.7.1", "zendframework/zend-filter": "2.7.1",
"dasprid/container-interop-doctrine": "0.2.3", "dasprid/container-interop-doctrine": "0.2.3",
"los/basepath": "^1.0" "los/basepath": "^1.0",
"zendframework/zend-http": "^2.6",
"symfony/css-selector": "^3.2",
"zendframework/zend-cache": "^2.7"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "^4.8", "phpunit/phpunit": "^4.8",

426
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "26537d5a4676e28b7df3a39ea661f76e", "content-hash": "7486df53c7fc215192835f2616d3e3a9",
"packages": [ "packages": [
{ {
"name": "container-interop/container-interop", "name": "container-interop/container-interop",
@ -860,6 +860,42 @@
], ],
"time": "2017-01-19T11:35:12+00:00" "time": "2017-01-19T11:35:12+00:00"
}, },
{
"name": "pepegar/streams-php",
"version": "1.1",
"source": {
"type": "git",
"url": "https://github.com/pepegar/streams-php.git",
"reference": "a89f155641043f8f00931f9901cc1efaea77f8bc"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/pepegar/streams-php/zipball/a89f155641043f8f00931f9901cc1efaea77f8bc",
"reference": "a89f155641043f8f00931f9901cc1efaea77f8bc",
"shasum": ""
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
},
"type": "library",
"autoload": {
"psr-0": {
"": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Pepe García",
"email": "jl.garhdez@gmail.com"
}
],
"description": "A port of the Streams library for Java8. Let's make PHP cooler.",
"time": "2014-07-03T20:46:44+00:00"
},
{ {
"name": "psr/http-message", "name": "psr/http-message",
"version": "1.0.1", "version": "1.0.1",
@ -1154,6 +1190,59 @@
"homepage": "https://symfony.com", "homepage": "https://symfony.com",
"time": "2017-02-06T12:04:21+00:00" "time": "2017-02-06T12:04:21+00:00"
}, },
{
"name": "symfony/css-selector",
"version": "v3.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/css-selector.git",
"reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/css-selector/zipball/f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
"reference": "f0e628f04fc055c934b3211cfabdb1c59eefbfaa",
"shasum": ""
},
"require": {
"php": ">=5.5.9"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Symfony\\Component\\CssSelector\\": ""
},
"exclude-from-classmap": [
"/Tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Jean-François Simon",
"email": "jeanfrancois.simon@sensiolabs.com"
},
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "https://symfony.com/contributors"
}
],
"description": "Symfony CssSelector Component",
"homepage": "https://symfony.com",
"time": "2017-01-02T20:32:22+00:00"
},
{ {
"name": "symfony/debug", "name": "symfony/debug",
"version": "v3.2.3", "version": "v3.2.3",
@ -1270,6 +1359,75 @@
], ],
"time": "2016-11-14T01:06:16+00:00" "time": "2016-11-14T01:06:16+00:00"
}, },
{
"name": "zendframework/zend-cache",
"version": "2.7.2",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-cache.git",
"reference": "c98331b96d3b9d9b24cf32d02660602edb34d039"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-cache/zipball/c98331b96d3b9d9b24cf32d02660602edb34d039",
"reference": "c98331b96d3b9d9b24cf32d02660602edb34d039",
"shasum": ""
},
"require": {
"php": "^5.5 || ^7.0",
"zendframework/zend-eventmanager": "^2.6.2 || ^3.0",
"zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3",
"zendframework/zend-stdlib": "^2.7 || ^3.0"
},
"require-dev": {
"phpbench/phpbench": "^0.10.0",
"phpunit/phpunit": "^4.8",
"zendframework/zend-coding-standard": "~1.0.0",
"zendframework/zend-serializer": "^2.6",
"zendframework/zend-session": "^2.6.2"
},
"suggest": {
"ext-apc": "APC or compatible extension, to use the APC storage adapter",
"ext-apcu": "APCU >= 5.1.0, to use the APCu storage adapter",
"ext-dba": "DBA, to use the DBA storage adapter",
"ext-memcache": "Memcache >= 2.0.0 to use the Memcache storage adapter",
"ext-memcached": "Memcached >= 1.0.0 to use the Memcached storage adapter",
"ext-mongo": "Mongo, to use MongoDb storage adapter",
"ext-redis": "Redis, to use Redis storage adapter",
"ext-wincache": "WinCache, to use the WinCache storage adapter",
"ext-xcache": "XCache, to use the XCache storage adapter",
"mongofill/mongofill": "Alternative to ext-mongo - a pure PHP implementation designed as a drop in replacement",
"zendframework/zend-serializer": "Zend\\Serializer component",
"zendframework/zend-session": "Zend\\Session component"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.7-dev",
"dev-develop": "2.8-dev"
},
"zf": {
"component": "Zend\\Cache",
"config-provider": "Zend\\Cache\\ConfigProvider"
}
},
"autoload": {
"psr-4": {
"Zend\\Cache\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "provides a generic way to cache any data",
"homepage": "https://github.com/zendframework/zend-cache",
"keywords": [
"cache",
"zf2"
],
"time": "2016-12-16T11:35:47+00:00"
},
{ {
"name": "zendframework/zend-diactoros", "name": "zendframework/zend-diactoros",
"version": "1.3.10", "version": "1.3.10",
@ -1364,6 +1522,60 @@
], ],
"time": "2016-06-30T19:48:38+00:00" "time": "2016-06-30T19:48:38+00:00"
}, },
{
"name": "zendframework/zend-eventmanager",
"version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-eventmanager.git",
"reference": "c3bce7b7d47c54040b9ae51bc55491c72513b75d"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/c3bce7b7d47c54040b9ae51bc55491c72513b75d",
"reference": "c3bce7b7d47c54040b9ae51bc55491c72513b75d",
"shasum": ""
},
"require": {
"php": "^5.6 || ^7.0"
},
"require-dev": {
"athletic/athletic": "^0.1",
"container-interop/container-interop": "^1.1.0",
"phpunit/phpunit": "^5.6",
"zendframework/zend-coding-standard": "~1.0.0",
"zendframework/zend-stdlib": "^2.7.3 || ^3.0"
},
"suggest": {
"container-interop/container-interop": "^1.1.0, to use the lazy listeners feature",
"zendframework/zend-stdlib": "^2.7.3 || ^3.0, to use the FilterChain feature"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.1-dev",
"dev-develop": "3.2-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\EventManager\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "Trigger and listen to events within a PHP application",
"homepage": "https://github.com/zendframework/zend-eventmanager",
"keywords": [
"event",
"eventmanager",
"events",
"zf2"
],
"time": "2016-12-19T21:47:12+00:00"
},
{ {
"name": "zendframework/zend-expressive", "name": "zendframework/zend-expressive",
"version": "1.0.6", "version": "1.0.6",
@ -1704,6 +1916,56 @@
], ],
"time": "2016-04-18T18:32:43+00:00" "time": "2016-04-18T18:32:43+00:00"
}, },
{
"name": "zendframework/zend-http",
"version": "2.6.0",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-http.git",
"reference": "09f4d279f46d86be63171ff62ee0f79eca878678"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-http/zipball/09f4d279f46d86be63171ff62ee0f79eca878678",
"reference": "09f4d279f46d86be63171ff62ee0f79eca878678",
"shasum": ""
},
"require": {
"php": "^5.5 || ^7.0",
"zendframework/zend-loader": "^2.5",
"zendframework/zend-stdlib": "^2.5 || ^3.0",
"zendframework/zend-uri": "^2.5",
"zendframework/zend-validator": "^2.5"
},
"require-dev": {
"phpunit/phpunit": "^4.0",
"zendframework/zend-coding-standard": "~1.0.0",
"zendframework/zend-config": "^2.5"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.6-dev",
"dev-develop": "2.7-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Http\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "provides an easy interface for performing Hyper-Text Transfer Protocol (HTTP) requests",
"homepage": "https://github.com/zendframework/zend-http",
"keywords": [
"http",
"zf2"
],
"time": "2017-01-31T14:41:02+00:00"
},
{ {
"name": "zendframework/zend-hydrator", "name": "zendframework/zend-hydrator",
"version": "2.2.1", "version": "2.2.1",
@ -1816,6 +2078,50 @@
], ],
"time": "2016-04-01T02:34:00+00:00" "time": "2016-04-01T02:34:00+00:00"
}, },
{
"name": "zendframework/zend-loader",
"version": "2.5.1",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-loader.git",
"reference": "c5fd2f071bde071f4363def7dea8dec7393e135c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-loader/zipball/c5fd2f071bde071f4363def7dea8dec7393e135c",
"reference": "c5fd2f071bde071f4363def7dea8dec7393e135c",
"shasum": ""
},
"require": {
"php": ">=5.3.23"
},
"require-dev": {
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev",
"dev-develop": "2.6-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Loader\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"homepage": "https://github.com/zendframework/zend-loader",
"keywords": [
"loader",
"zf2"
],
"time": "2015-06-03T14:05:47+00:00"
},
{ {
"name": "zendframework/zend-servicemanager", "name": "zendframework/zend-servicemanager",
"version": "3.2.0", "version": "3.2.0",
@ -1974,6 +2280,124 @@
"psr-7" "psr-7"
], ],
"time": "2017-01-23T22:59:03+00:00" "time": "2017-01-23T22:59:03+00:00"
},
{
"name": "zendframework/zend-uri",
"version": "2.5.2",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-uri.git",
"reference": "0bf717a239432b1a1675ae314f7c4acd742749ed"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-uri/zipball/0bf717a239432b1a1675ae314f7c4acd742749ed",
"reference": "0bf717a239432b1a1675ae314f7c4acd742749ed",
"shasum": ""
},
"require": {
"php": "^5.5 || ^7.0",
"zendframework/zend-escaper": "^2.5",
"zendframework/zend-validator": "^2.5"
},
"require-dev": {
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev",
"dev-develop": "2.6-dev"
}
},
"autoload": {
"psr-4": {
"Zend\\Uri\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "a component that aids in manipulating and validating » Uniform Resource Identifiers (URIs)",
"homepage": "https://github.com/zendframework/zend-uri",
"keywords": [
"uri",
"zf2"
],
"time": "2016-02-17T22:38:51+00:00"
},
{
"name": "zendframework/zend-validator",
"version": "2.8.2",
"source": {
"type": "git",
"url": "https://github.com/zendframework/zend-validator.git",
"reference": "99b528e01276054458da9553b587cfb959dfa436"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/zendframework/zend-validator/zipball/99b528e01276054458da9553b587cfb959dfa436",
"reference": "99b528e01276054458da9553b587cfb959dfa436",
"shasum": ""
},
"require": {
"container-interop/container-interop": "^1.1",
"php": "^5.5 || ^7.0",
"zendframework/zend-stdlib": "^2.7 || ^3.0"
},
"require-dev": {
"fabpot/php-cs-fixer": "1.7.*",
"phpunit/phpunit": "^4.0",
"zendframework/zend-cache": "^2.6.1",
"zendframework/zend-config": "^2.6",
"zendframework/zend-db": "^2.7",
"zendframework/zend-filter": "^2.6",
"zendframework/zend-http": "^2.5.4",
"zendframework/zend-i18n": "^2.6",
"zendframework/zend-math": "^2.6",
"zendframework/zend-servicemanager": "^2.7.5 || ^3.0.3",
"zendframework/zend-session": "^2.6.2",
"zendframework/zend-uri": "^2.5"
},
"suggest": {
"zendframework/zend-db": "Zend\\Db component",
"zendframework/zend-filter": "Zend\\Filter component, required by the Digits validator",
"zendframework/zend-i18n": "Zend\\I18n component to allow translation of validation error messages as well as to use the various Date validators",
"zendframework/zend-i18n-resources": "Translations of validator messages",
"zendframework/zend-math": "Zend\\Math component",
"zendframework/zend-servicemanager": "Zend\\ServiceManager component to allow using the ValidatorPluginManager and validator chains",
"zendframework/zend-session": "Zend\\Session component",
"zendframework/zend-uri": "Zend\\Uri component, required by the Uri and Sitemap\\Loc validators"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.8-dev",
"dev-develop": "2.9-dev"
},
"zf": {
"component": "Zend\\Validator",
"config-provider": "Zend\\Validator\\ConfigProvider"
}
},
"autoload": {
"psr-4": {
"Zend\\Validator\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"description": "provides a set of commonly needed validators",
"homepage": "https://github.com/zendframework/zend-validator",
"keywords": [
"validator",
"zf2"
],
"time": "2017-01-29T17:24:24+00:00"
} }
], ],
"packages-dev": [ "packages-dev": [

View File

@ -15,6 +15,7 @@ return [
'invokables' => [ 'invokables' => [
// Fully\Qualified\InterfaceName::class => Fully\Qualified\ClassName::class, // Fully\Qualified\InterfaceName::class => Fully\Qualified\ClassName::class,
Helper\ServerUrlHelper::class => Helper\ServerUrlHelper::class, Helper\ServerUrlHelper::class => Helper\ServerUrlHelper::class,
\App\Service\CiNodeService::class => \App\Service\CiNodeService::class,
], ],
// Use 'factories' for services provided by callbacks/factory classes. // Use 'factories' for services provided by callbacks/factory classes.
'factories' => [ 'factories' => [
@ -23,6 +24,7 @@ return [
'doctrine.entity_manager.orm_default' => \ContainerInteropDoctrine\EntityManagerFactory::class, 'doctrine.entity_manager.orm_default' => \ContainerInteropDoctrine\EntityManagerFactory::class,
'doctrine.hydrator' => \App\Hydrator\DoctrineObjectFactory::class, 'doctrine.hydrator' => \App\Hydrator\DoctrineObjectFactory::class,
\App\Service\CiConfigService::class => \App\Service\CiConfigServiceFactory::class, \App\Service\CiConfigService::class => \App\Service\CiConfigServiceFactory::class,
\App\Service\CiExecutorService::class => \App\Service\CiExecutorServiceFactory::class,
], ],
], ],
]; ];

View File

@ -9,6 +9,9 @@ return [
'factories' => [ 'factories' => [
App\Action\CiConfigAction::class => App\Action\CiConfigFactory::class, App\Action\CiConfigAction::class => App\Action\CiConfigFactory::class,
App\Action\CiConfigItemAction::class => App\Action\CiConfigItemFactory::class, App\Action\CiConfigItemAction::class => App\Action\CiConfigItemFactory::class,
App\Action\CiExecutorAction::class => App\Action\CiExecutorFactory::class,
App\Action\JcatPackageAction::class => App\Action\JcatPackageFactory::class,
App\Action\CiStreamAction::class => App\Action\CiStreamFactory::class,
App\Action\HomePageAction::class => App\Action\HomePageFactory::class, App\Action\HomePageAction::class => App\Action\HomePageFactory::class,
], ],
], ],
@ -51,5 +54,23 @@ return [
'allowed_methods' => ['DELETE'], 'allowed_methods' => ['DELETE'],
// 'allowed_methods' => ['GET','DELETE'], // 'allowed_methods' => ['GET','DELETE'],
], ],
[
'name' => 'api.ci-executor',
'path' => '/api/ci-executor',
'middleware' => App\Action\CiExecutorAction::class,
'allowed_methods' => ['GET'],
],
[
'name' => 'api.jcat-package',
'path' => '/api/jcat-package',
'middleware' => App\Action\JcatPackageAction::class,
'allowed_methods' => ['GET'],
],
[
'name' => 'api.ci-streams',
'path' => '/api/ci-stream',
'middleware' => App\Action\CiStreamAction::class,
'allowed_methods' => ['GET'],
],
], ],
]; ];

View File

@ -0,0 +1,27 @@
<?php
namespace App\Action;
use App\Response\JsonCorsResponse;
use App\Service\CiExecutorService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class CiExecutorAction extends AbstractAction
{
/**
* @var CiExecutorService
*/
private $ciExecutorService;
public function __construct(CiExecutorService $ciExecutorService)
{
$this->ciExecutorService = $ciExecutorService;
}
public function getList(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{
return new JsonCorsResponse($this->ciExecutorService->debug());
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Action;
use App\Service\CiExecutorService;
use Interop\Container\ContainerInterface;
class CiExecutorFactory
{
public function __invoke(ContainerInterface $container)
{
$service = $container->get(CiExecutorService::class);
return new CiExecutorAction($service);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Action;
use App\Response\JsonCorsResponse;
use App\Service\CiExecutorService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class CiStreamAction extends AbstractAction
{
/**
* @var CiExecutorService
*/
private $ciExecutorService;
public function __construct(CiExecutorService $ciExecutorService)
{
$this->ciExecutorService = $ciExecutorService;
}
public function getList(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{
return new JsonCorsResponse($this->ciExecutorService->getCiStreams());
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Action;
use App\Service\CiExecutorService;
use Interop\Container\ContainerInterface;
class CiStreamFactory
{
public function __invoke(ContainerInterface $container)
{
$service = $container->get(CiExecutorService::class);
return new CiStreamAction($service);
}
}

View File

@ -0,0 +1,27 @@
<?php
namespace App\Action;
use App\Response\JsonCorsResponse;
use App\Service\CiExecutorService;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
class JcatPackageAction extends AbstractAction
{
/**
* @var CiExecutorService
*/
private $ciExecutorService;
public function __construct(CiExecutorService $ciExecutorService)
{
$this->ciExecutorService = $ciExecutorService;
}
public function getList(ServerRequestInterface $request, ResponseInterface $response, callable $next = null)
{
return new JsonCorsResponse($this->ciExecutorService->getJcatPackages());
}
}

View File

@ -0,0 +1,15 @@
<?php
namespace App\Action;
use App\Service\CiExecutorService;
use Interop\Container\ContainerInterface;
class JcatPackageFactory
{
public function __invoke(ContainerInterface $container)
{
$service = $container->get(CiExecutorService::class);
return new JcatPackageAction($service);
}
}

View File

@ -21,6 +21,7 @@ class CiConfig implements JsonSerializable
/** /**
* @ORM\OneToMany(targetEntity="CiConfigItem", mappedBy="dailyConfig", cascade={"persist", "remove"}, orphanRemoval=true) * @ORM\OneToMany(targetEntity="CiConfigItem", mappedBy="dailyConfig", cascade={"persist", "remove"}, orphanRemoval=true)
* @var CiConfigItem[]
*/ */
private $configItems; private $configItems;
@ -51,7 +52,7 @@ class CiConfig implements JsonSerializable
} }
/** /**
* @return mixed * @return CiConfigItem[]|ArrayCollection
*/ */
public function getConfigItems() public function getConfigItems()
{ {

View File

@ -0,0 +1,783 @@
<?php
namespace App\Service;
use App\Entity\CiConfig;
use App\Entity\CiConfigItem;
use Doctrine\ORM\EntityManager;
use Symfony\Component\CssSelector\CssSelectorConverter;
use Zend\Cache\Storage\Adapter\Filesystem;
use Zend\Http\Client;
use Zend\Json\Json;
class CiExecutorService
{
const JENKINS_REDIRECT_URL = "http://jvirtu1.tsp.eth.ericsson.se/jenkins";
const NODE_STATUS_PATH = '/computer';
const CONFIG_1_PATH = '/me/my-views/view/Configuration/job/Config_1_edvidan';
const CONFIG_2_PATH = '/me/my-views/view/Configuration/job/manual_config_2_edvidan';
const ADD_JCAT_PATH = '/view/Tools/job/JCAT_deploy_handler_tool';
const JCAT_DEPLOY_SOURCE_URL = 'http://jcat.tsp.eth.ericsson.se/www/autotest/deploy';
const JCAT_CACHE_KEY = "jcat";
const PACKAGE_CACHE_KEY = "packages";
const STREAM_CACHE_KEY = "stream";
private $testTypeMap = [
'isDoRollbackBefore' => 'rollback_before',
'isDoForcedRollback' => 'ForcedRollback',
'isDoUpgrade' => 'upgrade',
'isDoDummyUpgrade' => 'SystemDummy',
'isDoLrt' => 'lrt',
'isDoDsv' => 'cwosdsv',
// 'isDoNmDsv' => '',
'isDoForcedRollbackDummy' => 'ForcedRollbackDummy',
'isDoRollbackAfter' => 'rollback_after',
];
private $jenkinsBaseUrl = null;
/**
* @var EntityManager
*/
private $entityManager;
/**
* @var Client
*/
private $httpClient;
/**
* @var CiNodeService
*/
private $nodeService;
/**
* CiExecutorService constructor.
* @param EntityManager $entityManager
* @param Client $httpClient
* @param CiNodeService $nodeService
*/
public function __construct(EntityManager $entityManager, Client $httpClient, CiNodeService $nodeService)
{
$this->entityManager = $entityManager;
$this->httpClient = $httpClient;
$this->nodeService = $nodeService;
$this->jenkinsBaseUrl = $this->getActiveJenkinsUrl();
}
public function debug()
{
/** @var CiConfig $config */
$config = $this->entityManager->find(CiConfig::class, 20170317);
return $this->runTest($config->getConfigItems()->first());
}
/**
* Get available jcat versions from config2 page
*
* @param bool $cached
* @return array
*/
public function getJcatPackages($cached = true)
{
if (!$cached) {
$config2Html = $this->getConfig2Html();
$staplerTokens = $this->getStaplerTokens($config2Html, "JCAT_TYPE");
return $this->getJcatVersions($staplerTokens['url'], $staplerTokens['token']);
// return $this->getJcatVersions($config2Html);
}
$cache = $this->getCache(self::JCAT_CACHE_KEY);
$result = $cache->getItem(self::PACKAGE_CACHE_KEY, $success);
if(!$success) {
$config2Html = $this->getConfig2Html();
$staplerTokens = $this->getStaplerTokens($config2Html, "JCAT_TYPE");
$packages =$this->getJcatVersions($staplerTokens['url'], $staplerTokens['token']);
// $packages =$this->getJcatVersions($config2Html);
$cache->setItem(self::PACKAGE_CACHE_KEY, serialize($packages));
} else {
$packages = unserialize($result);
}
return $packages;
}
/**
* @param bool $cached
* @return array|mixed
*/
public function getCiStreams($cached = true)
{
if (!$cached) {
$config2Html = $this->getConfig2Html();
return $this->getStreams($config2Html);
}
$cache = $this->getCache(self::STREAM_CACHE_KEY);
$result = $cache->getItem(self::STREAM_CACHE_KEY, $success);
if(!$success) {
$config2Html = $this->getConfig2Html();
$streams =$this->getStreams($config2Html);
$cache->setItem(self::STREAM_CACHE_KEY, serialize($streams));
} else {
$streams = unserialize($result);
}
return $streams;
}
/**
* Executes a daily configuration from the database.
* This method is meant to be called periodically from cron
*
* @todo implement locking mechanism, so cli task won't start if there is a job already running
* @param CiConfig $ciConfig
*/
public function executePendingTests(CiConfig $ciConfig)
{
foreach ($ciConfig->getConfigItems() as $configItem) {
$this->runTest($configItem);
}
}
/**
* Run a single test configuration item in a daily job
*
* @param CiConfigItem $configItem
* @return array|bool
*/
public function runTest(CiConfigItem $configItem)
{
$nodes = $this->nodeService->getTestNodeList($configItem->getNodes());
// @todo implement marking of "sub-job" to track if a node already has the tests going
// $availableNodes = array_filter($nodes, function($node) {
// return $this->isNodeOnline($node) && $this->isNodeIdle($node);
// });
//
// if(0 == count($availableNodes)) {
// return false;
// }
// @todo remove this part, and check for sub-job success that also needs to be saved, if any node fails, all nodes fail now
foreach($nodes as $node) {
if(!$this->isNodeOnline($node) || !$this->isNodeIdle($node)) {
return false;
}
}
// Build Config1 and wait till it's finished
// @todo reorganize this into config1build?
$config1Status = $this->buildConfigOne($nodes);
$config1JobId = $this->getConfig1JobId();
while(!$this->isConfig1Built($config1JobId)) {
sleep(2);
set_time_limit(30);
}
// Get the generated config2 page and parse it for required data
$config2Html = $this->getConfig2Html();
$streams = $this->getStreams($config2Html);
$staplerTokens = $this->getStaplerTokens($config2Html, "STREAM");
if(true === ($streamExists = in_array($configItem->getStream(), $streams))) {
$package = $this->getPackage($configItem->getStream(), $staplerTokens['url'], $staplerTokens['token']);
} else {
$package = false;
}
$jcatVersions = $this->getJcatVersions($staplerTokens['url'], $staplerTokens['token']);
// Check if the desired JCAT version is available, try to create it if it's not
if(!in_array($configItem->getJcat(), $jcatVersions)) {
// wait for jcat package to become available
$this->addJcatPackageToJenkins($configItem->getJcat());
$jcatDeployJobId = $this->getJcatDeployJobId();
while(!$this->isJcatPackageDeployed($jcatDeployJobId)) {
sleep(2);
set_time_limit(30);
}
// @todo check if we have to rebuild config1 or can just proceed with knowing the right parameters
}
$nodeBases = [];
$nodeTraffics = [];
foreach($nodes as $type => $typeNodes) {
foreach($typeNodes as $node => $backupPostfix) {
if(false === strpos($node, "-")) {
$nodeBaseName = sprintf("%s_%s", $node, $backupPostfix);
$nodeBases[$node] = in_array($nodeBaseName, $this->getNodeBaseNames($config2Html, $node)) ? $nodeBaseName : false;
$nodeTraffics[$node] = $this->getNodeTrafficConfigs($config2Html, $node);
} else {
list($zone1, $zone2) = explode("-", $node);
$zone1BaseName = sprintf("%s_%s", $zone1, $backupPostfix);
$zone2BaseName = sprintf("%s_%s", $zone2, $backupPostfix);
$nodeBases[$zone1] = in_array($zone1BaseName, $this->getNodeBaseNames($config2Html, $zone1)) ? $zone1BaseName : false;
$nodeBases[$zone2] = in_array($zone2BaseName, $this->getNodeBaseNames($config2Html, $zone2)) ? $zone2BaseName : false;
$nodeTraffics[$node] = $this->getNodeTrafficConfigs($config2Html, str_replace("-", "_", $node));
}
}
}
$this->buildConfigTwo($configItem, $package, $nodes, $nodeBases, $nodeTraffics);
return [
"config1ok"=> $config1Status,
// "stapler" => $staplerTokens,
// "packages" => $package,
"jcat" => $jcatVersions,
"bases" => $nodeBases,
"traffic" => $nodeTraffics,
"configsOk" => $this->config1PreCheck(),
"active.jenkins" => $this->getActiveJenkinsUrl(),
"jcat.exists" => $this->getJcatDeployUrl("TSP_JCAT-138.0_CORE"),
"jcat.nodes" => $this->getAvailableJcatTargetNodes(),
"cwis8.on" => $this->isNodeOnline("cwis8"),
];
}
/**
* Checks is both Config1 and Config2 jobs are idle.
* We can only start building new configs if there is no job running at the moment.
*
* @return bool
*/
private function config1PreCheck(): bool
{
$config1JobId = $this->getConfig1JobId();
$this->httpClient->setUri($this->jenkinsBaseUrl . self::CONFIG_1_PATH . "/${config1JobId}/api/json");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
if($parsedResponse->building == true) {
return false;
}
$config2JobId = $this->getConfig2JobId();
$this->httpClient->setUri($this->jenkinsBaseUrl . self::CONFIG_1_PATH . "/${config2JobId}/api/json");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
if($parsedResponse->building == true) {
return false;
}
return true;
}
/**
* @param $nodes
* @return bool
* @todo build uri parameters OR switch to the other uri for api stuff
*/
private function buildConfigOne($nodes): bool
{
$appendParams = [];
foreach($nodes as $type => $typeNodes) {
foreach($typeNodes as $node => $basePostfix) {
$appendParams[] = sprintf("%s=%s", $type, $node);
}
}
$this->httpClient->setUri($this->jenkinsBaseUrl . self::CONFIG_1_PATH . '/buildWithParameters?delay=0sec&' . implode("&", $appendParams));
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('POST');
$response = $this->httpClient->send();
sleep(2);
return $response->isSuccess();
}
private function getConfig1JobId()
{
return $this->getJobId($this->jenkinsBaseUrl . self::CONFIG_1_PATH);
}
private function getConfig2JobId()
{
return $this->getJobId($this->jenkinsBaseUrl . self::CONFIG_2_PATH);
}
private function getJobId($uri)
{
$this->httpClient->setUri($uri . '/api/json');
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
return $parsedResponse->lastBuild->number;
}
private function isConfig1Built(int $jobId): bool
{
$this->httpClient->setUri($this->jenkinsBaseUrl . self::CONFIG_1_PATH . "/${jobId}/api/json");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
if($parsedResponse->building == false) {
if ($parsedResponse->result == 'SUCCESS') {
return true;
}
throw new \Exception("Build failed with result: " . $parsedResponse->result);
}
return false;
}
/**
* @return string
* @throws \Exception
* @todo investigate why GET method on the config page returns HTTP405
*/
private function getConfig2Html(): string
{
$this->httpClient->setUri($this->jenkinsBaseUrl . self::CONFIG_2_PATH . "/build");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
if($response->getStatusCode() == 401) {
throw new \Exception("Not authenticated");
}
return $response->getBody();
}
private function getStaplerTokens($config2Body, $blockName = "STREAM")
{
if(0 === ($didMatch = preg_match(sprintf('#referencedParameters\.push\("%s"\);.*?makeStaplerProxy\(\'(.*?)\',\'(.*?)\'.*?// Create Jenkins proxy#msi', $blockName), $config2Body, $matches))) {
throw new \Exception("Couldn't match stapler tokens in response body");
}
return [
'url' => $matches[1],
'token' => $matches[2],
];
}
private function getStreams($config2Body)
{
$cssToXpathConverter = new CssSelectorConverter();
$xpathQuery = $cssToXpathConverter->toXPath('input[value=STREAM]');
$domDocument = new \DOMDocument();
$domDocument->loadHTML($config2Body);
$xpath = new \DOMXPath($domDocument);
$element = $xpath->query($xpathQuery);
if($element->length == 0) {
throw new \Exception("Can't find STREAM");
}
if($element[0]->nextSibling->nodeName != "select") {
throw new \Exception("Can't find STREAM dropdown");
}
$streams = [];
foreach ($element[0]->nextSibling->childNodes as $option) {
$streams[] = $option->textContent;
}
sort($streams, SORT_NATURAL);
return array_values(array_filter(array_unique($streams), function($item){
return $item != "" && $item != "none";
}));
}
private function getPackage($stream, $url, $token): string
{
$this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/doUpdate');
$this->httpClient->resetParameters(false, false);
$headers = $this->httpClient->getRequest()->getHeaders();
$headers->addHeaderLine("Crumb", $token);
$headers->addHeaderLine("Content-type", "application/x-stapler-method-invocation;charset=UTF-8");
$request = $this->httpClient->getRequest();
$request->setMethod('POST');
$request->setContent(sprintf('["STREAM=%s"]', $stream));
$updateResponse = $this->httpClient->send();
if(!$updateResponse->isSuccess()) {
throw new \Exception("Stapler doUpdate error");
}
sleep(1);
$this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/getChoicesForUI');
$request->setContent("[]");
$choicesResponse = $this->httpClient->send();
if(!$choicesResponse->isSuccess()) {
throw new \Exception("Stapler getChoicesForUI error");
}
$packages = Json::decode($choicesResponse->getBody());
if($packages[0][0] == "Script error") {
throw new \Exception("STREAM stapler script error");
}
return array_shift($packages[0]);
}
/**
* @param $url
* @param $token
* @return mixed
* @throws \Exception
*/
private function getJcatVersions($url, $token)
{
// v1
// $cssToXpathConverter = new CssSelectorConverter();
// $xpathQuery = $cssToXpathConverter->toXPath('input[value=JCAT_DIR__MAIN]');
//
// $domDocument = new \DOMDocument();
// $domDocument->loadHTML($config2Body);
//
// $xpath = new \DOMXPath($domDocument);
// $element = $xpath->query($xpathQuery);
//
// if($element->length == 0) {
// throw new \Exception("Can't find JCAT_DIR__MAIN");
// }
//
// if($element[0]->nextSibling->nodeName != "select") {
// throw new \Exception("Can't find JCAT dropdown");
// }
//
// $jcatVersions = [];
// foreach ($element[0]->nextSibling->childNodes as $option) {
// $jcatVersions[] = $option->textContent;
// }
//
// rsort($jcatVersions, SORT_NATURAL);
// return array_values(array_filter(array_unique($jcatVersions), function($item){return $item != "";}));
// v2
$this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/doUpdate');
$this->httpClient->resetParameters(false, false);
$headers = $this->httpClient->getRequest()->getHeaders();
$headers->addHeaderLine("Crumb", $token);
$headers->addHeaderLine("Content-type", "application/x-stapler-method-invocation;charset=UTF-8");
$request = $this->httpClient->getRequest();
$request->setMethod('POST');
$request->setContent('["JCAT_TYPE=INSTALLED"]');
$updateResponse = $this->httpClient->send();
if(!$updateResponse->isSuccess()) {
throw new \Exception("Stapler doUpdate error");
}
sleep(1);
$this->httpClient->setUri($this->jenkinsBaseUrl . $url . '/getChoicesForUI');
$request->setContent("[]");
$choicesResponse = $this->httpClient->send();
if(!$choicesResponse->isSuccess()) {
throw new \Exception("Stapler getChoicesForUI error");
}
$jcats = Json::decode($choicesResponse->getBody());
rsort($jcats[0]);
if($jcats[0][0] == "Script error") {
throw new \Exception("JCAT stapler script error");
}
return $jcats[0];
}
private function getNodeBaseNames($config2Body, $nodeName)
{
$cssToXpathConverter = new CssSelectorConverter();
$xpathQuery = $cssToXpathConverter->toXPath(sprintf('input[value=%s_BASE_BACKUP]', $nodeName));
$domDocument = new \DOMDocument();
$domDocument->loadHTML($config2Body);
$xpath = new \DOMXPath($domDocument);
$element = $xpath->query($xpathQuery);
if($element->length == 0) {
throw new \Exception(sprintf("Can't find %s_BASE_BACKUP", $nodeName));
}
if($element[0]->nextSibling->nodeName != "select") {
throw new \Exception(sprintf("Can't find %s_BASE_BACKUP dropdown", $nodeName));
}
$baseNames = [];
foreach ($element[0]->nextSibling->childNodes as $option) {
$baseNames[] = $option->textContent;
}
rsort($baseNames, SORT_NATURAL);
return array_filter($baseNames, function($item){return $item != "";});
}
private function getNodeTrafficConfigs($config2Body, $nodeName)
{
$cssToXpathConverter = new CssSelectorConverter();
$xpathQuery = $cssToXpathConverter->toXPath(sprintf('input[value=%s_TRAFFIC]', $nodeName));
$domDocument = new \DOMDocument();
$domDocument->loadHTML($config2Body);
$xpath = new \DOMXPath($domDocument);
$element = $xpath->query($xpathQuery);
if($element->length == 0) {
throw new \Exception(sprintf("Can't find %s_TRAFFIC", $nodeName));
}
if($element[0]->nextSibling->nodeName != "select") {
throw new \Exception(sprintf("Can't find %s_TRAFFIC dropdown", $nodeName));
}
$trafficConfigs = [];
foreach ($element[0]->nextSibling->childNodes as $option) {
$trafficConfigs[] = $option->textContent;
}
rsort($trafficConfigs, SORT_NATURAL);
return array_filter($trafficConfigs, function($item){return $item != "";});
}
/**
* @param CiConfigItem $configItem
* @param bool|string $package
* @param array $nodes
* @param array $nodeBases
* @param array $nodeTraffics
* @return bool
*/
private function buildConfigTwo(CiConfigItem $configItem, $package, array $nodes, array $nodeBases, array $nodeTraffics)
{
$params = [];
if(false === $package) {
// stream doesn't exist, have to be created as new. enforces test to be nightly
$params[] = "MODE=nightly";
$params[] = "NEW_STREAM=" . $configItem->getStream();
} else {
$params[] = "MODE=" . ($configItem->isNightly() ? 'nightly' : 'manual');
$params[] = "STREAM=" . $configItem->getStream();
$params[] = "PACKAGE_NAME=" . $configItem->getStream();
}
$params[] = "RECIPIENTS=PDLSPCORED@pdl.internal.ericsson.com";
$params[] = "JCAT_DIR__MAIN=" . $configItem->getJcat();
$params[] = "JCAT_DIR__UPGRADE=" . $configItem->getJcat();
foreach($nodes as $node) {
if(false === strpos($node, "-")) {
$params[] = sprintf("%s_BASE_BACKUP=%s_%s", $node, $node, $nodeBases[$node]);
} else {
list($zone1, $zone2) = explode("-", $node);
$params[] = sprintf("%s_BASE_BACKUP=%s_%s",$zone1, $zone1, $nodeBases[$zone1]);
$params[] = sprintf("%s_BASE_BACKUP=%s_%s",$zone2, $zone2, $nodeBases[$zone2]);
}
// todo create suites parameters
foreach ($this->testTypeMap as $callable => $paramName) {
if($configItem->$callable()) {
$params[] = sprintf("%s_SUITES=%s", $node, $paramName);
}
}
$params[] = sprintf("%s_TRAFFIC=%s", $node, $nodeTraffics[$node]);
}
$this->httpClient->setUri($this->jenkinsBaseUrl . self::CONFIG_2_PATH . '/buildWithParameters?delay=0sec&' . implode("&", $params));
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('POST');
$response = $this->httpClient->send();
sleep(2);
return $response->isSuccess();
}
/**
* @param string $namespace
* @return Filesystem
*/
private function getCache(string $namespace): Filesystem
{
$cache = new Filesystem();
$cache->getOptions()
->setCacheDir("data/cache")
->setTtl(3600)
->setNamespace($namespace)
;
return $cache;
}
/**
* Returns uri of jcat deploy or boolean FALSE, if it can't find/guess it.
*
* @param string $jcatVersion The jcat version in the format of TSP-JCATxxx.y[type]
* @return bool|string
*/
private function getJcatDeployUrl(string $jcatVersion)
{
preg_match('#TSP_JCAT-([0-9]{3,}\.[0-9]+)(.*)?#', $jcatVersion, $matches);
$version = $matches[1];
$deployType = trim($matches[2],"_");
unset($matches);
// package has no type specified, or type is COMMON
if($deployType == "" || $deployType == "COMMON") {
$uri = self::JCAT_DEPLOY_SOURCE_URL . sprintf("/JCAT-%s/TSP_JCAT-%s.tar.gz", $version, $version);
$this->httpClient->setUri($uri);
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('HEAD');
$response = $this->httpClient->send();
if($response->isOk()) {
return $uri;
}
return false;
}
// package type specified exists on jcat server
$uri = self::JCAT_DEPLOY_SOURCE_URL . sprintf("/JCAT-%s-%s/TSP_JCAT-%s-%s.tar.gz", $deployType, $version, $deployType, $version);
$this->httpClient->setUri($uri);
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('HEAD');
$response = $this->httpClient->send();
if($response->isOk()) {
return $uri;
}
// package type specified exists with 'TSP' prefix on jcat server
$uri = self::JCAT_DEPLOY_SOURCE_URL . sprintf("/JCAT-TSP%s-%s/TSP_JCAT-TSP%s-%s.tar.gz", $deployType, $version, $deployType, $version);
$this->httpClient->setUri($uri);
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('HEAD');
$response = $this->httpClient->send();
if($response->isOk()) {
return $uri;
}
return false;
}
private function addJcatPackageToJenkins($jcatVersion)
{
$availableJcatTargetNodes = $this->getAvailableJcatTargetNodes();
$jcatDeployUri = $this->getJcatDeployUrl($jcatVersion);
$appendParams = [
"NEW_DEPLOY_NAME=$jcatVersion",
"NEW_DEPLOY_URL=$jcatDeployUri",
"ACTION=add",
];
foreach($availableJcatTargetNodes as $node) {
$appendParams[] = "NODES=$node";
}
$this->httpClient->setUri($this->jenkinsBaseUrl . self::ADD_JCAT_PATH . '/buildWithParameters?delay=0sec&' . implode("&", $appendParams));
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('POST');
$response = $this->httpClient->send();
return $response->isSuccess();
}
/**
* Returns last started jcat deploy creator jobId
*
* @return int
*/
private function getJcatDeployJobId(): ?int
{
return $this->getJobId($this->jenkinsBaseUrl . self::ADD_JCAT_PATH);
}
/**
* @todo check if build result is instant or 'inQueue' reflects build state at all
* @param int $jobId
* @return bool
* @throws \Exception
*/
private function isJcatPackageDeployed(int $jobId): bool
{
$this->httpClient->setUri($this->jenkinsBaseUrl . self::ADD_JCAT_PATH . "/${jobId}/api/json");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
if($parsedResponse->inQueue == false) {
if ($parsedResponse->lastBuild->number == $parsedResponse->lastSuccessfulBuild->number) {
return true;
}
throw new \Exception("Build failed.");
}
return false;
}
private function getAvailableJcatTargetNodes()
{
$this->httpClient->setUri($this->jenkinsBaseUrl . self::ADD_JCAT_PATH . "/build");
$this->httpClient->resetParameters(false, false);
$response = $this->httpClient->send();
$jcatHandlerPageBody = $response->getBody();
$cssToXpathConverter = new CssSelectorConverter();
$xpathQuery = $cssToXpathConverter->toXPath('input[value=NODES]');
$domDocument = new \DOMDocument();
$domDocument->loadHTML($jcatHandlerPageBody);
$xpath = new \DOMXPath($domDocument);
$element = $xpath->query($xpathQuery);
if($element->length == 0) {
throw new \Exception("Can't find NODES");
}
if($element[0]->nextSibling->nodeName != "select") {
throw new \Exception("Can't find NODES dropdown");
}
$trafficConfigs = [];
foreach ($element[0]->nextSibling->childNodes as $option) {
$trafficConfigs[] = $option->textContent;
}
sort($trafficConfigs, SORT_NATURAL);
return $trafficConfigs;
}
private function getActiveJenkinsUrl(): string
{
$this->httpClient->setUri(self::JENKINS_REDIRECT_URL);
$this->httpClient->resetParameters(false, false);
$this->httpClient->setOptions(['maxredirects' => 0]);
$request = $this->httpClient->getRequest();
$request->setMethod('HEAD');
$response = $this->httpClient->send();
if($response->isRedirect()) {
$this->httpClient->setOptions(['maxredirects' => 5]);
return rtrim($response->getHeaders()->get("location")->getFieldValue(), "/");
}
throw new \Exception("Jenkins redirect url is not working, return code was: " . $response->getStatusCode());
}
public function isNodeOnline(string $node): bool
{
$this->httpClient->setUri($this->jenkinsBaseUrl . self::NODE_STATUS_PATH . "/${node}/api/json");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
return !$parsedResponse->offline;
}
public function isNodeIdle(string $node): bool
{
$this->httpClient->setUri($this->jenkinsBaseUrl . self::NODE_STATUS_PATH . "/${node}/api/json");
$this->httpClient->resetParameters(false, false);
$request = $this->httpClient->getRequest();
$request->setMethod('GET');
$response = $this->httpClient->send();
$body = $response->getBody();
$parsedResponse = Json::decode($body);
return $parsedResponse->idle;
}
}

View File

@ -0,0 +1,19 @@
<?php
namespace App\Service;
use Interop\Container\ContainerInterface;
use Zend\Http\Client;
class CiExecutorServiceFactory
{
public function __invoke(ContainerInterface $container)
{
$nodeService = $container->get(CiNodeService::class);
$entityManager = $container->get('doctrine.entity_manager.orm_default');
$config = $container->get('config');
$httpClient = new Client();
$httpClient->setAuth($config['ci.auth']['user'], $config['ci.auth']['pass']);
return new CiExecutorService($entityManager, $httpClient, $nodeService);
}
}

View File

@ -0,0 +1,155 @@
<?php
namespace App\Service;
class CiNodeService
{
private $nodes = [
[
"name" => 'esx4b', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => ["7101_base_Jenkins_CI_20161006"], "defaultBase" => "7101_base_Jenkins_CI_20161006", "canAutoStart" => true,
],
[
"name" => 'esx10a', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'esx10b', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'asumi', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'michiyo', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'sakura', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'takumi', "type" => 'esx', "size" => 1, "team" => "detoqs",
"bases" => ["7000_base_Jenkins_CI_20160701"], "defaultBase" => "7000_base_Jenkins_CI_20160701", "canAutoStart" => true,
],
[
"name" => 'cwsled', "type" => 'maia', "size" => 1, "team" => "taurus",
"bases" => [], "defaultBase" => "", "canAutoStart" => false,
],
[
"name" => 'g8z1', "type" => 'nsp5', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'to22', "type" => 'nsp5', "size" => 1, "team" => "detoqs",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'cwis8', "type" => 'nsp6', "size" => 3, "team" => "vikinx",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'cwis9', "type" => 'nsp6', "size" => 3, "team" => "oorio",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'ivis1', "type" => 'nsp6', "size" => 1, "team" => "vikinx",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'ivis2', "type" => 'nsp6', "size" => 1, "team" => "oorio",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'nmis1', "type" => 'nsp6', "size" => 2, "team" => "unknown",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'tina', "type" => 'nsp6', "size" => 1, "team" => "oorio",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'alla', "type" => 'nsp6.1', "size" => 3, "team" => "unknown",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'katyusa', "type" => 'nsp6.1', "size" => 2, "team" => "unknown",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'elena', "type" => 'nsp6.1', "size" => 2, "team" => "oorio",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'natasha', "type" => 'nsp6.1', "size" => 2, "team" => "trex",
"bases" => ["7101_base_Jenkins_CI_20161217"], "defaultBase" => "7101_base_Jenkins_CI_20161217", "canAutoStart" => true,
],
[
"name" => 'mazsola-tade', "type" => 'nsp6.1', "size" => 1, "team" => "vikinx",
"bases" => ["7111_base_Jenkins_CI_20170130"], "defaultBase" => "7111_base_Jenkins_CI_20170130", "canAutoStart" => true,
],
[
"name" => 'pikkolo', "type" => 'nsp6.1', "size" => 1, "team" => "taurus",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'sonia', "type" => 'nsp6.1', "size" => 1, "team" => "trex",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'tatiana', "type" => 'nsp6.1', "size" => 2, "team" => "taurus",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'opossum', "type" => 'gep5', "size" => 1, "team" => "taurus",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'petymeg', "type" => 'gep5', "size" => 2, "team" => "vikinx",
"bases" => [], "defaultBase" => "", "canAutoStart" => true,
],
[
"name" => 'gicnode4', "type" => 'gep5', "size" => 2, "team" => "oorio",
"bases" => [], "defaultBase" => "", "canAutoStart" => false,
],
[
"name" => 'gicnode10', "type" => 'gep5', "size" => 1, "team" => "trex",
"bases" => [], "defaultBase" => "", "canAutoStart" => false,
],
[
"name" => 'gicnode19', "type" => 'gep5', "size" => 2, "team" => "trex",
"bases" => [], "defaultBase" => "", "canAutoStart" => false,
],
];
public function getNodes(): array
{
return $this->nodes;
}
public function getNode($node): ?array
{
return array_pop(array_filter($this->nodes, function($item) use ($node) {
return $item['name'] == $node;
}));
}
public function getTestNodeList(array $nodes): ?array
{
$filteredNodes = array_filter($this->nodes, function($item) use ($nodes) {
return in_array($item['name'], $nodes);
});
$result = [];
foreach ($filteredNodes as $filteredNode) {
$type = strtoupper($filteredNode['type']);
if(!isset($result[$type])) {
$result[$type] = [];
}
$result[$type][$filteredNode['name']] = $filteredNode['defaultBase'];
}
return $result;
}
}