summaryrefslogtreecommitdiffstats
path: root/node-admin
diff options
context:
space:
mode:
authorJon Marius Venstad <jvenstad@yahoo-inc.com>2018-03-10 11:26:21 +0100
committerJon Marius Venstad <jvenstad@yahoo-inc.com>2018-03-12 15:58:58 +0100
commit6b1f2ba9ad2fca1e13b72efd134f42c4eebbc0c7 (patch)
tree2909a6fbfd217f1adfcfd2e0bcd06f9726c8cfa6 /node-admin
parent7b9cf1820056d161ce761d0c040f7ceb21728f13 (diff)
Stash, sort of
Diffstat (limited to 'node-admin')
-rw-r--r--node-admin/src/main/application/templates/motd.sh.vm27
-rw-r--r--node-admin/src/main/application/templates/prompt.sh.vm27
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ConfigServerContainerData.java5
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/ContainerData.java2
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerData.java64
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerData.java30
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/nodeagent/NodeAgentImpl.java14
-rw-r--r--node-admin/src/main/java/com/yahoo/vespa/hosted/node/admin/task/util/file/TemplateFile.java2
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/MotdContainerDataTest.java57
-rw-r--r--node-admin/src/test/java/com/yahoo/vespa/hosted/node/admin/containerdata/PromptContainerDataTest.java34
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"));
+ });
+
+ }
+
+}