From 00006f4e576e180d3c67a03cc3b1c4f0f8c4f34e Mon Sep 17 00:00:00 2001 From: HÃ¥kon Hallingstad Date: Tue, 2 Jan 2018 11:32:13 +0100 Subject: Revert "Revert "Support node admin modes"" --- .../node/admin/nodeadmin/NodeAdminConfig.java | 37 +++++++ .../hosted/node/admin/nodeadmin/NodeAdminMain.java | 115 +++++++++++++++++++++ .../node/admin/provider/NodeAdminProvider.java | 67 ++---------- .../node/admin/integrationTests/DockerMock.java | 3 + 4 files changed, 164 insertions(+), 58 deletions(-) create mode 100644 node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminConfig.java create mode 100644 node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminMain.java (limited to 'node-admin') diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminConfig.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminConfig.java new file mode 100644 index 00000000000..9caf1307aa4 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminConfig.java @@ -0,0 +1,37 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.node.admin.nodeadmin; + +import com.fasterxml.jackson.annotation.JsonIgnoreProperties; +import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.databind.ObjectMapper; + +import java.io.File; +import java.io.IOException; +import java.util.logging.Logger; + +@JsonIgnoreProperties(ignoreUnknown = true) +public class NodeAdminConfig { + private static final Logger logger = Logger.getLogger(NodeAdminConfig.class.getName()); + private static final ObjectMapper mapper = new ObjectMapper(); + + enum Mode { + tenant, + config_server_host + } + + @JsonProperty("mode") + public Mode mode = Mode.tenant; + + public static NodeAdminConfig fromFile(File file) { + if (!file.exists()) { + return new NodeAdminConfig(); + } + + try { + return mapper.readValue(file, NodeAdminConfig.class); + } catch (IOException e) { + throw new RuntimeException("Failed to read " + file + " as a " + + NodeAdminConfig.class.getName(), e); + } + } +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminMain.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminMain.java new file mode 100644 index 00000000000..02d63f5e5ed --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeadmin/NodeAdminMain.java @@ -0,0 +1,115 @@ +// Copyright 2017 Yahoo Holdings. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package com.yahoo.vespa.hosted.node.admin.nodeadmin; + +import com.yahoo.concurrent.classlock.ClassLocking; +import com.yahoo.net.HostName; +import com.yahoo.system.ProcessExecuter; +import com.yahoo.vespa.defaults.Defaults; +import com.yahoo.vespa.hosted.dockerapi.Docker; +import com.yahoo.vespa.hosted.dockerapi.metrics.MetricReceiverWrapper; +import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; +import com.yahoo.vespa.hosted.node.admin.docker.DockerOperationsImpl; +import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; +import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer; +import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgent; +import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentImpl; +import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; +import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepositoryImpl; +import com.yahoo.vespa.hosted.node.admin.orchestrator.Orchestrator; +import com.yahoo.vespa.hosted.node.admin.orchestrator.OrchestratorImpl; +import com.yahoo.vespa.hosted.node.admin.util.ConfigServerHttpRequestExecutor; +import com.yahoo.vespa.hosted.node.admin.util.Environment; + +import java.io.File; +import java.time.Clock; +import java.time.Duration; +import java.util.function.Function; + +/** + * NodeAdminMain is the main component of the node admin JDisc application: + * - It will read config and check its environment to figure out its responsibilities + * - It will "start" (only) the necessary components. + * - Other components MUST NOT try to start (typically in constructor) since the features + * they provide is NOT WANTED and possibly destructive, and/or the environment may be + * incompatible. For instance, trying to contact the Docker daemon too early will + * be fatal: the node admin may not have installed and started the docker daemon. + */ +public class NodeAdminMain implements AutoCloseable { + private static final Duration NODE_AGENT_SCAN_INTERVAL = Duration.ofSeconds(30); + private static final Duration NODE_ADMIN_CONVERGE_STATE_INTERVAL = Duration.ofSeconds(30); + + private final Docker docker; + private final MetricReceiverWrapper metricReceiver; + private final ClassLocking classLocking; + + private NodeAdminStateUpdater nodeAdminStateUpdater; + + public NodeAdminMain(Docker docker, MetricReceiverWrapper metricReceiver, ClassLocking classLocking) { + this.docker = docker; + this.metricReceiver = metricReceiver; + this.classLocking = classLocking; + start(); + } + + @Override + public void close() { + nodeAdminStateUpdater.stop(); + } + + public NodeAdminStateUpdater getNodeAdminStateUpdater() { + return nodeAdminStateUpdater; + } + + public void start() { + String staticConfigPath = Defaults.getDefaults().underVespaHome("conf/node-admin.json"); + NodeAdminConfig config = NodeAdminConfig.fromFile(new File(staticConfigPath)); + + switch (config.mode) { + case tenant: + setupTenantHostNodeAdmin(); + break; + case config_server_host: + setupConfigServerHostNodeAdmin(); + break; + default: + throw new IllegalStateException( + "Unknown bootstrap mode: " + config.mode.name()); + } + } + + private void setupTenantHostNodeAdmin() { + Clock clock = Clock.systemUTC(); + String dockerHostHostName = HostName.getLocalhost(); + ProcessExecuter processExecuter = new ProcessExecuter(); + Environment environment = new Environment(); + + ConfigServerHttpRequestExecutor requestExecutor = ConfigServerHttpRequestExecutor.create(environment.getConfigServerUris()); + NodeRepository nodeRepository = new NodeRepositoryImpl(requestExecutor); + Orchestrator orchestrator = new OrchestratorImpl(requestExecutor); + + docker.start(); + DockerOperations dockerOperations = new DockerOperationsImpl(docker, environment, processExecuter); + + StorageMaintainer storageMaintainer = new StorageMaintainer(docker, processExecuter, metricReceiver, environment, clock); + AclMaintainer aclMaintainer = new AclMaintainer(dockerOperations, nodeRepository, dockerHostHostName); + + Function nodeAgentFactory = + (hostName) -> new NodeAgentImpl(hostName, nodeRepository, orchestrator, dockerOperations, + storageMaintainer, aclMaintainer, environment, clock, NODE_AGENT_SCAN_INTERVAL); + NodeAdmin nodeAdmin = new NodeAdminImpl(dockerOperations, nodeAgentFactory, storageMaintainer, aclMaintainer, + metricReceiver, clock); + + nodeAdminStateUpdater = new NodeAdminStateUpdater(nodeRepository, orchestrator, storageMaintainer, nodeAdmin, + dockerHostHostName, clock, NODE_ADMIN_CONVERGE_STATE_INTERVAL, classLocking); + + nodeAdminStateUpdater.start(); + } + + private void setupConfigServerHostNodeAdmin() { + // TODO: + // - install and start docker daemon + // - Read config that specifies which containers to start how + // - use thin static backends for node repo, orchestrator, and others + // - Start core node admin. + } +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminProvider.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminProvider.java index 3777d7e20d1..ea9b38efa26 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminProvider.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/provider/NodeAdminProvider.java @@ -4,78 +4,29 @@ package com.yahoo.vespa.hosted.node.admin.provider; import com.google.inject.Inject; import com.yahoo.concurrent.classlock.ClassLocking; import com.yahoo.container.di.componentgraph.Provider; -import com.yahoo.net.HostName; - -import com.yahoo.system.ProcessExecuter; import com.yahoo.vespa.hosted.dockerapi.Docker; import com.yahoo.vespa.hosted.dockerapi.metrics.MetricReceiverWrapper; -import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; -import com.yahoo.vespa.hosted.node.admin.maintenance.acl.AclMaintainer; -import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; -import com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdmin; -import com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminImpl; +import com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminMain; import com.yahoo.vespa.hosted.node.admin.nodeadmin.NodeAdminStateUpdater; -import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgent; -import com.yahoo.vespa.hosted.node.admin.nodeagent.NodeAgentImpl; -import com.yahoo.vespa.hosted.node.admin.docker.DockerOperationsImpl; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepository; -import com.yahoo.vespa.hosted.node.admin.noderepository.NodeRepositoryImpl; -import com.yahoo.vespa.hosted.node.admin.orchestrator.Orchestrator; -import com.yahoo.vespa.hosted.node.admin.orchestrator.OrchestratorImpl; -import com.yahoo.vespa.hosted.node.admin.util.ConfigServerHttpRequestExecutor; -import com.yahoo.vespa.hosted.node.admin.util.Environment; - -import java.time.Clock; -import java.time.Duration; -import java.util.function.Function; -/** - * Set up node admin for production. - * - * @author dybis - */ public class NodeAdminProvider implements Provider { - - // WARNING: reducing the node agent interval will increase the load on the config servers - private static final Duration NODE_AGENT_SCAN_INTERVAL = Duration.ofSeconds(60); - private static final Duration NODE_ADMIN_CONVERGE_STATE_INTERVAL = Duration.ofSeconds(30); - - private final NodeAdminStateUpdater nodeAdminStateUpdater; + private final NodeAdminMain nodeAdminMain; @Inject - public NodeAdminProvider(Docker docker, MetricReceiverWrapper metricReceiver, ClassLocking classLocking) { - Clock clock = Clock.systemUTC(); - String dockerHostHostName = HostName.getLocalhost(); - ProcessExecuter processExecuter = new ProcessExecuter(); - Environment environment = new Environment(); - - ConfigServerHttpRequestExecutor requestExecutor = ConfigServerHttpRequestExecutor.create(environment.getConfigServerUris()); - NodeRepository nodeRepository = new NodeRepositoryImpl(requestExecutor); - Orchestrator orchestrator = new OrchestratorImpl(requestExecutor); - DockerOperations dockerOperations = new DockerOperationsImpl(docker, environment, processExecuter); - - StorageMaintainer storageMaintainer = new StorageMaintainer(docker, processExecuter, metricReceiver, environment, clock); - AclMaintainer aclMaintainer = new AclMaintainer(dockerOperations, nodeRepository, dockerHostHostName); - - Function nodeAgentFactory = - (hostName) -> new NodeAgentImpl(hostName, nodeRepository, orchestrator, dockerOperations, - storageMaintainer, aclMaintainer, environment, clock, NODE_AGENT_SCAN_INTERVAL); - NodeAdmin nodeAdmin = new NodeAdminImpl(dockerOperations, nodeAgentFactory, storageMaintainer, aclMaintainer, - metricReceiver, clock); - - nodeAdminStateUpdater = new NodeAdminStateUpdater(nodeRepository, orchestrator, storageMaintainer, nodeAdmin, - dockerHostHostName, clock, NODE_ADMIN_CONVERGE_STATE_INTERVAL, classLocking); - - nodeAdminStateUpdater.start(); + public NodeAdminProvider(Docker docker, + MetricReceiverWrapper metricReceiver, + ClassLocking classLocking) { + nodeAdminMain = new NodeAdminMain(docker, metricReceiver, classLocking); + nodeAdminMain.start(); } @Override public NodeAdminStateUpdater get() { - return nodeAdminStateUpdater; + return nodeAdminMain.getNodeAdminStateUpdater(); } @Override public void deconstruct() { - nodeAdminStateUpdater.stop(); + nodeAdminMain.close(); } } diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java index a1cc1850d23..7a5d713936d 100644 --- a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/integrationTests/DockerMock.java @@ -32,6 +32,9 @@ public class DockerMock implements Docker { this.callOrderVerifier = callOrderVerifier; } + @Override + public void start() { } + @Override public CreateContainerCommand createContainerCommand( DockerImage dockerImage, -- cgit v1.2.3