public static final Optional<String> httpPost( Entity framework, String subUrl, String dataUrl, Map<String, Object> substitutions) { String targetUrl = Urls.mergePaths(framework.sensors().get(MesosFramework.FRAMEWORK_URL), subUrl); String templateContents = ResourceUtils.create().getResourceAsString(dataUrl); String processedJson = TemplateProcessor.processTemplateContents(templateContents, substitutions); LOG.debug("Posting JSON to {}: {}", targetUrl, processedJson); URI postUri = URI.create(targetUrl); HttpToolResponse response = HttpTool.httpPost( MesosUtils.buildClient(framework), postUri, MutableMap.of( HttpHeaders.CONTENT_TYPE, "application/json", HttpHeaders.ACCEPT, "application/json"), processedJson.getBytes()); LOG.debug("Response: " + response.getContentAsString()); if (!HttpTool.isStatusCodeHealthy(response.getResponseCode())) { LOG.warn( "Invalid response code {}: {}", response.getResponseCode(), response.getReasonPhrase()); return Optional.absent(); } else { LOG.debug("Successfull call to {}: {}", targetUrl); return Optional.of(response.getContentAsString()); } }
@Override public void install() { Maybe<Object> url = ((EntityInternal) getEntity()).config().getRaw(SoftwareProcess.DOWNLOAD_URL); if (url.isPresentAndNonNull()) { DownloadResolver resolver = Entities.newDownloader(this); List<String> urls = resolver.getTargets(); downloadedFilename = resolver.getFilename(); List<String> commands = new LinkedList<String>(); commands.addAll(BashCommands.commandsToDownloadUrlsAs(urls, downloadedFilename)); commands.addAll(ArchiveUtils.installCommands(downloadedFilename)); int result = newScript(ImmutableMap.of(INSTALL_INCOMPLETE, true), INSTALLING) .failOnNonZeroResultCode(false) .body .append(commands) .execute(); if (result != 0) { // could not install at remote machine; try resolving URL here and copying across for (String urlI : urls) { result = ArchiveUtils.install( getMachine(), urlI, Urls.mergePaths(getInstallDir(), downloadedFilename)); if (result == 0) break; } if (result != 0) throw new IllegalStateException("Error installing archive: " + downloadedFilename); } } // If downloadUrl did partial install (see INSTALL_INCOMPLETE above) then always execute install // so mark it as completed. String installCommand = getEntity().getConfig(VanillaSoftwareProcess.INSTALL_COMMAND); if (url.isPresentAndNonNull() && Strings.isBlank(installCommand)) installCommand = "# mark as complete"; if (Strings.isNonBlank(installCommand)) { newScript(INSTALLING) .failOnNonZeroResultCode() .environmentVariablesReset(getShellEnvironment()) .body .append(installCommand) .execute(); } }
public static final Optional<String> httpDelete(Entity framework, String subUrl) { String targetUrl = Urls.mergePaths(framework.sensors().get(MesosFramework.FRAMEWORK_URL), subUrl); LOG.debug("Deleting {}", targetUrl); URI deleteUri = URI.create(targetUrl); HttpToolResponse response = HttpTool.httpDelete( buildClient(framework), deleteUri, MutableMap.of(HttpHeaders.ACCEPT, "application/json")); LOG.debug("Response: " + response.getContentAsString()); if (!HttpTool.isStatusCodeHealthy(response.getResponseCode())) { LOG.warn( "Invalid response code {}: {}", response.getResponseCode(), response.getReasonPhrase()); return Optional.absent(); } else { LOG.debug("Successfull call to {}: {}", targetUrl); return Optional.of(response.getContentAsString()); } }
@SuppressWarnings({"unchecked", "deprecation"}) protected void startWithChefSoloAsync() { String baseDir = MachineLifecycleEffectorTasks.resolveOnBoxDir( entity(), Machines.findUniqueMachineLocation(entity().getLocations(), SshMachineLocation.class) .get()); String installDir = Urls.mergePaths(baseDir, "installs/chef"); @SuppressWarnings("rawtypes") Map<String, String> cookbooks = (Map) ConfigBag.newInstance(entity().getConfig(CHEF_COOKBOOK_URLS)) .putIfAbsent(entity().getConfig(CHEF_COOKBOOKS)) .getAllConfig(); if (cookbooks.isEmpty()) log.warn("No cookbook_urls set for " + entity() + "; launch will likely fail subsequently"); DynamicTasks.queue( ChefSoloTasks.installChef(installDir, false), ChefSoloTasks.installCookbooks(installDir, cookbooks, false)); // TODO chef for and run a prestart recipe if necessary // TODO open ports String primary = getPrimaryCookbook(); // put all config under brooklyn/cookbook/config Navigator<MutableMap<Object, Object>> attrs = Jsonya.newInstancePrimitive().at("brooklyn"); if (Strings.isNonBlank(primary)) attrs.at(primary); attrs.at("config"); attrs.put(entity().getAllConfigBag().getAllConfig()); // and put launch attrs at root try { attrs .root() .put( (Map<?, ?>) Tasks.resolveDeepValue( entity().getConfig(CHEF_LAUNCH_ATTRIBUTES), Object.class, entity().getExecutionContext())); } catch (Exception e) { Exceptions.propagate(e); } Collection<? extends String> runList = entity().getConfig(CHEF_LAUNCH_RUN_LIST); if (runList == null) runList = entity().getConfig(CHEF_RUN_LIST); if (runList == null) { if (Strings.isNonBlank(primary)) runList = ImmutableList.of(primary + "::" + "start"); else throw new IllegalStateException( "Require a primary cookbook or a run_list to effect " + "start" + " on " + entity()); } String runDir = Urls.mergePaths( baseDir, "apps/" + entity().getApplicationId() + "/chef/entities/" + entity().getEntityType().getSimpleName() + "_" + entity().getId()); DynamicTasks.queue( ChefSoloTasks.buildChefFile( runDir, installDir, "launch", runList, (Map<String, Object>) attrs.root().get())); DynamicTasks.queue( ChefSoloTasks.runChef(runDir, "launch", entity().getConfig(CHEF_RUN_CONVERGE_TWICE))); }
public String getJmxSslTrustStoreFilePath() { return Urls.mergePaths(jmxSupport.getRunDir(), "jmx-truststore"); }
public String getJmxSslKeyStoreFilePath() { return Urls.mergePaths(jmxSupport.getRunDir(), "jmx-keystore"); }
/* * TODO this is much messier than we would like because postgres runs as user postgres, * meaning the dirs must be RW by that user, and accessible (thus all parent paths), * which may rule out putting it in a location used by the default user. * Two irritating things: * * currently we sometimes make up a different onbox base dir; * * currently we put files to /tmp for staging * Could investigate if it really needs to run as user postgres; * could also see whether default user can be added to group postgres, * and the run dir (and all parents) made accessible to group postgres. */ @Override public void install() { String version = getEntity().getConfig(SoftwareProcess.SUGGESTED_VERSION); String majorMinorVersion = version.substring(0, version.lastIndexOf("-")); String shortVersion = majorMinorVersion.replace(".", ""); String altTarget = "/opt/brooklyn/postgres/"; String altInstallDir = Urls.mergePaths(altTarget, "install/" + majorMinorVersion); Iterable<String> pgctlLocations = ImmutableList.of( altInstallDir + "/bin", "/usr/lib/postgresql/" + majorMinorVersion + "/bin/", "/opt/local/lib/postgresql" + shortVersion + "/bin/", "/usr/pgsql-" + majorMinorVersion + "/bin", "/usr/local/bin/", "/usr/bin/", "/bin/"); DynamicTasks.queueIfPossible( SshTasks.dontRequireTtyForSudo( getMachine(), // sudo is absolutely required here, in customize we set user to postgres OnFailingTask.FAIL)) .orSubmitAndBlock(); DynamicTasks.waitForLast(); // Check whether we can find a usable pg_ctl, and if not install one MutableList<String> findOrInstall = MutableList.<String>of() .append("which pg_ctl") .appendAll( Iterables.transform(pgctlLocations, StringFunctions.formatter("test -x %s/pg_ctl"))) .append( installPackage( ImmutableMap.of( "yum", "postgresql" + shortVersion + " postgresql" + shortVersion + "-server", "apt", "postgresql-" + majorMinorVersion, "port", "postgresql" + shortVersion + " postgresql" + shortVersion + "-server"), null)) // due to impl of installPackage, it will not come to the line below I don't think .append( warn( format( "WARNING: failed to find or install postgresql %s binaries", majorMinorVersion))); // Link to correct binaries folder (different versions of pg_ctl and psql don't always play well // together) MutableList<String> linkFromHere = MutableList.<String>of() .append( ifExecutableElse1( "pg_ctl", chainGroup( "PG_EXECUTABLE=`which pg_ctl`", "PG_DIR=`dirname $PG_EXECUTABLE`", "echo 'found pg_ctl in '$PG_DIR' on path so linking PG bin/ to that dir'", "ln -s $PG_DIR bin"))) .appendAll( Iterables.transform( pgctlLocations, givenDirIfFileExistsInItLinkToDir("pg_ctl", "bin"))) .append( fail( format( "WARNING: failed to find postgresql %s binaries for pg_ctl, may already have another version installed; aborting", majorMinorVersion), 9)); newScript(INSTALLING) .body .append( dontRequireTtyForSudo(), ifExecutableElse0("yum", getYumRepository(version, majorMinorVersion, shortVersion)), ifExecutableElse0("apt-get", getAptRepository()), "rm -f bin", // if left over from previous incomplete/failed install (not sure why that // keeps happening!) alternativesGroup(findOrInstall), alternativesGroup(linkFromHere)) .failOnNonZeroResultCode() .queue(); // check that the proposed install dir is one that user postgres can access // TODO if command above fails then the following `getUnchecked` blocks forever if (DynamicTasks.queue( SshEffectorTasks.ssh(sudoAsUser("postgres", "ls " + getInstallDir())) .allowingNonZeroExitCode() .summary("check postgres user can access install dir")) .asTask() .getUnchecked() != 0) { log.info( "Postgres install dir " + getInstallDir() + " for " + getEntity() + " is not accessible to user 'postgres'; " + "using " + altInstallDir + " instead"); String newRunDir = Urls.mergePaths( altTarget, "apps", getEntity().getApplication().getId(), getEntity().getId()); if (DynamicTasks.queue( SshEffectorTasks.ssh("ls " + altInstallDir + "/pg_ctl") .allowingNonZeroExitCode() .summary("check whether " + altInstallDir + " is set up")) .asTask() .getUnchecked() == 0) { // alt target already exists with binary; nothing to do for install } else { DynamicTasks.queue( SshEffectorTasks.ssh( "mkdir -p " + altInstallDir, "rm -rf '" + altInstallDir + "'", "mv " + getInstallDir() + " " + altInstallDir, "rm -rf '" + getInstallDir() + "'", "ln -s " + altInstallDir + " " + getInstallDir(), "mkdir -p " + newRunDir, "chown -R postgres:postgres " + altTarget) .runAsRoot() .requiringExitCodeZero() .summary("move install dir from user to postgres owned space")); } DynamicTasks.waitForLast(); setInstallDir(altInstallDir); setRunDir(newRunDir); } }