diff --git a/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java b/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java index b70332eb06..7b9e72507c 100644 --- a/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java +++ b/software/base/src/main/java/brooklyn/entity/java/JavaSoftwareProcessSshDriver.java @@ -262,10 +262,10 @@ protected boolean checkForAndInstallJava6or7() { } else { // Let's hope not! if (version.isPresent()) { - log.debug("Found Java version {} on {}@{}. Going to install Java 7.", + log.debug("Found old Java version {} on {}@{}. Going to install latest Java version.", new Object[]{version.get(), getEntity(), getLocation()}); } - return tryJavaInstall("7", BashCommands.installJava7OrFail()) == 0; + return tryJavaInstall("latest", BashCommands.installJava7Or6OrFail()) == 0; } } diff --git a/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java b/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java index d7dbd0464b..421a3b376d 100644 --- a/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java +++ b/software/messaging/src/main/java/brooklyn/entity/messaging/rabbit/RabbitSshDriver.java @@ -1,6 +1,21 @@ +/* + * Copyright 2012-2014 by Cloudsoft Corporation Limited + * + * Licensed 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.entity.messaging.rabbit; -import static brooklyn.util.ssh.BashCommands.installPackage; +import static brooklyn.util.ssh.BashCommands.*; import static java.lang.String.format; import java.util.List; @@ -16,7 +31,6 @@ import brooklyn.location.basic.SshMachineLocation; import brooklyn.util.collections.MutableMap; import brooklyn.util.net.Networking; -import brooklyn.util.ssh.BashCommands; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -51,15 +65,20 @@ public void install() { List urls = resolver.getTargets(); String saveAs = resolver.getFilename(); setExpandedInstallDir(getInstallDir()+"/"+resolver.getUnpackedDirectoryName(format("rabbitmq_server-%s", getVersion()))); - + List commands = ImmutableList.builder() - .add(installPackage(// NOTE only 'port' states the version of Erlang used, maybe remove this constraint? + .add(ifExecutableElse0("zypper", 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"))))) + .add(installPackage( // NOTE only 'port' states the version of Erlang used, maybe remove this constraint? ImmutableMap.of( "apt", "erlang-nox erlang-dev", "port", "erlang@"+getErlangVersion()+"+ssl"), "erlang")) - .addAll(BashCommands.commandsToDownloadUrlsAs(urls, saveAs)) - .add(BashCommands.installExecutable("tar")) + .addAll(commandsToDownloadUrlsAs(urls, saveAs)) + .add(installExecutable("tar")) .add(format("tar xvzf %s",saveAs)) .build(); diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNode.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNode.java index 137f971758..f568250dcf 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNode.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNode.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 by Cloudsoft Corp. + * Copyright 2012-2014 by Cloudsoft Corporation Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,13 +27,19 @@ /** * An {@link brooklyn.entity.Entity} that represents a CouchDB node in a {@link CouchDBCluster}. */ -@Catalog(name="CouchDB Node", description="Apache CouchDB is a database that uses JSON for documents, JavaScript for MapReduce queries, and regular HTTP for an API", iconUrl="classpath:///couchdb-logo.png") +@Catalog(name="CouchDB Node", + description="Apache CouchDB is a database that uses JSON for documents, JavaScript for MapReduce queries, " + + "and regular HTTP for an API", + iconUrl="classpath:///couchdb-logo.png") @ImplementedBy(CouchDBNodeImpl.class) public interface CouchDBNode extends SoftwareProcess, WebAppService { @SetFromFlag("version") ConfigKey SUGGESTED_VERSION = ConfigKeys.newConfigKeyWithDefault(SoftwareProcess.SUGGESTED_VERSION, "1.2.1"); + @SetFromFlag("erlangVersion") + ConfigKey ERLANG_VERSION = ConfigKeys.newStringConfigKey("erlang.version", "Erlang runtime version", "R15B"); + @SetFromFlag("clusterName") BasicAttributeSensorAndConfigKey CLUSTER_NAME = CouchDBCluster.CLUSTER_NAME; diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeDriver.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeDriver.java index 5f73126c22..d4960678ce 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeDriver.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeDriver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 by Cloudsoft Corp. + * Copyright 2012-2014 by Cloudsoft Corporation Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,9 +15,9 @@ */ package brooklyn.entity.nosql.couchdb; -import brooklyn.entity.java.JavaSoftwareProcessDriver; +import brooklyn.entity.basic.SoftwareProcessDriver; -public interface CouchDBNodeDriver extends JavaSoftwareProcessDriver { +public interface CouchDBNodeDriver extends SoftwareProcessDriver { Integer getHttpPort(); diff --git a/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java b/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java index 49362411b9..461a3918e4 100644 --- a/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java +++ b/software/nosql/src/main/java/brooklyn/entity/nosql/couchdb/CouchDBNodeSshDriver.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2013 by Cloudsoft Corp. + * Copyright 2012-2014 by Cloudsoft Corporation Limited * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,8 @@ */ package brooklyn.entity.nosql.couchdb; -import java.io.ByteArrayInputStream; +import static brooklyn.util.ssh.BashCommands.*; + import java.util.List; import java.util.Map; import java.util.Set; @@ -23,12 +24,13 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import brooklyn.entity.java.JavaSoftwareProcessSshDriver; +import brooklyn.entity.basic.AbstractSoftwareProcessSshDriver; +import brooklyn.entity.basic.Attributes; import brooklyn.location.Location; import brooklyn.location.basic.SshMachineLocation; import brooklyn.util.collections.MutableMap; import brooklyn.util.net.Networking; -import brooklyn.util.ssh.BashCommands; +import brooklyn.util.os.Os; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; @@ -37,16 +39,17 @@ /** * Start a {@link CouchDBNode} in a {@link Location} accessible over ssh. */ -public class CouchDBNodeSshDriver extends JavaSoftwareProcessSshDriver implements CouchDBNodeDriver { +public class CouchDBNodeSshDriver extends AbstractSoftwareProcessSshDriver implements CouchDBNodeDriver { private static final Logger log = LoggerFactory.getLogger(CouchDBNodeSshDriver.class); public CouchDBNodeSshDriver(CouchDBNodeImpl entity, SshMachineLocation machine) { super(entity, machine); + + entity.setAttribute(Attributes.LOG_FILE_LOCATION, getLogFileLocation()); } - @Override - protected String getLogFileLocation() { return String.format("%s/couchdb.log", getRunDir()); } + public String getLogFileLocation() { return Os.mergePathsUnix(getRunDir(), "couchdb.log"); } @Override public Integer getHttpPort() { return entity.getAttribute(CouchDBNode.HTTP_PORT); } @@ -66,21 +69,34 @@ public CouchDBNodeSshDriver(CouchDBNodeImpl entity, SshMachineLocation machine) @Override public String getCouchDBConfigFileName() { return entity.getAttribute(CouchDBNode.COUCHDB_CONFIG_FILE_NAME); } + public String getErlangVersion() { return entity.getConfig(CouchDBNode.ERLANG_VERSION); } + @Override public void install() { log.info("Installing {}", entity); List commands = ImmutableList.builder() - .add(BashCommands.installPackage("erlang")) - .add(BashCommands.installPackage("couchdb")) - .add("which service && sudo service couchdb stop") + .add(ifExecutableElse0("zypper", chainGroup( // SLES 11 not supported, would require building from source + 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")), + ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/server:/database/openSUSE_11.4 db_suse_11")), + ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/server:/database/openSUSE_12.3 db_suse_12")), + ok(sudo("zypper --non-interactive addrepo http://download.opensuse.org/repositories/server:/database/openSUSE_13.1 db_suse_13"))))) + .add(installPackage( // NOTE only 'port' states the version of Erlang used, maybe remove this constraint? + ImmutableMap.of( + "apt", "erlang-nox erlang-dev", + "port", "erlang@"+getErlangVersion()+"+ssl"), + "erlang")) + .add(installPackage("couchdb")) + .add(ifExecutableElse0("service", sudo("service couchdb stop"))) .build(); newScript(INSTALLING) - .failOnNonZeroResultCode() .body.append(commands) .execute(); } + @Override public Set getPortsUsed() { Set result = Sets.newLinkedHashSet(super.getPortsUsed()); result.addAll(getPortMap().values()); @@ -101,36 +117,33 @@ public void customize() { newScript(CUSTOMIZING).execute(); // Copy the configuration files across - String configFileContents = processTemplate(getCouchDBConfigTemplateUrl()); - String destinationConfigFile = String.format("%s/%s", getRunDir(), getCouchDBConfigFileName()); - getMachine().copyTo(new ByteArrayInputStream(configFileContents.getBytes()), destinationConfigFile); - String uriFileContents = processTemplate(getCouchDBUriTemplateUrl()); - String destinationUriFile = String.format("%s/couch.uri", getRunDir()); - getMachine().copyTo(new ByteArrayInputStream(uriFileContents.getBytes()), destinationUriFile); + String destinationConfigFile = Os.mergePathsUnix(getRunDir(), getCouchDBConfigFileName()); + copyTemplate(getCouchDBConfigTemplateUrl(), destinationConfigFile); + String destinationUriFile = Os.mergePathsUnix(getRunDir(), "couch.uri"); + copyTemplate(getCouchDBUriTemplateUrl(), destinationUriFile); } @Override public void launch() { log.info("Launching {}", entity); - newScript(MutableMap.of("usePidFile", false), LAUNCHING) - .body.append(String.format("sudo nohup couchdb -p %s -a %s/%s -o couchdb-console.log -e couchdb-error.log -b &", getPidFile(), getRunDir(), getCouchDBConfigFileName())) - .failOnNonZeroResultCode() + newScript(MutableMap.of(USE_PID_FILE, false), LAUNCHING) + .body.append(sudo(String.format("nohup couchdb -p %s -a %s -o couchdb-console.log -e couchdb-error.log -b &", getPidFile(), Os.mergePathsUnix(getRunDir(), getCouchDBConfigFileName())))) .execute(); } - public String getPidFile() { return String.format("%s/couchdb.pid", getRunDir()); } + public String getPidFile() { return Os.mergePathsUnix(getRunDir(), "couchdb.pid"); } @Override public boolean isRunning() { - return newScript(MutableMap.of("usePidFile", false), CHECK_RUNNING) - .body.append(String.format("sudo couchdb -p %s -s", getPidFile())) + return newScript(MutableMap.of(USE_PID_FILE, false), CHECK_RUNNING) + .body.append(sudo(String.format("couchdb -p %s -s", getPidFile()))) .execute() == 0; } @Override public void stop() { - newScript(MutableMap.of("usePidFile", false), STOPPING) - .body.append(String.format("sudo couchdb -p %s -k", getPidFile())) + newScript(MutableMap.of(USE_PID_FILE, false), STOPPING) + .body.append(sudo(String.format("couchdb -p %s -k", getPidFile()))) .failOnNonZeroResultCode() .execute(); } diff --git a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxSshDriver.java b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxSshDriver.java index ec8f68f5a4..917293f305 100644 --- a/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxSshDriver.java +++ b/software/webapp/src/main/java/brooklyn/entity/proxy/nginx/NginxSshDriver.java @@ -126,15 +126,18 @@ public void install() { "onlyifmissing", "gcc", "yum", "gcc", "apt", "gcc", + "zypper", "gcc", "port", null); MutableMap installMakePackageFlags = MutableMap.of( "onlyifmissing", "make", "yum", "make", "apt", "make", + "zypper", "make", "port", null); MutableMap installPackageFlags = MutableMap.of( "yum", "openssl-devel pcre-devel", "apt", "libssl-dev zlib1g-dev libpcre3-dev", + "zypper", "libopenssl-devel pcre-devel", "port", null); String stickyModuleVersion = entity.getConfig(NginxController.STICKY_VERSION); diff --git a/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java b/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java index 6097098d75..e79576f3db 100644 --- a/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java +++ b/utils/common/src/main/java/brooklyn/util/ssh/BashCommands.java @@ -1,3 +1,18 @@ +/* + * Copyright 2012-2014 by Cloudsoft Corporation Limited + * + * Licensed 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 java.lang.String.format; @@ -15,6 +30,7 @@ import brooklyn.util.text.Strings; import com.google.common.annotations.Beta; +import com.google.common.base.Preconditions; import com.google.common.collect.ImmutableMap; public class BashCommands { @@ -66,7 +82,7 @@ public static String ok(String command) { * If null is supplied, it is returned (sometimes used to indicate no command desired). */ public static String sudo(String command) { - if (command.startsWith("( ")) + if (command.startsWith("( ") || command.endsWith(" &")) return sudoNew(command); else return sudoOld(command); @@ -287,6 +303,7 @@ public static String installPackageOrFail(Map flags, String packageDefaultN } 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)); @@ -295,6 +312,12 @@ public static String installPackageOr(Map flags, String packageDefaultName, List commands = new LinkedList(); 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( @@ -424,25 +447,58 @@ private static Object getFlag(Map flags, String flagName, Object defaultVal } /** - * Returns the command that installs Java 1.6. - * See also: JavaSoftwareProcessSshDriver.installJava, which does a much more thorough job. + * Install a particular Java runtime, fails if not possible. + *

+ * Note Java 8 is not yet supported on SUSE * - * @return the command that install Java 1.6. + * @return The command to install the given Java runtime. + * @see #installJava6OrFail() + * @see #installJava7Or6OrFail() + * @see #installJavaLatestOrFail() */ + public static String installJava(Integer 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 installPackage(MutableMap.of("apt", "openjdk-6-jdk","yum", "java-1.6.0-openjdk-devel"), null); + return ok(installJava6()); } - public static String installJava6OrFail() { - return installPackageOrFail(MutableMap.of("apt", "openjdk-6-jdk","yum", "java-1.6.0-openjdk-devel"), null); + 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 BashCommands.installPackageOrFail(MutableMap.of("apt", "openjdk-7-jdk","yum", "java-1.7.0-openjdk-devel"), null); + return alternatives(installJava7(), fail("java 7 install failed", 9)); } - public static String installJava7Or6OrFail() { - return BashCommands.installPackageOr(MutableMap.of("apt", "openjdk-7-jdk","yum", "java-1.7.0-openjdk-devel"), null, - BashCommands.installJava6OrFail()); + return alternatives(installJava7(), installJava6(), fail("java install failed", 9)); + } + public static String installJavaLatestOrFail() { + return alternatives(installJava8(), installJava7(), installJava6(), fail("java latest install failed", 9)); } /** cats the given text to the given command, using bash << multi-line input syntax */