diff --git a/pom.xml b/pom.xml
index c8c7b729..94382f3e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -153,6 +153,12 @@
commons-cli
1.4
+
+
+ io.kubernetes
+ client-java
+ 8.0.2
+
diff --git a/src/main/java/org/fogbowcloud/arrebol/ArrebolController.java b/src/main/java/org/fogbowcloud/arrebol/ArrebolController.java
index 679ec5a9..f8a819e1 100644
--- a/src/main/java/org/fogbowcloud/arrebol/ArrebolController.java
+++ b/src/main/java/org/fogbowcloud/arrebol/ArrebolController.java
@@ -13,6 +13,7 @@
import org.fogbowcloud.arrebol.execution.Worker;
import org.fogbowcloud.arrebol.execution.WorkerTypes;
import org.fogbowcloud.arrebol.execution.creator.DockerWorkerCreator;
+import org.fogbowcloud.arrebol.execution.creator.K8sWorkerCreator;
import org.fogbowcloud.arrebol.execution.creator.RawWorkerCreator;
import org.fogbowcloud.arrebol.execution.creator.WorkerCreator;
import org.fogbowcloud.arrebol.models.command.CommandState;
@@ -32,6 +33,7 @@
import org.fogbowcloud.arrebol.scheduler.DefaultScheduler;
import org.fogbowcloud.arrebol.scheduler.FifoSchedulerPolicy;
import org.fogbowcloud.arrebol.utils.ConfValidator;
+import org.hibernate.boot.registry.classloading.spi.ClassLoaderService.Work;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
@@ -188,7 +190,9 @@ private void buildWorkerCreator(Configuration configuration) throws Exception {
this.workerCreator = new DockerWorkerCreator(configuration);
} else if (poolType.equals(WorkerTypes.RAW.getType())) {
this.workerCreator = new RawWorkerCreator(configuration);
- } else {
+ } else if (poolType.equals(WorkerTypes.K8S.getType())) {
+ this.workerCreator = new K8sWorkerCreator(configuration);
+ }else {
String poolTypeMsg = "Worker Pool Type configuration property wrong or missing. Please, verify your configuration file.";
throw new IllegalArgumentException(poolTypeMsg);
}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/TaskExecutionResult.java b/src/main/java/org/fogbowcloud/arrebol/execution/TaskExecutionResult.java
index 7da5b89c..20cd9d31 100644
--- a/src/main/java/org/fogbowcloud/arrebol/execution/TaskExecutionResult.java
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/TaskExecutionResult.java
@@ -7,6 +7,7 @@ public class TaskExecutionResult {
// this class is more like an struct, not very much OO but it ok
public static final int UNDETERMINED_RESULT = Integer.MAX_VALUE;
+ public static final int SUCCESS_RESULT = 0;
private final RESULT taskResult;
private final int[] exitcodes;
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/WorkerTypes.java b/src/main/java/org/fogbowcloud/arrebol/execution/WorkerTypes.java
index ff353477..2d737e01 100644
--- a/src/main/java/org/fogbowcloud/arrebol/execution/WorkerTypes.java
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/WorkerTypes.java
@@ -2,7 +2,8 @@
public enum WorkerTypes {
DOCKER("docker"),
- RAW("raw");
+ RAW("raw"),
+ K8S("k8s");
private String type;
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/creator/K8sWorkerCreator.java b/src/main/java/org/fogbowcloud/arrebol/execution/creator/K8sWorkerCreator.java
new file mode 100644
index 00000000..744ead95
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/creator/K8sWorkerCreator.java
@@ -0,0 +1,79 @@
+package org.fogbowcloud.arrebol.execution.creator;
+
+import java.io.IOException;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.UUID;
+
+import org.apache.log4j.Logger;
+import org.fogbowcloud.arrebol.execution.Worker;
+import org.fogbowcloud.arrebol.execution.k8s.K8sConfiguration;
+import org.fogbowcloud.arrebol.execution.k8s.K8sTaskExecutor;
+import org.fogbowcloud.arrebol.execution.k8s.client.DefaultK8sClient;
+import org.fogbowcloud.arrebol.execution.k8s.client.K8sClient;
+import org.fogbowcloud.arrebol.execution.k8s.resource.DefaultK8sClusterResource;
+import org.fogbowcloud.arrebol.execution.k8s.resource.K8sClusterResource;
+import org.fogbowcloud.arrebol.models.configuration.Configuration;
+import org.fogbowcloud.arrebol.models.specification.Specification;
+import org.fogbowcloud.arrebol.processor.spec.WorkerNode;
+import org.fogbowcloud.arrebol.resource.MatchAnyWorker;
+import org.fogbowcloud.arrebol.utils.AppUtil;
+
+public class K8sWorkerCreator implements WorkerCreator {
+
+ private final K8sConfiguration configuration;
+ private final Logger LOGGER = Logger.getLogger(K8sWorkerCreator.class);
+
+ public K8sWorkerCreator(Configuration configuration) throws Exception {
+ this.configuration = new K8sConfiguration(configuration);
+ }
+
+ @Override
+ public Collection createWorkers(Integer poolId) {
+ Collection workers = new LinkedList<>();
+ String address = configuration.getAddress();
+ int poolSize = configuration.getCapacity();
+ String namespace = configuration.getNamespace();
+ String volumeName = configuration.getVolumeName();
+ for (int i = 0; i < poolSize; i++) {
+ LOGGER.info("Creating k8s worker with address=" + address);
+ Worker worker = createK8sWorker(poolId, address, namespace, volumeName);
+ workers.add(worker);
+ }
+
+ return workers;
+ }
+
+ @Override
+ public Collection createWorkers(Integer poolId, WorkerNode workerNode) {
+ Collection workers = new LinkedList<>();
+ String namespace = configuration.getNamespace();
+ String volumeName = configuration.getVolumeName();
+ for(int i = 0; i < workerNode.getPoolSize(); i++){
+ LOGGER.info("Creating k8s worker with address=" + workerNode.getAddress());
+ Worker worker = createK8sWorker(poolId, workerNode.getAddress(), namespace, volumeName);
+ workers.add(worker);
+ }
+ return workers;
+ }
+
+ private Worker createK8sWorker(Integer poolId, String address, String namespace, String volumeName) {
+ String id = "k8s-executor-" + UUID.randomUUID().toString();
+ K8sClusterResource k8sClusterResource = new DefaultK8sClusterResource(id, address);
+ //TODO Add some specification here, something about the CPU and RAM requirements maybe
+ Specification resourceSpec = null;
+
+ K8sClient k8sClient = null;
+ try {
+ k8sClient = new DefaultK8sClient(address, namespace, volumeName);
+ } catch (IOException e) {
+ LOGGER.error("Error while create k8s client in worker [" + id + "]", e);
+ }
+
+ K8sTaskExecutor k8sTaskExecutor = new K8sTaskExecutor(k8sClusterResource, k8sClient);
+ Worker worker = new MatchAnyWorker(AppUtil.generateUniqueStringId(), resourceSpec, poolId, k8sTaskExecutor);
+ LOGGER.info("Created K8s Worker [" + worker.getId() + "]");
+ return worker;
+ }
+
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/K8sConfiguration.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/K8sConfiguration.java
new file mode 100644
index 00000000..1d044fc7
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/K8sConfiguration.java
@@ -0,0 +1,60 @@
+package org.fogbowcloud.arrebol.execution.k8s;
+
+import org.fogbowcloud.arrebol.execution.k8s.constants.K8sConstants;
+import org.fogbowcloud.arrebol.models.configuration.Configuration;
+import org.fogbowcloud.arrebol.models.configuration.Property;
+
+public class K8sConfiguration {
+ private final Integer capacity;
+ private final String address;
+ private final String namespace;
+ private final String volumeName;
+
+ public K8sConfiguration(Configuration configuration) throws Exception {
+ checkK8sConfigurationProperties(configuration);
+ Property capacity = configuration.getProperty(K8sConstants.K8S_CLUSTER_CAPACITY);
+ Property address = configuration.getProperty(K8sConstants.K8S_CLUSTER_ADDRESS);
+ Property namespace = configuration.getProperty(K8sConstants.K8S_CLUSTER_NAMESPACE);
+ Property volumeName = configuration.getProperty(K8sConstants.K8S_CLUSTER_VOLUME_NAME);
+ this.capacity = capacity.getValue().intValue();
+ this.address = address.getValue();
+ this.namespace = namespace.getValue();
+ this.volumeName = volumeName.getValue();
+ }
+
+ private void checkK8sConfigurationProperties(Configuration configuration) throws Exception {
+ String verifyMsg = " Please, verify your configuration file.";
+ String capacityMsg = "K8s cluster capacity configuration property wrong or missing." + verifyMsg;
+ String addressMsg = "K8s cluster address configuration property wrong or missing." + verifyMsg;
+ String namespaceMsg = "K8s cluster namespace configuration property wrong or missing." + verifyMsg;
+
+ Property capacity = configuration.getProperty(K8sConstants.K8S_CLUSTER_CAPACITY);
+ Property address = configuration.getProperty(K8sConstants.K8S_CLUSTER_ADDRESS);
+ Property namespace = configuration.getProperty(K8sConstants.K8S_CLUSTER_NAMESPACE);
+
+ if (address.getValue() == null || address.getValue().trim().isEmpty()) {
+ throw new Exception(addressMsg);
+ } else if (capacity.getValue() == null || capacity.getValue().intValue() == 0) {
+ throw new Exception(capacityMsg);
+ } else if (namespace.getValue() == null || namespace.getValue().trim().isEmpty()) {
+ throw new Exception(namespaceMsg);
+ }
+ }
+
+ public Integer getCapacity() {
+ return capacity;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public String getVolumeName() {
+ return volumeName;
+ }
+
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/K8sTaskExecutor.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/K8sTaskExecutor.java
new file mode 100644
index 00000000..01398fb1
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/K8sTaskExecutor.java
@@ -0,0 +1,166 @@
+package org.fogbowcloud.arrebol.execution.k8s;
+
+import static java.lang.Thread.sleep;
+import static org.fogbowcloud.arrebol.execution.docker.constants.DockerConstants.ADDRESS_METADATA_KEY;
+
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+
+import javax.persistence.CascadeType;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.OneToOne;
+import javax.persistence.Transient;
+
+import org.apache.log4j.Logger;
+import org.fogbowcloud.arrebol.execution.TaskExecutionResult;
+import org.fogbowcloud.arrebol.execution.TaskExecutor;
+import org.fogbowcloud.arrebol.execution.TaskExecutionResult.RESULT;
+import org.fogbowcloud.arrebol.execution.k8s.client.DefaultK8sClient;
+import org.fogbowcloud.arrebol.execution.k8s.client.K8sClient;
+import org.fogbowcloud.arrebol.execution.k8s.resource.DefaultK8sClusterResource;
+import org.fogbowcloud.arrebol.execution.k8s.resource.K8sClusterResource;
+import org.fogbowcloud.arrebol.models.command.Command;
+import org.fogbowcloud.arrebol.models.command.CommandState;
+import org.fogbowcloud.arrebol.models.task.RequirementsContants;
+import org.fogbowcloud.arrebol.models.task.Task;
+
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.models.V1Job;
+
+@Entity
+public class K8sTaskExecutor implements TaskExecutor {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+ @Transient
+ private final Logger LOGGER = Logger.getLogger(K8sTaskExecutor.class);
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = DefaultK8sClusterResource.class)
+ private K8sClusterResource k8sClusterResource;
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = DefaultK8sClient.class)
+ private K8sClient k8sClient;
+ @Transient
+ private static final long POOLING_PERIOD_TIME_MS = 5 * 1000;
+
+ public K8sTaskExecutor(K8sClusterResource k8sClusterResource, K8sClient k8sClient) {
+ this.k8sClusterResource = k8sClusterResource;
+ this.k8sClient = k8sClient;
+ }
+
+ public K8sTaskExecutor() {
+ }
+
+ @Override
+ public TaskExecutionResult execute(Task task) {
+ TaskExecutionResult taskExecutionResult = null;
+
+ String jobName = task.getId();
+
+ List commands = task.getTaskSpec().getCommands();
+ String command = joinCommands(commands);
+
+ Map requirements = task.getTaskSpec().getRequirements();
+ String imageId = getImageId(requirements);
+
+ LOGGER.debug("Image id: " + imageId);
+ LOGGER.debug("Command: " + command);
+
+ int tasksListSize = task.getTaskSpec().getCommands().size();
+
+ try {
+ V1Job job = k8sClient.createJob(jobName, imageId, command);
+ boolean jobIsRunning = true;
+
+ while (jobIsRunning) {
+ try {
+ sleep(POOLING_PERIOD_TIME_MS);
+ } catch (InterruptedException e) {
+ LOGGER.error(e.getMessage(), e);
+ }
+
+ job = k8sClient.getJob(jobName);
+ jobIsRunning = job.getStatus().getActive() != null;
+ }
+
+ if (wasSuccessful(job)) {
+ finishSuccessfulExecution(task);
+ taskExecutionResult = getSuccessResultInstance(tasksListSize);
+ } else {
+ finishFailExecution(task);
+ taskExecutionResult = getFailResultInstance(tasksListSize);
+ }
+ } catch (ApiException e) {
+ LOGGER.error("Error while call K8s client API. " + e.getMessage(), e);
+ finishFailExecution(task);
+ taskExecutionResult = getFailResultInstance(tasksListSize);
+ return taskExecutionResult;
+ }
+
+ return taskExecutionResult;
+ }
+
+ @Override
+ public Map getMetadata() {
+ Map metadata = new HashMap<>();
+ String address = this.k8sClusterResource.getApiAddress();
+ metadata.put(ADDRESS_METADATA_KEY, address);
+ return metadata;
+ }
+
+ private String joinCommands(List commands) {
+ String result = "";
+ for (Command command : commands)
+ result += command.getCommand() + " && ";
+ result = result.substring(0, result.length() - 4);
+
+ return result;
+ }
+
+ private String getImageId(Map requirements) throws IllegalArgumentException {
+ String imageId = null;
+ if (Objects.nonNull(requirements))
+ imageId = requirements.get(RequirementsContants.IMAGE_KEY);
+
+ return imageId;
+ }
+
+ private boolean wasSuccessful(V1Job job) {
+ Integer succeededAmount = job.getStatus().getSucceeded();
+ return succeededAmount != null && succeededAmount > 0;
+ }
+
+ private void finishSuccessfulExecution(Task task) {
+ for (Command c : task.getTaskSpec().getCommands()) {
+ c.setState(CommandState.FINISHED);
+ c.setExitcode(TaskExecutionResult.SUCCESS_RESULT);
+ }
+ }
+
+ private void finishFailExecution(Task task) {
+ for (Command c : task.getTaskSpec().getCommands()) {
+ c.setState(CommandState.FAILED);
+ c.setExitcode(TaskExecutionResult.UNDETERMINED_RESULT);
+ }
+ }
+
+ private TaskExecutionResult getFailResultInstance(int size) {
+ int[] exitCodes = new int[size];
+ Arrays.fill(exitCodes, TaskExecutionResult.UNDETERMINED_RESULT);
+ TaskExecutionResult taskExecutionResult = new TaskExecutionResult(RESULT.FAILURE, exitCodes);
+ return taskExecutionResult;
+ }
+
+ private TaskExecutionResult getSuccessResultInstance(int size) {
+ int[] exitCodes = new int[size];
+ Arrays.fill(exitCodes, TaskExecutionResult.SUCCESS_RESULT);
+ TaskExecutionResult taskExecutionResult = new TaskExecutionResult(RESULT.SUCCESS, exitCodes);
+ return taskExecutionResult;
+ }
+
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/client/DefaultK8sClient.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/client/DefaultK8sClient.java
new file mode 100644
index 00000000..6d907555
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/client/DefaultK8sClient.java
@@ -0,0 +1,151 @@
+package org.fogbowcloud.arrebol.execution.k8s.client;
+
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Objects;
+
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Transient;
+
+import org.apache.log4j.Logger;
+
+import io.kubernetes.client.openapi.ApiClient;
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.Configuration;
+import io.kubernetes.client.openapi.apis.BatchV1Api;
+import io.kubernetes.client.openapi.models.V1Container;
+import io.kubernetes.client.openapi.models.V1Job;
+import io.kubernetes.client.openapi.models.V1JobSpec;
+import io.kubernetes.client.openapi.models.V1ObjectMeta;
+import io.kubernetes.client.openapi.models.V1PersistentVolumeClaimVolumeSource;
+import io.kubernetes.client.openapi.models.V1PodSpec;
+import io.kubernetes.client.openapi.models.V1PodTemplateSpec;
+import io.kubernetes.client.openapi.models.V1Status;
+import io.kubernetes.client.openapi.models.V1Volume;
+import io.kubernetes.client.openapi.models.V1VolumeMount;
+import io.kubernetes.client.util.ClientBuilder;
+
+@Entity
+public class DefaultK8sClient implements K8sClient {
+
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ private Integer id;
+
+ private String namespace;
+
+ @Transient
+ private BatchV1Api batchApi;
+
+ private String volumeName;
+
+ @Transient
+ private final Logger LOGGER = Logger.getLogger(DefaultK8sClient.class);
+
+ public DefaultK8sClient(String host, String namespace, String volumeName) throws IOException {
+ ApiClient client = ClientBuilder.defaultClient();
+ client.setBasePath(host);
+ client.setDebugging(true);
+
+ Configuration.setDefaultApiClient(client);
+ this.batchApi = new BatchV1Api();
+ this.namespace = namespace;
+ this.volumeName = volumeName;
+ }
+
+ public DefaultK8sClient() {}
+
+ @Override
+ public V1Job createJob(String name, String imageId, String command) throws ApiException {
+ List commandList = buildCommands(command);
+ V1Container podContainer = new V1Container()
+ .name(name)
+ .image(imageId)
+ .command(commandList);
+
+
+ V1PodSpec podSpec = new V1PodSpec()
+ .restartPolicy("Never")
+ .containers(Arrays.asList(
+ podContainer
+ )
+ );
+
+ if(Objects.nonNull(volumeName)) {
+ podContainer.volumeMounts(Arrays.asList(
+ new V1VolumeMount()
+ .name("k8s-nfs")
+ .mountPath("/nfs")
+ )
+ );
+
+ podSpec.volumes(Arrays.asList(
+ new V1Volume()
+ .name("k8s-nfs")
+ .persistentVolumeClaim(
+ new V1PersistentVolumeClaimVolumeSource()
+ .claimName(volumeName)
+ )
+ )
+ );
+ }
+
+ V1Job job = new V1Job()
+ .apiVersion("batch/v1")
+ .kind("Job")
+ .metadata(
+ new V1ObjectMeta().name(name))
+ .spec(new V1JobSpec()
+ .template(new V1PodTemplateSpec()
+ .metadata(new V1ObjectMeta().labels(Collections.singletonMap("app",name)))
+ .spec(podSpec)
+ ).backoffLimit(2)
+ );
+
+ return batchApi.createNamespacedJob(namespace, job, null, null, null);
+
+ }
+
+ private List buildCommands(String command) {
+ List commands = new LinkedList();
+ commands.add(new String("/bin/sh"));
+ commands.add(new String("-c"));
+ commands.add(new String(command));
+ return commands;
+ }
+
+ @Override
+ public V1Status deleteJob(String name) throws ApiException {
+ return batchApi.deleteNamespacedJob(name, namespace, null, null, null, null, null, null);
+ }
+
+ @Override
+ public V1Job getJob(String name) throws ApiException {
+ return batchApi.readNamespacedJob(name, this.namespace, null, null, null);
+ }
+
+ public Integer getId() {
+ return id;
+ }
+
+ public String getNamespace() {
+ return namespace;
+ }
+
+ public BatchV1Api getBatchApi() {
+ return batchApi;
+ }
+
+ public String getVolumeName() {
+ return volumeName;
+ }
+
+
+
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/client/K8sClient.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/client/K8sClient.java
new file mode 100644
index 00000000..a4fbaaf7
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/client/K8sClient.java
@@ -0,0 +1,15 @@
+package org.fogbowcloud.arrebol.execution.k8s.client;
+
+import io.kubernetes.client.openapi.ApiException;
+import io.kubernetes.client.openapi.models.V1Job;
+import io.kubernetes.client.openapi.models.V1Status;
+
+public interface K8sClient {
+
+ V1Job createJob(String name, String containerImage, String command) throws ApiException;
+
+ V1Status deleteJob(String name) throws ApiException;
+
+ V1Job getJob(String name) throws ApiException;
+
+}
\ No newline at end of file
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/constants/K8sConstants.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/constants/K8sConstants.java
new file mode 100644
index 00000000..d2c824c9
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/constants/K8sConstants.java
@@ -0,0 +1,9 @@
+package org.fogbowcloud.arrebol.execution.k8s.constants;
+
+public class K8sConstants {
+ public static final String K8S_CLUSTER_CAPACITY = "capacity";
+ public static final String K8S_CLUSTER_ADDRESS = "address";
+ public static final String K8S_CLUSTER_NAMESPACE = "namespace";
+ public static final String K8S_CLUSTER_VOLUME_NAME = "volumeName";
+
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/resource/DefaultK8sClusterResource.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/resource/DefaultK8sClusterResource.java
new file mode 100644
index 00000000..ab994d68
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/resource/DefaultK8sClusterResource.java
@@ -0,0 +1,35 @@
+package org.fogbowcloud.arrebol.execution.k8s.resource;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+
+@Entity
+public class DefaultK8sClusterResource implements K8sClusterResource {
+
+ @Id
+ private String id;
+ private String address;
+
+ public DefaultK8sClusterResource(String id, String address) {
+ this.id = id;
+ this.address = address;
+ }
+
+ public DefaultK8sClusterResource() {
+ }
+
+ @Override
+ public String getId() {
+ return id;
+ }
+
+ @Override
+ public String getApiAddress() {
+ return address;
+ }
+
+ public String getAddress() {
+ return address;
+ }
+
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/execution/k8s/resource/K8sClusterResource.java b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/resource/K8sClusterResource.java
new file mode 100644
index 00000000..6fc647ff
--- /dev/null
+++ b/src/main/java/org/fogbowcloud/arrebol/execution/k8s/resource/K8sClusterResource.java
@@ -0,0 +1,8 @@
+package org.fogbowcloud.arrebol.execution.k8s.resource;
+
+public interface K8sClusterResource {
+
+ String getId();
+
+ String getApiAddress();
+}
diff --git a/src/main/java/org/fogbowcloud/arrebol/resource/MatchAnyWorker.java b/src/main/java/org/fogbowcloud/arrebol/resource/MatchAnyWorker.java
index 18aaa9cb..11c27283 100644
--- a/src/main/java/org/fogbowcloud/arrebol/resource/MatchAnyWorker.java
+++ b/src/main/java/org/fogbowcloud/arrebol/resource/MatchAnyWorker.java
@@ -12,6 +12,7 @@
import org.fogbowcloud.arrebol.execution.TaskExecutor;
import org.fogbowcloud.arrebol.execution.Worker;
import org.fogbowcloud.arrebol.execution.docker.DockerTaskExecutor;
+import org.fogbowcloud.arrebol.execution.k8s.K8sTaskExecutor;
import org.fogbowcloud.arrebol.models.specification.Specification;
import org.fogbowcloud.arrebol.models.task.Task;
@@ -32,7 +33,7 @@ public class MatchAnyWorker implements Worker {
private Specification spec;
@Transient
private int poolId;
- @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = DockerTaskExecutor.class)
+ @OneToOne(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = K8sTaskExecutor.class)
private TaskExecutor executor;
public MatchAnyWorker(String id, Specification spec, int poolId, TaskExecutor delegatedExecutor) {
diff --git a/src/main/resources/arrebol-k8s.json b/src/main/resources/arrebol-k8s.json
new file mode 100644
index 00000000..f8478897
--- /dev/null
+++ b/src/main/resources/arrebol-k8s.json
@@ -0,0 +1,19 @@
+{
+ "poolType":"k8s",
+ "properties": [
+ {
+ "key":"capacity",
+ "value": 5
+ },
+ {
+ "key": "address",
+ "value": "http://127.0.0.1:8001"
+ },{
+ "key": "namespace",
+ "value": "default"
+ },{
+ "key": "volumeName",
+ "value": "nfs"
+ }
+ ]
+}