Skip to content

Commit 1636dfa

Browse files
committed
Fix #18592: support memory and cpu constraints in Docker Swarm
1 parent 5827437 commit 1636dfa

1 file changed

Lines changed: 28 additions & 1 deletion

File tree

src/main/java/eu/openanalytics/containerproxy/backend/docker/DockerSwarmBackend.java

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import com.spotify.docker.client.messages.swarm.EndpointSpec;
2929
import com.spotify.docker.client.messages.swarm.NetworkAttachmentConfig;
3030
import com.spotify.docker.client.messages.swarm.PortConfig;
31+
import com.spotify.docker.client.messages.swarm.ResourceRequirements;
32+
import com.spotify.docker.client.messages.swarm.Resources;
3133
import com.spotify.docker.client.messages.swarm.Secret;
3234
import com.spotify.docker.client.messages.swarm.SecretBind;
3335
import com.spotify.docker.client.messages.swarm.SecretFile;
@@ -116,12 +118,35 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
116118
networks[networks.length - 1] = NetworkAttachmentConfig.builder().target(spec.getNetwork()).build();
117119
}
118120

121+
Resources.Builder reservationsBuilder = Resources.builder();
122+
// reservations are used by the Docker swarm scheduler
123+
if (spec.getCpuRequest() != null) {
124+
// note: 1 CPU = 1 * 10e8 nanoCpu -> equivalent to --cpus option
125+
reservationsBuilder.nanoCpus((long) (Double.parseDouble(spec.getCpuRequest()) * 10e8));
126+
}
127+
if (spec.getMemoryRequest() != null) {
128+
reservationsBuilder.memoryBytes(memoryToBytes(spec.getMemoryRequest()));
129+
}
130+
131+
Resources.Builder limitsBuilder = Resources.builder();
132+
if (spec.getCpuLimit() != null) {
133+
// note: 1 CPU = 1 * 10e8 nanoCpu -> equivalent to --cpus option
134+
limitsBuilder.nanoCpus((long) (Double.parseDouble(spec.getCpuLimit()) * 10e8));
135+
}
136+
if (spec.getMemoryLimit() != null) {
137+
limitsBuilder.memoryBytes(memoryToBytes(spec.getMemoryLimit()));
138+
}
139+
119140
String serviceName = "sp-service-" + UUID.randomUUID().toString();
120141
ServiceSpec.Builder serviceSpecBuilder = ServiceSpec.builder()
121142
.networks(networks)
122143
.name(serviceName)
123144
.taskTemplate(TaskSpec.builder()
124145
.containerSpec(containerSpec)
146+
.resources(ResourceRequirements.builder()
147+
.reservations(reservationsBuilder.build())
148+
.limits(limitsBuilder.build())
149+
.build())
125150
.build());
126151

127152
List<PortConfig> portsToPublish = new ArrayList<>();
@@ -159,7 +184,9 @@ protected Container startContainer(ContainerSpec spec, Proxy proxy) throws Excep
159184
Task serviceTask = dockerClient
160185
.listTasks(Task.Criteria.builder().serviceName(serviceName).build())
161186
.stream().findAny().orElseThrow(() -> new IllegalStateException("Swarm service has no tasks"));
162-
container.setId(serviceTask.status().containerStatus().containerId());
187+
if (serviceTask.status().containerStatus() != null) {
188+
container.setId(serviceTask.status().containerStatus().containerId());
189+
}
163190
} catch (Exception e) {
164191
throw new RuntimeException("Failed to inspect swarm service tasks", e);
165192
}

0 commit comments

Comments
 (0)