DockerRouting::run()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 0
1
<?php
2
3
namespace Dock\Installer\DNS\Mac;
4
5
use Dock\Docker\Machine\Machine;
6
use Dock\Installer\InstallerTask;
7
use Dock\IO\PharFileExtractor;
8
use Dock\IO\ProcessRunner;
9
use Dock\IO\UserInteraction;
10
use SRIO\ChainOfResponsibility\DependentChainProcessInterface;
11
use Symfony\Component\Process\Exception\ProcessFailedException;
12
13
class DockerRouting extends InstallerTask implements DependentChainProcessInterface
14
{
15
    /**
16
     * @var ProcessRunner
17
     */
18
    private $processRunner;
19
    /**
20
     * @var UserInteraction
21
     */
22
    private $userInteraction;
23
    /**
24
     * @var PharFileExtractor
25
     */
26
    private $fileExtractor;
27
    /**
28
     * @var Machine
29
     */
30
    private $machine;
31
32
    /**
33
     * @param Machine           $machine
34
     * @param UserInteraction   $userInteraction
35
     * @param ProcessRunner     $processRunner
36
     * @param PharFileExtractor $fileExtractor
37
     */
38
    public function __construct(Machine $machine, UserInteraction $userInteraction, ProcessRunner $processRunner, PharFileExtractor $fileExtractor)
39
    {
40
        $this->machine = $machine;
41
        $this->userInteraction = $userInteraction;
42
        $this->processRunner = $processRunner;
43
        $this->fileExtractor = $fileExtractor;
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function run()
50
    {
51
        $this->userInteraction->writeTitle('Configure routing for direct Docker containers access');
52
53
        $machineIp = $this->machine->getIp();
54
55
        $this->configureRouting($machineIp);
56
        $this->addPermanentRouting($machineIp);
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62
    public function dependsOn()
63
    {
64
        return ['machine'];
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function getName()
71
    {
72
        return 'routing';
73
    }
74
75
    /**
76
     * @param string $machineIp
77
     *
78
     * @throws ProcessFailedException
79
     */
80
    private function configureRouting($machineIp)
81
    {
82
        $this->processRunner->run('sudo route -n delete 172.16.0.0/12', false);
83
        $this->processRunner->run(sprintf('sudo route -n add 172.16.0.0/12 %s', $machineIp));
84
    }
85
86
    /**
87
     * @param string $machineIp
88
     */
89
    private function addPermanentRouting($machineIp)
90
    {
91
        $filePath = $this->fileExtractor->extract(__DIR__.'/fixtures/com.docker.route.plist');
92
93
        // Replace the machine IP
94
        file_put_contents($filePath, str_replace('__MACHINE_IP__', $machineIp, file_get_contents($filePath)));
95
96
        // Replace the network interface used
97
        $machineInterface = $this->resolveNetworkInterface($machineIp);
98
        file_put_contents($filePath, str_replace('__MACHINE_INTERFACE__', $machineInterface, file_get_contents($filePath)));
99
100
        $this->processRunner->run(sprintf('sudo cp %s /Library/LaunchDaemons/com.docker.route.plist', $filePath));
101
        $this->processRunner->run('sudo launchctl load /Library/LaunchDaemons/com.docker.route.plist');
102
    }
103
104
    /**
105
     * Resolve the network interface name for the given IP.
106
     *
107
     * @param string $machineIp
108
     *
109
     * @return string
110
     */
111
    private function resolveNetworkInterface($machineIp)
112
    {
113
        $process = $this->processRunner->run('ifconfig `route get '.$machineIp.' | grep "interface: " | sed "s/[^:]*: \(.*\)/\1/"` | head -n 1 | sed "s/\([^:]*\): .*/\1/"');
114
        $interface = $process->getOutput();
115
116
        return trim($interface);
117
    }
118
}
119