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']; } }