serverctl/src/Container/ContainerManager.php

132 lines
3.3 KiB
PHP

<?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';
$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']??[]);
foreach ($ports as $port) {
$args[] = '-p';
$args[] = $port['port'];
}
// 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);
}
/**
* Stop a service
*/
public function stopService(array $service, string $instanceName)
{
$args = [];
$serviceName = $service['name'];
$instanceName = $options['name']??'default';
$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'];
}
}