70 lines
2.0 KiB
PHP
70 lines
2.0 KiB
PHP
<?php
|
|
|
|
namespace App\Services\Dns;
|
|
|
|
use RuntimeException;
|
|
|
|
/**
|
|
* Writes one file per host into config('provisioning.dns.hosts_dir') — an
|
|
* /etc/hosts-format line ("<ip> <fqdn>") per entry, in the directory dnsmasq's
|
|
* --hostsdir watches via inotify (see vpn-dns in docker-compose.yml). No
|
|
* restart, no reload call: the file landing on disk IS the publish.
|
|
*
|
|
* The directory is shared with the app's own containers over a plain Docker
|
|
* volume, not SSH — unlike SshTraefikWriter, everything that touches it runs
|
|
* on the same Docker host. Left world-writable/readable (0775/0664) because
|
|
* whichever container touches it first (queue-provisioning as root in
|
|
* production, www-data under `app`) must not lock the other out.
|
|
*/
|
|
class FileHostDnsDirectory implements HostDnsDirectory
|
|
{
|
|
public function write(string $name, string $fqdn, string $ip): void
|
|
{
|
|
$this->ensureDir();
|
|
|
|
$path = $this->path($name);
|
|
|
|
if (@file_put_contents($path, "{$ip} {$fqdn}\n") === false) {
|
|
throw new RuntimeException("Could not write DNS hosts entry: {$path}");
|
|
}
|
|
|
|
@chmod($path, 0664);
|
|
}
|
|
|
|
public function remove(string $name): void
|
|
{
|
|
$path = $this->path($name);
|
|
|
|
// Nothing to do is not a failure — a host whose name was never
|
|
// written (or already removed) still has to purge cleanly.
|
|
if (is_file($path) && ! @unlink($path)) {
|
|
throw new RuntimeException("Could not remove DNS hosts entry: {$path}");
|
|
}
|
|
}
|
|
|
|
private function ensureDir(): void
|
|
{
|
|
$dir = $this->dir();
|
|
|
|
if (is_dir($dir)) {
|
|
return;
|
|
}
|
|
|
|
if (! @mkdir($dir, 0775, true) && ! is_dir($dir)) {
|
|
throw new RuntimeException("Could not create DNS hosts directory: {$dir}");
|
|
}
|
|
|
|
@chmod($dir, 0775);
|
|
}
|
|
|
|
private function path(string $name): string
|
|
{
|
|
return rtrim($this->dir(), '/')."/{$name}.hosts";
|
|
}
|
|
|
|
private function dir(): string
|
|
{
|
|
return (string) config('provisioning.dns.hosts_dir');
|
|
}
|
|
}
|