Initial commit
This commit is contained in:
		
							
								
								
									
										132
									
								
								src/Container/ContainerManager.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										132
									
								
								src/Container/ContainerManager.php
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,132 @@
 | 
			
		||||
<?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'];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user