/**
* 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.app;
import java.util.Set;
import javax.inject.Singleton;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableMultimap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Multimap;
import com.google.inject.AbstractModule;
import org.apache.aurora.GuiceUtils;
import org.apache.aurora.common.args.Arg;
import org.apache.aurora.common.args.CmdLine;
import org.apache.aurora.common.args.constraints.Positive;
import org.apache.aurora.common.inject.TimedInterceptor;
import org.apache.aurora.common.stats.Stats;
import org.apache.aurora.common.stats.StatsProvider;
import org.apache.aurora.common.util.Clock;
import org.apache.aurora.gen.Container;
import org.apache.aurora.gen.Container._Fields;
import org.apache.aurora.scheduler.SchedulerModule;
import org.apache.aurora.scheduler.SchedulerServicesModule;
import org.apache.aurora.scheduler.app.SchedulerMain.DriverKind;
import org.apache.aurora.scheduler.async.AsyncModule;
import org.apache.aurora.scheduler.configuration.ConfigurationManager.ConfigurationManagerSettings;
import org.apache.aurora.scheduler.events.PubsubEventModule;
import org.apache.aurora.scheduler.filter.SchedulingFilterImpl;
import org.apache.aurora.scheduler.http.JettyServerModule;
import org.apache.aurora.scheduler.mesos.SchedulerDriverModule;
import org.apache.aurora.scheduler.metadata.MetadataModule;
import org.apache.aurora.scheduler.offers.OffersModule;
import org.apache.aurora.scheduler.preemptor.PreemptorModule;
import org.apache.aurora.scheduler.pruning.PruningModule;
import org.apache.aurora.scheduler.quota.QuotaModule;
import org.apache.aurora.scheduler.reconciliation.ReconciliationModule;
import org.apache.aurora.scheduler.scheduling.SchedulingModule;
import org.apache.aurora.scheduler.sla.SlaModule;
import org.apache.aurora.scheduler.state.StateModule;
import org.apache.aurora.scheduler.stats.AsyncStatsModule;
import org.apache.aurora.scheduler.thrift.Thresholds;
import org.apache.aurora.scheduler.updater.UpdaterModule;
import org.apache.mesos.Scheduler;
import static java.util.Objects.requireNonNull;
/**
* Binding module for the aurora scheduler application.
*/
public class AppModule extends AbstractModule {
private static final int DEFAULT_MAX_TASKS_PER_JOB = 4000;
@Positive
@CmdLine(name = "max_tasks_per_job", help = "Maximum number of allowed tasks in a single job.")
public static final Arg<Integer> MAX_TASKS_PER_JOB = Arg.create(DEFAULT_MAX_TASKS_PER_JOB);
private static final int DEFAULT_MAX_UPDATE_INSTANCE_FAILURES = DEFAULT_MAX_TASKS_PER_JOB * 5;
@Positive
@CmdLine(name = "max_update_instance_failures", help = "Upper limit on the number of "
+ "failures allowed during a job update. This helps cap potentially unbounded entries into "
+ "storage.")
public static final Arg<Integer> MAX_UPDATE_INSTANCE_FAILURES = Arg.create(
DEFAULT_MAX_UPDATE_INSTANCE_FAILURES);
@CmdLine(name = "allowed_container_types",
help = "Container types that are allowed to be used by jobs.")
private static final Arg<Set<_Fields>> ALLOWED_CONTAINER_TYPES =
Arg.create(ImmutableSet.of(Container._Fields.MESOS));
@CmdLine(name = "allow_docker_parameters",
help = "Allow to pass docker container parameters in the job.")
private static final Arg<Boolean> ENABLE_DOCKER_PARAMETERS = Arg.create(false);
@CmdLine(name = "default_docker_parameters",
help = "Default docker parameters for any job that does not explicitly declare parameters.")
private static final Arg<Multimap<String, String>> DEFAULT_DOCKER_PARAMETERS =
Arg.create(ImmutableMultimap.of());
@CmdLine(name = "require_docker_use_executor",
help = "If false, Docker tasks may run without an executor (EXPERIMENTAL)")
private static final Arg<Boolean> REQUIRE_DOCKER_USE_EXECUTOR = Arg.create(true);
@CmdLine(name = "enable_mesos_fetcher", help = "Allow jobs to pass URIs "
+ "to the Mesos Fetcher. Note that enabling this feature could pose "
+ "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;
private final DriverKind kind;
@VisibleForTesting
public AppModule(ConfigurationManagerSettings configurationManagerSettings, DriverKind kind) {
this.configurationManagerSettings = requireNonNull(configurationManagerSettings);
this.kind = kind;
}
public AppModule(boolean allowGpuResource, DriverKind kind) {
this(new ConfigurationManagerSettings(
ImmutableSet.copyOf(ALLOWED_CONTAINER_TYPES.get()),
ENABLE_DOCKER_PARAMETERS.get(),
DEFAULT_DOCKER_PARAMETERS.get(),
REQUIRE_DOCKER_USE_EXECUTOR.get(),
allowGpuResource,
ENABLE_MESOS_FETCHER.get(),
ALLOW_CONTAINER_VOLUMES.get()),
kind);
}
@Override
protected void configure() {
bind(ConfigurationManagerSettings.class).toInstance(configurationManagerSettings);
bind(Thresholds.class)
.toInstance(new Thresholds(MAX_TASKS_PER_JOB.get(), MAX_UPDATE_INSTANCE_FAILURES.get()));
// Enable intercepted method timings and context classloader repair.
TimedInterceptor.bind(binder());
GuiceUtils.bindJNIContextClassLoader(binder(), Scheduler.class);
GuiceUtils.bindExceptionTrap(binder(), Scheduler.class);
bind(Clock.class).toInstance(Clock.SYSTEM_CLOCK);
install(new PubsubEventModule());
// Filter layering: notifier filter -> base impl
PubsubEventModule.bindSchedulingFilterDelegate(binder()).to(SchedulingFilterImpl.class);
bind(SchedulingFilterImpl.class).in(Singleton.class);
install(new AsyncModule());
install(new OffersModule());
install(new PruningModule());
install(new ReconciliationModule());
install(new SchedulingModule());
install(new AsyncStatsModule());
install(new MetadataModule());
install(new QuotaModule());
install(new JettyServerModule());
install(new PreemptorModule());
install(new SchedulerDriverModule(kind));
install(new SchedulerServicesModule());
install(new SchedulerModule());
install(new StateModule());
install(new SlaModule());
install(new UpdaterModule());
bind(StatsProvider.class).toInstance(Stats.STATS_PROVIDER);
}
}