/*- * -\-\- * Helios Services * -- * Copyright (C) 2016 Spotify AB * -- * 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 com.spotify.helios.agent; import static com.google.common.base.Preconditions.checkNotNull; import com.spotify.docker.client.DockerClient; import com.spotify.docker.client.DockerHost; import com.spotify.helios.common.descriptors.Job; import com.spotify.helios.common.descriptors.TaskStatus; import com.spotify.helios.serviceregistration.ServiceRegistrar; import com.spotify.helios.servicescommon.statistics.SupervisorMetrics; import java.io.File; import java.util.List; import java.util.Map; /** * Creates job supervisors. * * @see Supervisor */ public class SupervisorFactory { private final AgentModel model; private final DockerClient dockerClient; private final String namespace; private final Map<String, String> envVars; private final ServiceRegistrar registrar; private final List<ContainerDecorator> containerDecorators; private final DockerHost dockerHost; private final String host; private final SupervisorMetrics metrics; private final String defaultRegistrationDomain; private final List<String> dns; private final boolean agentRunningInContainer; public SupervisorFactory(final AgentModel model, final DockerClient dockerClient, final Map<String, String> envVars, final ServiceRegistrar registrar, final List<ContainerDecorator> containerDecorators, final DockerHost dockerHost, final String host, final SupervisorMetrics supervisorMetrics, final String namespace, final String defaultRegistrationDomain, final List<String> dns) { this.dockerClient = dockerClient; this.namespace = namespace; this.model = checkNotNull(model, "model"); this.envVars = checkNotNull(envVars, "envVars"); this.registrar = registrar; this.containerDecorators = containerDecorators; this.dockerHost = dockerHost; this.host = host; this.metrics = supervisorMetrics; this.defaultRegistrationDomain = checkNotNull(defaultRegistrationDomain, "defaultRegistrationDomain"); this.dns = checkNotNull(dns, "dns"); this.agentRunningInContainer = checkIfAgentRunningInContainer(); } private static boolean checkIfAgentRunningInContainer() { return new File("/", ".dockerenv").exists(); } /** * Create a new application container. * @param job The job definition. * @param existingContainerId ID of existing container. * @param ports The ports. * @param listener The listener. * @return A new container. */ public Supervisor create(final Job job, final String existingContainerId, final Map<String, Integer> ports, final Supervisor.Listener listener) { final RestartPolicy policy = RestartPolicy.newBuilder().build(); final TaskConfig taskConfig = TaskConfig.builder() .host(host) .job(job) .ports(ports) .envVars(envVars) .containerDecorators(containerDecorators) .namespace(namespace) .defaultRegistrationDomain(defaultRegistrationDomain) .dns(dns) .build(); final TaskStatus.Builder taskStatus = TaskStatus.newBuilder() .setJob(job) .setEnv(taskConfig.containerEnv()) .setPorts(taskConfig.ports()); final StatusUpdater statusUpdater = new DefaultStatusUpdater(model, taskStatus); final FlapController flapController = FlapController.create(); final TaskMonitor taskMonitor = new TaskMonitor(job.getId(), flapController, statusUpdater); final HealthChecker healthChecker = HealthCheckerFactory.create( taskConfig, dockerClient, dockerHost, agentRunningInContainer); final TaskRunnerFactory runnerFactory = TaskRunnerFactory.builder() .config(taskConfig) .registrar(registrar) .dockerClient(dockerClient) .healthChecker(healthChecker) .listener(taskMonitor) .build(); return Supervisor.newBuilder() .setJob(job) .setExistingContainerId(existingContainerId) .setDockerClient(dockerClient) .setRestartPolicy(policy) .setMetrics(metrics) .setListener(listener) .setRunnerFactory(runnerFactory) .setStatusUpdater(statusUpdater) .setMonitor(taskMonitor) .build(); } }