Пример #1
0
  public HsErrPidList() {
    if (Functions.getIsUnitTest()) {
      return;
    }
    try {
      FileChannel ch = new FileInputStream(getSecretKeyFile()).getChannel();
      map = ch.map(MapMode.READ_ONLY, 0, 1);

      scan("./hs_err_pid%p.log");
      if (Functions.isWindows()) {
        File dir = Kernel32Utils.getTempDir();
        if (dir != null) {
          scan(dir.getPath() + "\\hs_err_pid%p.log");
        }
      } else {
        scan("/tmp/hs_err_pid%p.log");
      }
      // on different platforms, rules about the default locations are a lot more subtle.

      // check our arguments in the very end since this might fail on some platforms
      JavaVMArguments args = JavaVMArguments.current();
      for (String a : args) {
        // see http://www.oracle.com/technetwork/java/javase/felog-138657.html
        if (a.startsWith(ERROR_FILE_OPTION)) {
          scan(a.substring(ERROR_FILE_OPTION.length()));
        }
      }
    } catch (UnsupportedOperationException e) {
      // ignore
    } catch (Throwable e) {
      LOGGER.log(Level.WARNING, "Failed to list up hs_err_pid files", e);
    }
  }
Пример #2
0
 {
   StaplerRequest req = Stapler.getCurrentRequest();
   iconSize =
       req != null
           ? Functions.validateIconSize(Functions.getCookie(req, "iconSize", "32x32"))
           : "32x32";
 }
 /** Expect errors from {@link org.codehaus.groovy.runtime.NullObject}. */
 @Issue("kohsuke/groovy-sandbox #15")
 @Test
 public void nullPointerException() throws Exception {
   try {
     assertEvaluate(new ProxyWhitelist(), "should be rejected", "def x = null; x.member");
   } catch (NullPointerException x) {
     assertEquals(
         Functions.printThrowable(x),
         "Cannot get property 'member' on null object",
         x.getMessage());
   }
   try {
     assertEvaluate(new ProxyWhitelist(), "should be rejected", "def x = null; x.member = 42");
   } catch (NullPointerException x) {
     assertEquals(
         Functions.printThrowable(x),
         "Cannot set property 'member' on null object",
         x.getMessage());
   }
   try {
     assertEvaluate(new ProxyWhitelist(), "should be rejected", "def x = null; x.member()");
   } catch (NullPointerException x) {
     assertEquals(
         Functions.printThrowable(x),
         "Cannot invoke method member() on null object",
         x.getMessage());
   }
 }
Пример #4
0
 public Map<String, String> call() {
   Map<String, String> r = new LinkedHashMap<String, String>();
   ThreadInfo[] data = Functions.getThreadInfos();
   Functions.ThreadGroupMap map = Functions.sortThreadsAndGetGroupMap(data);
   for (ThreadInfo ti : data) r.put(ti.getThreadName(), Functions.dumpThreadInfo(ti, map));
   return r;
 }
    public ContextMenu add(Action a) {
      StaplerRequest req = Stapler.getCurrentRequest();
      String text = a.getDisplayName();
      String base = Functions.getIconFilePath(a);
      if (base == null) return this;
      String icon =
          Stapler.getCurrentRequest().getContextPath()
              + (base.startsWith("images/") ? Functions.getResourcePath() : "")
              + '/'
              + base;

      String url = Functions.getActionUrl(req.findAncestor(ModelObject.class).getUrl(), a);

      return add(url, icon, text);
    }
Пример #6
0
 @Extension
 public static DescriptorImpl install() {
   if (!Functions.isWindows()) {
     return new DescriptorImpl();
   }
   return null;
 }
Пример #7
0
  public void testSymlink() throws Exception {
    if (Functions.isWindows()) return;

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    StreamTaskListener l = new StreamTaskListener(baos);
    File d = Util.createTempDir();
    try {
      new FilePath(new File(d, "a")).touch(0);
      Util.createSymlink(d, "a", "x", l);
      assertEquals("a", Util.resolveSymlink(new File(d, "x"), l));

      // test a long name
      StringBuilder buf = new StringBuilder(768);
      for (int i = 0; i < 768; i++) buf.append('0' + (i % 10));
      Util.createSymlink(d, buf.toString(), "x", l);

      String log = baos.toString();
      if (log.length() > 0) {
        System.err.println("log output: " + log);
        if (log.contains("ln failed: 78" /*ENAMETOOLONG*/)) {
          buf.setLength(0);
          // Try again with shorter name for this system
          for (int i = 0; i < 254; i++) buf.append('0' + (i % 10));
          Util.createSymlink(d, buf.toString(), "x", l);
        }
      }

      assertEquals(buf.toString(), Util.resolveSymlink(new File(d, "x"), l));
    } finally {
      Util.deleteRecursive(d);
    }
  }
Пример #8
0
 @Override
 protected synchronized JSON data() {
   JSONArray r = new JSONArray();
   for (User u : modified) {
     UserInfo i = users.get(u);
     JSONObject entry =
         new JSONObject()
             .accumulate("id", u.getId())
             .accumulate("fullName", u.getFullName())
             .accumulate("url", u.getUrl())
             .accumulate(
                 "avatar",
                 i.avatar != null
                     ? i.avatar
                     : Stapler.getCurrentRequest().getContextPath()
                         + Functions.getResourcePath()
                         + "/images/"
                         + iconSize
                         + "/user.png")
             .accumulate("timeSortKey", i.getTimeSortKey())
             .accumulate("lastChangeTimeString", i.getLastChangeTimeString());
     AbstractProject<?, ?> p = i.getProject();
     if (p != null) {
       entry
           .accumulate("projectUrl", p.getUrl())
           .accumulate("projectFullDisplayName", p.getFullDisplayName());
     }
     r.add(entry);
   }
   modified.clear();
   return r;
 }
Пример #9
0
  /** Fake installation on Unix. */
  @Test
  public void fakeUnixInstall() throws Exception {
    Assume.assumeFalse("If we're on Windows, don't bother doing this", Functions.isWindows());

    File bundle = File.createTempFile("fake-jdk-by-hudson", "sh");
    try {
      new FilePath(bundle)
          .write(
              "#!/bin/bash -ex\n"
                  + "mkdir -p jdk1.6.0_dummy/bin\n"
                  + "touch jdk1.6.0_dummy/bin/java",
              "ASCII");
      TaskListener l = StreamTaskListener.fromStdout();

      new JDKInstaller("", true)
          .install(
              new LocalLauncher(l),
              Platform.LINUX,
              new JDKInstaller.FilePathFileSystem(j.jenkins),
              l,
              tmp.getRoot().getPath(),
              bundle.getPath());

      assertTrue(new File(tmp.getRoot(), "bin/java").exists());
    } finally {
      bundle.delete();
    }
  }
  @Issue("JENKINS-30941")
  @Test
  public void cleanUpSucceeds() throws Exception {
    /** Issue was just present on Linux not windows - but the test will run on both */
    final String credentialsId = "zipfile";

    /* do the dance to get a simple zip file into jenkins */
    InputStream zipStream = this.getClass().getResourceAsStream("a.zip");
    try {
      assertThat(zipStream, is(not(nullValue())));
      File zip = tmp.newFile("a.zip");
      FileUtils.copyInputStreamToFile(zipStream, zip);
      FileItem fi = new FileItemImpl(zip);
      FileCredentialsImpl fc =
          new FileCredentialsImpl(
              CredentialsScope.GLOBAL, credentialsId, "Just a zip file", fi, fi.getName(), null);
      CredentialsProvider.lookupStores(j.jenkins)
          .iterator()
          .next()
          .addCredentials(Domain.global(), fc);
    } finally {
      IOUtils.closeQuietly(zipStream);
      zipStream = null;
    }

    final String unixFile = "/dir/testfile.txt";
    final String winFile =
        unixFile.replace(
            "/", "\\\\"); /* two \\ as we escape the code and then escape for the script */
    // if this file does not have a line ending then the text is not echoed to the log.
    // fixed in workflow 1.11+ (which is not released at the time of writing)
    final String contents = "Test of ZipFileBinding\n";

    WorkflowJob p = j.jenkins.createProject(WorkflowJob.class, "p");
    p.setDefinition(
        new CpsFlowDefinition(
            ""
                + "node {\n"
                + "  withCredentials([[$class: 'ZipFileBinding', credentialsId: '"
                + credentialsId
                + "', variable: 'ziploc']]) {\n"
                + (Functions.isWindows()
                    ? "    bat 'type %ziploc%" + winFile + "'\n"
                    : "    sh 'cat ${ziploc}" + unixFile + "'\n")
                + "    def text = readFile encoding: 'UTF-8', file: \"${env.ziploc}"
                + unixFile
                + "\"\n"
                + "    if (!text.equals('''"
                + contents
                + "''')) {\n"
                + "      error ('incorrect details from zip file')\n"
                + "    }\n"
                + "  }\n"
                + "}\n",
            true));

    WorkflowRun run = p.scheduleBuild2(0).get();
    j.assertBuildStatusSuccess(run);
    j.assertLogContains(contents, run);
  }
 /** @return configured dot executable or a default */
 public String getDotExeOrDefault() {
   if (Util.fixEmptyAndTrim(dotExe) == null) {
     return Functions.isWindows() ? "dot.exe" : "dot";
   } else {
     return dotExe;
   }
 }
Пример #12
0
 @Test
 public void deleteFile() throws Exception {
   Assume.assumeTrue(Functions.isWindows());
   Class<?> c;
   try {
     c = Class.forName("java.nio.file.FileSystemException");
   } catch (ClassNotFoundException x) {
     throw new AssumptionViolatedException("prior to JDK 7", x);
   }
   File d = Util.createTempDir();
   try {
     File f = new File(d, "f");
     OutputStream os = new FileOutputStream(f);
     try {
       Util.deleteFile(f);
       fail("should not have been deletable");
     } catch (IOException x) {
       assertEquals(c, x.getClass());
     } finally {
       os.close();
     }
   } finally {
     Util.deleteRecursive(d);
   }
 }
Пример #13
0
  @Test
  public void testIsSymlink() throws IOException, InterruptedException {
    Assume.assumeTrue(!Functions.isWindows());

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    StreamTaskListener l = new StreamTaskListener(baos);
    File d = Util.createTempDir();
    try {
      new FilePath(new File(d, "original")).touch(0);
      assertFalse(Util.isSymlink(new File(d, "original")));
      Util.createSymlink(d, "original", "link", l);

      assertTrue(Util.isSymlink(new File(d, "link")));

      // test linking to another directory
      File dir = new File(d, "dir");
      assertTrue("Couldn't create " + dir, dir.mkdir());
      assertFalse(Util.isSymlink(new File(d, "dir")));

      File anotherDir = new File(d, "anotherDir");
      assertTrue("Couldn't create " + anotherDir, anotherDir.mkdir());

      Util.createSymlink(d, "dir", "anotherDir/symlinkDir", l);
      // JENKINS-12331: either a bug in createSymlink or this isn't supposed to work:
      // assertTrue(Util.isSymlink(new File(d,"anotherDir/symlinkDir")));
    } finally {
      Util.deleteRecursive(d);
    }
  }
Пример #14
0
 @Restricted(DoNotUse.class) // accessed via REST API
 public HttpResponse doGenerateSnippet(StaplerRequest req, @QueryParameter String json)
     throws Exception {
   // TODO JENKINS-31458 is there not an easier way to do this?
   JSONObject jsonO = JSONObject.fromObject(json);
   Jenkins j = Jenkins.getActiveInstance();
   Class<?> c = j.getPluginManager().uberClassLoader.loadClass(jsonO.getString("stapler-class"));
   StepDescriptor descriptor = (StepDescriptor) j.getDescriptor(c.asSubclass(Step.class));
   Object o;
   try {
     o = descriptor.newInstance(req, jsonO);
   } catch (RuntimeException x) { // e.g. IllegalArgumentException
     return HttpResponses.plainText(Functions.printThrowable(x));
   }
   try {
     String groovy = object2Groovy(o);
     if (descriptor.isAdvanced()) {
       String warning = Messages.Snippetizer_this_step_should_not_normally_be_used_in();
       groovy = "// " + warning + "\n" + groovy;
     }
     return HttpResponses.plainText(groovy);
   } catch (UnsupportedOperationException x) {
     Logger.getLogger(CpsFlowExecution.class.getName())
         .log(Level.WARNING, "failed to render " + json, x);
     return HttpResponses.plainText(x.getMessage());
   }
 }
Пример #15
0
    @Override
    public Publisher newInstance(StaplerRequest req, JSONObject formData) {
      Mailer m = new Mailer();
      req.bindParameters(m, "mailer_");
      m.dontNotifyEveryUnstableBuild = req.getParameter("mailer_notifyEveryUnstableBuild") == null;

      if (hudsonUrl == null) {
        // if Hudson URL is not configured yet, infer some default
        hudsonUrl = Functions.inferHudsonURL(req);
        save();
      }

      return m;
    }
Пример #16
0
    public final String getUrl() {
        // try to stick to the current view if possible
        StaplerRequest req = Stapler.getCurrentRequest();
        if (req != null) {
            String seed = Functions.getNearestAncestorUrl(req,this);
            if(seed!=null) {
                // trim off the context path portion and leading '/', but add trailing '/'
                return seed.substring(req.getContextPath().length()+1)+'/';
            }
        }

        // otherwise compute the path normally
        return getParent().getUrl()+getShortUrl();
    }
    /**
     * If true, we can do ADSI/COM based look up that's far more reliable. False if we need to do
     * the authentication in pure Java via {@link ActiveDirectoryUnixAuthenticationProvider}
     */
    public boolean canDoNativeAuth() {
      if (!Functions.isWindows()) return false;

      try {
        ClassFactory.createConnection().dispose();
        return true;
      } catch (Throwable t) {
        if (!WARNED) {
          LOGGER.log(
              Level.INFO, "COM4J isn't working. Falling back to non-native authentication", t);
          WARNED = true;
        }
        return false;
      }
    }
 private static void expectRejection(
     MatrixProject project, String combinationFilter, String signature) throws IOException {
   ScriptApproval scriptApproval = ScriptApproval.get();
   assertEquals(Collections.emptySet(), scriptApproval.getPendingSignatures());
   try {
     project.setCombinationFilter(combinationFilter);
   } catch (RejectedAccessException x) {
     assertEquals(Functions.printThrowable(x), signature, x.getSignature());
   }
   Set<ScriptApproval.PendingSignature> pendingSignatures = scriptApproval.getPendingSignatures();
   assertEquals(1, pendingSignatures.size());
   assertEquals(signature, pendingSignatures.iterator().next().signature);
   scriptApproval.approveSignature(signature);
   assertEquals(Collections.emptySet(), scriptApproval.getPendingSignatures());
 }
Пример #19
0
  @Bug(22641)
  public void testProcessProperlyKilledUnix() throws Exception {
    ProcessTree.enabled = true;
    if (Functions.isWindows()) return; // This test does not involve windows.

    FreeStyleProject sleepProject = createFreeStyleProject();
    FreeStyleProject processJob = createFreeStyleProject();

    sleepProject.getBuildersList().add(new Shell("nohup sleep 100000 &"));

    assertBuildStatusSuccess(sleepProject.scheduleBuild2(0).get());

    processJob.getBuildersList().add(new Shell("ps -ef | grep sleep"));

    assertLogNotContains("sleep 100000", processJob.scheduleBuild2(0).get());
  }
Пример #20
0
  @Test
  public void testSymlink() throws Exception {
    Assume.assumeTrue(!Functions.isWindows());

    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    StreamTaskListener l = new StreamTaskListener(baos);
    File d = Util.createTempDir();
    try {
      new FilePath(new File(d, "a")).touch(0);
      assertNull(Util.resolveSymlink(new File(d, "a")));
      Util.createSymlink(d, "a", "x", l);
      assertEquals("a", Util.resolveSymlink(new File(d, "x")));

      // test a long name
      StringBuilder buf = new StringBuilder(768);
      for (int i = 0; i < 768; i++) buf.append((char) ('0' + (i % 10)));
      Util.createSymlink(d, buf.toString(), "x", l);

      String log = baos.toString();
      if (log.length() > 0) System.err.println("log output: " + log);

      assertEquals(buf.toString(), Util.resolveSymlink(new File(d, "x")));

      // test linking from another directory
      File anotherDir = new File(d, "anotherDir");
      assertTrue("Couldn't create " + anotherDir, anotherDir.mkdir());

      Util.createSymlink(d, "a", "anotherDir/link", l);
      assertEquals("a", Util.resolveSymlink(new File(d, "anotherDir/link")));

      // JENKINS-12331: either a bug in createSymlink or this isn't supposed to work:
      // assertTrue(Util.isSymlink(new File(d,"anotherDir/link")));

      File external = File.createTempFile("something", "");
      try {
        Util.createSymlink(d, external.getAbsolutePath(), "outside", l);
        assertEquals(external.getAbsolutePath(), Util.resolveSymlink(new File(d, "outside")));
      } finally {
        assertTrue(external.delete());
      }
    } finally {
      Util.deleteRecursive(d);
    }
  }
Пример #21
0
  /**
   * Gets the {@link User} object by its id or full name.
   *
   * @param create If true, this method will never return null for valid input (by creating a new
   *     {@link User} object if none exists.) If false, this method will return null if {@link User}
   *     object with the given name doesn't exist.
   */
  public static User get(String idOrFullName, boolean create) {
    if (idOrFullName == null) return null;
    String id =
        idOrFullName
            .replace('\\', '_')
            .replace('/', '_')
            .replace('<', '_')
            .replace('>', '_'); // 4 replace() still faster than regex
    if (Functions.isWindows()) id = id.replace(':', '_');

    synchronized (byName) {
      User u = byName.get(id);
      if (u == null) {
        User tmp = new User(id, idOrFullName);
        if (create || tmp.getConfigFile().exists()) {
          byName.put(id, u = tmp);
        }
      }
      return u;
    }
  }
Пример #22
0
    /**
     * Send an email to the admin address
     *
     * @throws IOException
     * @throws ServletException
     * @throws InterruptedException
     */
    public FormValidation doSendTestMail(
        @QueryParameter String smtpServer,
        @QueryParameter String adminAddress,
        @QueryParameter boolean useSMTPAuth,
        @QueryParameter String smtpAuthUserName,
        @QueryParameter String smtpAuthPassword,
        @QueryParameter boolean useSsl,
        @QueryParameter String smtpPort)
        throws IOException, ServletException, InterruptedException {
      try {
        if (!useSMTPAuth) smtpAuthUserName = smtpAuthPassword = null;

        MimeMessage msg =
            new MimeMessage(
                createSession(
                    smtpServer,
                    smtpPort,
                    useSsl,
                    smtpAuthUserName,
                    Secret.fromString(smtpAuthPassword)));
        msg.setSubject("Test email #" + ++testEmailCount);
        msg.setContent(
            "This is test email #"
                + testEmailCount
                + " sent from Hudson Continuous Integration server.",
            "text/plain");
        msg.setFrom(new InternetAddress(adminAddress));
        msg.setSentDate(new Date());
        msg.setRecipient(Message.RecipientType.TO, new InternetAddress(adminAddress));

        Transport.send(msg);

        return FormValidation.ok("Email was successfully sent");
      } catch (MessagingException e) {
        return FormValidation.errorWithMarkup(
            "<p>Failed to send out e-mail</p><pre>"
                + Util.escape(Functions.printThrowable(e))
                + "</pre>");
      }
    }
    private boolean createSdCard(File homeDir) {
      // Build command: mksdcard 32M /home/foo/.android/avd/whatever.avd/sdcard.img
      ArgumentListBuilder builder =
          Utils.getToolCommand(androidSdk, !Functions.isWindows(), Tool.MKSDCARD, null);
      builder.add(sdCardSize);
      builder.add(new File(getAvdDirectory(homeDir), "sdcard.img"));

      // Run!
      try {
        ProcessBuilder procBuilder = new ProcessBuilder(builder.toList());
        if (androidSdkHome != null) {
          procBuilder.environment().put("ANDROID_SDK_HOME", androidSdkHome);
        }
        procBuilder.start().waitFor();
      } catch (InterruptedException ex) {
        return false;
      } catch (IOException ex) {
        return false;
      }

      return true;
    }
 @Override
 public String getHelpFile() {
   return Functions.getResourcePath() + "/plugin/android-device/help-buildConfig.html";
 }
    /** validate the value for a remote (repository) location. */
    public FormValidation doCheckCredentialsId(
        StaplerRequest req,
        @AncestorInPath SCMSourceOwner context,
        @QueryParameter String remoteBase,
        @QueryParameter String value) {
      // TODO suspiciously similar to
      // SubversionSCM.ModuleLocation.DescriptorImpl.checkCredentialsId; refactor into shared
      // method?
      // Test the connection only if we may use the credentials
      if (context == null && !Jenkins.getActiveInstance().hasPermission(Jenkins.ADMINISTER)
          || context != null && !context.hasPermission(CredentialsProvider.USE_ITEM)) {
        return FormValidation.ok();
      }

      // if check remote is reporting an issue then we don't need to
      String url = Util.fixEmptyAndTrim(remoteBase);
      if (url == null) return FormValidation.ok();

      if (!URL_PATTERN.matcher(url).matches()) return FormValidation.ok();

      try {
        String urlWithoutRevision = SvnHelper.getUrlWithoutRevision(url);

        SVNURL repoURL = SVNURL.parseURIDecoded(urlWithoutRevision);

        StandardCredentials credentials =
            value == null
                ? null
                : CredentialsMatchers.firstOrNull(
                    CredentialsProvider.lookupCredentials(
                        StandardCredentials.class,
                        context,
                        ACL.SYSTEM,
                        URIRequirementBuilder.fromUri(repoURL.toString()).build()),
                    CredentialsMatchers.withId(value));
        if (checkRepositoryPath(context, repoURL, credentials) != SVNNodeKind.NONE) {
          // something exists; now check revision if any

          SVNRevision revision = getRevisionFromRemoteUrl(url);
          if (revision != null && !revision.isValid()) {
            return FormValidation.errorWithMarkup(
                hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_invalidRevision());
          }

          return FormValidation.ok();
        }

        SVNRepository repository = null;
        try {
          repository =
              getRepository(
                  context, repoURL, credentials, Collections.<String, Credentials>emptyMap(), null);
          long rev = repository.getLatestRevision();
          // now go back the tree and find if there's anything that exists
          String repoPath = getRelativePath(repoURL, repository);
          String p = repoPath;
          while (p.length() > 0) {
            p = SVNPathUtil.removeTail(p);
            if (repository.checkPath(p, rev) == SVNNodeKind.DIR) {
              // found a matching path
              List<SVNDirEntry> entries = new ArrayList<SVNDirEntry>();
              repository.getDir(p, rev, false, entries);

              // build up the name list
              List<String> paths = new ArrayList<String>();
              for (SVNDirEntry e : entries)
                if (e.getKind() == SVNNodeKind.DIR) paths.add(e.getName());

              String head = SVNPathUtil.head(repoPath.substring(p.length() + 1));
              String candidate = EditDistance.findNearest(head, paths);

              return FormValidation.error(
                  hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPathSuggest(
                      p, head, candidate != null ? "/" + candidate : ""));
            }
          }

          return FormValidation.error(
              hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_badPath(repoPath));
        } finally {
          if (repository != null) repository.closeSession();
        }
      } catch (SVNException e) {
        LOGGER.log(Level.INFO, "Failed to access subversion repository " + url, e);
        String message =
            hudson.scm.subversion.Messages.SubversionSCM_doCheckRemote_exceptionMsg1(
                    Util.escape(url),
                    Util.escape(e.getErrorMessage().getFullMessage()),
                    "javascript:document.getElementById('svnerror').style.display='block';"
                        + "document.getElementById('svnerrorlink').style.display='none';"
                        + "return false;")
                + "<br/><pre id=\"svnerror\" style=\"display:none\">"
                + Functions.printThrowable(e)
                + "</pre>";
        return FormValidation.errorWithMarkup(message);
      }
    }
Пример #26
0
 /**
  * Used to render the side panel "Back to project" link.
  *
  * <p>In a rare situation where a build can be reached from multiple paths, returning different
  * URLs from this method based on situations might be desirable.
  *
  * <p>If you override this method, you'll most likely also want to override {@link
  * #getDisplayName()}.
  */
 public String getUpUrl() {
   return Functions.getNearestAncestorUrl(Stapler.getCurrentRequest(), getParent()) + '/';
 }
    public Boolean call() throws AndroidEmulatorException {
      if (logger == null) {
        logger = listener.getLogger();
      }

      final File homeDir = Utils.getHomeDirectory(androidSdk.getSdkHome());
      final File avdDirectory = getAvdDirectory(homeDir);
      final boolean emulatorExists = getAvdConfigFile(homeDir).exists();

      // Can't do anything if a named emulator doesn't exist
      if (isNamedEmulator() && !emulatorExists) {
        throw new EmulatorDiscoveryException(Messages.AVD_DOES_NOT_EXIST(avdName, avdDirectory));
      }

      // Check whether AVD needs to be created
      boolean createSdCard = false;
      boolean createSnapshot = false;
      File snapshotsFile = new File(getAvdDirectory(homeDir), "snapshots.img");
      if (emulatorExists) {
        // AVD exists: check whether there's anything still to be set up
        File sdCardFile = new File(getAvdDirectory(homeDir), "sdcard.img");
        boolean sdCardRequired = getSdCardSize() != null;

        // Check if anything needs to be done for snapshot-enabled builds
        if (shouldUseSnapshots() && androidSdk.supportsSnapshots()) {
          if (!snapshotsFile.exists()) {
            createSnapshot = true;
          }

          // We should ensure that we start out with a clean SD card for the build
          if (sdCardRequired && sdCardFile.exists()) {
            sdCardFile.delete();
          }
        }

        // Flag that we need to generate an SD card, if there isn't one existing
        if (sdCardRequired && !sdCardFile.exists()) {
          createSdCard = true;
        }

        // If everything is ready, then return
        if (!createSdCard && !createSnapshot) {
          return true;
        }
      } else {
        AndroidEmulator.log(logger, Messages.CREATING_AVD(avdDirectory));
      }

      // We can't continue if we don't know where to find emulator images or tools
      if (!androidSdk.hasKnownRoot()) {
        throw new EmulatorCreationException(Messages.SDK_NOT_SPECIFIED());
      }
      final File sdkRoot = new File(androidSdk.getSdkRoot());
      if (!sdkRoot.exists()) {
        throw new EmulatorCreationException(Messages.SDK_NOT_FOUND(androidSdk.getSdkRoot()));
      }

      // If we need to initialise snapshot support for an existing emulator, do so
      if (createSnapshot) {
        // Copy the snapshots file into place
        File snapshotDir = new File(sdkRoot, "tools/lib/emulator");
        Util.copyFile(new File(snapshotDir, "snapshots.img"), snapshotsFile);

        // Update the AVD config file mark snapshots as enabled
        Map<String, String> configValues;
        try {
          configValues = parseAvdConfigFile(homeDir);
          configValues.put("snapshot.present", "true");
          writeAvdConfigFile(homeDir, configValues);
        } catch (IOException e) {
          throw new EmulatorCreationException(Messages.AVD_CONFIG_NOT_READABLE(), e);
        }
      }

      // If we need create an SD card for an existing emulator, do so
      if (createSdCard) {
        AndroidEmulator.log(logger, Messages.ADDING_SD_CARD(sdCardSize, getAvdName()));
        if (!createSdCard(homeDir)) {
          throw new EmulatorCreationException(Messages.SD_CARD_CREATION_FAILED());
        }

        // Update the AVD config file
        Map<String, String> configValues;
        try {
          configValues = parseAvdConfigFile(homeDir);
          configValues.put("sdcard.size", sdCardSize);
          writeAvdConfigFile(homeDir, configValues);
        } catch (IOException e) {
          throw new EmulatorCreationException(Messages.AVD_CONFIG_NOT_READABLE(), e);
        }
      }

      // Return if everything is now ready for use
      if (emulatorExists) {
        return true;
      }

      // Build up basic arguments to `android` command
      final StringBuilder args = new StringBuilder(100);
      args.append("create avd ");

      // Overwrite any existing files
      args.append("-f ");

      // Initialise snapshot support, regardless of whether we will actually use it
      if (androidSdk.supportsSnapshots()) {
        args.append("-a ");
      }

      if (sdCardSize != null) {
        args.append("-c ");
        args.append(sdCardSize);
        args.append(" ");
      }
      args.append("-s ");
      args.append(screenResolution.getSkinName());
      args.append(" -n ");
      args.append(getAvdName());
      boolean isUnix = !Functions.isWindows();
      ArgumentListBuilder builder =
          Utils.getToolCommand(androidSdk, isUnix, Tool.ANDROID, args.toString());

      // Tack on quoted platform name at the end, since it can be anything
      builder.add("-t");
      builder.add(osVersion.getTargetName());

      if (targetAbi != null) {
        builder.add("--abi");
        builder.add(targetAbi);
      }

      // Log command line used, for info
      AndroidEmulator.log(logger, builder.toStringWithQuote());

      // Run!
      boolean avdCreated = false;
      final Process process;
      try {
        ProcessBuilder procBuilder = new ProcessBuilder(builder.toList());
        if (androidSdk.hasKnownHome()) {
          procBuilder.environment().put("ANDROID_SDK_HOME", androidSdk.getSdkHome());
        }
        process = procBuilder.start();
      } catch (IOException ex) {
        throw new EmulatorCreationException(Messages.AVD_CREATION_FAILED());
      }

      // Redirect process's stderr to a stream, for logging purposes
      ByteArrayOutputStream stderr = new ByteArrayOutputStream();
      ByteArrayOutputStream stdout = new ByteArrayOutputStream();
      new StreamCopyThread("", process.getErrorStream(), stderr).start();

      // Command may prompt us whether we want to further customise the AVD.
      // Just "press" Enter to continue with the selected target's defaults.
      try {
        boolean processAlive = true;

        // Block until the command outputs something (or process ends)
        final PushbackInputStream in = new PushbackInputStream(process.getInputStream(), 10);
        int len = in.read();
        if (len == -1) {
          // Check whether the process has exited badly, as sometimes no output is valid.
          // e.g. When creating an AVD with Google APIs, no user input is requested.
          if (process.waitFor() != 0) {
            AndroidEmulator.log(logger, Messages.AVD_CREATION_FAILED());
            AndroidEmulator.log(logger, stderr.toString(), true);
            throw new EmulatorCreationException(Messages.AVD_CREATION_FAILED());
          }
          processAlive = false;
        }
        in.unread(len);

        // Write CRLF, if required
        if (processAlive) {
          final OutputStream stream = process.getOutputStream();
          stream.write('\r');
          stream.write('\n');
          stream.flush();
          stream.close();
        }

        // read the rest of stdout (for debugging purposes)
        Util.copyStream(in, stdout);
        in.close();

        // Wait for happy ending
        if (process.waitFor() == 0) {
          // Do a sanity check to ensure the AVD was really created
          avdCreated = getAvdConfigFile(homeDir).exists();
        }

      } catch (IOException e) {
        throw new EmulatorCreationException(Messages.AVD_CREATION_ABORTED(), e);
      } catch (InterruptedException e) {
        throw new EmulatorCreationException(Messages.AVD_CREATION_INTERRUPTED(), e);
      } finally {
        process.destroy();
      }

      // For reasons unknown, the return code may not be correctly reported on Windows.
      // So check whether stderr contains failure info (useful for other platforms too).
      String errOutput = stderr.toString();
      String output = stdout.toString();
      if (errOutput.contains("list targets")) {
        AndroidEmulator.log(logger, Messages.INVALID_AVD_TARGET(osVersion.getTargetName()));
        avdCreated = false;
        errOutput = null;
      } else if (errOutput.contains("more than one ABI")) {
        AndroidEmulator.log(
            logger, Messages.MORE_THAN_ONE_ABI(osVersion.getTargetName(), output), true);
        avdCreated = false;
        errOutput = null;
      }

      // Check everything went ok
      if (!avdCreated) {
        if (errOutput != null && errOutput.length() != 0) {
          AndroidEmulator.log(logger, stderr.toString(), true);
        }
        throw new EmulatorCreationException(Messages.AVD_CREATION_FAILED());
      }

      // Done!
      return false;
    }
 private void configureDumpEnvBuilder() throws IOException {
   if (Functions.isWindows()) project.getBuildersList().add(new BatchFile("set"));
   else project.getBuildersList().add(new Shell("export"));
 }
Пример #29
0
 public String getShellOrDefault() {
   if (shell == null) {
     return Functions.isWindows() ? "sh" : "/bin/sh";
   }
   return shell;
 }
Пример #30
0
 public String call() throws IOException {
   return Functions.isWindows() ? "sh" : "/bin/sh";
 }