From 174640195e3e6df8ff1b74b3c99562551a73679b Mon Sep 17 00:00:00 2001 From: Benno Evers Date: Thu, 12 Oct 2017 18:04:25 +0200 Subject: [PATCH 1/5] Don't kill executors who send a TASK_STARTING update. (#860) --- .../mesos/chronos/scheduler/mesos/MesosJobFramework.scala | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosJobFramework.scala b/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosJobFramework.scala index 9bf392a97..d357ea576 100644 --- a/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosJobFramework.scala +++ b/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosJobFramework.scala @@ -205,10 +205,7 @@ class MesosJobFramework @Inject()( val (jobName, _, _, _) = TaskUtils.parseTaskId(taskStatus.getTaskId.getValue) taskStatus.getState match { - case TaskState.TASK_RUNNING => - scheduler.handleStartedTask(taskStatus) - updateRunningTask(jobName, taskStatus) - case TaskState.TASK_STAGING => + case TaskState.TASK_RUNNING | TaskState.TASK_STAGING | TaskState.TASK_STARTING => scheduler.handleStartedTask(taskStatus) updateRunningTask(jobName, taskStatus) case _ => From 6c8f15cf45fd14d9a210152b12ce4b84199db095 Mon Sep 17 00:00:00 2001 From: Alexander Rukletsov Date: Fri, 8 Dec 2017 15:02:19 +0100 Subject: [PATCH 2/5] Update 2.5.1 changelog. --- changelog.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index f9b7df3e9..3044f06eb 100644 --- a/changelog.md +++ b/changelog.md @@ -1,3 +1,8 @@ +## Changes from 2.5.0 to 2.5.1 + +### Correctly handle `TASK_STARTING` status updates. + + ## Changes from 2.4.0 to 2.5.0 ### Highlights of this Release @@ -24,7 +29,7 @@ Check the [REST API documentation](https://mesos.github.io/chronos/docs/api.html #### Changed the default framework name The framework name doesn't include the version number anymore. -#### New API endpoints +#### New API endpoints The new `/scheduler/leader` endpoint makes it possible to get the current leader. It is now possible to mark a job as successful via the `/scheduler/job/success` API endpoint. From 05d304cbacad4e4700ae320db0211275a5db0329 Mon Sep 17 00:00:00 2001 From: Alexander Rukletsov Date: Fri, 8 Dec 2017 14:54:42 +0100 Subject: [PATCH 3/5] Set version to 2.5.1. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 77b8d2f72..062fea606 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.apache.mesos chronos - 2.5.0 + 2.5.1 2012 From d350f67717d92a39b811b15610f66a85d90788ac Mon Sep 17 00:00:00 2001 From: vixns Date: Fri, 23 Dec 2016 15:30:53 +0100 Subject: [PATCH 4/5] cherry pick the cni support out of chronos 3.0.2 --- docs/docs/api.md | 96 +++++++++++++++++++ .../chronos/scheduler/jobs/Containers.scala | 45 ++++++++- .../mesos/chronos/scheduler/jobs/Jobs.scala | 6 +- .../mesos/chronos/scheduler/jobs/Label.scala | 25 +++++ .../scheduler/mesos/MesosTaskBuilder.scala | 63 ++++++++++-- .../mesos/chronos/utils/JobDeserializer.scala | 72 ++++++++++++-- .../mesos/chronos/utils/JobSerializer.scala | 67 ++++++++++++- .../chronos/scheduler/api/SerDeTest.scala | 23 +++-- .../mesos/MesosTaskBuilderSpec.scala | 22 +++-- 9 files changed, 381 insertions(+), 38 deletions(-) create mode 100644 src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Label.scala diff --git a/docs/docs/api.md b/docs/docs/api.md index aa049a8c1..77adedee7 100644 --- a/docs/docs/api.md +++ b/docs/docs/api.md @@ -17,6 +17,8 @@ All examples in this section assume that you've found a running leader at `chron - [Adding a Scheduled Job](#adding-a-scheduled-job) - [Adding a Dependent Job](#adding-a-dependent-job) - [Adding a Docker Job](#adding-a-docker-job) +- [Adding a Containerized Job](#adding-a-containerized-job) +- [Using External Volumes](#using-external-volumes) - [Updating Task Progress](#updating-task-progress) - [Describing the Dependency Graph](#describing-the-dependency-graph) - [Asynchronous Jobs](#asynchronous-jobs) @@ -26,6 +28,7 @@ All examples in this section assume that you've found a running leader at `chron - [Constraints](#constraints) + ## Leaders When you have multiple Chronos nodes running, only one of them will be elected as the leader. @@ -278,6 +281,99 @@ There is also support for passing in arbitrary docker config options. } ``` +## Adding a Containerized Job + +A containerized job takes the same format as a scheduled job or a dependency job and runs on a Mesos container. +To configure it, an additional `container` argument is required, which contains a type (required), an image (required), a network name (optional), mounted volumes (optional) and whether Mesos should always pull the latest image before executing or not (optional). + +```json +{ + "container": { + "type": "MESOS", + "forcePullImage": true, + "image": "debian", + "networkInfos": [ + { + "name": "mynet" + } + ], + "volumes": [ + { + "containerPath": "/var/log/", + "hostPath": "/logs/", + "mode": "RW" + } + } + ] + } +} +``` +## Using External Volumes + +Docker and Mesos Containerized jobs can use external volumes, typically volumes mounted using docker volume plugins. +To configure it, do not add a `hostPath` argument, instead add an `external` argument, which contain a `name`, `provider`, and `options` (optional). + +```json +"volumes": [ + { + "mode": "RW", + "containerPath": "/tmp", + "external": { + "name": "test", + "provider": "local-persist", + "options": [ + { + "key": "mountpoint", + "value": "/tmp/test" + } + ] + } + } +] +``` + +Here is a more elaborate example with a Mesos container, a network name, a mounted and an external volumes. +```json +{ + "container": { + "type": "MESOS", + "forcePullImage": true, + "image": "debian", + "networkInfos": [ + { + "name": "mynet", + "labels": [ + { + "key": "service", + "value": "test" + } + ] + } + ], + "volumes": [ + { + "containerPath": "/var/log/", + "hostPath": "/logs/", + "mode": "RW" + }, + { + "mode": "RW", + "containerPath": "/tmp", + "external": { + "name": "test", + "provider": "local-persist", + "options": [ + { + "key": "mountpoint", + "value": "/tmp/test" + } + ] + } + } + ] + } +} +``` ## Updating Task Progress Task progress can be updated by providing the number of additional elements processed. This will increment the existing count of elements processed. diff --git a/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Containers.scala b/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Containers.scala index 0373fff67..a5bd6d2bc 100644 --- a/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Containers.scala +++ b/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Containers.scala @@ -12,21 +12,58 @@ object VolumeMode extends Enumeration { object NetworkMode extends Enumeration { type NetworkMode = Value - // Bridged and Host - val BRIDGE, HOST = Value + // Bridged, Host and USER + val BRIDGE, HOST, USER = Value +} + +object ContainerType extends Enumeration { + type ContainerType = Value + + // Docker, Mesos + val DOCKER, MESOS = Value +} + + +object ProtocolType extends Enumeration { + type ProtocolType = Value + + val IPv4, IPv6 = Value } import org.apache.mesos.chronos.scheduler.jobs.NetworkMode._ import org.apache.mesos.chronos.scheduler.jobs.VolumeMode._ +import org.apache.mesos.chronos.scheduler.jobs.ContainerType._ +import org.apache.mesos.chronos.scheduler.jobs.ProtocolType._ + +case class ExternalVolume( + @JsonProperty name: String, + @JsonProperty provider: String, + @JsonProperty options: Seq[Parameter]) case class Volume( @JsonProperty hostPath: Option[String], @JsonProperty containerPath: String, - @JsonProperty mode: Option[VolumeMode]) + @JsonProperty mode: Option[VolumeMode], + @JsonProperty external: Option[ExternalVolume]) + +case class PortMapping( + @JsonProperty hostPort: Int, + @JsonProperty containerPort: Int, + @JsonProperty protocol: Option[String]) + +case class Network( + @JsonProperty name: String, + @JsonProperty protocol: Option[ProtocolType], + @JsonProperty labels: Seq[Label], + @JsonProperty portMappings: Seq[PortMapping]) -case class DockerContainer( +case class Container( @JsonProperty image: String, + @JsonProperty `type`: ContainerType = ContainerType.DOCKER, @JsonProperty volumes: Seq[Volume], @JsonProperty parameters: Seq[Parameter], @JsonProperty network: NetworkMode = NetworkMode.HOST, + // DEPRECATED, "networkName" will be removed in a future version. + @JsonProperty networkName: Option[String], + @JsonProperty networkInfos: Seq[Network], @JsonProperty forcePullImage: Boolean = false) diff --git a/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Jobs.scala b/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Jobs.scala index 2c1238d99..1045ae02c 100644 --- a/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Jobs.scala +++ b/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Jobs.scala @@ -72,7 +72,7 @@ trait BaseJob { def runAsUser: String = "" - def container: DockerContainer = null + def container: Container = null def environmentVariables: Seq[EnvironmentVariable] = List() @@ -114,7 +114,7 @@ case class ScheduleBasedJob( @JsonProperty override val fetch: Seq[Fetch] = List(), @JsonProperty override val highPriority: Boolean = false, @JsonProperty override val runAsUser: String = "", - @JsonProperty override val container: DockerContainer = null, + @JsonProperty override val container: Container = null, @JsonProperty scheduleTimeZone: String = "", @JsonProperty override val environmentVariables: Seq[EnvironmentVariable] = List(), @JsonProperty override val shell: Boolean = true, @@ -152,7 +152,7 @@ case class DependencyBasedJob( @JsonProperty override val fetch: Seq[Fetch] = List(), @JsonProperty override val highPriority: Boolean = false, @JsonProperty override val runAsUser: String = "", - @JsonProperty override val container: DockerContainer = null, + @JsonProperty override val container: Container = null, @JsonProperty override val environmentVariables: Seq[EnvironmentVariable] = List(), @JsonProperty override val shell: Boolean = true, @JsonProperty override val arguments: Seq[String] = List(), diff --git a/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Label.scala b/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Label.scala new file mode 100644 index 000000000..0a3483ae9 --- /dev/null +++ b/src/main/scala/org/apache/mesos/chronos/scheduler/jobs/Label.scala @@ -0,0 +1,25 @@ +package org.apache.mesos.chronos.scheduler.jobs + +import org.apache.mesos.{Protos => mesos} + +/** + * Represents an environment variable definition for the job + */ +case class Label( + key: String, + value: String) { + + def toProto(): mesos.Label = + mesos.Label.newBuilder + .setKey(key) + .setValue(value) + .build +} + +object Label { + def apply(proto: mesos.Label): Label = + Label( + proto.getKey, + proto.getValue + ) +} diff --git a/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilder.scala b/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilder.scala index 80d9a1bc2..4fb76628d 100644 --- a/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilder.scala +++ b/src/main/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilder.scala @@ -11,6 +11,8 @@ import com.google.protobuf.ByteString import org.apache.mesos.Protos.ContainerInfo.DockerInfo import org.apache.mesos.Protos.Environment.Variable import org.apache.mesos.Protos._ +import org.apache.mesos.chronos.scheduler.config.SchedulerConfiguration +import org.apache.mesos.chronos.scheduler.jobs.{BaseJob, ContainerType, Fetch, TaskUtils} import scala.collection.JavaConverters._ import scala.collection.Map @@ -173,16 +175,63 @@ class MesosTaskBuilder @Inject()(val conf: SchedulerConfiguration) { v.mode.map { m => volumeBuilder.setMode(Volume.Mode.valueOf(m.toString.toUpperCase)) } + v.external.foreach { e => + volumeBuilder.setSource(Volume.Source.newBuilder() + .setType(Volume.Source.Type.DOCKER_VOLUME) + .setDockerVolume(Volume.Source.DockerVolume.newBuilder() + .setDriver(e.provider) + .setName(e.name) + .setDriverOptions(Parameters.newBuilder() + .addAllParameter(e.options.map(_.toProto()).asJava).build() + ).build() + ).build() + ).build() + } volumeBuilder.build() }.foreach(builder.addVolumes) - builder.setType(ContainerInfo.Type.DOCKER) - builder.setDocker(DockerInfo.newBuilder() - .setImage(job.container.image) - .setNetwork(DockerInfo.Network.valueOf(job.container.network.toString.toUpperCase)) - .setForcePullImage(job.container.forcePullImage) - .addAllParameters(job.container.parameters.map(_.toProto).asJava) - .build()).build + + job.container.`type` match { + case ContainerType.DOCKER => + builder.setType(ContainerInfo.Type.DOCKER) + builder.setDocker(DockerInfo.newBuilder() + .setImage(job.container.image) + .setNetwork(DockerInfo.Network.valueOf(job.container.network.toString.toUpperCase)) + .setForcePullImage(job.container.forcePullImage) + .addAllParameters(job.container.parameters.map(_.toProto()).asJava) + .build()) + case ContainerType.MESOS => + builder.setType(ContainerInfo.Type.MESOS) + builder.setMesos(ContainerInfo.MesosInfo.newBuilder() + .setImage(Image.newBuilder() + // TODO add APPC image support + .setType(Image.Type.DOCKER) + .setDocker(Image.Docker.newBuilder() + .setName(job.container.image) + // TODO add setCredential + .build()) + .setCached(!job.container.forcePullImage) + .build()) + .build()) + } + job.container.networkName.foreach { + n => builder.addNetworkInfos(NetworkInfo.newBuilder() + .setName(n).build() + ) + } + + job.container.networkInfos.foreach { + n => builder.addNetworkInfos(NetworkInfo.newBuilder() + .setName(n.name) + .setLabels(Labels.newBuilder() + .addAllLabels(n.labels.map(_.toProto()).asJava).build() + ) + // TODO add protocol, portMappings, requires mesos >= 1.1.0 + .build() + ) + } + + builder.build } private def appendExecutorData(taskInfo: TaskInfo.Builder, job: BaseJob, environment: Environment.Builder, uriProtos: Seq[CommandInfo.URI]) { diff --git a/src/main/scala/org/apache/mesos/chronos/utils/JobDeserializer.scala b/src/main/scala/org/apache/mesos/chronos/utils/JobDeserializer.scala index 979336693..77eab0b82 100644 --- a/src/main/scala/org/apache/mesos/chronos/utils/JobDeserializer.scala +++ b/src/main/scala/org/apache/mesos/chronos/utils/JobDeserializer.scala @@ -144,7 +144,7 @@ class JobDeserializer extends JsonDeserializer[BaseJob] { } } - var environmentVariables = scala.collection.mutable.ListBuffer[EnvironmentVariable]() + val environmentVariables = scala.collection.mutable.ListBuffer[EnvironmentVariable]() if (node.has("environmentVariables")) { node.get("environmentVariables").elements().map { case node: ObjectNode => @@ -160,8 +160,8 @@ class JobDeserializer extends JsonDeserializer[BaseJob] { if (node.has("runAsUser") && node.get("runAsUser") != null) node.get("runAsUser").asText else JobDeserializer.config.user() - var container: DockerContainer = null - if (node.has("container")) { + var container: Container = null + if (node.has("container") && node.get("container").has("image")) { val containerNode = node.get("container") val networkMode = if (containerNode.has("network") && containerNode.get("network") != null) @@ -179,7 +179,23 @@ class JobDeserializer extends JsonDeserializer[BaseJob] { val mode = if (node.has("mode")) Option(VolumeMode.withName(node.get("mode").asText.toUpperCase)) else None - Volume(hostPath, node.get("containerPath").asText, mode) + + val externalVolumeOptions = scala.collection.mutable.ListBuffer[Parameter]() + if(node.has("external") && node.get("external").has("options")) { + node.get("external").get("options").elements().map { + case node: ObjectNode => + Parameter(node.get("key").asText(), node.get("value").asText) + }.foreach(externalVolumeOptions.add) + } + val external = + if (node.has("external")) Option(ExternalVolume( + node.get("external").get("name").asText, + node.get("external").get("provider").asText, + externalVolumeOptions + )) + else None + + Volume(hostPath, node.get("containerPath").asText, mode, external) }.foreach(volumes.add) } @@ -188,7 +204,51 @@ class JobDeserializer extends JsonDeserializer[BaseJob] { Try(containerNode.get("forcePullImage").asText.toBoolean).getOrElse(false) else false - var parameters = scala.collection.mutable.ListBuffer[Parameter]() + val containerType = + if (containerNode.has("type") && containerNode.get("type") != null) + ContainerType.withName(containerNode.get("type").asText.toUpperCase) + else ContainerType.DOCKER + + val networkName = + if (containerNode.has("networkName") && containerNode.get("networkName") != null) + Option(containerNode.get("networkName").asText) + else None + + val networks = scala.collection.mutable.ListBuffer[Network]() + if (containerNode.has("networkInfos")) { + containerNode.get("networkInfos").elements().map { + case node: ObjectNode => + val name = node.get("name").asText() + val protocol = + if (node.has("protocol") && node.get("protocol") != null) + Option(ProtocolType.withName(node.get("protocol").asText)) + else None + val labels = scala.collection.mutable.ListBuffer[Label]() + if(node.has("labels")) { + node.get("labels").elements().map { + case node: ObjectNode => + Label(node.get("key").asText(), node.get("value").asText) + }.foreach(labels.add) + } + val portMappings = scala.collection.mutable.ListBuffer[PortMapping]() + if(node.has("portMappings")) { + node.get("portMappings").elements().map { + case pm: ObjectNode => + val hostPort = pm.get("hostPort").asInt() + val containerPort = pm.get("containerPort").asInt() + val protocol = + if(pm.has("protocol") && pm.get("protocol") != null) + Option(pm.get("protocol").asText()) + else None + PortMapping(hostPort, containerPort, protocol) + }.foreach(portMappings.add) + } + + Network(name, protocol, labels, portMappings) + }.foreach(networks.add) + } + + val parameters = scala.collection.mutable.ListBuffer[Parameter]() if (containerNode.has("parameters")) { containerNode.get("parameters").elements().map { case node: ObjectNode => @@ -196,7 +256,7 @@ class JobDeserializer extends JsonDeserializer[BaseJob] { }.foreach(parameters.add) } - container = DockerContainer(containerNode.get("image").asText, volumes, parameters, networkMode, forcePullImage) + container = Container(containerNode.get("image").asText, containerType, volumes, parameters, networkMode, networkName, networks, forcePullImage) } val constraints = scala.collection.mutable.ListBuffer[Constraint]() diff --git a/src/main/scala/org/apache/mesos/chronos/utils/JobSerializer.scala b/src/main/scala/org/apache/mesos/chronos/utils/JobSerializer.scala index 4ef3e6147..2ee43025c 100644 --- a/src/main/scala/org/apache/mesos/chronos/utils/JobSerializer.scala +++ b/src/main/scala/org/apache/mesos/chronos/utils/JobSerializer.scala @@ -129,13 +129,56 @@ class JobSerializer extends JsonSerializer[BaseJob] { if (baseJob.container != null) { json.writeFieldName("container") json.writeStartObject() - // TODO: Handle more container types when added. json.writeFieldName("type") - json.writeString("docker") + json.writeString(baseJob.container.`type`.toString) json.writeFieldName("image") json.writeString(baseJob.container.image) json.writeFieldName("network") json.writeString(baseJob.container.network.toString) + baseJob.container.networkName.foreach { + networkName => + json.writeFieldName("networkName") + json.writeString(networkName) + } + json.writeFieldName("networkInfos") + json.writeStartArray() + baseJob.container.networkInfos.foreach { n => + json.writeStartObject() + json.writeFieldName("name") + json.writeString(n.name) + n.protocol.foreach { p => + json.writeFieldName("protocol") + json.writeString(p.toString) + } + json.writeFieldName("labels") + json.writeStartArray() + n.labels.foreach { label => + json.writeStartObject() + json.writeFieldName("key") + json.writeString(label.key) + json.writeFieldName("value") + json.writeString(label.value) + json.writeEndObject() + } + json.writeEndArray() + json.writeFieldName("portMappings") + json.writeStartArray() + n.portMappings.foreach{ p => + json.writeStartObject() + json.writeFieldName("hostPort") + json.writeString(p.hostPort.toString) + json.writeFieldName("containerPort") + json.writeString(p.containerPort.toString) + p.protocol.foreach { protocol => + json.writeFieldName("protocol") + json.writeString(protocol) + } + json.writeEndObject() + } + json.writeEndArray() + json.writeEndObject() + } + json.writeEndArray() json.writeFieldName("volumes") json.writeStartArray() baseJob.container.volumes.foreach { v => @@ -150,6 +193,26 @@ class JobSerializer extends JsonSerializer[BaseJob] { json.writeFieldName("mode") json.writeString(mode.toString) } + v.external.foreach { external => + json.writeFieldName("external") + json.writeStartObject() + json.writeFieldName("name") + json.writeString(external.name) + json.writeFieldName("provider") + json.writeString(external.provider) + json.writeFieldName("options") + json.writeStartArray() + external.options.foreach { o => + json.writeStartObject() + json.writeFieldName("key") + json.writeString(o.key) + json.writeFieldName("value") + json.writeString(o.value) + json.writeEndObject() + } + json.writeEndArray() + json.writeEndObject() + } json.writeEndObject() } json.writeEndArray() diff --git a/src/test/scala/org/apache/mesos/chronos/scheduler/api/SerDeTest.scala b/src/test/scala/org/apache/mesos/chronos/scheduler/api/SerDeTest.scala index 5bdc54ccc..8426623fd 100644 --- a/src/test/scala/org/apache/mesos/chronos/scheduler/api/SerDeTest.scala +++ b/src/test/scala/org/apache/mesos/chronos/scheduler/api/SerDeTest.scala @@ -1,6 +1,7 @@ package org.apache.mesos.chronos.scheduler.api import org.apache.mesos.chronos.scheduler.jobs.constraints.{EqualsConstraint, LikeConstraint, UnlikeConstraint} +import org.apache.mesos.chronos.scheduler.jobs.{DependencyBasedJob, Container, EnvironmentVariable, ScheduleBasedJob, _} import org.apache.mesos.chronos.utils.{JobDeserializer, JobSerializer} import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.databind.module.SimpleModule @@ -26,15 +27,20 @@ class SerDeTest extends SpecificationWithJUnit { ) val volumes = Seq( - Volume(Option("/host/dir"), "container/dir", Option(VolumeMode.RO)), - Volume(None, "container/dir", None) + Volume(Option("/host/dir"), "container/dir", Option(VolumeMode.RO), None), + Volume(None, "container/dir", None, None) + ) + + val networks = Seq( + Network("testnet", Option(ProtocolType.IPv4), Seq(), Seq()), + Network("testnet2", Option(ProtocolType.IPv4), Seq(Label("testlabel", "testvalue")), Seq()) ) val forcePullImage = false val parameters = scala.collection.mutable.ListBuffer[Parameter]() - val container = DockerContainer("dockerImage", volumes, parameters, NetworkMode.BRIDGE, forcePullImage) + val container = Container("dockerImage", ContainerType.DOCKER, volumes, parameters, NetworkMode.BRIDGE, None, networks, forcePullImage) val arguments = Seq( "-testOne" @@ -74,14 +80,19 @@ class SerDeTest extends SpecificationWithJUnit { ) val volumes = Seq( - Volume(Option("/host/dir"), "container/dir", Option(VolumeMode.RW)), - Volume(None, "container/dir", None) + Volume(Option("/host/dir"), "container/dir", Option(VolumeMode.RW), None), + Volume(None, "container/dir", None, None) + ) + + val networks = Seq( + Network("testnet", Option(ProtocolType.IPv4), Seq(), Seq()), + Network("testnet2", Option(ProtocolType.IPv4), Seq(Label("testlabel", "testvalue")), Seq()) ) val forcePullImage = true val parameters = scala.collection.mutable.ListBuffer[Parameter]() - val container = DockerContainer("dockerImage", volumes, parameters, NetworkMode.HOST, forcePullImage) + val container = Container("dockerImage", ContainerType.DOCKER, volumes, parameters, NetworkMode.HOST, None, networks, forcePullImage) val arguments = Seq( "-testOne" diff --git a/src/test/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilderSpec.scala b/src/test/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilderSpec.scala index e4c949051..4b422416c 100644 --- a/src/test/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilderSpec.scala +++ b/src/test/scala/org/apache/mesos/chronos/scheduler/mesos/MesosTaskBuilderSpec.scala @@ -3,14 +3,11 @@ package org.apache.mesos.chronos.scheduler.mesos import scala.collection.JavaConversions._ import org.apache.mesos.Protos._ import org.apache.mesos.chronos.scheduler.config.SchedulerConfiguration -import org.apache.mesos.chronos.scheduler.jobs.Parameter -import org.apache.mesos.chronos.scheduler.jobs.Volume -import org.apache.mesos.chronos.scheduler.jobs._ -import org.apache.mesos.chronos.scheduler.jobs.constraints.{LikeConstraint, EqualsConstraint} -import org.joda.time.Minutes +import org.apache.mesos.chronos.scheduler.jobs.{Label, Parameter, Volume, _} +import org.apache.mesos.chronos.scheduler.jobs.constraints.{EqualsConstraint, LikeConstraint} import org.specs2.mock.Mockito import org.specs2.mutable.SpecificationWithJUnit - +import org.joda.time.Minutes class MesosTaskBuilderSpec extends SpecificationWithJUnit with Mockito { @@ -27,13 +24,18 @@ class MesosTaskBuilderSpec extends SpecificationWithJUnit with Mockito { val job = { val volumes = Seq( - Volume(Option("/host/dir"), "container/dir", Option(VolumeMode.RW)), - Volume(None, "container/dir", None) + Volume(Option("/host/dir"), "container/dir", Option(VolumeMode.RW), None), + Volume(None, "container/dir", None, None) + ) + + val networks = Seq( + Network("testnet", None, Seq(), Seq()), + Network("testnet", None, Seq(Label("testlabel", "testvalue")), Seq()) ) - var parameters = scala.collection.mutable.ListBuffer[Parameter]() + val parameters = scala.collection.mutable.ListBuffer[Parameter]() - val container = DockerContainer("dockerImage", volumes, parameters, NetworkMode.HOST, true) + val container = Container("dockerImage", ContainerType.DOCKER, volumes, parameters, NetworkMode.HOST, None, networks, forcePullImage = true) val constraints = Seq( EqualsConstraint("rack", "rack-1"), From 8c3ca380589b5c3fc00dde7418c43e9155fdc0ce Mon Sep 17 00:00:00 2001 From: Eric Meaney Date: Fri, 31 May 2019 14:21:54 -0500 Subject: [PATCH 5/5] bump the minor version number --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 062fea606..bf97a3306 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.apache.mesos chronos - 2.5.1 + 2.5.2 2012