ContainerOperationsImpl implements ContainerOperations { void addEtcHosts(ContainerData containerData, String hostname, Optional<? extends InetAddress> ipV4Local, Optional<? extends InetAddress> ipV6Local) { StringBuilder etcHosts = new StringBuilder( "# This file was generated by " + ContainerOperationsImpl.class.getName() + "\n" + "127.0.0.1\tlocalhost\n" + "::1\tlocalhost ip6-localhost ip6-loopback\n" + "fe00::0\tip6-localnet\n" + "ff00::0\tip6-mcastprefix\n" + "ff02::1\tip6-allnodes\n" + "ff02::2\tip6-allrouters\n"); ipV6Local.ifPresent(ipv6 -> etcHosts.append(ipv6.getHostAddress()).append('\t').append(hostname).append('\n')); ipV4Local.ifPresent(ipv4 -> etcHosts.append(ipv4.getHostAddress()).append('\t').append(hostname).append('\n')); containerData.addFile(fileSystem.getPath("/etc/hosts"), etcHosts.toString()); } ContainerOperationsImpl(ContainerEngine containerEngine, Terminal terminal, IPAddresses ipAddresses, FileSystem fileSystem); @Override void createContainer(NodeAgentContext context, ContainerData containerData, ContainerResources containerResources); @Override void startContainer(NodeAgentContext context); @Override void removeContainer(NodeAgentContext context, Container container); @Override void updateContainer(NodeAgentContext context, ContainerResources containerResources); @Override Optional<Container> getContainer(NodeAgentContext context); @Override boolean pullImageAsyncIfNeeded(DockerImage dockerImage); @Override ProcessResult executeCommandInContainerAsRoot(NodeAgentContext context, Long timeoutSeconds, String... command); @Override ProcessResult executeCommandInContainerAsRoot(NodeAgentContext context, String... command); @Override CommandResult executeCommandInNetworkNamespace(NodeAgentContext context, String... command); @Override void resumeNode(NodeAgentContext context); @Override void suspendNode(NodeAgentContext context); @Override void restartVespa(NodeAgentContext context); @Override void startServices(NodeAgentContext context); @Override void stopServices(NodeAgentContext context); @Override Optional<ContainerStats> getContainerStats(NodeAgentContext context); @Override boolean noManagedContainersRunning(); @Override boolean deleteUnusedContainerImages(List<DockerImage> excludes, Duration minImageAgeToDelete);  }
@Test public void verifyEtcHosts() { ContainerData containerData = mock(ContainerData.class); String hostname = "hostname"; InetAddress ipV6Local = InetAddresses.forString("::1"); InetAddress ipV4Local = InetAddresses.forString("127.0.0.1"); dockerOperations.addEtcHosts(containerData, hostname, Optional.empty(), Optional.of(ipV6Local)); verify(containerData, times(1)).addFile( fileSystem.getPath("/etc/hosts"), "# This file was generated by com.yahoo.vespa.hosted.node.admin.docker.ContainerOperationsImpl\n" + "127.0.0.1 localhost\n" + "::1 localhost ip6-localhost ip6-loopback\n" + "fe00::0 ip6-localnet\n" + "ff00::0 ip6-mcastprefix\n" + "ff02::1 ip6-allnodes\n" + "ff02::2 ip6-allrouters\n" + "0:0:0:0:0:0:0:1 hostname\n"); dockerOperations.addEtcHosts(containerData, hostname, Optional.of(ipV4Local), Optional.of(ipV6Local)); verify(containerData, times(1)).addFile( fileSystem.getPath("/etc/hosts"), "# This file was generated by com.yahoo.vespa.hosted.node.admin.docker.ContainerOperationsImpl\n" + "127.0.0.1 localhost\n" + "::1 localhost ip6-localhost ip6-loopback\n" + "fe00::0 ip6-localnet\n" + "ff00::0 ip6-mcastprefix\n" + "ff02::1 ip6-allnodes\n" + "ff02::2 ip6-allrouters\n" + "0:0:0:0:0:0:0:1 hostname\n" + "127.0.0.1 hostname\n"); }