aurora-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From zma...@apache.org
Subject aurora git commit: Enable per task volume mounts via scheduler API
Date Mon, 31 Oct 2016 23:15:44 GMT
Repository: aurora
Updated Branches:
  refs/heads/master 2a8c667ec -> 13d48619e


Enable per task volume mounts via scheduler API

This allows users to specify volume mounts for tasks using the unified
containerizer if the operator permits them. This is analogous to enabling docker
parameters per task and using the `--volume` parameter.

This does not include the needed DSL changes or an e2e test which will be in a
subsequent diff.

Bugs closed: AURORA-1107

Reviewed at https://reviews.apache.org/r/52588/


Project: http://git-wip-us.apache.org/repos/asf/aurora/repo
Commit: http://git-wip-us.apache.org/repos/asf/aurora/commit/13d48619
Tree: http://git-wip-us.apache.org/repos/asf/aurora/tree/13d48619
Diff: http://git-wip-us.apache.org/repos/asf/aurora/diff/13d48619

Branch: refs/heads/master
Commit: 13d48619ef20c6e36c6477856059c57114329b4c
Parents: 2a8c667
Author: Zameer Manji <zmanji@apache.org>
Authored: Mon Oct 31 16:11:49 2016 -0700
Committer: Zameer Manji <zmanji@apache.org>
Committed: Mon Oct 31 16:11:49 2016 -0700

----------------------------------------------------------------------
 RELEASE-NOTES.md                                |  3 ++
 .../thrift/org/apache/aurora/gen/api.thrift     |  2 +
 docs/reference/scheduler-configuration.md       | 20 ++++++--
 .../apache/aurora/scheduler/app/AppModule.java  |  8 ++-
 .../aurora/scheduler/base/TaskTestUtil.java     |  1 +
 .../configuration/ConfigurationManager.java     | 17 ++++++-
 .../scheduler/mesos/MesosTaskFactory.java       |  8 +++
 .../aurora/scheduler/storage/db/DbStorage.java  |  5 ++
 .../scheduler/storage/db/TaskConfigManager.java |  8 ++-
 .../scheduler/storage/db/TaskConfigMapper.java  | 11 ++++
 .../V009_CreateContainerVolumesTable.java       | 53 ++++++++++++++++++++
 .../storage/db/typehandlers/TypeHandlers.java   |  1 +
 .../db/typehandlers/VolumeModeTypeHandler.java  | 23 +++++++++
 .../scheduler/storage/db/views/DbContainer.java |  6 ++-
 .../scheduler/storage/db/TaskConfigMapper.xml   | 27 ++++++++++
 .../aurora/scheduler/storage/db/schema.sql      | 17 +++++++
 .../configuration/ConfigurationManagerTest.java | 23 +++++++++
 .../mesos/MesosTaskFactoryImplTest.java         | 39 ++++++++++++++
 .../storage/AbstractTaskStoreTest.java          | 16 ++++++
 .../aurora/scheduler/thrift/Fixtures.java       |  3 +-
 .../aurora/scheduler/thrift/ThriftIT.java       |  3 +-
 21 files changed, 283 insertions(+), 11 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/RELEASE-NOTES.md
----------------------------------------------------------------------
diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md
index b050778..d89ef2f 100644
--- a/RELEASE-NOTES.md
+++ b/RELEASE-NOTES.md
@@ -7,6 +7,9 @@
 - Introduce a new `--ip` option to bind the Thermos observer to a specific rather than all
   interfaces.
 - Fix error that prevents the scheduler from being launched with `-enable_revocable_ram`.
+- The Aurora Scheduler API supports volume mounts per task for the Mesos
+  Containerizer if the scheduler is running with the `-allow_container_volumes`
+  flag.
 
 ### Deprecations and removals:
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/api/src/main/thrift/org/apache/aurora/gen/api.thrift
----------------------------------------------------------------------
diff --git a/api/src/main/thrift/org/apache/aurora/gen/api.thrift b/api/src/main/thrift/org/apache/aurora/gen/api.thrift
index 0c74665..c3ec965 100644
--- a/api/src/main/thrift/org/apache/aurora/gen/api.thrift
+++ b/api/src/main/thrift/org/apache/aurora/gen/api.thrift
@@ -203,6 +203,8 @@ union Image {
 struct MesosContainer {
   /** the optional filesystem image to use when launching this task. */
   1: optional Image image
+  /** the optional list of volumes to mount into the task. */
+  2: optional list<Volume> volumes
 }
 
 /** Describes a parameter passed to docker cli */

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/docs/reference/scheduler-configuration.md
----------------------------------------------------------------------
diff --git a/docs/reference/scheduler-configuration.md b/docs/reference/scheduler-configuration.md
index e6b19f0..8955653 100644
--- a/docs/reference/scheduler-configuration.md
+++ b/docs/reference/scheduler-configuration.md
@@ -42,6 +42,8 @@ Required flags:
 	Endpoint specification for the ZooKeeper servers.
 
 Optional flags:
+-allow_container_volumes (default false)
+	Allow passing in volumes in the job. Enabling this could pose a privilege escalation threat.
 -allow_docker_parameters (default false)
 	Allow to pass docker container parameters in the job.
 -allow_gpu_resource (default false)
@@ -56,9 +58,11 @@ Optional flags:
 	The number of worker threads to process async task operations with.
 -backup_interval (default (1, hrs))
 	Minimum interval on which to write a storage backup.
--cron_scheduler_num_threads (default 100)
+-cron_scheduler_num_threads (default 10)
 	Number of threads to use for the cron scheduler thread pool.
--cron_start_initial_backoff (default (1, secs))
+-cron_scheduling_max_batch_size (default 10) [must be > 0]
+	The maximum number of triggered cron jobs that can be processed in a batch.
+-cron_start_initial_backoff (default (5, secs))
 	Initial backoff delay while waiting for a previous cron run to be killed.
 -cron_start_max_backoff (default (1, mins))
 	Max backoff delay while waiting for a previous cron run to be killed.
@@ -100,8 +104,8 @@ Optional flags:
 	When 'framework_authentication_file' flag is set, the FrameworkInfo registered with the
mesos master will also contain the principal. This is necessary if you intend to use mesos
authorization via mesos ACLs. The default will change in a future release. Changing this value
is backwards incompatible. For details, see MESOS-703.
 -framework_failover_timeout (default (21, days))
 	Time after which a framework is considered deleted.  SHOULD BE VERY HIGH.
--framework_name (default TwitterScheduler)
-	Name used to register the Aurora framework with Mesos. Changing this value can be backwards
incompatible. For details, see MESOS-703.
+-framework_name (default Aurora)
+	Name used to register the Aurora framework with Mesos.
 -global_container_mounts (default [])
 	A comma separated list of mount points (in host:container form) to mount into all (non-mesos)
containers.
 -history_max_per_job_threshold (default 100)
@@ -150,8 +154,12 @@ Optional flags:
 	Maximum delay between attempts to schedule a PENDING tasks.
 -max_status_update_batch_size (default 1000) [must be > 0]
 	The maximum number of status updates that can be processed in a batch.
+-max_task_event_batch_size (default 300) [must be > 0]
+	The maximum number of task state change events that can be processed in a batch.
 -max_tasks_per_job (default 4000) [must be > 0]
 	Maximum number of allowed tasks in a single job.
+-max_tasks_per_schedule_attempt (default 5) [must be > 0]
+	The maximum number of tasks to pick in a single scheduling attempt.
 -max_update_instance_failures (default 20000) [must be > 0]
 	Upper limit on the number of failures allowed during a job update. This helps cap potentially
unbounded entries into storage.
 -min_offer_hold_time (default (5, mins))
@@ -200,9 +208,11 @@ Optional flags:
 	Difference between explicit and implicit reconciliation intervals intended to create a non-overlapping
task reconciliation schedule.
 -require_docker_use_executor (default true)
 	If false, Docker tasks may run without an executor (EXPERIMENTAL)
+-scheduling_max_batch_size (default 3) [must be > 0]
+	The maximum number of scheduling attempts that can be processed in a batch.
 -shiro_ini_path
 	Path to shiro.ini for authentication and authorization configuration.
--shiro_realm_modules (default [org.apache.aurora.scheduler.app.MoreModules$1@158a8276])
+-shiro_realm_modules (default [class org.apache.aurora.scheduler.http.api.security.IniShiroRealmModule])
 	Guice modules for configuring Shiro Realms.
 -sla_non_prod_metrics (default [])
 	Metric categories collected for non production tasks.

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/app/AppModule.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/app/AppModule.java b/src/main/java/org/apache/aurora/scheduler/app/AppModule.java
index c6c2a6d..e2ef9c3 100644
--- a/src/main/java/org/apache/aurora/scheduler/app/AppModule.java
+++ b/src/main/java/org/apache/aurora/scheduler/app/AppModule.java
@@ -99,6 +99,11 @@ public class AppModule extends AbstractModule {
       + "a privilege escalation threat.")
   private static final Arg<Boolean> ENABLE_MESOS_FETCHER = Arg.create(false);
 
+  @CmdLine(name = "allow_container_volumes",
+      help = "Allow passing in volumes in the job. Enabling this could pose a privilege "
+          + "escalation threat.")
+  private static final Arg<Boolean> ALLOW_CONTAINER_VOLUMES = Arg.create(false);
+
   private final ConfigurationManagerSettings configurationManagerSettings;
 
   @VisibleForTesting
@@ -113,7 +118,8 @@ public class AppModule extends AbstractModule {
         DEFAULT_DOCKER_PARAMETERS.get(),
         REQUIRE_DOCKER_USE_EXECUTOR.get(),
         allowGpuResource,
-        ENABLE_MESOS_FETCHER.get()));
+        ENABLE_MESOS_FETCHER.get(),
+        ALLOW_CONTAINER_VOLUMES.get()));
   }
 
   @Override

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java b/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java
index 3bd22a0..aba7300 100644
--- a/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java
+++ b/src/main/java/org/apache/aurora/scheduler/base/TaskTestUtil.java
@@ -85,6 +85,7 @@ public final class TaskTestUtil {
           ImmutableMultimap.of(),
           true,
           true,
+          true,
           true);
   public static final ExecutorID EXECUTOR_ID = ExecutorID.newBuilder()
       .setValue("PLACEHOLDER")

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java
b/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java
index 701f79c..f96cd7a 100644
--- a/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java
+++ b/src/main/java/org/apache/aurora/scheduler/configuration/ConfigurationManager.java
@@ -44,6 +44,7 @@ import org.apache.aurora.scheduler.resources.ResourceType;
 import org.apache.aurora.scheduler.storage.entities.IConstraint;
 import org.apache.aurora.scheduler.storage.entities.IContainer;
 import org.apache.aurora.scheduler.storage.entities.IJobConfiguration;
+import org.apache.aurora.scheduler.storage.entities.IMesosContainer;
 import org.apache.aurora.scheduler.storage.entities.IResource;
 import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
 import org.apache.aurora.scheduler.storage.entities.ITaskConstraint;
@@ -118,6 +119,7 @@ public class ConfigurationManager {
     private final boolean requireDockerUseExecutor;
     private final boolean allowGpuResource;
     private final boolean enableMesosFetcher;
+    private final boolean allowContainerVolumes;
 
     public ConfigurationManagerSettings(
         ImmutableSet<Container._Fields> allowedContainerTypes,
@@ -125,7 +127,8 @@ public class ConfigurationManager {
         Multimap<String, String> defaultDockerParameters,
         boolean requireDockerUseExecutor,
         boolean allowGpuResource,
-        boolean enableMesosFetcher) {
+        boolean enableMesosFetcher,
+        boolean allowContainerVolumes) {
 
       this.allowedContainerTypes = requireNonNull(allowedContainerTypes);
       this.allowDockerParameters = allowDockerParameters;
@@ -133,6 +136,7 @@ public class ConfigurationManager {
       this.requireDockerUseExecutor = requireDockerUseExecutor;
       this.allowGpuResource = allowGpuResource;
       this.enableMesosFetcher = enableMesosFetcher;
+      this.allowContainerVolumes = allowContainerVolumes;
     }
   }
 
@@ -234,6 +238,10 @@ public class ConfigurationManager {
   @VisibleForTesting
   static final String INVALID_EXECUTOR_CONFIG = "Executor name may not be left unset.";
 
+  @VisibleForTesting
+  static final String NO_CONTAINER_VOLUMES =
+      "This scheduler is configured to disallow container volumes.";
+
   /**
    * Check validity of and populates defaults in a task configuration.  This will return
a deep copy
    * of the provided task configuration with default configuration values applied, and configuration
@@ -373,6 +381,13 @@ public class ConfigurationManager {
       throw new TaskDescriptionException(MESOS_FETCHER_DISABLED);
     }
 
+    if (config.getContainer().isSetMesos()) {
+      IMesosContainer container = config.getContainer().getMesos();
+      if (!settings.allowContainerVolumes && !container.getVolumes().isEmpty()) {
+        throw new TaskDescriptionException(NO_CONTAINER_VOLUMES);
+      }
+    }
+
     maybeFillLinks(builder);
 
     return ITaskConfig.build(builder);

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/mesos/MesosTaskFactory.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/mesos/MesosTaskFactory.java b/src/main/java/org/apache/aurora/scheduler/mesos/MesosTaskFactory.java
index 9038c36..abbe81a 100644
--- a/src/main/java/org/apache/aurora/scheduler/mesos/MesosTaskFactory.java
+++ b/src/main/java/org/apache/aurora/scheduler/mesos/MesosTaskFactory.java
@@ -258,6 +258,13 @@ public interface MesosTaskFactory {
         ContainerInfo.MesosInfo.Builder mesosContainerBuilder =
             ContainerInfo.MesosInfo.newBuilder();
 
+        Iterable<Protos.Volume> containerVolumes = Iterables.transform(mesosContainer.getVolumes(),
+            input -> Protos.Volume.newBuilder()
+            .setMode(Protos.Volume.Mode.valueOf(input.getMode().name()))
+            .setHostPath(input.getHostPath())
+            .setContainerPath(input.getContainerPath())
+            .build());
+
         Protos.Volume volume = Protos.Volume.newBuilder()
             .setImage(imageBuilder)
             .setContainerPath(TASK_FILESYSTEM_MOUNT_POINT)
@@ -268,6 +275,7 @@ public interface MesosTaskFactory {
             .setType(ContainerInfo.Type.MESOS)
             .setMesos(mesosContainerBuilder)
             .addAllVolumes(executorSettings.getExecutorConfig(executorName).get().getVolumeMounts())
+            .addAllVolumes(containerVolumes)
             .addVolumes(volume));
       }
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java b/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
index acb4498..923e904 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/DbStorage.java
@@ -30,6 +30,7 @@ import org.apache.aurora.gen.CronCollisionPolicy;
 import org.apache.aurora.gen.JobUpdateAction;
 import org.apache.aurora.gen.JobUpdateStatus;
 import org.apache.aurora.gen.MaintenanceMode;
+import org.apache.aurora.gen.Mode;
 import org.apache.aurora.gen.ScheduleStatus;
 import org.apache.aurora.scheduler.async.AsyncModule.AsyncExecutor;
 import org.apache.aurora.scheduler.async.GatedWorkQueue;
@@ -239,6 +240,10 @@ class DbStorage extends AbstractIdleService implements Storage {
       enumValueMapper.addEnumValue("resource_types", resourceType.getValue(), resourceType.name());
     }
 
+    for (Mode mode : Mode.values()) {
+      enumValueMapper.addEnumValue("volume_modes", mode.getValue(), mode.name());
+    }
+
     createPoolMetrics();
   }
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigManager.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigManager.java b/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigManager.java
index e137e57..d2eb6aa 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigManager.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigManager.java
@@ -27,6 +27,7 @@ import org.apache.aurora.scheduler.storage.entities.IConstraint;
 import org.apache.aurora.scheduler.storage.entities.IDockerContainer;
 import org.apache.aurora.scheduler.storage.entities.IDockerImage;
 import org.apache.aurora.scheduler.storage.entities.IImage;
+import org.apache.aurora.scheduler.storage.entities.IMesosContainer;
 import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
 import org.apache.aurora.scheduler.storage.entities.IValueConstraint;
 
@@ -128,7 +129,8 @@ class TaskConfigManager {
     } else if (config.getContainer().isSetMesos()
         && config.getContainer().getMesos().isSetImage()) {
 
-      IImage image = config.getContainer().getMesos().getImage();
+      IMesosContainer container = config.getContainer().getMesos();
+      IImage image = container.getImage();
 
       switch (image.getSetField()) {
         case DOCKER:
@@ -148,6 +150,10 @@ class TaskConfigManager {
         default:
           throw new IllegalStateException("Unexpected image type: " + image.getSetField());
       }
+
+      if (!container.getVolumes().isEmpty()) {
+        configMapper.insertVolumes(configInsert.getId(), container.getVolumes());
+      }
     }
 
     return configInsert.getId();

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.java b/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.java
index 151306a..cda55c5 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.java
@@ -28,6 +28,7 @@ import org.apache.aurora.scheduler.storage.entities.IMesosFetcherURI;
 import org.apache.aurora.scheduler.storage.entities.IMetadata;
 import org.apache.aurora.scheduler.storage.entities.ITaskConfig;
 import org.apache.aurora.scheduler.storage.entities.IValueConstraint;
+import org.apache.aurora.scheduler.storage.entities.IVolume;
 import org.apache.ibatis.annotations.Param;
 
 /**
@@ -196,4 +197,14 @@ interface TaskConfigMapper extends GarbageCollectedTableMapper {
   void insertResources(
       @Param("configId") long configId,
       @Param("values") List<Pair<Integer, String>> values);
+
+  /**
+   * Inserts a task's volume mounts.
+   *
+   * @param configId Task config ID.
+   * @param volumes Volumes to insert.
+   */
+  void insertVolumes(
+      @Param("configId") long configId,
+      @Param("volumes") List<IVolume> volumes);
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/migration/V009_CreateContainerVolumesTable.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/migration/V009_CreateContainerVolumesTable.java
b/src/main/java/org/apache/aurora/scheduler/storage/db/migration/V009_CreateContainerVolumesTable.java
new file mode 100644
index 0000000..f6cd06a
--- /dev/null
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/migration/V009_CreateContainerVolumesTable.java
@@ -0,0 +1,53 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.storage.db.migration;
+
+import java.math.BigDecimal;
+
+import org.apache.ibatis.migration.MigrationScript;
+
+public class V009_CreateContainerVolumesTable implements MigrationScript {
+  @Override
+  public BigDecimal getId() {
+    return BigDecimal.valueOf(9L);
+  }
+
+  @Override
+  public String getDescription() {
+    return "Create the task_config_volumes and volume_modes tables";
+  }
+
+  @Override
+  public String getUpScript() {
+    return "CREATE TABLE IF NOT EXISTS volume_modes("
+        + "id INT PRIMARY KEY,"
+        + "name VARCHAR NOT NULL,"
+        + "UNIQUE(name)"
+        + ");"
+        + "CREATE TABLE IF NOT EXISTS task_config_volumes("
+        + "id IDENTITY,"
+        + "task_config_id BIGINT NOT NULL REFERENCES task_configs(id) ON DELETE CASCADE,"
+        + "host_path VARCHAR NOT NULL,"
+        + "container_path VARCHAR NOT NULL,"
+        + "mode INT NOT NULL REFERENCES volume_modes(id),"
+        + "UNIQUE(task_config_id)"
+        + ");";
+  }
+
+  @Override
+  public String getDownScript() {
+    return "DROP TABLE IF EXISTS volume_modes;"
+        + "DROP TABLE IF EXISTS task_config_volumes;";
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/TypeHandlers.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/TypeHandlers.java
b/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/TypeHandlers.java
index e30c387..07e8c0b 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/TypeHandlers.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/TypeHandlers.java
@@ -35,6 +35,7 @@ public final class TypeHandlers {
         .add(MaintenanceModeTypeHandler.class)
         .add(ScheduleStatusTypeHandler.class)
         .add(ResourceTypeHandler.class)
+        .add(VolumeModeTypeHandler.class)
         .build();
   }
 }

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/VolumeModeTypeHandler.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/VolumeModeTypeHandler.java
b/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/VolumeModeTypeHandler.java
new file mode 100644
index 0000000..97f65e4
--- /dev/null
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/typehandlers/VolumeModeTypeHandler.java
@@ -0,0 +1,23 @@
+/**
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.aurora.scheduler.storage.db.typehandlers;
+
+import org.apache.aurora.gen.Mode;
+
+public class VolumeModeTypeHandler extends AbstractTEnumTypeHandler<Mode> {
+  @Override
+  protected Mode fromValue(int value) {
+    return Mode.findByValue(value);
+  }
+}

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/java/org/apache/aurora/scheduler/storage/db/views/DbContainer.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/aurora/scheduler/storage/db/views/DbContainer.java b/src/main/java/org/apache/aurora/scheduler/storage/db/views/DbContainer.java
index 8d4d7ec..6a36e27 100644
--- a/src/main/java/org/apache/aurora/scheduler/storage/db/views/DbContainer.java
+++ b/src/main/java/org/apache/aurora/scheduler/storage/db/views/DbContainer.java
@@ -13,13 +13,17 @@
  */
 package org.apache.aurora.scheduler.storage.db.views;
 
+import java.util.List;
+
 import org.apache.aurora.gen.Container;
 import org.apache.aurora.gen.DockerContainer;
 import org.apache.aurora.gen.MesosContainer;
+import org.apache.aurora.gen.Volume;
 
 public final class DbContainer {
   private DockerContainer docker;
   private DbImage image;
+  private List<Volume> volumes;
 
   private DbContainer() {
   }
@@ -30,7 +34,7 @@ public final class DbContainer {
     }
 
     if (image != null) {
-      return Container.mesos(new MesosContainer().setImage(image.toThrift()));
+      return Container.mesos(new MesosContainer().setImage(image.toThrift()).setVolumes(volumes));
     }
 
     return Container.mesos(new MesosContainer());

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
b/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
index 3fce25f..97f6b80 100644
--- a/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
+++ b/src/main/resources/org/apache/aurora/scheduler/storage/db/TaskConfigMapper.xml
@@ -120,6 +120,7 @@
   <resultMap id="containerMap" type="org.apache.aurora.scheduler.storage.db.views.DbContainer">
     <association property="docker" resultMap="dockerContainerMap" />
     <association property="image" columnPrefix="image_" resultMap="imageMap" />
+    <collection property="volumes" columnPrefix="volume_" resultMap="volumeMap" notNullColumn="id"
/>
   </resultMap>
 
   <resultMap id="metadataMap" type="org.apache.aurora.gen.Metadata">
@@ -130,6 +131,11 @@
     <id column="id" />
   </resultMap>
 
+  <resultMap id="volumeMap" type="org.apache.aurora.gen.Volume">
+    <id column="id" />
+    <result property="mode" column="mode" typeHandler="org.apache.aurora.scheduler.storage.db.typehandlers.VolumeModeTypeHandler"
/>
+  </resultMap>
+
   <resultMap id="resourceMap" type="org.apache.aurora.scheduler.storage.db.views.DBResource">
     <id column="id" />
     <result property="type"
@@ -201,6 +207,10 @@
       di.tag as c_image_docker_tag,
       ai.name as c_image_appc_name,
       ai.image_id as c_image_appc_image_id,
+      v.id as c_volume_id,
+      v.host_path as c_volume_host_path,
+      v.container_path as c_volume_container_path,
+      v.mode as c_volume_mode,
       tc.id AS constraint_id,
       tc.name AS constraint_name,
       tlc.id AS constraint_l_id,
@@ -216,6 +226,7 @@
     LEFT OUTER JOIN task_config_mesos_fetcher_uris AS u ON u.task_config_id = c.id
     LEFT OUTER JOIN task_config_docker_images AS di ON di.task_config_id = c.id
     LEFT OUTER JOIN task_config_appc_images AS ai ON ai.task_config_id = c.id
+    LEFT OUTER JOIN task_config_volumes AS v ON v.task_config_id = c.id
     LEFT OUTER JOIN task_constraints AS tc ON tc.task_config_id = c.id
     LEFT OUTER JOIN limit_constraints as tlc ON tlc.constraint_id = tc.id
     LEFT OUTER JOIN value_constraints as tvc ON tvc.constraint_id = tc.id
@@ -419,6 +430,22 @@
     )
   </insert>
 
+  <insert id="insertVolumes">
+    INSERT INTO task_config_volumes (
+      task_config_id,
+      host_path,
+      container_path,
+      mode
+    ) VALUES (
+    <foreach item="volume" collection="volumes" separator="),(">
+      #{configId},
+      #{volume.hostPath},
+      #{volume.containerPath},
+      #{volume.mode, typeHandler=org.apache.aurora.scheduler.storage.db.typehandlers.VolumeModeTypeHandler}
+    </foreach>
+    )
+  </insert>
+
   <select id="selectAllRowIds" resultType="long">
     SELECT id FROM task_configs
   </select>

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/main/resources/org/apache/aurora/scheduler/storage/db/schema.sql
----------------------------------------------------------------------
diff --git a/src/main/resources/org/apache/aurora/scheduler/storage/db/schema.sql b/src/main/resources/org/apache/aurora/scheduler/storage/db/schema.sql
index e943c64..ff1623a 100644
--- a/src/main/resources/org/apache/aurora/scheduler/storage/db/schema.sql
+++ b/src/main/resources/org/apache/aurora/scheduler/storage/db/schema.sql
@@ -222,6 +222,23 @@ CREATE TABLE task_config_appc_images(
   UNIQUE(task_config_id)
 );
 
+CREATE TABLE volume_modes(
+  id INT PRIMARY KEY,
+  name VARCHAR NOT NULL,
+
+  UNIQUE(name)
+);
+
+CREATE TABLE task_config_volumes(
+  id IDENTITY,
+  task_config_id BIGINT NOT NULL REFERENCES task_configs(id) ON DELETE CASCADE,
+  host_path VARCHAR NOT NULL,
+  container_path VARCHAR NOT NULL,
+  mode INT NOT NULL REFERENCES volume_modes(id),
+
+  UNIQUE(task_config_id)
+);
+
 CREATE TABLE task_states(
   id INT PRIMARY KEY,
   name VARCHAR NOT NULL,

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java
b/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java
index db9f276..5419d7e 100644
--- a/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/configuration/ConfigurationManagerTest.java
@@ -20,19 +20,24 @@ import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableMultimap;
 import com.google.common.collect.ImmutableSet;
 
+import org.apache.aurora.gen.AppcImage;
 import org.apache.aurora.gen.Constraint;
 import org.apache.aurora.gen.Container;
 import org.apache.aurora.gen.CronCollisionPolicy;
 import org.apache.aurora.gen.DockerParameter;
 import org.apache.aurora.gen.ExecutorConfig;
 import org.apache.aurora.gen.Identity;
+import org.apache.aurora.gen.Image;
 import org.apache.aurora.gen.JobConfiguration;
 import org.apache.aurora.gen.JobKey;
 import org.apache.aurora.gen.LimitConstraint;
+import org.apache.aurora.gen.MesosContainer;
 import org.apache.aurora.gen.MesosFetcherURI;
+import org.apache.aurora.gen.Mode;
 import org.apache.aurora.gen.TaskConfig;
 import org.apache.aurora.gen.TaskConstraint;
 import org.apache.aurora.gen.ValueConstraint;
+import org.apache.aurora.gen.Volume;
 import org.apache.aurora.gen.apiConstants;
 import org.apache.aurora.scheduler.base.JobKeys;
 import org.apache.aurora.scheduler.base.TaskTestUtil;
@@ -54,6 +59,7 @@ import static org.apache.aurora.gen.test.testConstants.INVALID_IDENTIFIERS;
 import static org.apache.aurora.gen.test.testConstants.VALID_IDENTIFIERS;
 import static org.apache.aurora.scheduler.base.UserProvidedStrings.isGoodIdentifier;
 import static org.apache.aurora.scheduler.configuration.ConfigurationManager.DEDICATED_ATTRIBUTE;
+import static org.apache.aurora.scheduler.configuration.ConfigurationManager.NO_CONTAINER_VOLUMES;
 import static org.hamcrest.CoreMatchers.is;
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
@@ -122,6 +128,7 @@ public class ConfigurationManagerTest {
           ImmutableMultimap.of(),
           true,
           false,
+          true,
           false),
       TaskTestUtil.TIER_MANAGER,
       TaskTestUtil.THRIFT_BACKFILL,
@@ -133,6 +140,7 @@ public class ConfigurationManagerTest {
           ImmutableMultimap.of("foo", "bar"),
           false,
           true,
+          true,
           true),
       TaskTestUtil.TIER_MANAGER,
       TaskTestUtil.THRIFT_BACKFILL,
@@ -296,6 +304,7 @@ public class ConfigurationManagerTest {
             ImmutableMultimap.of("foo", "bar"),
             false,
             false,
+            false,
             false),
         TaskTestUtil.TIER_MANAGER,
         TaskTestUtil.THRIFT_BACKFILL,
@@ -318,6 +327,7 @@ public class ConfigurationManagerTest {
                     ImmutableMultimap.of("foo", "bar"),
                     false,
                     false,
+                    false,
                     false),
             TaskTestUtil.TIER_MANAGER,
             TaskTestUtil.THRIFT_BACKFILL,
@@ -325,6 +335,19 @@ public class ConfigurationManagerTest {
   }
 
   @Test
+  public void testContainerVolumesDisabled() throws Exception {
+    TaskConfig builder = CONFIG_WITH_CONTAINER.newBuilder();
+    MesosContainer container = new MesosContainer()
+        .setImage(Image.appc(new AppcImage("name", "id")))
+        .setVolumes(ImmutableList.of(new Volume("container", "host", Mode.RO)));
+    builder.setContainer(Container.mesos(container));
+
+    expectTaskDescriptionException(NO_CONTAINER_VOLUMES);
+
+    CONFIGURATION_MANAGER.validateAndPopulate(ITaskConfig.build(builder));
+  }
+
+  @Test
   public void testTaskLinks() throws Exception {
     TaskConfig builder = CONFIG_WITH_CONTAINER.newBuilder();
     builder.addToResources(namedPort("health"));

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
b/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
index bd052ab..234acc1 100644
--- a/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/mesos/MesosTaskFactoryImplTest.java
@@ -370,6 +370,45 @@ public class MesosTaskFactoryImplTest extends EasyMockTest {
   }
 
   @Test
+  public void testContainerVolumes() {
+    String imageName = "some-image-name";
+    String imageTag = "some-image-tag";
+    org.apache.aurora.gen.Volume volume =
+        new org.apache.aurora.gen.Volume("container", "/host", org.apache.aurora.gen.Mode.RO);
+    IAssignedTask taskWithImageAndVolumes = IAssignedTask.build(TASK.newBuilder()
+        .setTask(
+            new TaskConfig(TASK.getTask().newBuilder()
+                .setContainer(Container.mesos(
+                    new MesosContainer()
+                        .setImage(Image.docker(new DockerImage(imageName, imageTag)))
+                        .setVolumes(ImmutableList.of(volume)))))));
+
+    expect(tierManager.getTier(taskWithImageAndVolumes.getTask())).andReturn(DEV_TIER);
+    control.replay();
+
+    taskFactory = new MesosTaskFactoryImpl(config, tierManager, SERVER_INFO);
+    TaskInfo task = taskFactory.createFrom(taskWithImageAndVolumes, OFFER_THERMOS_EXECUTOR);
+
+    assertEquals(
+        ContainerInfo.newBuilder()
+            .setType(Type.MESOS)
+            .setMesos(MesosInfo.newBuilder())
+            .addVolumes(Volume.newBuilder()
+                .setContainerPath("container")
+                .setHostPath("/host")
+                .setMode(Mode.RO))
+            .addVolumes(Volume.newBuilder()
+                .setContainerPath(TASK_FILESYSTEM_MOUNT_POINT)
+                .setImage(Protos.Image.newBuilder()
+                    .setType(Protos.Image.Type.DOCKER)
+                    .setDocker(Protos.Image.Docker.newBuilder()
+                        .setName(imageName + ":" + imageTag)))
+                .setMode(Mode.RO))
+            .build(),
+        task.getExecutor().getContainer());
+  }
+
+  @Test
   public void testMetadataLabelMapping() {
     expect(tierManager.getTier(TASK.getTask())).andReturn(DEV_TIER);
     taskFactory = new MesosTaskFactoryImpl(config, tierManager, SERVER_INFO);

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/test/java/org/apache/aurora/scheduler/storage/AbstractTaskStoreTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/storage/AbstractTaskStoreTest.java
b/src/test/java/org/apache/aurora/scheduler/storage/AbstractTaskStoreTest.java
index 3d07292..80be339 100644
--- a/src/test/java/org/apache/aurora/scheduler/storage/AbstractTaskStoreTest.java
+++ b/src/test/java/org/apache/aurora/scheduler/storage/AbstractTaskStoreTest.java
@@ -51,8 +51,10 @@ import org.apache.aurora.gen.MaintenanceMode;
 import org.apache.aurora.gen.MesosContainer;
 import org.apache.aurora.gen.MesosFetcherURI;
 import org.apache.aurora.gen.Metadata;
+import org.apache.aurora.gen.Mode;
 import org.apache.aurora.gen.ScheduledTask;
 import org.apache.aurora.gen.TaskQuery;
+import org.apache.aurora.gen.Volume;
 import org.apache.aurora.scheduler.base.JobKeys;
 import org.apache.aurora.scheduler.base.Query;
 import org.apache.aurora.scheduler.base.TaskTestUtil;
@@ -192,6 +194,20 @@ public abstract class AbstractTaskStoreTest extends TearDownTestCase
{
   }
 
   @Test
+  public void testSaveWithContainerVolumes() {
+    ScheduledTask builder = TASK_B.newBuilder();
+    Image image = Image.docker(new DockerImage().setName("some-name").setTag("some-tag"));
+    List<Volume> volumes = ImmutableList.of(new Volume("container", "host", Mode.RO));
+    builder.getAssignedTask().getTask().getContainer().getMesos().setImage(image)
+        .setVolumes(volumes);
+
+    IScheduledTask task = IScheduledTask.build(builder);
+
+    saveTasks(task);
+    assertStoreContents(task);
+  }
+
+  @Test
   public void testSaveWithDockerImage() {
     ScheduledTask builder = TASK_A.newBuilder();
 

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/test/java/org/apache/aurora/scheduler/thrift/Fixtures.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/Fixtures.java b/src/test/java/org/apache/aurora/scheduler/thrift/Fixtures.java
index 95b3716..43e32ee 100644
--- a/src/test/java/org/apache/aurora/scheduler/thrift/Fixtures.java
+++ b/src/test/java/org/apache/aurora/scheduler/thrift/Fixtures.java
@@ -21,6 +21,7 @@ import java.util.UUID;
 import com.google.common.base.Function;
 import com.google.common.base.Optional;
 import com.google.common.collect.FluentIterable;
+import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Lists;
@@ -115,7 +116,7 @@ final class Fixtures {
         .setConstraints(ImmutableSet.of())
         .setMetadata(ImmutableSet.of())
         .setMesosFetcherUris(ImmutableSet.of())
-        .setContainer(Container.mesos(new MesosContainer()))
+        .setContainer(Container.mesos(new MesosContainer().setVolumes(ImmutableList.of())))
         .setResources(ImmutableSet.of(
             Resource.numCpus(1),
             Resource.ramMb(1024),

http://git-wip-us.apache.org/repos/asf/aurora/blob/13d48619/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java b/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java
index e578f5a..0119ccb 100644
--- a/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java
+++ b/src/test/java/org/apache/aurora/scheduler/thrift/ThriftIT.java
@@ -156,7 +156,8 @@ public class ThriftIT extends EasyMockTest {
         ImmutableMultimap.of(),
         false,
         true,
-        true);
+        true,
+        false);
 
     createThrift(configurationManagerSettings);
 


Mime
View raw message