/** * @return string * @throws ContainerException */ public function start() { try { $containerConfig = new \Docker\API\Model\ContainerConfig(); $containerConfig->setImage($this->image); $hostConfig = new \Docker\API\Model\HostConfig(); $mapPorts = new \ArrayObject(); $exposedPorts = new \ArrayObject(); foreach ($this->ports as $from => $to) { $exposedPorts[$from] = new \stdClass(); $hostPortBinding = new \Docker\API\Model\PortBinding(); list($host, $port) = explode(':', $to); $hostPortBinding->setHostIp($host); if (!empty($port)) { $hostPortBinding->setHostPort($port); } $mapPorts[$from] = [$hostPortBinding]; } $containerConfig->setExposedPorts($exposedPorts); $hostConfig->setPortBindings($mapPorts); $hostConfig->setLinks($this->links); $hostConfig->setBinds($this->volumes); $containerConfig->setHostConfig($hostConfig); $envs = []; foreach ($this->envs as $k => $v) { $envs[] = $k . "=" . $v; } $containerConfig->setEnv($envs); $containerCreateResult = $this->containerManager->create($containerConfig); $this->containerId = $containerCreateResult->getId(); $this->containerManager->start($this->containerId); return $this->containerId; } catch (ClientErrorException $e) { throw new ContainerException($e->getResponse()->getBody()->getContents(), $e->getCode(), $e); } catch (ServerErrorException $e) { throw new ContainerException($e->getResponse()->getBody()->getContents(), $e->getCode(), $e); } catch (\Exception $e) { throw new ContainerException($e->getMessage(), $e->getCode(), $e); } }
public function denormalize($data, $class, $format = null, array $context = []) { if (empty($data)) { return null; } if (isset($data->{'$ref'})) { return new Reference($data->{'$ref'}, $context['rootSchema'] ?: null); } $object = new \Docker\API\Model\ContainerConfig(); if (!isset($context['rootSchema'])) { $context['rootSchema'] = $object; } if (property_exists($data, 'Id')) { $object->setId($data->{'Id'}); } if (property_exists($data, 'Names')) { $value = $data->{'Names'}; if (is_array($data->{'Names'})) { $values = []; foreach ($data->{'Names'} as $value_1) { $values[] = $value_1; } $value = $values; } if (is_null($data->{'Names'})) { $value = $data->{'Names'}; } $object->setNames($value); } if (property_exists($data, 'Image')) { $object->setImage($data->{'Image'}); } if (property_exists($data, 'ImageID')) { $object->setImageID($data->{'ImageID'}); } if (property_exists($data, 'Command')) { $object->setCommand($data->{'Command'}); } if (property_exists($data, 'Created')) { $object->setCreated($data->{'Created'}); } if (property_exists($data, 'Status')) { $object->setStatus($data->{'Status'}); } if (property_exists($data, 'Ports')) { $value_2 = $data->{'Ports'}; if (is_array($data->{'Ports'})) { $values_1 = []; foreach ($data->{'Ports'} as $value_3) { $values_1[] = $this->serializer->deserialize($value_3, 'Docker\\API\\Model\\Port', 'raw', $context); } $value_2 = $values_1; } if (is_null($data->{'Ports'})) { $value_2 = $data->{'Ports'}; } $object->setPorts($value_2); } if (property_exists($data, 'Labels')) { $value_4 = $data->{'Labels'}; if (is_object($data->{'Labels'})) { $values_2 = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); foreach ($data->{'Labels'} as $key => $value_5) { $values_2[$key] = $value_5; } $value_4 = $values_2; } if (is_null($data->{'Labels'})) { $value_4 = $data->{'Labels'}; } $object->setLabels($value_4); } if (property_exists($data, 'SizeRw')) { $object->setSizeRw($data->{'SizeRw'}); } if (property_exists($data, 'SizeRootFs')) { $object->setSizeRootFs($data->{'SizeRootFs'}); } if (property_exists($data, 'Hostname')) { $object->setHostname($data->{'Hostname'}); } if (property_exists($data, 'Domainname')) { $object->setDomainname($data->{'Domainname'}); } if (property_exists($data, 'User')) { $object->setUser($data->{'User'}); } if (property_exists($data, 'AttachStdin')) { $object->setAttachStdin($data->{'AttachStdin'}); } if (property_exists($data, 'AttachStdout')) { $object->setAttachStdout($data->{'AttachStdout'}); } if (property_exists($data, 'AttachStderr')) { $object->setAttachStderr($data->{'AttachStderr'}); } if (property_exists($data, 'Tty')) { $object->setTty($data->{'Tty'}); } if (property_exists($data, 'OpenStdin')) { $object->setOpenStdin($data->{'OpenStdin'}); } if (property_exists($data, 'StdinOnce')) { $object->setStdinOnce($data->{'StdinOnce'}); } if (property_exists($data, 'Env')) { $value_6 = $data->{'Env'}; if (is_array($data->{'Env'})) { $values_3 = []; foreach ($data->{'Env'} as $value_7) { $values_3[] = $value_7; } $value_6 = $values_3; } if (is_null($data->{'Env'})) { $value_6 = $data->{'Env'}; } $object->setEnv($value_6); } if (property_exists($data, 'Cmd')) { $value_8 = $data->{'Cmd'}; if (is_array($data->{'Cmd'})) { $values_4 = []; foreach ($data->{'Cmd'} as $value_9) { $values_4[] = $value_9; } $value_8 = $values_4; } if (is_string($data->{'Cmd'})) { $value_8 = $data->{'Cmd'}; } $object->setCmd($value_8); } if (property_exists($data, 'Entrypoint')) { $value_10 = $data->{'Entrypoint'}; if (is_array($data->{'Entrypoint'})) { $values_5 = []; foreach ($data->{'Entrypoint'} as $value_11) { $values_5[] = $value_11; } $value_10 = $values_5; } if (is_string($data->{'Entrypoint'})) { $value_10 = $data->{'Entrypoint'}; } $object->setEntrypoint($value_10); } if (property_exists($data, 'Mounts')) { $value_12 = $data->{'Mounts'}; if (is_array($data->{'Mounts'})) { $values_6 = []; foreach ($data->{'Mounts'} as $value_13) { $values_6[] = $this->serializer->deserialize($value_13, 'Docker\\API\\Model\\Mount', 'raw', $context); } $value_12 = $values_6; } if (is_null($data->{'Mounts'})) { $value_12 = $data->{'Mounts'}; } $object->setMounts($value_12); } if (property_exists($data, 'WorkingDir')) { $object->setWorkingDir($data->{'WorkingDir'}); } if (property_exists($data, 'NetworkDisabled')) { $object->setNetworkDisabled($data->{'NetworkDisabled'}); } if (property_exists($data, 'MacAddress')) { $object->setMacAddress($data->{'MacAddress'}); } if (property_exists($data, 'ExposedPorts')) { $value_14 = $data->{'ExposedPorts'}; if (is_object($data->{'ExposedPorts'})) { $values_7 = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); foreach ($data->{'ExposedPorts'} as $key_1 => $value_15) { $values_7[$key_1] = $value_15; } $value_14 = $values_7; } if (is_null($data->{'ExposedPorts'})) { $value_14 = $data->{'ExposedPorts'}; } $object->setExposedPorts($value_14); } if (property_exists($data, 'NetworkSettings')) { $object->setNetworkSettings($this->serializer->deserialize($data->{'NetworkSettings'}, 'Docker\\API\\Model\\NetworkConfig', 'raw', $context)); } if (property_exists($data, 'HostConfig')) { $object->setHostConfig($this->serializer->deserialize($data->{'HostConfig'}, 'Docker\\API\\Model\\HostConfig', 'raw', $context)); } return $object; }
/** * Uses Docker to deploy the given project to a live server * @param \GitDeployer\Objects\Project $project The project to deploy * @param string $gitpath The path to the checked-out project * @param array $config The configuration options to pass to this deployer * @return mixed */ public function deploy(\GitDeployer\Objects\Project $project, $gitpath, $config) { $useTunnel = false; // -> Connect to the docker daemon on a tcp or unix socket if (!isset($config['host']) || strlen($config['host']) < 1) { $config['host'] = getenv('DOCKER_HOST'); } if (strlen($config['host']) < 1) { throw new \Exception('Neither the "host" parameter was specified in the .deployer file nor is the DOCKER_HOST environment variable set!'); } if (stristr($config['host'], 'tcp://')) { // Setting the docker host to tcp:// may enable usage of the SSH tunnel functionality if (isset($config['ssh']) && is_array($config['ssh'])) { if (isset($config['ssh']['tunnel']) && $config['ssh']['tunnel'] == true) { $useProc = false; $useTunnel = true; parent::showMessage('DOCKER', 'Connecting to Docker daemon via SSH...', $this->output); // Check if the ssh binary is executable, else bail out // since we can't open a tunnel without it if (!$this->commandExists('ssh')) { throw new \Exception('SSH client not found: Please make sure the "ssh" command is available, and in your $PATH!'); } else { if (!isset($config['ssh']['host']) || strlen($config['ssh']['host']) < 1) { throw new \Exception('Please specify at least a SSH host in your .deployerfile to connect to!'); } if (!isset($config['ssh']['user']) || strlen($config['ssh']['user']) < 1) { $config['ssh']['user'] = "******"; } $config['ssh']['port'] = isset($config['ssh']['port']) && strlen($config['ssh']['port']) > 0 ? $config['ssh']['port'] : 22; if (!isset($config['ssh']['privatekey']) || strlen($config['ssh']['privatekey']) < 1) { throw new \Exception('Please correctly specify your SSH private key in the .deployerfile!'); } // -> Open tunnel via SSH command $randport = rand(60000, 65000); $remotedesc = str_replace('tcp://', '', $config['host']); $cmdstring = 'ssh -N -i ' . escapeshellarg($config['ssh']['privatekey']) . ' -L ' . $randport . ':' . $remotedesc . ' -p ' . $config['ssh']['port'] . ' ' . $config['ssh']['user'] . '@' . $config['ssh']['host']; if (isset($config['ssh']['password']) && strlen($config['ssh']['password']) > 1) { if (!extension_loaded('expect')) { throw new \Exception('Expect extension not found: Please make sure the PHP expect extension is available in your PHP installation!'); } $stream = fopen('expect://' . $cmdstring, 'r'); $cases = array(array('Enter passphrase', PASSWORD)); ini_set("expect.timeout", 30); switch (expect_expectl($stream, $cases)) { case PASSWORD: fwrite($stream, $config['ssh']['password'] . "\n"); // Wait for tunnel port to be available while (true) { $socket = @fsockopen('127.0.0.1', $randport, $errno, $errstr, 5); if ($socket) { fclose($socket); break; } } break; default: throw new \Exception('Unable to connect to the remote SSH host! Invalid string received: Expected passphrase prompt.'); } } else { $stream = proc_open('exec ' . $cmdstring, array(), $pipes); $useProc = true; // Wait for tunnel port to be available while (true) { $socket = @fsockopen('127.0.0.1', $randport, $errno, $errstr, 5); if ($socket) { fclose($socket); break; } } } } } } } $client = new \Docker\DockerClient(array('remote_socket' => 'tcp://127.0.0.1:' . $randport, 'ssl' => isset($config['ssl']) && $config['ssl'] == true ? true : false)); $docker = new \Docker\Docker($client); // -> Build the docker image if a Dockerfile is present if (!file_exists($gitpath . '/Dockerfile')) { throw new \Exception('No Dockerfile found - aborting build!'); } parent::showMessage('DOCKER', 'Building image (no-cache)...', $this->output); parent::showMessage('DOCKER', 'Uploading context...', $this->output); $context = new \Docker\Context\Context($gitpath); $imageManager = $docker->getImageManager(); $buildStream = $imageManager->build($context->toStream(), array('t' => 'git-deployer/' . $project->name()), \Docker\Manager\ContainerManager::FETCH_STREAM); $buildStream->onFrame(function (\Docker\API\Model\BuildInfo $buildInfo) { parent::showMessage('BUILD', $buildInfo->getStream(), $this->output); }); $buildStream->wait(); // -> Stop and remove the old container with the same name, sicne we're going // to replace the app here with the newly built container parent::showMessage('DOCKER', 'Getting running containers...', $this->output); $containersOnHost = $docker->getContainerManager()->findAll(); if (count($containersOnHost) > 0) { // We check for a container with the same name as the one we are going to deploy foreach ($containersOnHost as $key => $container) { $containerFound = false; // Search by name foreach ($container->getNames() as $name) { $cleanName = $this->cleanName($project->name()); preg_match('#\\/.*\\/(.*)#', $name, $matches); if ($cleanName == $matches[1]) { $containerFound = true; } } // Search by image if ($container->getImage() == 'git-deployer/' . $project->name()) { $containerFound = true; } if ($containerFound) { parent::showMessage('DOCKER', 'Stopping old container ' . $container->getId() . '...', $this->output); $docker->getContainerManager()->stop($container->getId()); $docker->getContainerManager()->remove($container->getId()); } } } // -> Start the container up if we have built sucessfully parent::showMessage('DOCKER', 'Starting new container...', $this->output); $hostConfig = new \Docker\API\Model\HostConfig(); $containerConfig = new \Docker\API\Model\ContainerConfig(); $containerConfig->setNames(array('git-deployer/' . $this->cleanName($project->name()))); $containerConfig->setImage('git-deployer/' . $project->name()); // Add environment from the config file, if any $envArray = array(); if (isset($config['environment'])) { foreach ($config['environment'] as $key => $value) { $envArray[] = $key . '=' . $value; } } $containerConfig->setEnv($envArray); // Add exposed ports from the config file, if any if (isset($config['ports']) && is_array($config['ports']) && count($config['ports']) > 0) { $exposedPorts = new \ArrayObject(); $mapPorts = new \ArrayObject(); foreach ($config['ports'] as $portdesc) { $portspec = $this->parsePortSpecification($portdesc); // Exposed port $exposedPort = $portspec['port'] . (strlen($portspec['protocol']) > 0 ? '/' . $portspec['protocol'] : '/tcp'); $exposedPorts[$exposedPort] = new \stdClass(); // Host port binding $hostPortBinding = new \Docker\API\Model\PortBinding(); $mapPorts[$exposedPort] = array($hostPortBinding); } $containerConfig->setExposedPorts($exposedPorts); $hostConfig->setPortBindings($mapPorts); } // Add restart policy if (isset($config['restart']) && strlen($config['restart']) > 0) { $policy = $this->parseRestartPolicy($config['restart']); $restartPolicy = new \Docker\API\Model\RestartPolicy(); $restartPolicy->setName($policy['Name']); if (isset($policy['MaximumRetryCount'])) { $restartPolicy->setMaximumRetryCount($policy['MaximumRetryCount']); } $hostConfig->setRestartPolicy($restartPolicy); } // Add binds if (isset($config['volumes']) && is_array($config['volumes']) && count($config['volumes']) > 0) { $binds = new \ArrayObject(); foreach ($config['volumes'] as $volume) { $binds[] = $volume; } $hostConfig->setBinds($binds); } $containerConfig->setHostConfig($hostConfig); $containerCreateResult = $docker->getContainerManager()->create($containerConfig, array('name' => $this->cleanName($project->name()))); if ($containerCreateResult->getId()) { $docker->getContainerManager()->start($containerCreateResult->getId()); } // -> Clean up and close the SSH tunnel if ($useTunnel) { if ($useProc) { proc_terminate($stream, 9); proc_close($stream); } else { fclose($stream); } } return array(true, 'No trace'); }
public function denormalize($data, $class, $format = null, array $context = []) { if (empty($data)) { return null; } if (isset($data->{'$ref'})) { return new Reference($data->{'$ref'}, $context['rootSchema'] ?: null); } $object = new \Docker\API\Model\ContainerConfig(); if (!isset($context['rootSchema'])) { $context['rootSchema'] = $object; } if (isset($data->{'Id'})) { $object->setId($data->{'Id'}); } if (isset($data->{'Names'})) { $values_59 = []; foreach ($data->{'Names'} as $value_60) { $values_59[] = $value_60; } $object->setNames($values_59); } if (isset($data->{'Image'})) { $object->setImage($data->{'Image'}); } if (isset($data->{'Command'})) { $object->setCommand($data->{'Command'}); } if (isset($data->{'Created'})) { $object->setCreated($data->{'Created'}); } if (isset($data->{'Status'})) { $object->setStatus($data->{'Status'}); } if (isset($data->{'Ports'})) { $values_61 = []; foreach ($data->{'Ports'} as $value_62) { $values_61[] = $this->serializer->deserialize($value_62, 'Docker\\API\\Model\\Port', 'raw', $context); } $object->setPorts($values_61); } if (isset($data->{'Labels'})) { $values_63 = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); foreach ($data->{'Labels'} as $key_65 => $value_64) { $values_63[$key_65] = $value_64; } $object->setLabels($values_63); } if (isset($data->{'SizeRw'})) { $object->setSizeRw($data->{'SizeRw'}); } if (isset($data->{'SizeRootFs'})) { $object->setSizeRootFs($data->{'SizeRootFs'}); } if (isset($data->{'Hostname'})) { $object->setHostname($data->{'Hostname'}); } if (isset($data->{'Domainname'})) { $object->setDomainname($data->{'Domainname'}); } if (isset($data->{'User'})) { $object->setUser($data->{'User'}); } if (isset($data->{'AttachStdin'})) { $object->setAttachStdin($data->{'AttachStdin'}); } if (isset($data->{'AttachStdout'})) { $object->setAttachStdout($data->{'AttachStdout'}); } if (isset($data->{'AttachStderr'})) { $object->setAttachStderr($data->{'AttachStderr'}); } if (isset($data->{'Tty'})) { $object->setTty($data->{'Tty'}); } if (isset($data->{'OpenStdin'})) { $object->setOpenStdin($data->{'OpenStdin'}); } if (isset($data->{'StdinOnce'})) { $object->setStdinOnce($data->{'StdinOnce'}); } if (isset($data->{'Env'})) { $values_66 = []; foreach ($data->{'Env'} as $value_67) { $values_66[] = $value_67; } $object->setEnv($values_66); } if (isset($data->{'Cmd'})) { $value_68 = $data->{'Cmd'}; if (is_array($data->{'Cmd'})) { $values_69 = []; foreach ($data->{'Cmd'} as $value_70) { $values_69[] = $value_70; } $value_68 = $values_69; } if (is_string($data->{'Cmd'})) { $value_68 = $data->{'Cmd'}; } $object->setCmd($value_68); } if (isset($data->{'Entrypoint'})) { $value_71 = $data->{'Entrypoint'}; if (is_array($data->{'Entrypoint'})) { $values_72 = []; foreach ($data->{'Entrypoint'} as $value_73) { $values_72[] = $value_73; } $value_71 = $values_72; } if (is_string($data->{'Entrypoint'})) { $value_71 = $data->{'Entrypoint'}; } $object->setEntrypoint($value_71); } if (isset($data->{'Mounts'})) { $values_74 = []; foreach ($data->{'Mounts'} as $value_75) { $values_74[] = $this->serializer->deserialize($value_75, 'Docker\\API\\Model\\Mount', 'raw', $context); } $object->setMounts($values_74); } if (isset($data->{'WorkingDir'})) { $object->setWorkingDir($data->{'WorkingDir'}); } if (isset($data->{'NetworkDisabled'})) { $object->setNetworkDisabled($data->{'NetworkDisabled'}); } if (isset($data->{'MacAddress'})) { $object->setMacAddress($data->{'MacAddress'}); } if (isset($data->{'ExposedPorts'})) { $values_76 = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); foreach ($data->{'ExposedPorts'} as $key_78 => $value_77) { $values_76[$key_78] = $value_77; } $object->setExposedPorts($values_76); } if (isset($data->{'HostConfig'})) { $object->setHostConfig($this->serializer->deserialize($data->{'HostConfig'}, 'Docker\\API\\Model\\HostConfig', 'raw', $context)); } return $object; }
public function denormalize($data, $class, $format = null, array $context = []) { if (empty($data)) { return null; } if (isset($data->{'$ref'})) { return new Reference($data->{'$ref'}, $context['rootSchema'] ?: null); } $object = new \Docker\API\Model\ContainerConfig(); if (!isset($context['rootSchema'])) { $context['rootSchema'] = $object; } if (isset($data->{'Id'})) { $object->setId($data->{'Id'}); } if (isset($data->{'Names'})) { $values_81 = []; foreach ($data->{'Names'} as $value_82) { $values_81[] = $value_82; } $object->setNames($values_81); } if (isset($data->{'Image'})) { $object->setImage($data->{'Image'}); } if (isset($data->{'Command'})) { $object->setCommand($data->{'Command'}); } if (isset($data->{'Created'})) { $object->setCreated($data->{'Created'}); } if (isset($data->{'Status'})) { $object->setStatus($data->{'Status'}); } if (isset($data->{'Ports'})) { $values_83 = []; foreach ($data->{'Ports'} as $value_84) { $values_83[] = $this->serializer->deserialize($value_84, 'Docker\\API\\Model\\Port', 'raw', $context); } $object->setPorts($values_83); } if (isset($data->{'Labels'})) { $values_85 = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); foreach ($data->{'Labels'} as $key_87 => $value_86) { $values_85[$key_87] = $value_86; } $object->setLabels($values_85); } if (isset($data->{'SizeRw'})) { $object->setSizeRw($data->{'SizeRw'}); } if (isset($data->{'SizeRootFs'})) { $object->setSizeRootFs($data->{'SizeRootFs'}); } if (isset($data->{'Hostname'})) { $object->setHostname($data->{'Hostname'}); } if (isset($data->{'Domainname'})) { $object->setDomainname($data->{'Domainname'}); } if (isset($data->{'User'})) { $object->setUser($data->{'User'}); } if (isset($data->{'AttachStdin'})) { $object->setAttachStdin($data->{'AttachStdin'}); } if (isset($data->{'AttachStdout'})) { $object->setAttachStdout($data->{'AttachStdout'}); } if (isset($data->{'AttachStderr'})) { $object->setAttachStderr($data->{'AttachStderr'}); } if (isset($data->{'Tty'})) { $object->setTty($data->{'Tty'}); } if (isset($data->{'OpenStdin'})) { $object->setOpenStdin($data->{'OpenStdin'}); } if (isset($data->{'StdinOnce'})) { $object->setStdinOnce($data->{'StdinOnce'}); } if (isset($data->{'Env'})) { $values_88 = []; foreach ($data->{'Env'} as $value_89) { $values_88[] = $value_89; } $object->setEnv($values_88); } if (isset($data->{'Cmd'})) { $value_90 = $data->{'Cmd'}; if (is_array($data->{'Cmd'})) { $values_91 = []; foreach ($data->{'Cmd'} as $value_92) { $values_91[] = $value_92; } $value_90 = $values_91; } if (is_string($data->{'Cmd'})) { $value_90 = $data->{'Cmd'}; } $object->setCmd($value_90); } if (isset($data->{'Entrypoint'})) { $value_93 = $data->{'Entrypoint'}; if (is_array($data->{'Entrypoint'})) { $values_94 = []; foreach ($data->{'Entrypoint'} as $value_95) { $values_94[] = $value_95; } $value_93 = $values_94; } if (is_string($data->{'Entrypoint'})) { $value_93 = $data->{'Entrypoint'}; } $object->setEntrypoint($value_93); } if (isset($data->{'Mounts'})) { $values_96 = []; foreach ($data->{'Mounts'} as $value_97) { $values_96[] = $this->serializer->deserialize($value_97, 'Docker\\API\\Model\\Mount', 'raw', $context); } $object->setMounts($values_96); } if (isset($data->{'WorkingDir'})) { $object->setWorkingDir($data->{'WorkingDir'}); } if (isset($data->{'NetworkDisabled'})) { $object->setNetworkDisabled($data->{'NetworkDisabled'}); } if (isset($data->{'MacAddress'})) { $object->setMacAddress($data->{'MacAddress'}); } if (isset($data->{'ExposedPorts'})) { $values_98 = new \ArrayObject([], \ArrayObject::ARRAY_AS_PROPS); foreach ($data->{'ExposedPorts'} as $key_100 => $value_99) { $values_98[$key_100] = $value_99; } $object->setExposedPorts($values_98); } if (isset($data->{'NetworkSettings'})) { $object->setNetworkSettings($this->serializer->deserialize($data->{'NetworkSettings'}, 'Docker\\API\\Model\\NetworkConfig', 'raw', $context)); } if (isset($data->{'HostConfig'})) { $object->setHostConfig($this->serializer->deserialize($data->{'HostConfig'}, 'Docker\\API\\Model\\HostConfig', 'raw', $context)); } return $object; }