Repository: incubator-slider Updated Branches: refs/heads/develop 3e711eba0 -> 477f18dee
SLIDER-625 re-enable reading passwords from the command line, use that mechanism for some accumulo tests Project: http://git-wip-us.apache.org/repos/asf/incubator-slider/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-slider/commit/477f18de Tree: http://git-wip-us.apache.org/repos/asf/incubator-slider/tree/477f18de Diff: http://git-wip-us.apache.org/repos/asf/incubator-slider/diff/477f18de Branch: refs/heads/develop Commit: 477f18dee38a3985d5bd615f9b938f735b014996 Parents: 3e711eb Author: Billie Rinaldi <[email protected]> Authored: Tue Nov 11 12:41:10 2014 -0800 Committer: Billie Rinaldi <[email protected]> Committed: Wed Nov 12 16:46:13 2014 -0800 ---------------------------------------------------------------------- .../funtest/accumulo/AccumuloBasicIT.groovy | 8 +-- .../funtest/accumulo/AccumuloSSLTestBase.groovy | 1 - .../src/test/resources/test_password_file | 4 ++ slider-assembly/src/main/scripts/slider.py | 28 +++++++- .../org/apache/slider/client/SliderClient.java | 75 ++++++++++++++++---- 5 files changed, 94 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy ---------------------------------------------------------------------- diff --git a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy index bb9abba..f1e1899 100644 --- a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy +++ b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloBasicIT.groovy @@ -95,12 +95,9 @@ class AccumuloBasicIT extends AccumuloAgentCommandTestBase { conf.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, jks) CredentialProvider provider = CredentialProviderFactory.getProviders(conf).get(0) - provider.createCredentialEntry( - CustomAuthenticator.ROOT_INITIAL_PASSWORD_PROPERTY, PASSWORD.toCharArray()) + // root initial password and trace password will be initialized at runtime provider.createCredentialEntry(Property.INSTANCE_SECRET.toString(), INSTANCE_SECRET.toCharArray()) - provider.createCredentialEntry(Property.TRACE_TOKEN_PROPERTY_PREFIX - .toString() + "password", PASSWORD.toCharArray()) provider.createCredentialEntry(Property.RPC_SSL_KEYSTORE_PASSWORD .toString(), KEY_PASS.toCharArray()) provider.createCredentialEntry(Property.RPC_SSL_TRUSTSTORE_PASSWORD @@ -131,7 +128,8 @@ class AccumuloBasicIT extends AccumuloAgentCommandTestBase { [ ACTION_CREATE, getClusterName(), ARG_TEMPLATE, APP_TEMPLATE, - ARG_RESOURCES, APP_RESOURCE + ARG_RESOURCES, APP_RESOURCE, "<", + sysprop("test.app.resources.dir") + "/test_password_file" ]) logShell(shell) http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy ---------------------------------------------------------------------- diff --git a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy index d3165dc..cea28b1 100644 --- a/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy +++ b/app-packages/accumulo/src/test/groovy/org/apache/slider/funtest/accumulo/AccumuloSSLTestBase.groovy @@ -85,7 +85,6 @@ class AccumuloSSLTestBase extends AccumuloBasicIT { String provider = tree.global.get(PROVIDER_PROPERTY) provider = provider.replace("hdfs/user", conf.get("fs.defaultFS").replace("://", "@") + "/user") - System.out.println("provider after "+provider) File rootKeyStoreFile = new File(TEST_APP_PKG_DIR, "root.jks") if (!rootKeyStoreFile.exists() && !trustStoreFile.exists()) { http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/app-packages/accumulo/src/test/resources/test_password_file ---------------------------------------------------------------------- diff --git a/app-packages/accumulo/src/test/resources/test_password_file b/app-packages/accumulo/src/test/resources/test_password_file new file mode 100644 index 0000000..1fff8af --- /dev/null +++ b/app-packages/accumulo/src/test/resources/test_password_file @@ -0,0 +1,4 @@ +secret_password +secret_password +secret_password +secret_password http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/slider-assembly/src/main/scripts/slider.py ---------------------------------------------------------------------- diff --git a/slider-assembly/src/main/scripts/slider.py b/slider-assembly/src/main/scripts/slider.py index 26c9adc..e1112eb 100644 --- a/slider-assembly/src/main/scripts/slider.py +++ b/slider-assembly/src/main/scripts/slider.py @@ -21,6 +21,7 @@ import subprocess import time import platform from threading import Thread +import getpass CONF = "conf" IS_WINDOWS = platform.system() == "Windows" @@ -40,6 +41,7 @@ DEFAULT_JVM_OPTS = "-Djava.net.preferIPv4Stack=true -Djava.awt.headless=true -Xm ON_POSIX = 'posix' in sys.builtin_module_names finished = False +needPassword = False DEBUG = False """ @@ -162,6 +164,7 @@ def print_output(name, src, toStdErr): :return: """ + global needPassword debug ("starting printer for %s" % name ) line = "" while not finished: @@ -169,6 +172,8 @@ def print_output(name, src, toStdErr): if done: out(toStdErr, line + "\n") flush(toStdErr) + if line.find("Enter password for") >= 0: + needPassword = True line = "" out(toStdErr, line) # closedown: read remainder of stream @@ -182,6 +187,23 @@ def print_output(name, src, toStdErr): flush(toStdErr) src.close() +def read_input(name, exe): + """ + Read input from stdin and send to process + :param name: + :param process: process to send input to + :return: + """ + global needPassword + debug ("starting reader for %s" % name ) + while not finished: + if needPassword: + needPassword = False + if sys.stdin.isatty(): + cred = getpass.getpass() + else: + cred = sys.stdin.readline().rstrip() + exe.stdin.write(cred + "\n") def runProcess(commandline): """ @@ -192,7 +214,7 @@ def runProcess(commandline): global finished debug ("Executing : %s" % commandline) exe = subprocess.Popen(commandline, - stdin=None, + stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=False, @@ -205,6 +227,9 @@ def runProcess(commandline): t2 = Thread(target=print_output, args=("stderr", exe.stderr, True)) t2.daemon = True t2.start() + t3 = Thread(target=read_input, args=("stdin", exe)) + t3.daemon = True + t3.start() debug("Waiting for completion") while exe.poll() is None: @@ -214,6 +239,7 @@ def runProcess(commandline): finished = True t.join() t2.join() + t3.join() return exe.returncode http://git-wip-us.apache.org/repos/asf/incubator-slider/blob/477f18de/slider-core/src/main/java/org/apache/slider/client/SliderClient.java ---------------------------------------------------------------------- diff --git a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java index 164e2fe..ef7856d 100644 --- a/slider-core/src/main/java/org/apache/slider/client/SliderClient.java +++ b/slider-core/src/main/java/org/apache/slider/client/SliderClient.java @@ -153,16 +153,19 @@ import org.codehaus.jettison.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStreamReader; import java.io.PrintStream; import java.io.StringWriter; import java.io.Writer; import java.net.InetSocketAddress; import java.net.URISyntaxException; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -628,26 +631,68 @@ public class SliderClient extends AbstractSliderLaunchedService implements RunSe return; } - for (Entry<String, List<String>> cred : tree.credentials.entrySet()) { - String provider = cred.getKey(); - List<String> aliases = cred.getValue(); - if (aliases == null || aliases.size()==0) { - continue; - } - Configuration c = new Configuration(conf); - c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider); - CredentialProvider credentialProvider = - CredentialProviderFactory.getProviders(c).get(0); - Set<String> existingAliases = new HashSet<String>(credentialProvider.getAliases()); - for (String alias : aliases) { - if (!existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) { - throw new IOException("Specified credentials have not been " + - "initialized in provider " + provider + ": " + alias); + BufferedReader br = null; + try { + for (Entry<String, List<String>> cred : tree.credentials.entrySet()) { + String provider = cred.getKey(); + List<String> aliases = cred.getValue(); + if (aliases == null || aliases.size() == 0) { + continue; + } + Configuration c = new Configuration(conf); + c.set(CredentialProviderFactory.CREDENTIAL_PROVIDER_PATH, provider); + CredentialProvider credentialProvider = + CredentialProviderFactory.getProviders(c).get(0); + Set<String> existingAliases = + new HashSet<String>(credentialProvider.getAliases()); + for (String alias : aliases) { + if (existingAliases.contains(alias.toLowerCase(Locale.ENGLISH))) { + log.info("Credentials for " + alias + " found in " + provider); + } else { + if (br == null) { + br = new BufferedReader(new InputStreamReader(System.in)); + } + char[] pass = readPassword(alias, br); + if (pass == null) + throw new IOException("Could not read credentials for " + alias + + " from stdin"); + credentialProvider.createCredentialEntry(alias, pass); + credentialProvider.flush(); + Arrays.fill(pass, ' '); + } } } + } finally { + if (br != null) { + br.close(); + } } } + // using a normal reader instead of a secure one, + // because stdin is not hooked up to the command line + private char[] readPassword(String alias, BufferedReader br) + throws IOException { + char[] cred = null; + + boolean noMatch; + do { + log.info(String.format("Enter password for %s: ", alias)); + char[] newPassword1 = br.readLine().toCharArray(); + log.info(String.format("Enter password for %s again: ", alias)); + char[] newPassword2 = br.readLine().toCharArray(); + noMatch = !Arrays.equals(newPassword1, newPassword2); + if (noMatch) { + if (newPassword1 != null) Arrays.fill(newPassword1, ' '); + log.info(String.format("Passwords don't match. Try again.")); + } else { + cred = newPassword1; + } + if (newPassword2 != null) Arrays.fill(newPassword2, ' '); + } while (noMatch); + return cred; + } + @Override public int actionBuild(String clustername, AbstractClusterBuildingActionArgs buildInfo) throws
