/** 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); }
/** 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 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,
/** * 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); }
/** * Returns a command which upgrades NSS on Yum based machines - Addresses https://issues.apache.org/jira/browse/BROOKLYN-320 * @return command */ public static String upgradeNSS(){ return chainGroup( "which yum", sudo("yum -y upgrade nss")); }
/** 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); }
private String getAptRepository() { return chainGroup( sudo("apt-key adv --fetch-keys http://apt.postgresql.org/pub/repos/apt/ACCC4CF8.asc"), "echo \"deb http://apt.postgresql.org/pub/repos/apt/ $(sudo lsb_release --codename --short)-pgdg main\" | sudo tee -a /etc/apt/sources.list.d/postgresql.list" ); }
@Override public String apply(@Nullable String dir) { return ifExecutableElse1(Urls.mergePaths(dir, filename), chainGroup("echo 'found "+filename+" in "+dir+" so linking to it in "+linkToMake+"'", "ln -s "+dir+" "+linkToMake)); } };
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); }
private String useYum(String osVersion, String arch, String epelRelease) { String osMajorVersion = osVersion.substring(0, osVersion.lastIndexOf(".")); return chainGroup( alternatives( sudo("rpm -qa | grep epel-release"), sudo(format("rpm -Uvh http://dl.fedoraproject.org/pub/epel/%s/%s/epel-release-%s.noarch.rpm", osMajorVersion, arch, epelRelease)))); }
/** * Adds the PPA for OpenJDK for older JDK versions (7 and lower) required by some software (e.g. JBoss) */ public static String addOpenJDKPPK(){ return chainGroup( sudo("sudo add-apt-repository -y ppa:openjdk-r/ppa"), sudo("sudo apt-get update")); }
private String getAptRepository() { String debFileName = "erlang-repo.deb"; return chainGroup( INSTALL_CURL, format("curl %s -o %s", entity.config().get(RabbitBroker.ERLANG_DEB_REPO_URL), debFileName), sudo(format("dpkg -i %s", debFileName)) ); }
/** 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")); }
private String setupAptRepo(SshMachineLocation sshMachineLocation) { final String osDetailsVersion = getOsVersion(sshMachineLocation); String repoUrl; if (osDetailsVersion.startsWith("14")) { repoUrl = UBUNTU_14_AMBARI_REPO_LOCATION; } else { repoUrl = UBUNTU_12_AMBARI_REPO_LOCATION; } return ifExecutableElse1("apt-get", chainGroup(sudo(commandToDownloadUrlAs(String.format(repoUrl, repoBaseUrl, getMajorVersion(), version), UBUNTU_REPO_LIST_LOCATION)), sudo("apt-key adv --recv-keys --keyserver keyserver.ubuntu.com B9733A7A07513CAD"), sudo("apt-get update"))); }
/** * Some machines require a TTY for sudo. Brooklyn by default does not use a TTY * so that it can get separate STDERR and 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. If this task has already been executed it * will try to detect the changes and do nothing. * <p> * This command must be run with allocatePTY set as a flag to ssh. * See {@link SshTasks#dontRequireTtyForSudo(SshMachineLocation, OnFailingTask)} 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() { String sudoersFileName = "/etc/sudoers"; String tmpSuffix = Identifiers.makeRandomLowercaseId(6); // Avoid clobbering // Visudo's quiet mode (-q) is not enabled. visudo's output is used for diagnostic purposes return ifFileExistsElse0(sudoersFileName, alternatives( sudo(format("grep brooklyn-removed-require-tty %s", sudoersFileName)), chainGroup( sudo(format("cp %1$s %1$s.%2$s", sudoersFileName, tmpSuffix)), sudo(format("sed -i.brooklyn.bak 's/.*requiretty.*/#brooklyn-removed-require-tty/' %1$s.%2$s", sudoersFileName, tmpSuffix)), sudo(format("visudo -c -f %1$s.%2$s", sudoersFileName, tmpSuffix)), sudo(format("mv %1$s.%2$s %1$s", sudoersFileName, tmpSuffix))))); }
public String installAmbariRequirements(SshMachineLocation machine) { return BashCommands.chainGroup(BashCommands.INSTALL_CURL, installExecutable("ntp"), BashCommands.alternatives(sudo("service ntpd start"), sudo("service ntp start")), createCommandToAddAmbariToRepositoriesList(machine)); }
return chainGroup( sudo(commandToDownloadUrlAs( format("http://yum.postgresql.org/%s/redhat/rhel-%s-%s/pgdg-%s%s-%s.noarch.rpm", majorMinorVersion, osMajorVersion, arch, osName, shortVersion, version),
/** * 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"); List<String> commands = new LinkedList<String>(); commands.add(ok(addOpenJDKPPK())); commands.add(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)))))); commands.add(ok(upgradeNSS())); return chainGroup(commands); }
return chainGroup( installPackage("apt-transport-https"), "echo 'deb https://apt.dockerproject.org/repo " + dockerRepoName + " main' | " + sudo("tee -a /etc/apt/sources.list.d/docker.list"),
private String getZypperRepository() { return chainGroup( ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/devel:/languages:/erlang/SLE_11_SP3 erlang_sles_11")), ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/devel:/languages:/erlang/openSUSE_11.4 erlang_suse_11")), ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/devel:/languages:/erlang/openSUSE_12.3 erlang_suse_12")), ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/devel:/languages:/erlang/openSUSE_13.1 erlang_suse_13"))); } }