Example #1
0
 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();
    }
  }
Example #3
0
 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);
    }
  }