* executor basics added to repo
This commit is contained in:
parent
2814f4f98e
commit
8bd0b827bf
@ -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
426
composer.lock
generated
@ -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": [
|
||||||
|
|||||||
@ -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,
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
@ -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'],
|
||||||
|
],
|
||||||
],
|
],
|
||||||
];
|
];
|
||||||
|
|||||||
27
src/App/Action/CiExecutorAction.php
Normal file
27
src/App/Action/CiExecutorAction.php
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/App/Action/CiExecutorFactory.php
Normal file
15
src/App/Action/CiExecutorFactory.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/App/Action/CiStreamAction.php
Normal file
27
src/App/Action/CiStreamAction.php
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/App/Action/CiStreamFactory.php
Normal file
15
src/App/Action/CiStreamFactory.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
src/App/Action/JcatPackageAction.php
Normal file
27
src/App/Action/JcatPackageAction.php
Normal 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());
|
||||||
|
}
|
||||||
|
}
|
||||||
15
src/App/Action/JcatPackageFactory.php
Normal file
15
src/App/Action/JcatPackageFactory.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
783
src/App/Service/CiExecutorService.php
Normal file
783
src/App/Service/CiExecutorService.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/App/Service/CiExecutorServiceFactory.php
Normal file
19
src/App/Service/CiExecutorServiceFactory.php
Normal 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
155
src/App/Service/CiNodeService.php
Normal file
155
src/App/Service/CiNodeService.php
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user