|
1 | 1 | package org.thp.cortex.services |
2 | 2 |
|
| 3 | +import java.util.concurrent.TimeUnit |
3 | 4 | import java.nio.charset.StandardCharsets |
4 | 5 | import java.nio.file._ |
5 | 6 |
|
6 | 7 | import scala.concurrent.duration.FiniteDuration |
7 | 8 | import scala.concurrent.{ExecutionContext, Future} |
8 | 9 | import scala.util.Try |
| 10 | +import scala.collection.JavaConverters._ |
9 | 11 |
|
10 | 12 | import play.api.libs.json.Json |
11 | 13 | import play.api.{Configuration, Logger} |
12 | 14 |
|
13 | 15 | import akka.actor.ActorSystem |
14 | | -import io.fabric8.kubernetes.client.{DefaultKubernetesClient, ConfigBuilder} |
| 16 | +import io.fabric8.kubernetes.client.{DefaultKubernetesClient, ConfigBuilder, Watcher} |
| 17 | +import io.fabric8.kubernetes.api.model.batch.{Job => KJob, JobBuilder => KJobBuilder} |
| 18 | + |
15 | 19 | // import com.spotify.docker.client.DockerClient.LogsParam |
16 | 20 | // import com.spotify.docker.client.messages.HostConfig.Bind |
17 | 21 | // import com.spotify.docker.client.messages.{ContainerConfig, HostConfig} |
@@ -44,14 +48,52 @@ class K8sJobRunnerSrv( |
44 | 48 |
|
45 | 49 | lazy val isAvailable: Boolean = |
46 | 50 | Try { |
47 | | - logger.info(s"Kubernetes is available:\n${client.getVersion().toString()}") |
| 51 | + val ver = client.getVersion() |
| 52 | + logger.info(s"Kubernetes is available: major ${ver.getMajor()} minor ${ver.getMinor()} git ${ver.getGitCommit()}") |
48 | 53 | true |
49 | 54 | }.recover { |
50 | 55 | case error => |
51 | 56 | logger.info(s"Kubernetes is not available", error) |
52 | 57 | false |
53 | 58 | }.get |
54 | 59 |
|
55 | | - def run(jobDirectory: Path, dockerImage: String, job: Job, timeout: Option[FiniteDuration])(implicit ec: ExecutionContext): Future[Unit] = { Future {} } |
| 60 | + def run(jobDirectory: Path, dockerImage: String, job: Job, timeout: Option[FiniteDuration])(implicit ec: ExecutionContext): Future[Unit] = { |
| 61 | + val kjob = new KJobBuilder() |
| 62 | + .withApiVersion("batch/v1") |
| 63 | + .withNewMetadata() |
| 64 | + .withName(job.workerId()) |
| 65 | + .withLabels(Map("cortex_workerId" -> job.workerId()).asJava) |
| 66 | + .endMetadata() |
| 67 | + .withNewSpec() |
| 68 | + .withNewTemplate() |
| 69 | + .withNewSpec() |
| 70 | + .addNewContainer() |
| 71 | + .withName("neuron") |
| 72 | + .withImage(dockerImage) |
| 73 | + .withArgs("/job") |
| 74 | + .endContainer() |
| 75 | + .withRestartPolicy("Never") |
| 76 | + .endSpec() |
| 77 | + .endTemplate() |
| 78 | + .endSpec() |
| 79 | + .build(); |
| 80 | + logger.info(s"Constructed k8s Job ${job.workerId()}\n") |
56 | 81 |
|
| 82 | + val execution = Future { |
| 83 | + val created_kjob = client.batch().jobs().create(kjob) |
| 84 | + logger.info(s"Created k8s Job ${created_kjob.getMetadata().getUid()}") |
| 85 | + logger.info(s"the status at creation time is ${created_kjob.getStatus().toString()}") |
| 86 | + // FIXME: use the given timeout value |
| 87 | + val ended_kjob = client.batch().jobs().withName(job.workerId()) |
| 88 | + .waitUntilCondition(j => (j.getStatus().getFailed() > 0 || j.getStatus().getSucceeded() > 0), |
| 89 | + 5, TimeUnit.MINUTES ); |
| 90 | + () |
| 91 | + }.andThen { |
| 92 | + case r => |
| 93 | + val foo_kjob = client.batch().jobs().withName(job.workerId()).get() |
| 94 | + logger.info(s"k8s Job ${foo_kjob.getMetadata().getUid()} status ${foo_kjob.getStatus().toString()}") |
| 95 | + Future {} |
| 96 | + } |
| 97 | + execution |
| 98 | + } |
57 | 99 | } |
0 commit comments