1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace TheAentMachine\AentDockerCompose\Command; |
4
|
|
|
|
5
|
|
|
use TheAentMachine\AentDockerCompose\DockerCompose\DockerComposeService; |
6
|
|
|
use TheAentMachine\AentDockerCompose\DockerCompose\EnvFile; |
7
|
|
|
use TheAentMachine\Aenthill\Aenthill; |
8
|
|
|
use TheAentMachine\Aenthill\CommonDependencies; |
9
|
|
|
use TheAentMachine\Aenthill\CommonEvents; |
10
|
|
|
use TheAentMachine\Aenthill\CommonMetadata; |
11
|
|
|
use TheAentMachine\Aenthill\Manifest; |
12
|
|
|
use TheAentMachine\Aenthill\Pheromone; |
13
|
|
|
use TheAentMachine\Command\AbstractJsonEventCommand; |
14
|
|
|
use TheAentMachine\Exception\CommonAentsException; |
15
|
|
|
use TheAentMachine\Exception\ManifestException; |
16
|
|
|
use TheAentMachine\Exception\MissingEnvironmentVariableException; |
17
|
|
|
use TheAentMachine\Service\Exception\ServiceException; |
18
|
|
|
use TheAentMachine\Service\Service; |
19
|
|
|
|
20
|
|
|
class NewServiceEventCommand extends AbstractJsonEventCommand |
21
|
|
|
{ |
22
|
|
|
protected function getEventName(): string |
23
|
|
|
{ |
24
|
|
|
return CommonEvents::NEW_SERVICE_EVENT; |
25
|
|
|
} |
26
|
|
|
|
27
|
|
|
/** |
28
|
|
|
* @param array $payload |
29
|
|
|
* @return array|null |
30
|
|
|
* @throws ManifestException |
31
|
|
|
* @throws MissingEnvironmentVariableException |
32
|
|
|
* @throws ServiceException |
33
|
|
|
* @throws CommonAentsException |
34
|
|
|
*/ |
35
|
|
|
protected function executeJsonEvent(array $payload): ?array |
36
|
|
|
{ |
37
|
|
|
$service = Service::parsePayload($payload); |
38
|
|
|
if (!$service->isForMyEnvType()) { |
39
|
|
|
return null; |
40
|
|
|
} |
41
|
|
|
|
42
|
|
|
$fileName = Manifest::mustGetMetadata(CommonMetadata::DOCKER_COMPOSE_FILENAME_KEY); |
43
|
|
|
$dockerComposePath = Pheromone::getContainerProjectDirectory() . '/' . $fileName; |
44
|
|
|
|
45
|
|
|
$this->getAentHelper()->title($fileName); |
46
|
|
|
|
47
|
|
|
// Virtual Host |
48
|
|
|
if ($service->getNeedVirtualHost()) { |
49
|
|
|
if (null === Manifest::getDependency(CommonDependencies::REVERSE_PROXY_KEY)) { |
50
|
|
|
$this->getAentHelper()->getCommonQuestions()->askForReverseProxy(); |
51
|
|
|
$this->runAddReverseProxy($dockerComposePath); |
52
|
|
|
} |
53
|
|
|
$service = $this->newVirtualHost($service); |
54
|
|
|
} |
55
|
|
|
|
56
|
|
|
if ($service->getNeedBuild()) { |
57
|
|
|
$service = $this->newImageToBuild($service); |
58
|
|
|
} |
59
|
|
|
|
60
|
|
|
$serviceName = $service->getServiceName(); |
61
|
|
|
|
62
|
|
|
// .env-xxx file |
63
|
|
|
$envMapDotEnvFile = DockerComposeService::getEnvironmentVariablesForDotEnv($service); |
64
|
|
|
$envFilePath = null; |
65
|
|
|
if ($envMapDotEnvFile) { |
|
|
|
|
66
|
|
|
// TODO: name of file is certainly impacted by name of docker-compose file. |
67
|
|
|
$envFilePath = '.env-' .$service->getServiceName(); |
68
|
|
|
$dotEnvFile = new EnvFile(Pheromone::getContainerProjectDirectory() . '/' . $envFilePath); |
69
|
|
|
foreach ($envMapDotEnvFile as $key => $env) { |
70
|
|
|
$dotEnvFile->set($key, $env->getValue(), $env->getComment()); |
71
|
|
|
} |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
|
75
|
|
|
// docker-compose |
76
|
|
|
$formattedPayload = DockerComposeService::dockerComposeServiceSerialize($service, $envFilePath); |
77
|
|
|
$this->log->debug(\GuzzleHttp\json_encode($formattedPayload, JSON_PRETTY_PRINT)); |
78
|
|
|
|
79
|
|
|
$dockerComposePath = Pheromone::getContainerProjectDirectory() . '/' . $fileName; |
80
|
|
|
DockerComposeService::mergeContentInDockerComposeFile($formattedPayload, $dockerComposePath, true); |
81
|
|
|
|
82
|
|
|
$this->output->writeln("Service <info>$serviceName</info> has been successfully added in <info>$fileName</info>!"); |
83
|
|
|
|
84
|
|
|
return null; |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @param string $dockerComposePath |
89
|
|
|
* @throws ManifestException |
90
|
|
|
* @throws ServiceException |
91
|
|
|
*/ |
92
|
|
|
private function runAddReverseProxy(string $dockerComposePath): void |
93
|
|
|
{ |
94
|
|
|
$reverseProxyKey = Manifest::mustGetDependency(CommonDependencies::REVERSE_PROXY_KEY); |
95
|
|
|
$repliedPayloads = Aenthill::runJson($reverseProxyKey, CommonEvents::ADD_EVENT, []); |
96
|
|
|
$payload = \GuzzleHttp\json_decode($repliedPayloads[0], true); |
97
|
|
|
$service = Service::parsePayload($payload); |
98
|
|
|
$formattedPayload = DockerComposeService::dockerComposeServiceSerialize($service); |
99
|
|
|
DockerComposeService::mergeContentInDockerComposeFile($formattedPayload, $dockerComposePath, true); |
100
|
|
|
|
101
|
|
|
$serviceName = $service->getServiceName(); |
102
|
|
|
$fileName = Manifest::mustGetMetadata(CommonMetadata::DOCKER_COMPOSE_FILENAME_KEY); |
103
|
|
|
$this->output->writeln("Reverse proxy <info>$serviceName</info> has been successfully added in <info>$fileName</info>!"); |
104
|
|
|
} |
105
|
|
|
|
106
|
|
|
|
107
|
|
|
/** |
108
|
|
|
* @param Service $service |
109
|
|
|
* @return Service |
110
|
|
|
* @throws ManifestException |
111
|
|
|
* @throws ServiceException |
112
|
|
|
*/ |
113
|
|
|
private function newVirtualHost(Service $service): Service |
114
|
|
|
{ |
115
|
|
|
$reverseProxyKey = Manifest::mustGetDependency(CommonDependencies::REVERSE_PROXY_KEY); |
116
|
|
|
$repliedPayloads = Aenthill::runJson($reverseProxyKey, CommonEvents::NEW_VIRTUAL_HOST_EVENT, $service->jsonSerialize()); |
117
|
|
|
$payload = \GuzzleHttp\json_decode($repliedPayloads[0], true); |
118
|
|
|
$service = Service::parsePayload($payload); |
119
|
|
|
|
120
|
|
|
$serviceName = $service->getServiceName(); |
121
|
|
|
$this->output->writeln("A new virtual host has been successfully added for <info>$serviceName</info>!"); |
122
|
|
|
$this->getAentHelper()->spacer(); |
123
|
|
|
|
124
|
|
|
return $service; |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* @param Service $service |
129
|
|
|
* @return Service |
130
|
|
|
*/ |
131
|
|
|
private function newImageToBuild(Service $service): Service |
132
|
|
|
{ |
133
|
|
|
$imageBuilderAentID = Manifest::getDependency(CommonDependencies::IMAGE_BUILDER_KEY); |
134
|
|
|
if (null === $imageBuilderAentID) { |
135
|
|
|
return $service; |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
$repliedPayloads = Aenthill::runJson($imageBuilderAentID, CommonEvents::NEW_IMAGE_EVENT, $service->imageJsonSerialize()); |
139
|
|
|
$payload = \GuzzleHttp\json_decode($repliedPayloads[0], true); |
140
|
|
|
$dockerfileName = $payload['dockerfileName']; |
141
|
|
|
$this->getAentHelper()->spacer(); |
142
|
|
|
|
143
|
|
|
$CIAentID = Manifest::getDependency(CommonDependencies::CI_KEY); |
144
|
|
|
if (null === $CIAentID) { |
145
|
|
|
return $service; |
146
|
|
|
} |
147
|
|
|
|
148
|
|
|
$serviceName = $service->getServiceName(); |
149
|
|
|
|
150
|
|
|
$repliedPayloads = Aenthill::runJson($CIAentID, CommonEvents::NEW_BUILD_IMAGE_JOB_EVENT, [ |
151
|
|
|
'serviceName' => $serviceName, |
152
|
|
|
'dockerfileName' => $dockerfileName, |
153
|
|
|
]); |
154
|
|
|
$payload = \GuzzleHttp\json_decode($repliedPayloads[0], true); |
155
|
|
|
|
156
|
|
|
$dockerImageName = $payload['dockerImageName']; |
157
|
|
|
$service->setImage($dockerImageName); |
158
|
|
|
$service->removeAllBindVolumes(); |
159
|
|
|
|
160
|
|
|
$this->getAentHelper()->spacer(); |
161
|
|
|
$this->output->writeln("Service <info>$serviceName</info> is now using image <info>$dockerImageName</info>!"); |
162
|
|
|
$this->getAentHelper()->spacer(); |
163
|
|
|
|
164
|
|
|
return $service; |
165
|
|
|
} |
166
|
|
|
} |
167
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.