2022-09-27 12:29:56 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace NoccyLabs\Serverctl\Container;
|
|
|
|
|
|
|
|
class ContainerManager
|
|
|
|
{
|
|
|
|
|
|
|
|
private string $dataPath;
|
|
|
|
|
|
|
|
public function __construct(?string $dataPath=null)
|
|
|
|
{
|
|
|
|
$this->dataPath = $dataPath ?? (getenv("HOME")."/.var/serverctl");
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Start a service
|
|
|
|
*
|
|
|
|
* Instance options:
|
|
|
|
* name: Instance name (default)
|
|
|
|
* portoffset: Port number offset (0)
|
|
|
|
*
|
|
|
|
* @param array $service The service definition from the registry
|
|
|
|
* @param array $options Instance options
|
|
|
|
*/
|
|
|
|
public function startService(array $service, array $options)
|
|
|
|
{
|
|
|
|
$args = [];
|
|
|
|
|
|
|
|
$serviceName = $service['name'];
|
|
|
|
$instanceName = $options['name']??'default';
|
2022-09-27 12:47:30 +02:00
|
|
|
$portOffset = intval($options['portoffset']??0);
|
2022-09-27 12:29:56 +02:00
|
|
|
|
|
|
|
$containerName = "sm_".$serviceName."_".$instanceName;
|
|
|
|
|
|
|
|
$args[] = 'run';
|
|
|
|
$args[] = '--rm'; // remove container after run
|
|
|
|
$args[] = '-d';
|
|
|
|
$args[] = '--name';
|
|
|
|
$args[] = $containerName;
|
|
|
|
|
|
|
|
// Map the ports
|
|
|
|
$ports = (array)($service['ports']??[]);
|
2022-09-27 12:47:30 +02:00
|
|
|
$mappedPorts = [];
|
2022-09-27 12:29:56 +02:00
|
|
|
foreach ($ports as $port) {
|
2022-09-27 12:47:30 +02:00
|
|
|
$portNumber = intval($port['port']) + $portOffset;
|
2022-09-27 12:29:56 +02:00
|
|
|
$args[] = '-p';
|
2022-09-27 12:47:30 +02:00
|
|
|
$args[] = $portNumber;
|
|
|
|
$mappedPorts[$port['info']] = $portNumber;
|
2022-09-27 12:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// Get the paths to persist
|
|
|
|
$volumes = (array)($service['persistence']??[]);
|
|
|
|
$volumePath = $this->getServiceDataPath($service)."/".$instanceName;
|
|
|
|
foreach ($volumes as $volume) {
|
|
|
|
// volume { path, hint }
|
|
|
|
$path = $volume['path'];
|
|
|
|
$hint = $volume['hint'] ?? crc32($path);
|
|
|
|
$args[] = '-v'; // add volume
|
|
|
|
$args[] = $volumePath."/".$hint.":".$path;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Get environment
|
|
|
|
$envs = (array)($service['environment']??[]);
|
|
|
|
foreach ($envs as $env=>$value) {
|
|
|
|
$args[] = '-e';
|
|
|
|
// TODO: use environment if set (override)
|
|
|
|
$args[] = sprintf("%s=%s", $env, $value);
|
|
|
|
}
|
|
|
|
|
|
|
|
$args[] = $service['image'];
|
|
|
|
|
|
|
|
$cmdl = 'docker '.join(' ',array_map('escapeshellarg', $args));
|
|
|
|
|
|
|
|
// TODO: Write command line, env and meta to state file
|
|
|
|
|
|
|
|
echo "$ {$cmdl}\n";
|
|
|
|
passthru($cmdl);
|
|
|
|
|
2022-09-27 12:47:30 +02:00
|
|
|
return [
|
|
|
|
'ports' => $mappedPorts
|
|
|
|
];
|
|
|
|
|
2022-09-27 12:29:56 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Stop a service
|
|
|
|
*/
|
|
|
|
public function stopService(array $service, string $instanceName)
|
|
|
|
{
|
|
|
|
$args = [];
|
|
|
|
|
|
|
|
$serviceName = $service['name'];
|
|
|
|
$containerName = "sm_".$serviceName."_".$instanceName;
|
|
|
|
|
|
|
|
$args[] = 'stop';
|
|
|
|
$args[] = $containerName;
|
|
|
|
|
|
|
|
$cmdl = 'docker '.join(' ',array_map('escapeshellarg', $args));
|
|
|
|
|
|
|
|
echo "$ {$cmdl}\n";
|
|
|
|
passthru($cmdl);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public function execute(array $service, string $instanceName, array $command)
|
|
|
|
{
|
|
|
|
$args = [];
|
|
|
|
|
|
|
|
$serviceName = $service['name'];
|
|
|
|
$instanceName = $options['name']??'default';
|
|
|
|
$containerName = "sm_".$serviceName."_".$instanceName;
|
|
|
|
|
|
|
|
$args[] = 'exec';
|
|
|
|
$args[] = '-it';
|
|
|
|
$args[] = $containerName;
|
|
|
|
|
|
|
|
array_push($args, ...$command);
|
|
|
|
|
|
|
|
$cmdl = 'docker '.join(' ',array_map('escapeshellarg', $args));
|
|
|
|
|
|
|
|
echo "$ {$cmdl}\n";
|
|
|
|
passthru($cmdl);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get running services
|
|
|
|
*/
|
|
|
|
public function getRunningServices(): array
|
|
|
|
{
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getServiceDataPath(array $service)
|
|
|
|
{
|
|
|
|
return $this->dataPath."/".$service['name'];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|