Skip to content

Commit

Permalink
Merge pull request kornelrabczak#25 from nikom1337/docker_hosts_manag…
Browse files Browse the repository at this point in the history
…ement

Docker hosts management
  • Loading branch information
Korneliusz Rabczak committed Sep 25, 2016
2 parents 67bc363 + 15f3fe3 commit 5fd2fd5
Show file tree
Hide file tree
Showing 14 changed files with 176 additions and 228 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ public class Cluster implements Identifiable, Serializable {
@Size(min = 5, max = 30)
private String name;

private int maxContainers;

@NotNull
private Duration healthCheckInterval = Duration.ofSeconds(15);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,23 @@

import java.io.Serializable;
import java.time.Instant;
import java.util.Random;

@Data
@NoArgsConstructor
public class DockerHost implements Serializable {
private static final long serialVersionUID = 1L;

private long id;
private final long id;

@NonNull
private String name;

@NonNull
private String dockerDaemonUrl;

private Instant created = Instant.now();
private final Instant created = Instant.now();

public DockerHost() {
id = new Random().nextLong();
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.thecookiezen.bussiness.containers.boundary;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.command.StatsCmd;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Info;

import java.util.Collection;

public interface ContainerFetcher {
Collection<Container> list();
Info getInfo();
Collection<Container> list(DockerClient dockerClient);

Info getInfo(DockerClient dockerClient);

DockerClient getDockerClient(final String dockerHost, final String apiVersion);

StatsCmd statsCmd(String containerId);
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import com.github.dockerjava.api.model.Info;
import com.github.dockerjava.core.DefaultDockerClientConfig;
import com.github.dockerjava.core.DockerClientBuilder;
import com.github.dockerjava.core.DockerClientConfig;
import com.thecookiezen.bussiness.containers.boundary.ContainerFetcher;
import org.springframework.stereotype.Component;

Expand All @@ -22,11 +21,15 @@ public class DockerFetcher implements ContainerFetcher {

@PostConstruct
void init() {
DockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost("tcp:https://0.0.0.0:2376")
.withApiVersion("1.24")
dockerClient = getDockerClient("tcp:https://0.0.0.0:2375", "1.24");
}

public DockerClient getDockerClient(final String dockerHost, final String apiVersion) {
DefaultDockerClientConfig config = DefaultDockerClientConfig.createDefaultConfigBuilder()
.withDockerHost(dockerHost)
.withApiVersion(apiVersion)
.build();
dockerClient = DockerClientBuilder.getInstance(config).build();
return DockerClientBuilder.getInstance(config).build();
}

@PreDestroy
Expand All @@ -35,12 +38,12 @@ void cleanUp() throws IOException {
}

@Override
public Collection<Container> list() {
public Collection<Container> list(DockerClient dockerClient) {
return dockerClient.listContainersCmd().withShowAll(true).exec();
}

@Override
public Info getInfo() {
public Info getInfo(DockerClient dockerClient) {
return dockerClient.infoCmd().exec();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,14 @@ public String addHost(@Valid DockerHost dockerHost, @RequestParam long clusterId
return "redirect:/clusters/all";
}

@RequestMapping(value = "clusters/node", method = RequestMethod.DELETE)
public String deleteHost(@RequestParam Long clusterId, @RequestParam Long hostId) {
Cluster cluster = clusterRepository.getById(clusterId).get();
cluster.getHosts().removeIf(h -> h.getId() == hostId);
clusterRepository.save(cluster);
return "redirect:/clusters/all";
}

@RequestMapping(value = "clusters", method = RequestMethod.POST)
public String saveOrUpdate(@Valid Cluster cluster, BindingResult bindingResult) {
log.info("saveOrUpdate");
Expand Down
30 changes: 1 addition & 29 deletions src/main/java/com/thecookiezen/presentation/IndexController.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,15 @@
package com.thecookiezen.presentation;

import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Info;
import com.thecookiezen.bussiness.cluster.boundary.ClusterRepository;
import com.thecookiezen.bussiness.containers.boundary.ContainerFetcher;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import java.util.Collection;

@Controller
@Log4j
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class IndexController {

ClusterRepository clusterRepository;

ContainerFetcher containerFetcher;

@RequestMapping("/index")
public String index(Model model) {
Collection<Container> list = containerFetcher.list();
Info info = containerFetcher.getInfo();
model.addAttribute("nodeInfo", info);
model.addAttribute("containers", list);
public String index() {
return "index";
}

@RequestMapping("/container")
public String container(Model model) {
return "container";
}

@RequestMapping("/test")
public String test() {
return "test";
}
}
53 changes: 53 additions & 0 deletions src/main/java/com/thecookiezen/presentation/NodeController.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package com.thecookiezen.presentation;

import com.github.dockerjava.api.DockerClient;
import com.github.dockerjava.api.model.Container;
import com.github.dockerjava.api.model.Info;
import com.thecookiezen.bussiness.cluster.boundary.ClusterRepository;
import com.thecookiezen.bussiness.cluster.entity.Cluster;
import com.thecookiezen.bussiness.cluster.entity.DockerHost;
import com.thecookiezen.bussiness.containers.boundary.ContainerFetcher;
import lombok.AllArgsConstructor;
import lombok.extern.log4j.Log4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import javax.ws.rs.NotFoundException;
import java.util.Collection;
import java.util.Optional;

@Controller
@Log4j
@AllArgsConstructor(onConstructor = @__(@Autowired))
public class NodeController {

ContainerFetcher containerFetcher;

ClusterRepository clusterRepository;

@RequestMapping("/clusters/node")
public String node(@RequestParam long clusterId, @RequestParam long nodeId, Model model) {
Optional<Cluster> byId = clusterRepository.getById(clusterId);
if (!byId.isPresent())
throw new NotFoundException("CHANGE ME !");

Cluster cluster = byId.get();
Optional<DockerHost> nodeOptional = cluster.getHosts().stream().filter(n -> n.getId() == nodeId).findFirst();
if (!nodeOptional.isPresent())
throw new NotFoundException("CHANGE ME !");

DockerClient dockerClient = containerFetcher.getDockerClient(nodeOptional.get().getDockerDaemonUrl(), cluster.getDockerApiVersion());
Collection<Container> list = containerFetcher.list(dockerClient);
Info info = containerFetcher.getInfo(dockerClient);

model.addAttribute("cluster", cluster);
model.addAttribute("node", nodeOptional.get());
model.addAttribute("nodeInfo", info);
model.addAttribute("containers", list);
return "clusters/node";
}

}
98 changes: 70 additions & 28 deletions src/main/resources/templates/clusters/all.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,80 @@ <h1>
<section class="content">
<div class="row">
<div class="col-md-10">
<div class="box">
<div class="box-body no-padding">
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>name</th>
<th style="width:120px">docker version</th>
<th>status</th>
<th>hosts</th>
<th>actions</th>
</tr>
</thead>
<tbody>
<tr th:each="cluster : ${clustersList}">
<td th:text="${cluster.id}"></td>
<td th:text="${cluster.name}"></td>
<td th:text="${cluster.dockerApiVersion}"></td>
<td>ok</td>
<td th:text="${cluster.hosts.size()}"></td>
<td>
<div class="btn-group">
<div class="box box-solid">
<div class="box-body">
<div class="box-group" id="accordion">
<div class="panel box box-success" th:each="cluster,iterStat : ${clustersList}">
<div class="box-header with-border">
<h4 class="box-title">
<a data-toggle="collapse" data-parent="#accordion"
th:href="${'#collapse_' + iterStat.index}"
th:text="${cluster.name}"
aria-expanded="false" class="collapsed">
</a>
</h4>
<div class="btn-group pull-right">
<a th:href="@{/clusters/newhost(clusterId=${cluster.id})}" class="btn btn-info">Add
Host</a>
<a th:href="@{/clusters/form(clusterId=${cluster.id})}" class="btn btn-warning">Edit</a>
<form th:action="@{/clusters(clusterId=${cluster.id})}" th:method="delete" style="float:left;">
<form th:action="@{/clusters(clusterId=${cluster.id})}" th:method="delete"
style="float:left;">
<button type="submit" class="btn btn-danger">Delete</button>
</form>
<a th:href="@{/clusters/newhost(clusterId=${cluster.id})}" class="btn btn-info">Add Host</a>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div th:id="${'collapse_' + iterStat.index}" class="panel-collapse collapse" aria-expanded="true">
<div class="box-body">
<dl class="dl-horizontal">
<dt>ID</dt>
<dd th:text="${cluster.id}"></dd>
<dt>Docker version</dt>
<dd th:text="${cluster.dockerApiVersion}"></dd>
<dt>Status</dt>
<dd>Ok</dd>
<dt>Hosts count</dt>
<dd th:text="${cluster.hosts.size()}"></dd>
</dl>
</div>

<div class="box-body no-padding">
<div class="box-header">
<h3 class="box-title">Hosts list</h3>
</div>
<table class="table table-condensed">
<tbody><tr>
<th style="width: 10px">#</th>
<th>Name</th>
<th>Url</th>
<th>Host space</th>
<th style="width: 40px">Status</th>
<th style="width: 40px">Action</th>
</tr>
<tr th:each="host : ${cluster.hosts}">
<td>
<a th:href="@{/clusters/node(clusterId=${cluster.id},nodeId=${host.id})}"
th:text="${host.id}"></a>
</td>
<td th:text="${host.name}"></td>
<td th:text="${host.dockerDaemonUrl}"></td>
<td>
<div class="progress progress-xs">
<div class="progress-bar progress-bar-danger" style="width: 55%"></div>
</div>
</td>
<td><span class="badge bg-red">Error</span></td>
<td>
<form th:action="@{/clusters/node(clusterId=${cluster.id},hostId=${host.id})}" th:method="delete">
<button type="submit" class="btn btn-danger"><i class="fa fa-trash-o"></i> Delete</button>
</form>
</td>
</tr>
</tbody></table>
<div class="box-footer clearfix"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Expand Down
14 changes: 14 additions & 0 deletions src/main/resources/templates/clusters/node.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html lang="en" layout:decorator="layout">
<head>
</head>
<body>

<div layout:fragment="content">

<div th:replace="fragments/node/info :: info"></div>

</div>

</body>
</html>
Loading

0 comments on commit 5fd2fd5

Please sign in to comment.