@Override
 public void preInstall() {
   resolver = Entities.newDownloader(this);
   String subpath = entity.getConfig(BrooklynNode.SUBPATH_IN_ARCHIVE);
   if (subpath == null) {
     // assume the dir name is `basename-VERSION` where download link is
     // `basename-VERSION-dist.tar.gz`
     String uploadUrl = entity.getConfig(BrooklynNode.DISTRO_UPLOAD_URL);
     String origDownloadName = uploadUrl;
     if (origDownloadName == null)
       origDownloadName = entity.getAttribute(BrooklynNode.DOWNLOAD_URL);
     if (origDownloadName != null) {
       // BasicDownloadResolver makes it crazy hard to get the template-evaluated value of
       // DOWNLOAD_URL
       origDownloadName =
           DownloadSubstituters.substitute(
               origDownloadName, DownloadSubstituters.getBasicEntitySubstitutions(this));
       origDownloadName = Urls.decode(origDownloadName);
       origDownloadName = Urls.getBasename(origDownloadName);
       String downloadName = origDownloadName;
       downloadName = Strings.removeFromEnd(downloadName, ".tar.gz");
       downloadName = Strings.removeFromEnd(downloadName, ".tgz");
       downloadName = Strings.removeFromEnd(downloadName, ".zip");
       if (!downloadName.equals(origDownloadName)) {
         downloadName = Strings.removeFromEnd(downloadName, "-dist");
         subpath = downloadName;
       }
     }
   }
   if (subpath == null) subpath = format("brooklyn-dist-%s", getVersion());
   setExpandedInstallDir(
       Os.mergePaths(getInstallDir(), resolver.getUnpackedDirectoryName(subpath)));
 }
  @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();
    }
  }