http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java b/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java deleted file mode 100644 index 570551d..0000000 --- a/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java +++ /dev/null @@ -1,712 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.ssh; - -import static com.google.common.base.Preconditions.checkArgument; -import static com.google.common.base.Preconditions.checkNotNull; - -import static java.lang.String.format; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; - -import brooklyn.util.collections.MutableMap; -import brooklyn.util.text.Identifiers; -import brooklyn.util.text.StringEscapes.BashStringEscapes; -import brooklyn.util.text.Strings; -import brooklyn.util.time.Duration; - -import com.google.common.annotations.Beta; -import com.google.common.base.Joiner; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.Lists; - -public class BashCommands { - - /** - * Returns a string for checking whether the given executable is available, - * and installing it if necessary. - * <p/> - * Uses {@link #installPackage} and accepts the same flags e.g. for apt, yum, rpm. - */ - public static String installExecutable(Map<?,?> flags, String executable) { - return onlyIfExecutableMissing(executable, installPackage(flags, executable)); - } - - public static String installExecutable(String executable) { - return installExecutable(MutableMap.of(), executable); - } - - /** - * Returns a command with all output redirected to /dev/null - */ - public static String quiet(String command) { - return format("(%s > /dev/null 2>&1)", command); - } - - /** - * Returns a command that always exits successfully - */ - public static String ok(String command) { - return String.format("(%s || true)", command); - } - - /** - * Returns a command for safely running as root, using {@code sudo}. - * <p/> - * Ensuring non-blocking if password not set by using - * {@code -n} which means to exit if password required - * (this is unsupported in Ubuntu 8 but all modern OS's seem okay with this!), - * and (perhaps unnecessarily ?) - * {@code -S} which reads from stdin (routed to {@code /dev/null}, it was claimed here previously, though I'm not sure?). - * <p/> - * Also specify {@code -E} to pass the parent environment in. - * <p/> - * If already root, simply runs the command, wrapped in brackets in case it is backgrounded. - * <p/> - * The command is not quoted or escaped in any ways. - * If you are doing privileged redirect you may need to pass e.g. "bash -c 'echo hi > file'". - * <p/> - * If null is supplied, it is returned (sometimes used to indicate no command desired). - */ - public static String sudo(String command) { - if (command.startsWith("( ") || command.endsWith(" &")) - return sudoNew(command); - else - return sudoOld(command); - } - - // TODO would like to move away from sudoOld -- but needs extensive testing! - - private static String sudoOld(String command) { - if (command==null) return null; - // some OS's (which?) fail if you try running sudo when you're already root (dumb but true) - return format("( if test \"$UID\" -eq 0; then ( %s ); else sudo -E -n -S -- %s; fi )", command, command); - } - private static String sudoNew(String command) { - if (command==null) return null; - // on some OS's e.g. Centos 6.5 in SL, sudo -- X tries to run X as a literal argument; - // in particular "( echo foo && echo bar )" fails when passed as an argument in that way, - // but works if passed to bash -c; - // but others e.g. OS X fail if you say sudo -- bash -c "( echo foo )" ... not liking the parentheses - // piping to sudo bash seems the most reliable way - return "( if test \"$UID\" -eq 0; then ( "+command+" ); else " - + "echo " + BashStringEscapes.wrapBash(command) + " | " - + "sudo -E -n -S -s -- bash" - + " ; fi )"; - } - - /** sudo to a given user and run the indicated command; - * @deprecated since 0.7.0 semantics of this are fiddly, e.g. whether user gets their environment */ - @Beta - public static String sudoAsUser(String user, String command) { - return sudoAsUserOld(user, command); - } - - private static String sudoAsUserOld(String user, String command) { - if (command == null) return null; - return format("{ sudo -E -n -u %s -s -- %s ; }", user, command); - } - // TODO would like to move away from sudoOld -- but needs extensive testing! -// private static String sudoAsUserNew(String user, String command) { -// if (command == null) return null; -// // no -E, run with permissions of this user -// // FIXME still doesn't always work e.g. doesn't have path of user -// // (Alex says: can't find any combinations which work reliably) -// return "{ sudo -n -S -i -u "+user+" -- "+BashStringEscapes.wrapBash(command)+" ; }"; -// } - - public static String addSbinPathCommand() { - return "export PATH=$PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"; - } - - /** executes a command, then as user tees the output to the given file. - * useful e.g. for appending to a file which is only writable by root or a priveleged user. */ - public static String executeCommandThenAsUserTeeOutputToFile(String commandWhoseOutputToWrite, String user, String file) { - return format("{ %s | sudo -E -n -u %s -s -- tee -a %s ; }", - commandWhoseOutputToWrite, user, file); - } - - /** some machines require a tty for sudo; brooklyn by default does not use a tty - * (so that it can get separate error+stdout streams); you can enable a tty as an - * option to every ssh command, or you can do it once and - * modify the machine so that a tty is not subsequently required. - * <p> - * this command must be run with allocatePTY set as a flag to ssh. see SshTasks.dontRequireTtyForSudo which sets that up. - * <p> - * (having a tty for sudo seems like another case of imaginary security which is just irritating. - * like water restrictions at airport security.) */ - public static String dontRequireTtyForSudo() { - return ifFileExistsElse0("/etc/sudoers", sudo("sed -i.brooklyn.bak 's/.*requiretty.*/#brooklyn-removed-require-tty/' /etc/sudoers")); - } - - /** generates ~/.ssh/id_rsa if that file does not exist */ - public static String generateKeyInDotSshIdRsaIfNotThere() { - return "[ -f ~/.ssh/id_rsa ] || ( mkdir -p ~/.ssh ; chmod 700 ~/.ssh ; ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa )"; - } - - // TODO a builder would be better than these ifBlahExistsElseBlah methods! - // (ideally formatting better also; though maybe SshTasks would be better?) - - /** - * Returns a command that runs only if the specified file (or link or directory) exists; - * if the command runs and fails that exit is preserved (but if the file does not exist exit code is zero). - * Executed as { { not-file-exists && ok ; } || command ; } for portability. - * ("if [ ... ] ; then xxx ; else xxx ; fi" syntax is not quite as portable, I seem to recall (not sure, Alex Aug 2013).) - */ - public static String ifFileExistsElse0(String path, String command) { - return alternativesGroup( - chainGroup(format("test ! -e %s", path), "true"), - command); - } - /** as {@link #ifFileExistsElse0(String, String)} but returns non-zero if the test fails (also returns non-zero if the command fails, - * so you can't tell the difference :( -- we need if ; then ; else ; fi semantics for that I think, but not sure how portable that is) */ - public static String ifFileExistsElse1(String path, String command) { - return chainGroup(format("test -e %s", path), command); - } - - /** - * Returns a command that runs only if the specified executable exists on the path (using `which`). - * if the command runs and fails that exit is preserved (but if the executable is not on the path exit code is zero). - * @see #ifFileExistsElse0(String, String) for implementation discussion, using <code>{ { test -z `which executable` && true ; } || command ; } - */ - public static String ifExecutableElse0(String executable, String command) { - return alternativesGroup( - chainGroup(format("test -z `which %s`", executable), "true"), - command); - } - - /** as {@link #ifExecutableElse0(String, String)} but returns 1 if the test fails (also returns non-zero if the command fails) */ - public static String ifExecutableElse1(String executable, String command) { - return chainGroup(format("which %s", executable), command); - } - - /** - * Returns a command which - * executes <code>statement</code> only if <code>command</code> is NOT found in <code>$PATH</code> - * - * @param command - * @param statement - * @return command - */ - public static String ifNotExecutable(String command, String statement) { - return String.format("{ { test ! -z `which %s`; } || { %s; } }", command, statement); - } - - /** - * Returns a command that runs only if the specified executable exists on the path (using `which`). - * if the command runs and fails that exit is preserved (but if the executable is not on the path exit code is zero). - * @see #ifFileExistsElse0(String, String) for implementation discussion, using <code>{ { test -z `which executable` && true ; } || command ; } - */ - public static String onlyIfExecutableMissing(String executable, String command) { - return alternativesGroup(format("which %s", executable), command); - } - - public static String ifExecutableElse(String command, String ifTrue, String otherwise) { - return com.google.common.base.Joiner.on('\n').join( - ifExecutableElse(command, ImmutableList.<String>of(ifTrue), ImmutableList.<String>of(otherwise))); - } - - public static ImmutableList<String> ifExecutableElse(String command, List<String> ifTrue, List<String> otherwise) { - return ImmutableList.<String>builder() - .add(String.format("if test -z `which %s`; then", command)) - .addAll(ifTrue) - .add("else") - .addAll(otherwise) - .add("fi") - .build(); - } - - /** - * Returns a sequence of chained commands that runs until one of them fails (i.e. joined by '&&') - * This currently runs as a subshell (so exits are swallowed) but behaviour may be changed imminently. - * (Use {@link #chainGroup(Collection)} or {@link #chainSubshell(Collection)} to be clear.) - */ - public static String chain(Collection<String> commands) { - return "( " + Strings.join(commands, " && ") + " )"; - } - - /** Convenience for {@link #chain(Collection)} */ - public static String chain(String ...commands) { - return "( " + Strings.join(commands, " && ") + " )"; - } - - /** As {@link #chain(Collection)}, but explicitly using { } grouping characters - * to ensure exits are propagated. */ - public static String chainGroup(Collection<String> commands) { - // spaces required around curly braces - return "{ " + Strings.join(commands, " && ") + " ; }"; - } - - /** As {@link #chainGroup(Collection)} */ - public static String chainGroup(String ...commands) { - return "{ " + Strings.join(commands, " && ") + " ; }"; - } - - /** As {@link #chain(Collection)}, but explicitly using ( ) grouping characters - * to ensure exits are caught. */ - public static String chainSubshell(Collection<String> commands) { - // the spaces are not required, but it might be possible that a (( expr )) is interpreted differently - // (won't hurt to have the spaces in any case!) - return "( " + Strings.join(commands, " && ") + " )"; - } - - /** As {@link #chainSubshell(Collection)} */ - public static String chainSubshell(String ...commands) { - return "( " + Strings.join(commands, " && ") + " )"; - } - - /** - * Returns a sequence of chained commands that runs until one of them succeeds (i.e. joined by '||'). - * This currently runs as a subshell (so exits are swallowed) but behaviour may be changed imminently. - * (Use {@link #alternativesGroup(Collection)} or {@link #alternativesSubshell(Collection)} to be clear.) - */ - public static String alternatives(Collection<String> commands) { - return "( " + Strings.join(commands, " || ") + " )"; - } - - /** As {@link #alternatives(Collection)} */ - public static String alternatives(String ...commands) { - return "( " + Strings.join(commands, " || ") + " )"; - } - - /** As {@link #alternatives(Collection)}, but explicitly using { } grouping characters - * to ensure exits are propagated. */ - public static String alternativesGroup(Collection<String> commands) { - // spaces required around curly braces - return "{ " + Strings.join(commands, " || ") + " ; }"; - } - - /** As {@link #alternativesGroup(Collection)} */ - public static String alternativesGroup(String ...commands) { - return "{ " + Strings.join(commands, " || ") + " ; }"; - } - - /** As {@link #alternatives(Collection)}, but explicitly using ( ) grouping characters - * to ensure exits are caught. */ - public static String alternativesSubshell(Collection<String> commands) { - // the spaces are not required, but it might be possible that a (( expr )) is interpreted differently - // (won't hurt to have the spaces in any case!) - return "( " + Strings.join(commands, " || ") + " )"; - } - - /** As {@link #alternativesSubshell(Collection)} */ - public static String alternativesSubshell(String ...commands) { - return "( " + Strings.join(commands, " || ") + " )"; - } - - /** returns the pattern formatted with the given arg if the arg is not null, otherwise returns null */ - public static String formatIfNotNull(String pattern, Object arg) { - if (arg==null) return null; - return format(pattern, arg); - } - - public static String installPackage(String packageDefaultName) { - return installPackage(MutableMap.of(), packageDefaultName); - } - /** - * Returns a command for installing the given package. - * <p> - * Warns, but does not fail or return non-zero if it ultimately fails. - * <p> - * Flags can contain common overrides for {@code apt}, {@code yum}, {@code port} and {@code brew} - * as the package names can be different for each of those. Setting the default package name to - * {@literal null} will use only the overridden package manager values. The {@code onlyifmissing} flag - * adds a check for an executable, and only attempts to install packages if it is not found. - * <pre> - * installPackage(ImmutableMap.of("yum", "openssl-devel", "apt", "openssl libssl-dev zlib1g-dev"), "libssl-devel"); - * installPackage(ImmutableMap.of("apt", "libaio1"), null); - * installPackage(ImmutableMap.of("onlyifmissing", "curl"), "curl"); - * </pre> - */ - public static String installPackage(Map<?,?> flags, String packageDefaultName) { - return installPackageOr(flags, packageDefaultName, null); - } - public static String installPackageOrFail(Map<?,?> flags, String packageDefaultName) { - return installPackageOr(flags, packageDefaultName, "exit 9"); - } - public static String installPackageOr(Map<?,?> flags, String packageDefaultName, String optionalCommandToRunIfNone) { - String ifMissing = (String) flags.get("onlyifmissing"); - String zypperInstall = formatIfNotNull("zypper --non-interactive --no-gpg-checks install %s", getFlag(flags, "zypper", packageDefaultName)); - String aptInstall = formatIfNotNull("apt-get install -y --allow-unauthenticated %s", getFlag(flags, "apt", packageDefaultName)); - String yumInstall = formatIfNotNull("yum -y --nogpgcheck install %s", getFlag(flags, "yum", packageDefaultName)); - String brewInstall = formatIfNotNull("brew install %s", getFlag(flags, "brew", packageDefaultName)); - String portInstall = formatIfNotNull("port install %s", getFlag(flags, "port", packageDefaultName)); - - List<String> commands = new LinkedList<String>(); - if (ifMissing != null) - commands.add(format("which %s", ifMissing)); - if (zypperInstall != null) - commands.add(ifExecutableElse1("zypper", - chainGroup( - "echo zypper exists, doing refresh", - ok(sudo("zypper --non-interactive --no-gpg-checks refresh")), - sudo(zypperInstall)))); - if (aptInstall != null) - commands.add(ifExecutableElse1("apt-get", - chainGroup( - "echo apt-get exists, doing update", - "export DEBIAN_FRONTEND=noninteractive", - ok(sudo("apt-get update")), - sudo(aptInstall)))); - if (yumInstall != null) - commands.add(ifExecutableElse1("yum", - chainGroup( - "echo yum exists, doing update", - ok(sudo("yum check-update")), - ok(sudo("yum -y install epel-release")), - sudo(yumInstall)))); - if (brewInstall != null) - commands.add(ifExecutableElse1("brew", brewInstall)); - if (portInstall != null) - commands.add(ifExecutableElse1("port", sudo(portInstall))); - - String lastCommand = ok(warn("WARNING: no known/successful package manager to install " + - (packageDefaultName!=null ? packageDefaultName : flags.toString()) + - ", may fail subsequently")); - if (optionalCommandToRunIfNone != null) - lastCommand = chain(lastCommand, optionalCommandToRunIfNone); - commands.add(lastCommand); - - return alternatives(commands); - } - - public static String warn(String message) { - return "( echo "+BashStringEscapes.wrapBash(message)+" | tee /dev/stderr )"; - } - - /** returns a command which logs a message to stdout and stderr then exits with the given error code */ - public static String fail(String message, int code) { - return chainGroup(warn(message), "exit "+code); - } - - /** requires the command to have a non-zero exit code; e.g. - * <code>require("which foo", "Command foo must be found", 1)</code> */ - public static String require(String command, String failureMessage, int exitCode) { - return alternativesGroup(command, fail(failureMessage, exitCode)); - } - - /** as {@link #require(String, String, int)} but returning the original exit code */ - public static String require(String command, String failureMessage) { - return alternativesGroup(command, chainGroup("EXIT_CODE=$?", warn(failureMessage), "exit $EXIT_CODE")); - } - - /** requires the test to pass, as valid bash `test` arguments; e.g. - * <code>requireTest("-f /etc/hosts", "Hosts file must exist", 1)</code> */ - public static String requireTest(String test, String failureMessage, int exitCode) { - return require("test "+test, failureMessage, exitCode); - } - - /** as {@link #requireTest(String, String, int)} but returning the original exit code */ - public static String requireTest(String test, String failureMessage) { - return require("test "+test, failureMessage); - } - - /** fails with nice error if the given file does not exist */ - public static String requireFile(String file) { - return requireTest("-f "+BashStringEscapes.wrapBash(file), "The required file \""+file+"\" does not exist"); - } - - /** fails with nice error if the given file does not exist */ - public static String requireExecutable(String command) { - return require("which "+BashStringEscapes.wrapBash(command), "The required executable \""+command+"\" does not exist"); - } - - public static String waitForFileContents(String file, String desiredContent, Duration timeout, boolean failOnTimeout) { - long secs = Math.max(timeout.toSeconds(), 1); - - List<String> commands = ImmutableList.of( - "for i in {1.."+secs+"}; do", - " grep '"+desiredContent+"' "+file+" && result=0 || result=$?", - " [ \"$result\" == 0 ] && break", - " sleep 1", - "done", - "if test \"$result\" -ne 0; then", - " "+ (failOnTimeout ? - "echo \"Couldn't find "+desiredContent+" in "+file+"; aborting\" && exit 1" : - "echo \"Couldn't find "+desiredContent+" in "+file+"; continuing\""), - "fi"); - return Joiner.on("\n").join(commands); - } - - public static String waitForPortFree(int port, Duration timeout, boolean failOnTimeout) { - long secs = Math.max(timeout.toSeconds(), 1); - - // TODO How platform-dependent are the args + output format of netstat? - // TODO Not using sudo as wrapping either netstat call or sudo(alternativesGroup(...)) fails; parentheses too confusing! - String netstatCommand = alternativesGroup( - "sudo netstat -antp --tcp", // for Centos - "sudo netstat -antp TCP"); // for OS X - - // number could appear in an IP address or as a port; look for white space at end, and dot or colon before - String grepCommand = "grep -E '(:|\\.)"+port+"($|\\s)' > /dev/null"; - - List<String> commands = ImmutableList.of( - "for i in {1.."+secs+"}; do", - " "+BashCommands.requireExecutable("netstat"), - " "+alternativesGroup( - chainGroup("which awk", "AWK_EXEC=awk"), - chainGroup("which gawk", "AWK_EXEC=gawk"), - chainGroup("which /usr/bin/awk", "AWK_EXEC=/usr/bin/awk"), - chainGroup("echo \"No awk to determine if Port "+port+" still in use; aborting\"", "exit 1")), - " "+netstatCommand+" | $AWK_EXEC '{print $4}' | "+grepCommand+" && result=0 || result=$?", - " [ \"$result\" != 0 ] && break", - " sleep 1", - "done", - "if test \"$result\" -eq 0; then", - " "+ (failOnTimeout ? - "echo \"Port "+port+" still in use (according to netstat); aborting\" && exit 1" : - "echo \"Port "+port+" still in use (according to netstat); continuing\""), - "fi"); - return Joiner.on("\n").join(commands); - } - - public static String unzip(String file, String targetDir) { - return "unzip " + file + (Strings.isNonBlank(targetDir) ? " -d "+targetDir : ""); - } - - public static final String INSTALL_TAR = installExecutable("tar"); - public static final String INSTALL_CURL = installExecutable("curl"); - public static final String INSTALL_WGET = installExecutable("wget"); - public static final String INSTALL_ZIP = installExecutable("zip"); - public static final String INSTALL_UNZIP = alternatives(installExecutable("unzip"), installExecutable("zip")); - public static final String INSTALL_SYSSTAT = installPackage(ImmutableMap.of("onlyifmissing", "iostat"), "sysstat"); - - /** - * Returns commands to download the URL, saving as the given file. Will try each URL in turn until one is successful - * (see `curl -f` documentation). - */ - public static List<String> commandsToDownloadUrlsAs(List<String> urls, String saveAs) { - return Arrays.asList(INSTALL_CURL, - require(simpleDownloadUrlAs(urls, saveAs), "Could not retrieve "+saveAs+". Tried: " + Joiner.on(", ").join(urls), 9)); - } - public static String commandToDownloadUrlsAs(List<String> urls, String saveAs) { - return chain(INSTALL_CURL, - require(simpleDownloadUrlAs(urls, saveAs), "Could not retrieve "+saveAs+". Tried: " + Joiner.on(", ").join(urls), 9)); - } - public static String commandToDownloadUrlAs(String url, String saveAs) { - return chain(INSTALL_CURL, - require(simpleDownloadUrlAs(Arrays.asList(url), saveAs), "Could not retrieve "+saveAs+" from " + url, 9)); - } - - /** - * Returns command to download the URL, sending the output to stdout -- - * suitable for redirect by appending " | tar xvf". - * Will try each URL in turn until one is successful - */ - public static String downloadToStdout(List<String> urls) { - return chain( - INSTALL_CURL + " > /dev/null", - require(simpleDownloadUrlAs(urls, null), - "Could not retrieve file. Tried: " + Joiner.on(", ").join(urls), 9)); - } - - /** as {@link #downloadToStdout(List)} but varargs for convenience */ - public static String downloadToStdout(String ...urls) { - return downloadToStdout(Arrays.asList(urls)); - } - - /** - * Same as {@link downloadUrlAs(List, String)}, except does not install curl, and does not exit on failure, - * and if saveAs is null it downloads it so stdout. - */ - public static String simpleDownloadUrlAs(List<String> urls, String saveAs) { - return simpleDownloadUrlAs(urls, null, null, saveAs); - } - - public static String simpleDownloadUrlAs(List<String> urls, String user, String password, String saveAs) { - if (urls.isEmpty()) throw new IllegalArgumentException("No URLs supplied to download "+saveAs); - - List<String> commands = new ArrayList<String>(); - for (String url : urls) { - String command = "curl -f -L -k --retry 10 --keepalive-time 30 --speed-time 30 "; - if (user!=null && password!=null) { - command = command + format("-u %s:%s ", user, password); - } - command = command + format("\"%s\"", url); - if (saveAs!=null) { - command = command + format(" -o %s", saveAs); - } - commands.add(command); - } - return alternatives(commands); - } - - private static Object getFlag(Map<?,?> flags, String flagName, Object defaultValue) { - Object found = flags.get(flagName); - return found == null ? defaultValue : found; - } - - /** - * Install a particular Java runtime, fails if not possible. - * <p> - * <em><strong>Note</strong> Java 8 is not yet supported on SUSE</em> - * - * @return The command to install the given Java runtime. - * @see #installJava6OrFail() - * @see #installJava7Or6OrFail() - * @see #installJavaLatestOrFail() - */ - public static String installJava(int version) { - Preconditions.checkArgument(version == 6 || version == 7 || version == 8, "Supported Java versions are 6, 7, or 8"); - return installPackageOr(MutableMap.of("apt", "openjdk-" + version + "-jdk","yum", "java-1." + version + ".0-openjdk-devel"), null, - ifExecutableElse1("zypper", chainGroup( - ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/SLE_11_SP3 java_sles_11")), - ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/openSUSE_11.4 java_suse_11")), - ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/openSUSE_12.3 java_suse_12")), - ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/Java:/openjdk6:/Factory/openSUSE_13.1 java_suse_13")), - alternatives(installPackageOrFail(MutableMap.of("zypper", "java-1_" + version + "_0-openjdk-devel"), null), - installPackageOrFail(MutableMap.of("zypper", "java-1_" + version + "_0-ibm"), null))))); - } - - public static String installJava6() { - return installJava(6); - } - public static String installJava7() { - return installJava(7); - } - public static String installJava8() { - return installJava(8); - } - - public static String installJava6IfPossible() { - return ok(installJava6()); - } - public static String installJava7IfPossible() { - return ok(installJava7()); - } - public static String installJava8IfPossible() { - return ok(installJava8()); - } - - public static String installJava6OrFail() { - return alternatives(installJava6(), fail("java 6 install failed", 9)); - } - public static String installJava7OrFail() { - return alternatives(installJava7(), fail("java 7 install failed", 9)); - } - public static String installJava7Or6OrFail() { - return alternatives(installJava7(), installJava6(), fail("java install failed", 9)); - } - public static String installJavaLatestOrFail() { - return alternatives(installJava8(), installJava7(), installJava6(), fail("java latest install failed", 9)); - } - - public static String installJavaLatestOrWarn() { - return alternatives(installJava8(), installJava7(), installJava6(), warn("java latest install failed, entity may subsequently fail")); - } - - /** cats the given text to the given command, using bash << multi-line input syntax */ - public static String pipeTextTo(String text, String command) { - String id = Identifiers.makeRandomId(8); - return "cat << EOF_"+id+" | "+command+"\n" - +text - +"\n"+"EOF_"+id+"\n"; - } - - public static String prependToEtcHosts(String ip, String... hostnames) { - String tempFileId = "bak"+Identifiers.makeRandomId(4); - return sudo(String.format("sed -i."+tempFileId+" -e '1i\\\n%s %s' /etc/hosts", ip, Joiner.on(" ").join(hostnames))); - } - - public static String appendToEtcHosts(String ip, String... hostnames) { - // Using sed rather than `echo ... >> /etc/hosts` because when embedded inside sudo, - // the redirect doesn't get executed by sudo. - String tempFileId = "bak"+Identifiers.makeRandomId(4); - return sudo(String.format("sed -i."+tempFileId+" -e '$a\\\n%s %s' /etc/hosts", ip, Joiner.on(" ").join(hostnames))); - } - - /** - * Sets the hostname, splitting the given hostname if it contains a dot to include the unqualified and fully qualified names. - * - * @see {@link #setHostname(String, String)} - */ - @Beta - public static List<String> setHostname(String newHostname) { - // See http://www.dns-sd.org/trailingdotsindomainnames.html. - // If we are given "abcd." then let's pass that as-is to setHostname("abcd.", null) - - if (newHostname.indexOf(".") > 0) { - String hostPart = newHostname.substring(0, newHostname.indexOf(".")); - String domainPart = newHostname.substring(hostPart.length()+1); - return setHostname(hostPart, domainPart); - } else { - return setHostname(newHostname, null); - } - } - - /** - * Sets the hostname to {@code hostPart + "." + domainPart}, or if domainPart is null/empty then {code hostPart}. - * - * @param hostPart - * @param domainPart - * @return - */ - @Beta - public static List<String> setHostname(String hostPart, String domainPart) { - // See: - // - http://www.rackspace.com/knowledge_center/article/centos-hostname-change - // - https://wiki.debian.org/HowTo/ChangeHostname - // - http://askubuntu.com/questions/9540/how-do-i-change-the-computer-name - // - // We prepend in /etc/hosts, to ensure the right fqn appears first. - // e.g. comment in http://askubuntu.com/questions/158957/how-to-set-the-fully-qualified-domain-name-in-12-04 - // says "It's important to note that the first domain in /etc/hosts should be your FQDN. " - // - // TODO Should we run `sudo service hostname restart` or `sudo /etc/init.d/hostname restart`? - // I don't think we need to because we've run `sudo hostname <newname>` - // - // TODO What if /etc/sysconfig/network doesn't have a line for HOSTNAME=...? - // - // TODO What about hostPart ending in "." - see http://www.dns-sd.org/trailingdotsindomainnames.html - // for what that means in DNS. However, hostname is not the same as the DNS name (hostnames - // predate the invention of DNS! - although frequently the DNS name has the same first portion - // as the hostname) so the link you gave is not relevant. However despite searching Google and - // man pages I [Ricard] am unable to find a reference which clearly states what characters are - // relevant in a hostname. I think it's safest to assume that the hostname is just [a-z,0-9,-] - // and no dots at all. - - checkNotNull(hostPart, "hostPart"); - checkArgument(!hostPart.contains("."), "hostPart '%s' must not contain '.'", hostPart); - - String tempFileId = "bak"+Identifiers.makeRandomId(4); - - List<String> allhostnames = Lists.newArrayList(); - String fqdn = hostPart; - if (Strings.isNonBlank(domainPart)) { - fqdn = hostPart+"."+domainPart; - allhostnames.add(fqdn); - } - allhostnames.add(hostPart); - allhostnames.add("localhost"); - - return ImmutableList.of( - sudo("sed -i."+tempFileId+" -e 's/^127.0.0.1/# Replaced by Brooklyn\\\n#127.0.0.1/' /etc/hosts"), - prependToEtcHosts("127.0.0.1", allhostnames.toArray(new String[allhostnames.size()])), - ifFileExistsElse0("/etc/sysconfig/network", sudo("sed -i."+tempFileId+" -e 's/^HOSTNAME=.*$/HOSTNAME="+hostPart+"/' /etc/sysconfig/network")), - ifFileExistsElse0("/etc/hostname", sudo("sed -i."+tempFileId+" -e 's/^[a-zA-Z_0-9].*$/"+hostPart+"/' /etc/hostname")), - sudo("hostname "+hostPart)); - } -}
http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java b/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java deleted file mode 100644 index c0e8213..0000000 --- a/utils/common/src/main/java/brooklyn/util/ssh/IptablesCommands.java +++ /dev/null @@ -1,261 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.ssh; - -import static brooklyn.util.ssh.BashCommands.alternatives; -import static brooklyn.util.ssh.BashCommands.chain; -import static brooklyn.util.ssh.BashCommands.installPackage; -import static brooklyn.util.ssh.BashCommands.sudo; - -import com.google.common.annotations.Beta; -import com.google.common.base.Optional; - -public class IptablesCommands { - - public enum Chain { - INPUT, FORWARD, OUTPUT - } - - public enum Policy { - ACCEPT, REJECT, DROP, LOG - } - - /*** @deprecated since 0.7; use {@link brooklyn.util.net.Protocol} */ - @Deprecated - public enum Protocol { - TCP("tcp"), UDP("udp"), ALL("all"); - - final String protocol; - - private Protocol(String protocol) { - this.protocol = protocol; - } - - @Override - public String toString() { - return protocol; - } - - brooklyn.util.net.Protocol convert() { - switch (this) { - case TCP: return brooklyn.util.net.Protocol.TCP; - case UDP: return brooklyn.util.net.Protocol.UDP; - case ALL: return brooklyn.util.net.Protocol.ALL; - default: throw new IllegalStateException("Unexpected protocol "+this); - } - } - } - - @Beta // implementation not portable across distros - public static String iptablesService(String cmd) { - return sudo(alternatives( - BashCommands.ifExecutableElse1("service", "service iptables " + cmd), - "/sbin/service iptables " + cmd)); - } - - @Beta // implementation not portable across distros - public static String iptablesServiceStop() { - return iptablesService("stop"); - } - - @Beta // implementation not portable across distros - public static String iptablesServiceStart() { - return iptablesService("start"); - } - - @Beta // implementation not portable across distros - public static String iptablesServiceRestart() { - return iptablesService("restart"); - } - - @Beta // implementation not portable across distros - public static String iptablesServiceStatus() { - return iptablesService("status"); - } - - @Beta // implementation not portable across distros - public static String firewalldService(String cmd) { - return sudo(alternatives( - BashCommands.ifExecutableElse1("systemctl", "systemctl " + cmd + " firewalld"), - "/usr/bin/systemctl " + cmd + " firewalld")); - } - - @Beta // implementation not portable across distros - public static String firewalldServiceStop() { - return firewalldService("stop"); - } - - @Beta // implementation not portable across distros - public static String firewalldServiceStart() { - return firewalldService("start"); - } - - @Beta // implementation not portable across distros - public static String firewalldServiceRestart() { - return firewalldService("restart"); - } - - @Beta // implementation not portable across distros - public static String firewalldServiceStatus() { - return firewalldService("status"); - } - - @Beta // implementation not portable across distros - public static String firewalldServiceIsActive() { - return firewalldService("is-active"); - } - - /** - * Returns the command that saves iptables rules on file. - * - * @return Returns the command that saves iptables rules on file. - * - */ - public static String saveIptablesRules() { - return alternatives(sudo("service iptables save"), - chain(installPackage("iptables-persistent"), sudo("/etc/init.d/iptables-persistent save"))); - } - - /** - * Returns the command that cleans up iptables rules. - * - * @return Returns the command that cleans up iptables rules. - */ - public static String cleanUpIptablesRules() { - return sudo("/sbin/iptables -F"); - } - - /** - * Returns the iptables rules. - * - * @return Returns the command that list all the iptables rules. - */ - public static String listIptablesRule() { - return sudo("/sbin/iptables -L -v -n"); - } - - /** - * Returns the command that inserts a rule on top of the iptables' rules to all interfaces. - * - * @return Returns the command that inserts a rule on top of the iptables' - * rules. - */ - public static String insertIptablesRule(Chain chain, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - return addIptablesRule("-I", chain, Optional.<String> absent(), protocol, port, policy); - } - - /** @deprecated since 0.7.0; use {@link #insertIptablesRule(Chain, brooklyn.util.net.Protocol, int, Policy)} */ - @Deprecated - public static String insertIptablesRule(Chain chain, Protocol protocol, int port, Policy policy) { - return insertIptablesRule(chain, protocol.convert(), port, policy); - } - - /** - * Returns the command that inserts a rule on top of the iptables' rules. - * - * @return Returns the command that inserts a rule on top of the iptables' - * rules. - */ - public static String insertIptablesRule(Chain chain, String networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - return addIptablesRule("-I", chain, Optional.of(networkInterface), protocol, port, policy); - } - - /** @deprecated since 0.7.0; use {@link #insertIptablesRule(Chain, String, brooklyn.util.net.Protocol, int, Policy)} */ - @Deprecated - public static String insertIptablesRule(Chain chain, String networkInterface, Protocol protocol, int port, Policy policy) { - return insertIptablesRule(chain, networkInterface, protocol.convert(), port, policy); - } - - /** - * Returns the command that appends a rule to iptables to all interfaces. - * - * @return Returns the command that appends a rule to iptables. - */ - public static String appendIptablesRule(Chain chain, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - return addIptablesRule("-A", chain, Optional.<String> absent(), protocol, port, policy); - } - - /** @deprecated since 0.7.0; use {@link #appendIptablesRule(Chain, brooklyn.util.net.Protocol, int, Policy)} */ - @Deprecated - public static String appendIptablesRule(Chain chain, Protocol protocol, int port, Policy policy) { - return appendIptablesRule(chain, protocol.convert(), port, policy); - } - - /** - * Returns the command that appends a rule to iptables. - * - * @return Returns the command that appends a rule to iptables. - */ - public static String appendIptablesRule(Chain chain, String networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - return addIptablesRule("-A", chain, Optional.of(networkInterface), protocol, port, policy); - } - - /** @deprecated since 0.7.0; use {@link #appendIptablesRule(Chain, String, brooklyn.util.net.Protocol, int, Policy)} */ - @Deprecated - public static String appendIptablesRule(Chain chain, String networkInterface, Protocol protocol, int port, Policy policy) { - return appendIptablesRule(chain, networkInterface, protocol.convert(), port, policy); - } - - /** - * Returns the command that creates a rule to iptables. - * - * @return Returns the command that creates a rule for iptables. - */ - public static String addIptablesRule(String direction, Chain chain, Optional<String> networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - String addIptablesRule; - if(networkInterface.isPresent()) { - addIptablesRule = String.format("/sbin/iptables %s %s -i %s -p %s --dport %d -j %s", direction, chain, networkInterface.get(), protocol, port, policy); - } else { - addIptablesRule = String.format("/sbin/iptables %s %s -p %s --dport %d -j %s", direction, chain, protocol, port, policy); - } - return sudo(addIptablesRule); - } - - /** @deprecated since 0.7.0; use {@link #addIptablesRule(String, Chain, Optional, brooklyn.util.net.Protocol, int, Policy)} */ - @Deprecated - public static String addIptablesRule(String direction, Chain chain, Optional<String> networkInterface, Protocol protocol, int port, Policy policy) { - return addIptablesRule(direction, chain, networkInterface, protocol.convert(), port, policy); - } - - /** - * Returns the command that adds firewalld direct rule. - * - * @return Returns the command that adds firewalld direct rule. - */ - public static String addFirewalldRule(Chain chain, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - return addFirewalldRule(chain, Optional.<String>absent(), protocol, port, policy); - } - - /** - * Returns the command that adds firewalld direct rule. - * - * @return Returns the command that adds firewalld direct rule. - */ - public static String addFirewalldRule(Chain chain, Optional<String> networkInterface, brooklyn.util.net.Protocol protocol, int port, Policy policy) { - String command = new String("/usr/bin/firewall-cmd"); - String commandPermanent = new String("/usr/bin/firewall-cmd --permanent"); - - String interfaceParameter = String.format("%s", networkInterface.isPresent() ? " -i " + networkInterface.get() : ""); - - String commandParameters = String.format(" --direct --add-rule ipv4 filter %s 0 %s -p %s --dport %d -j %s", - chain, interfaceParameter, protocol, port, policy); - - return sudo(chain(command + commandParameters, commandPermanent + commandParameters)); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java b/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java deleted file mode 100644 index a8a65c7..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/DelegatingPrintStream.java +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import java.io.IOException; -import java.io.PrintStream; -import java.util.Locale; - -/** PrintStream which simply delegates to the implementation of getDelegate() */ -public abstract class DelegatingPrintStream extends PrintStream { - - public DelegatingPrintStream() { - super(new IllegalOutputStream()); - } - - protected abstract PrintStream getDelegate(); - - public int hashCode() { - return getDelegate().hashCode(); - } - - public void write(byte[] b) throws IOException { - getDelegate().write(b); - } - - public boolean equals(Object obj) { - return getDelegate().equals(obj); - } - - public String toString() { - return getDelegate().toString(); - } - - public void flush() { - getDelegate().flush(); - } - - public void close() { - getDelegate().close(); - } - - public boolean checkError() { - return getDelegate().checkError(); - } - - public void write(int b) { - getDelegate().write(b); - } - - public void write(byte[] buf, int off, int len) { - getDelegate().write(buf, off, len); - } - - public void print(boolean b) { - getDelegate().print(b); - } - - public void print(char c) { - getDelegate().print(c); - } - - public void print(int i) { - getDelegate().print(i); - } - - public void print(long l) { - getDelegate().print(l); - } - - public void print(float f) { - getDelegate().print(f); - } - - public void print(double d) { - getDelegate().print(d); - } - - public void print(char[] s) { - getDelegate().print(s); - } - - public void print(String s) { - getDelegate().print(s); - } - - public void print(Object obj) { - getDelegate().print(obj); - } - - public void println() { - getDelegate().println(); - } - - public void println(boolean x) { - getDelegate().println(x); - } - - public void println(char x) { - getDelegate().println(x); - } - - public void println(int x) { - getDelegate().println(x); - } - - public void println(long x) { - getDelegate().println(x); - } - - public void println(float x) { - getDelegate().println(x); - } - - public void println(double x) { - getDelegate().println(x); - } - - public void println(char[] x) { - getDelegate().println(x); - } - - public void println(String x) { - getDelegate().println(x); - } - - public void println(Object x) { - getDelegate().println(x); - } - - public PrintStream printf(String format, Object... args) { - return getDelegate().printf(format, args); - } - - public PrintStream printf(Locale l, String format, Object... args) { - return getDelegate().printf(l, format, args); - } - - public PrintStream format(String format, Object... args) { - return getDelegate().format(format, args); - } - - public PrintStream format(Locale l, String format, Object... args) { - return getDelegate().format(l, format, args); - } - - public PrintStream append(CharSequence csq) { - return getDelegate().append(csq); - } - - public PrintStream append(CharSequence csq, int start, int end) { - return getDelegate().append(csq, start, end); - } - - public PrintStream append(char c) { - return getDelegate().append(c); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java b/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java deleted file mode 100644 index 827090a..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/IllegalOutputStream.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import java.io.OutputStream; - -/** output stream which throws if anyone tries to write to it */ -public class IllegalOutputStream extends OutputStream { - @Override public void write(int b) { - throw new IllegalStateException("should not write to this output stream"); - } - @Override public void write(byte[] b, int off, int len) { - throw new IllegalStateException("should not write to this output stream"); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java b/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java deleted file mode 100644 index d295e72..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/InputStreamSupplier.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import java.io.IOException; -import java.io.InputStream; - -import com.google.common.io.InputSupplier; - -public class InputStreamSupplier implements InputSupplier<InputStream> { - - private final InputStream target; - - /** @deprecated since 0.7.0; use {@link InputStreamSupplier#of(InputStream)} instead */ - @Deprecated - public InputStreamSupplier(InputStream target) { - this.target = target; - } - - @Override - public InputStream getInput() throws IOException { - return target; - } - - public static InputStreamSupplier of(InputStream target) { - return new InputStreamSupplier(target); - } - - public static InputStreamSupplier fromString(String input) { - return new InputStreamSupplier(Streams.newInputStreamWithContents(input)); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java b/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java deleted file mode 100644 index 8919af2..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/KnownSizeInputStream.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.io.InputStream; - -/** an input stream, whose size we know */ -public class KnownSizeInputStream extends InputStream { - - public static KnownSizeInputStream of(String contents) { - return of(contents.getBytes()); - } - - public static KnownSizeInputStream of(byte[] contents) { - return new KnownSizeInputStream(new ByteArrayInputStream(contents), contents.length); - } - - private final long length; - private final InputStream target; - - public KnownSizeInputStream(InputStream target, long length) { - this.target = checkNotNull(target, "target"); - this.length = length; - } - - public long length() { - return length; - } - - public InputStream getTarget() { - return target; - } - - @Override - public int read() throws IOException { - return target.read(); - } - - @Override - public int hashCode() { - return target.hashCode(); - } - - @Override - public int read(byte[] b) throws IOException { - return target.read(b); - } - - @Override - public boolean equals(Object obj) { - return target.equals(obj); - } - - @Override - public int read(byte[] b, int off, int len) throws IOException { - return target.read(b, off, len); - } - - @Override - public long skip(long n) throws IOException { - return target.skip(n); - } - - @Override - public int available() throws IOException { - return target.available(); - } - - @Override - public String toString() { - return target.toString(); - } - - @Override - public void close() throws IOException { - target.close(); - } - - @Override - public void mark(int readlimit) { - target.mark(readlimit); - } - - @Override - public void reset() throws IOException { - target.reset(); - } - - @Override - public boolean markSupported() { - return target.markSupported(); - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java b/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java deleted file mode 100644 index a3d5fab..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/ReaderInputStream.java +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import java.io.IOException; -import java.io.InputStream; -import java.io.Reader; - -public class ReaderInputStream extends InputStream { - - /** Source Reader */ - private Reader in; - - private String encoding = System.getProperty("file.encoding"); - - private byte[] slack; - - private int begin; - - /** - * Construct a <{@link ReaderInputStream} - * for the specified {@link Reader}. - * - * @param reader {@link Reader}; must not be {@code null}. - */ - public ReaderInputStream(Reader reader) { - in = reader; - } - - /** - * Construct a {@link ReaderInputStream} - * for the specified {@link Reader}, - * with the specified encoding. - * - * @param reader non-null {@link Reader}. - * @param encoding non-null {@link String} encoding. - */ - public ReaderInputStream(Reader reader, String encoding) { - this(reader); - if (encoding == null) { - throw new IllegalArgumentException("encoding must not be null"); - } else { - this.encoding = encoding; - } - } - - /** - * Reads from the {@link Reader}, returning the same value. - * - * @return the value of the next character in the {@link Reader}. - * - * @exception IOException if the original {@link Reader} fails to be read - */ - public synchronized int read() throws IOException { - if (in == null) { - throw new IOException("Stream Closed"); - } - - byte result; - if (slack != null && begin < slack.length) { - result = slack[begin]; - if (++begin == slack.length) { - slack = null; - } - } else { - byte[] buf = new byte[1]; - if (read(buf, 0, 1) <= 0) { - result = -1; - } - result = buf[0]; - } - - if (result < -1) { - result += 256; - } - - return result; - } - - /** - * Reads from the {@link Reader} into a byte array - * - * @param b the byte array to read into - * @param off the offset in the byte array - * @param len the length in the byte array to fill - * @return the actual number read into the byte array, -1 at - * the end of the stream - * @exception IOException if an error occurs - */ - public synchronized int read(byte[] b, int off, int len) - throws IOException { - if (in == null) { - throw new IOException("Stream Closed"); - } - - while (slack == null) { - char[] buf = new char[len]; // might read too much - int n = in.read(buf); - if (n == -1) { - return -1; - } - if (n > 0) { - slack = new String(buf, 0, n).getBytes(encoding); - begin = 0; - } - } - - if (len > slack.length - begin) { - len = slack.length - begin; - } - - System.arraycopy(slack, begin, b, off, len); - - if ((begin += len) >= slack.length) { - slack = null; - } - - return len; - } - - /** - * Marks the read limit of the StringReader. - * - * @param limit the maximum limit of bytes that can be read before the - * mark position becomes invalid - */ - public synchronized void mark(final int limit) { - try { - in.mark(limit); - } catch (IOException ioe) { - throw new RuntimeException(ioe.getMessage()); - } - } - - - /** - * @return the current number of bytes ready for reading - * @exception IOException if an error occurs - */ - public synchronized int available() throws IOException { - if (in == null) { - throw new IOException("Stream Closed"); - } - if (slack != null) { - return slack.length - begin; - } - if (in.ready()) { - return 1; - } else { - return 0; - } - } - - /** - * @return false - mark is not supported - */ - public boolean markSupported () { - return false; // would be imprecise - } - - /** - * Resets the StringReader. - * - * @exception IOException if the StringReader fails to be reset - */ - public synchronized void reset() throws IOException { - if (in == null) { - throw new IOException("Stream Closed"); - } - slack = null; - in.reset(); - } - - /** - * Closes the Stringreader. - * - * @exception IOException if the original StringReader fails to be closed - */ - public synchronized void close() throws IOException { - if (in != null) { - in.close(); - slack = null; - in = null; - } - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java b/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java deleted file mode 100644 index 7d5f9fe..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/StreamGobbler.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.OutputStream; -import java.io.PrintStream; -import java.util.concurrent.atomic.AtomicBoolean; - -import org.slf4j.Logger; - -public class StreamGobbler extends Thread implements Closeable { - - protected final InputStream stream; - protected final PrintStream out; - protected final Logger log; - private final AtomicBoolean running = new AtomicBoolean(true); - - public StreamGobbler(InputStream stream, OutputStream out, Logger log) { - this(stream, out != null ? new PrintStream(out) : null, log); - } - - public StreamGobbler(InputStream stream, PrintStream out, Logger log) { - this.stream = stream; - this.out = out; - this.log = log; - } - - @Override - public void close() { - running.set(false); - interrupt(); - } - - /** - * @deprecate Use close() instead. - */ - @Deprecated - public void shutdown() { - close(); - } - - String logPrefix = ""; - String printPrefix = ""; - public StreamGobbler setPrefix(String prefix) { - setLogPrefix(prefix); - setPrintPrefix(prefix); - return this; - } - public StreamGobbler setPrintPrefix(String prefix) { - printPrefix = prefix; - return this; - } - public StreamGobbler setLogPrefix(String prefix) { - logPrefix = prefix; - return this; - } - - @Override - public void run() { - int c = -1; - try { - while (running.get() && (c=stream.read())>=0) { - onChar(c); - } - onClose(); - } catch (IOException e) { - onClose(); - //TODO parametrise log level, for this error, and for normal messages - if (log!=null && log.isTraceEnabled()) log.trace(logPrefix+"exception reading from stream ("+e+")"); - } - } - - private final StringBuilder lineSoFar = new StringBuilder(16); - public void onChar(int c) { - if (c=='\n' || c=='\r') { - if (lineSoFar.length()>0) - //suppress blank lines, so that we can treat either newline char as a line separator - //(eg to show curl updates frequently) - onLine(lineSoFar.toString()); - lineSoFar.setLength(0); - } else { - lineSoFar.append((char)c); - } - } - - public void onLine(String line) { - //right trim, in case there is \r or other funnies - while (line.length()>0 && Character.isWhitespace(line.charAt(line.length()-1))) - line = line.substring(0, line.length()-1); - //right trim, in case there is \r or other funnies - while (line.length()>0 && (line.charAt(0)=='\n' || line.charAt(0)=='\r')) - line = line.substring(1); - if (!line.isEmpty()) { - if (out!=null) out.println(printPrefix+line); - if (log!=null && log.isDebugEnabled()) log.debug(logPrefix+line); - } - } - - public void onClose() { - onLine(lineSoFar.toString()); - if (out!=null) out.flush(); - lineSoFar.setLength(0); - finished = true; - synchronized (this) { notifyAll(); } - } - - private volatile boolean finished = false; - - /** convenience -- equivalent to calling join() */ - public void blockUntilFinished() throws InterruptedException { - synchronized (this) { while (!finished) wait(); } - } - - /** convenience -- similar to !Thread.isAlive() */ - public boolean isFinished() { - return finished; - } -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/Streams.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/Streams.java b/utils/common/src/main/java/brooklyn/util/stream/Streams.java deleted file mode 100644 index d7f0a7d..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/Streams.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import static com.google.common.base.Preconditions.checkNotNull; - -import java.io.ByteArrayOutputStream; -import java.io.Closeable; -import java.io.IOException; -import java.io.InputStream; -import java.io.InputStreamReader; -import java.io.OutputStream; -import java.io.Reader; -import java.io.StringReader; -import java.io.Writer; -import java.nio.charset.Charset; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import brooklyn.util.exceptions.Exceptions; - -import com.google.common.annotations.Beta; -import com.google.common.base.Charsets; -import com.google.common.base.Function; -import com.google.common.base.Preconditions; -import com.google.common.base.Supplier; -import com.google.common.io.ByteStreams; -import com.google.common.io.CharStreams; - -/** - * Methods to manage byte and character streams. - * - * @see com.google.common.io.ByteStreams - * @see com.google.common.io.CharStreams - */ -public class Streams { - - private static final Logger log = LoggerFactory.getLogger(Streams.class); - - /** drop-in non-deprecated replacement for {@link Closeable}'s deprecated closeQuiety; - * we may wish to review usages, particularly as we drop support for java 1.6, - * but until then use this instead of the deprecated method */ - @Beta - public static void closeQuietly(Closeable x) { - try { - if (x!=null) - x.close(); - } catch (Exception e) { - if (log.isDebugEnabled()) - log.debug("Error closing (ignored) "+x+": "+e); - } - } - - /** @deprecated since 0.7.0 use {@link #newInputStreamWithContents(String)} */ @Deprecated - public static InputStream fromString(String contents) { - return newInputStreamWithContents(contents); - } - - public static InputStream newInputStreamWithContents(String contents) { - byte[] bytes = checkNotNull(contents, "contents").getBytes(Charsets.UTF_8); - return KnownSizeInputStream.of(bytes); - } - - public static Reader newReaderWithContents(String contents) { - return new StringReader(contents); - } - - public static Reader reader(InputStream stream) { - return new InputStreamReader(stream); - } - - public static Reader reader(InputStream stream, Charset charset) { - return new InputStreamReader(stream, charset); - } - - /** reads the input stream fully, returning a byte array; throws unchecked exception on failure; - * to get a string, use <code>readFully(reader(is))</code> or <code>readFullyString(is)</code> */ - public static byte[] readFully(InputStream is) { - try { - return ByteStreams.toByteArray(is); - } catch (IOException ioe) { - throw Exceptions.propagate(ioe); - } - } - - public static String readFullyString(InputStream is) { - return readFully(reader(is)); - } - - public static String readFully(Reader is) { - try { - return CharStreams.toString(is); - } catch (IOException ioe) { - throw Exceptions.propagate(ioe); - } - } - - public static void copy(InputStream input, OutputStream output) { - try { - ByteStreams.copy(input, output); - output.flush(); - } catch (IOException ioe) { - throw Exceptions.propagate(ioe); - } - } - - public static void copy(Reader input, Writer output) { - try { - CharStreams.copy(input, output); - output.flush(); - } catch (IOException ioe) { - throw Exceptions.propagate(ioe); - } - } - - public static Supplier<Integer> sizeSupplier(final ByteArrayOutputStream src) { - Preconditions.checkNotNull(src); - return new Supplier<Integer>() { - @Override - public Integer get() { - return src.size(); - } - }; - } - - public static Function<ByteArrayOutputStream,Integer> sizeFunction() { - return new Function<ByteArrayOutputStream,Integer>() { - @Override - public Integer apply(ByteArrayOutputStream input) { - return input.size(); - } - }; - } - - public static ByteArrayOutputStream byteArrayOfString(String in) { - return byteArray(in.getBytes(Charsets.UTF_8)); - } - - public static ByteArrayOutputStream byteArray(byte[] in) { - ByteArrayOutputStream stream = new ByteArrayOutputStream(); - try { - stream.write(in); - } catch (IOException e) { - throw Exceptions.propagate(e); - } - return stream; - } - - public static boolean logStreamTail(Logger log, String message, ByteArrayOutputStream stream, int max) { - if (stream!=null && stream.size()>0) { - String streamS = stream.toString(); - if (max>=0 && streamS.length()>max) - streamS = "... "+streamS.substring(streamS.length()-max); - log.info(message+":\n"+streamS); - return true; - } - return false; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-brooklyn/blob/cf2f7a93/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java ---------------------------------------------------------------------- diff --git a/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java b/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java deleted file mode 100644 index 408aad8..0000000 --- a/utils/common/src/main/java/brooklyn/util/stream/ThreadLocalPrintStream.java +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one - * or more contributor license agreements. See the NOTICE file - * distributed with this work for additional information - * regarding copyright ownership. The ASF licenses this file - * to you 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 brooklyn.util.stream; - -import java.io.ByteArrayOutputStream; -import java.io.OutputStream; -import java.io.PrintStream; - -import org.apache.commons.io.output.TeeOutputStream; - -public class ThreadLocalPrintStream extends DelegatingPrintStream { - - protected PrintStream defaultPrintStream; - protected final ThreadLocal<PrintStream> customStream = new ThreadLocal<PrintStream>(); - - public ThreadLocalPrintStream(PrintStream defaultPrintStream) { - this.defaultPrintStream = defaultPrintStream; - } - - @Override - public PrintStream getDelegate() { - PrintStream delegate = customStream.get(); - if (delegate!=null) return delegate; - return defaultPrintStream; - } - - /** sets the PrintStream that callers from this thread should see; - * returns any previously custom PrintStream for this thread */ - public PrintStream setThreadLocalPrintStream(OutputStream stream) { - PrintStream old = customStream.get(); - if (!(stream instanceof PrintStream)) - stream = new PrintStream(stream); - customStream.set((PrintStream)stream); - return old; - } - - public PrintStream clearThreadLocalPrintStream() { - PrintStream old = customStream.get(); - customStream.remove(); - if (old!=null) old.flush(); - return old; - } - - /** creates a capturing context which eats the output to this stream, blocking the original target */ - public OutputCapturingContext capture() { - return new OutputCapturingContext(this); - } - - /** creates a capturing context which sees the output to this stream, without interrupting the original target */ - public OutputCapturingContext captureTee() { - ByteArrayOutputStream out = new ByteArrayOutputStream(); - PrintStream toRestore = setThreadLocalPrintStream(new TeeOutputStream(getDelegate(), out)); - return new OutputCapturingContext(this, out, toRestore); - } - - public static class OutputCapturingContext { - protected final ThreadLocalPrintStream stream; - protected final ByteArrayOutputStream out; - protected final OutputStream streamToRestore; - protected boolean finished = false; - /** constructor which installs a ByteArrayOutputStream to this stream */ - public OutputCapturingContext(ThreadLocalPrintStream stream) { - this.stream = stream; - this.out = new ByteArrayOutputStream(); - this.streamToRestore = stream.setThreadLocalPrintStream(out); - } - /** constructor for a capturing context which is already installed */ - public OutputCapturingContext(ThreadLocalPrintStream stream, ByteArrayOutputStream capturingStream, OutputStream optionalStreamToRestore) { - this.stream = stream; - this.out = capturingStream; - this.streamToRestore = optionalStreamToRestore; - } - public String getOutputSoFar() { - return out.toString(); - } - public String end() { - if (streamToRestore!=null) - stream.setThreadLocalPrintStream(streamToRestore); - else - stream.clearThreadLocalPrintStream(); - finished = true; - return out.toString(); - } - public boolean isActive() { - return !finished; - } - public ByteArrayOutputStream getOutputStream() { - return out; - } - @Override - public String toString() { - return getOutputSoFar(); - } - public boolean isEmpty() { - return out.size()==0; - } - } - - /** installs a thread local print stream to System.out if one is not already set; - * caller may then #capture and #captureTee on it. - * @return the ThreadLocalPrintStream which System.out is using */ - public synchronized static ThreadLocalPrintStream stdout() { - PrintStream oldOut = System.out; - if (oldOut instanceof ThreadLocalPrintStream) return (ThreadLocalPrintStream)oldOut; - ThreadLocalPrintStream newOut = new ThreadLocalPrintStream(System.out); - System.setOut(newOut); - return newOut; - } - - /** installs a thread local print stream to System.err if one is not already set; - * caller may then #capture and #captureTee on it. - * @return the ThreadLocalPrintStream which System.err is using */ - public synchronized static ThreadLocalPrintStream stderr() { - PrintStream oldErr = System.err; - if (oldErr instanceof ThreadLocalPrintStream) return (ThreadLocalPrintStream)oldErr; - ThreadLocalPrintStream newErr = new ThreadLocalPrintStream(System.err); - System.setErr(newErr); - return newErr; - } - -}
