diff options
author | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2018-03-10 11:26:21 +0100 |
---|---|---|
committer | Jon Marius Venstad <jvenstad@yahoo-inc.com> | 2018-03-12 15:58:58 +0100 |
commit | 6b1f2ba9ad2fca1e13b72efd134f42c4eebbc0c7 (patch) | |
tree | 2909a6fbfd217f1adfcfd2e0bcd06f9726c8cfa6 /node-admin | |
parent | 7b9cf1820056d161ce761d0c040f7ceb21728f13 (diff) |
Stash, sort of
Diffstat (limited to 'node-admin')
10 files changed, 255 insertions, 7 deletions
diff --git a/node-admin/src/main/application/templates/motd.sh.vm b/node-admin/src/main/application/templates/motd.sh.vm new file mode 100644 index 00000000000..43087520368 --- /dev/null +++ b/node-admin/src/main/application/templates/motd.sh.vm @@ -0,0 +1,27 @@ +#!/usr/bin/env bash + +function motd { + + local -r uptime=$(uptime | cut -f 3- -d ' ') + + local -r no_color='\e[0m' + local -r green='\e[0;32m' +## Use red zone name for main prod zones, yellow for other main zones and no colour for cd and dev zones. + local -r alert=#if($zone.getSystem() == "main")#if($zone.getEnvironment() == "prod")'\e[0;91m'#else'\e[0;33m'#end#else$green#end + + + echo -e " +${green}Zone : ${alert}$zone.getSystem().toUpperCase() $zone.getEnvironment().toUpperCase() $zone.getRegion().toUpperCase() +${green}Node type : ${no_color}$node.nodeType +${green}Host name : ${no_color}$(hostname) +${green}Uptime : ${no_color}$uptime +${green}Version : ${no_color}wanted=$node.wantedVespaVersion.orElse("unknown") installed=$node.vespaVersion.orElse("unknown") +#if($node.owner.isPresent()) +${green}Node state : ${no_color}$node.nodeState +${green}Owner : ${no_color}$node.owner.get().tenant $node.owner.get().application $node.owner.get().instance +#end +" +} + +# Display motd (gently) +[ ! -f ~/.hushlogin ] && motd diff --git a/node-admin/src/main/application/templates/prompt.sh.vm b/node-admin/src/main/application/templates/prompt.sh.vm new file mode 100644 index 00000000000..73232907a32 --- /dev/null +++ b/node-admin/src/main/application/templates/prompt.sh.vm @@ -0,0 +1,27 @@ +# Make sure we get UTC/GMT all over +export TZ=UTC + +# Skip the rest for non-interactice shells +[ -z "$PS1" ] && return + +# Check the window size after each command and, if necessary, +# Update the values of LINES and COLUMNS. +shopt -s checkwinsize + +# Colors; see https://wiki.archlinux.org/index.php/Color_Bash_Prompt +color_off='\[\e[0m\]' # Text Reset +color_bold='\[\e[1m\]' # Bold text + +env_colour=#if($zone.getSystem() == "main")#if($zone.getEnvironment() == "prod")'\e[0;91m'#else'\e[0;33m'#end#else$green#end + + +PS1="${env_colour}$zone.getRegion().toUpperCase()${color_off} [\u@${color_bold}\h${color_off}:\w]\$ " + +# Fix colors +if type dircolors > /dev/null 2>&1; then + eval $(dircolors -b) +fi + +# Make PS1 available in sub-shells +export PS1 + diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ConfigServerContainerData.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ConfigServerContainerData.java index 36da09a72aa..d77e468bc8d 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ConfigServerContainerData.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ConfigServerContainerData.java @@ -1,6 +1,5 @@ package com.yahoo.vespa.hosted.node.admin.containerdata; -import com.yahoo.vespa.hosted.dockerapi.ContainerName; import com.yahoo.vespa.hosted.node.admin.component.Environment; import java.nio.file.Path; @@ -18,9 +17,7 @@ public class ConfigServerContainerData { this.configServerNodeHostName = configServerNodeHostName; } - public void create() { - ContainerData containerData = ContainerData.createCleanContainerData( - environment, ContainerName.fromHostname(configServerNodeHostName)); + public void writeTo(ContainerData containerData) { containerData.addFile(getPath("configserver-config.xml"), createConfigServerConfigXml()); containerData.addFile(getPath("node-repository-config.xml"), createNodeRepoConfigXml()); } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ContainerData.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ContainerData.java index ebfb433de4a..1dc06d52e87 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ContainerData.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ContainerData.java @@ -37,7 +37,7 @@ public class ContainerData { this.destinationPathOnHost = environment.pathInHostFromPathInNode(containerName, ContainerData.containerDataPath); } - public static ContainerData createCleanContainerData(Environment environment, ContainerName containerName) { + public static ContainerData createClean(Environment environment, ContainerName containerName) { ContainerData containerData = new ContainerData(environment, containerName); IOExceptionUtil.uncheck(containerData::cleanup); return containerData; diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerData.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerData.java new file mode 100644 index 00000000000..566e8ca5c39 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerData.java @@ -0,0 +1,64 @@ +package com.yahoo.vespa.hosted.node.admin.containerdata; + +import com.yahoo.config.provision.ApplicationId; +import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; +import com.yahoo.vespa.hosted.node.admin.component.Environment; +import com.yahoo.vespa.hosted.node.admin.task.util.file.TemplateFile; +import com.yahoo.vespa.hosted.provision.Node.State; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Optional; +import java.util.function.BiConsumer; + +public class MotdContainerData { + + private static final Path motdPath = Paths.get("etc/profile.d/motd.sh"); + private static final Path templatePath = Paths.get("src/main/application/templates/motd.sh.vm"); + + private final TemplateFile template; + + public MotdContainerData(ContainerNodeSpec nodeSpec, Environment environment) { + template = new TemplateFile(templatePath) + .set("zone", environment) + .set("node", new Node(nodeSpec.nodeType, + nodeSpec.nodeState, + nodeSpec.vespaVersion, + nodeSpec.wantedVespaVersion, + nodeSpec.owner)); + } + + public void writeTo(ContainerData containerData) { + writeTo(containerData::addFile); + } + + void writeTo(BiConsumer<Path, String> fileWriter) { + System.out.println(template.render()); + fileWriter.accept(motdPath, template.render()); + } + + private static class Node { + + private final String type; + private final State state; + private final Optional<String> installed; + private final Optional<String> wanted; + private final Optional<ApplicationId> owner; + + public Node(String type, State state, Optional<String> installed, Optional<String> wanted, Optional<ContainerNodeSpec.Owner> owner) { + this.type = type; + this.state = state; + this.installed = installed; + this.wanted = wanted; + this.owner = owner.map(id -> ApplicationId.from(id.tenant, id.application, id.instance)); + } + + public String type() { return type; } + public State state() { return state; } + public Optional<String> installed() { return installed; } + public Optional<String> wanted() { return wanted; } + public Optional<ApplicationId> owner() { return owner; } + + } + +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerData.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerData.java new file mode 100644 index 00000000000..18fd12c0a47 --- /dev/null +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerData.java @@ -0,0 +1,30 @@ +package com.yahoo.vespa.hosted.node.admin.containerdata; + +import com.yahoo.vespa.hosted.node.admin.component.Environment; +import com.yahoo.vespa.hosted.node.admin.task.util.file.TemplateFile; + +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.function.BiConsumer; + +public class PromptContainerData { + + private static final Path promptPath = Paths.get("etc/profile.d/prompt.sh"); + private static final Path templatePath = Paths.get("src/main/application/templates/prompt.sh.vm"); + + private final TemplateFile template; + + public PromptContainerData(Environment environment) { + template = new TemplateFile(templatePath) + .set("zone", environment); + } + + public void writeTo(ContainerData containerData) { + writeTo(containerData::addFile); + } + + void writeTo(BiConsumer<Path, String> fileWriter) { + fileWriter.accept(promptPath, template.render()); + } + +} diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java index 37464dcb50b..19aba69528a 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java @@ -16,6 +16,9 @@ import com.yahoo.vespa.hosted.dockerapi.metrics.DimensionMetrics; import com.yahoo.vespa.hosted.dockerapi.metrics.Dimensions; import com.yahoo.vespa.hosted.dockerapi.metrics.MetricReceiverWrapper; import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; +import com.yahoo.vespa.hosted.node.admin.containerdata.ContainerData; +import com.yahoo.vespa.hosted.node.admin.containerdata.MotdContainerData; +import com.yahoo.vespa.hosted.node.admin.containerdata.PromptContainerData; import com.yahoo.vespa.hosted.node.admin.docker.DockerOperations; import com.yahoo.vespa.hosted.node.admin.maintenance.StorageMaintainer; import com.yahoo.vespa.hosted.node.admin.containerdata.ConfigServerContainerData; @@ -681,9 +684,18 @@ public class NodeAgentImpl implements NodeAgent { } private void createContainerData(ContainerNodeSpec nodeSpec) { + // Doing this fails three tests ... Wat? + ContainerData containerData = ContainerData.createClean(environment, + ContainerName.fromHostname(nodeSpec.hostname)); + if (nodeSpec.nodeType.equals(NodeType.config.name())) { logger.info("Creating files needed by config server"); - new ConfigServerContainerData(environment, nodeSpec.hostname).create(); + new ConfigServerContainerData(environment, nodeSpec.hostname).writeTo(containerData); } + + logger.info("Creating files for message of the day and the bash prompt"); + new MotdContainerData(nodeSpec, environment).writeTo(containerData); + new PromptContainerData(environment).writeTo(containerData); } + } diff --git a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java index e9d0770f933..ecde0aca9af 100644 --- a/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java +++ b/node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java @@ -38,7 +38,7 @@ public class TemplateFile { return new FileWriter(destinationPath, this::render); } - private String render() { + public String render() { Template template = velocityEngine.getTemplate(templatePath.getFileName().toString(), "UTF-8"); StringWriter writer = new StringWriter(); template.merge(velocityContext, writer); diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerDataTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerDataTest.java new file mode 100644 index 00000000000..9d2ef7980c5 --- /dev/null +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerDataTest.java @@ -0,0 +1,57 @@ +package com.yahoo.vespa.hosted.node.admin.containerdata; + +import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; +import com.yahoo.vespa.hosted.node.admin.component.Environment; +import com.yahoo.vespa.hosted.node.admin.config.ConfigServerConfig; +import com.yahoo.vespa.hosted.provision.Node; +import org.junit.Test; + +import java.nio.file.Paths; +import java.util.Collections; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MotdContainerDataTest { + + @Test + public void writesMotd() { + MotdContainerData motdContainerData = new MotdContainerData(new ContainerNodeSpec.Builder() + .nodeType("tenant") + .owner(new ContainerNodeSpec.Owner("tenant1", + "application1", + "default")) + .nodeState(Node.State.dirty) + .vespaVersion("7.0.0") + .hostname("nope") + .nodeFlavor("nope") + .allowedToBeDown(false) + .membership(new ContainerNodeSpec.Membership(null, null, null, 0, false)) + .minCpuCores(0) + .minMainMemoryAvailableGb(0) + .minDiskAvailableGb(0) + .fastDisk(false) + .ipAddresses(Collections.emptySet()) + .build(), + new Environment.Builder() + .configServerConfig(new ConfigServerConfig(new ConfigServerConfig.Builder())) + .system("main") + .environment("prod") + .region("aws-us-east-1a") + .build()); + + motdContainerData.writeTo((path, content) -> { + assertEquals(path, Paths.get("etc/profile.d/motd.sh")); + + assertTrue(content.contains("tenant")); + assertTrue(content.contains("[0;91m")); + assertTrue(content.contains("MAIN PROD AWS-US-EAST-1A")); + assertTrue(content.contains("tenant1 application1 default")); + assertTrue(content.contains("dirty")); + assertTrue(content.contains("wanted-unknown")); + assertTrue(content.contains("installed=7.0.0")); + }); + + } + +} diff --git a/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerDataTest.java b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerDataTest.java new file mode 100644 index 00000000000..4d64af75453 --- /dev/null +++ b/node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerDataTest.java @@ -0,0 +1,34 @@ +package com.yahoo.vespa.hosted.node.admin.containerdata; + +import com.yahoo.vespa.hosted.node.admin.ContainerNodeSpec; +import com.yahoo.vespa.hosted.node.admin.component.Environment; +import com.yahoo.vespa.hosted.node.admin.config.ConfigServerConfig; +import com.yahoo.vespa.hosted.provision.Node; +import org.junit.Test; + +import java.nio.file.Paths; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class PromptContainerDataTest { + + @Test + public void writesMotd() { + PromptContainerData promptContainerData = new PromptContainerData(new Environment.Builder() + .configServerConfig(new ConfigServerConfig(new ConfigServerConfig.Builder())) + .system("main") + .environment("prod") + .region("aws-us-east-1a") + .build()); + + promptContainerData.writeTo((path, content) -> { + assertEquals(path, Paths.get("etc/profile.d/prompt.sh")); + + assertTrue(content.contains("[0;91m")); + assertTrue(content.contains("AWS-US-EAST-1A")); + }); + + } + +} |