use of hudson.util.ArgumentListBuilder in project hudson-2.x by hudson.
the class JDKInstaller method install.
/**
* Performs the JDK installation to a system, provided that the bundle was already downloaded.
*
* @param launcher
* Used to launch processes on the system.
* @param p
* Platform of the system. This determines how the bundle is installed.
* @param fs
* Abstraction of the file system manipulation on this system.
* @param log
* Where the output from the installation will be written.
* @param expectedLocation
* Path to install JDK to. Must be absolute and in the native file system notation.
* @param jdkBundle
* Path to the installed JDK bundle. (The bundle to download can be determined by {@link #locate(TaskListener, Platform, CPU)} call.)
*/
public void install(Launcher launcher, Platform p, FileSystem fs, TaskListener log, String expectedLocation, String jdkBundle) throws IOException, InterruptedException {
PrintStream out = log.getLogger();
out.println("Installing " + jdkBundle);
switch(p) {
case LINUX:
case SOLARIS:
fs.chmod(jdkBundle, 0755);
int exit = launcher.launch().cmds(jdkBundle, "-noregister").stdin(new ByteArrayInputStream("yes".getBytes())).stdout(out).pwd(new FilePath(launcher.getChannel(), expectedLocation)).join();
if (exit != 0)
throw new AbortException(Messages.JDKInstaller_FailedToInstallJDK(exit));
// JDK creates its own sub-directory, so pull them up
List<String> paths = fs.listSubDirectories(expectedLocation);
for (Iterator<String> itr = paths.iterator(); itr.hasNext(); ) {
String s = itr.next();
if (!s.matches("j(2s)?dk.*"))
itr.remove();
}
if (paths.size() != 1)
throw new AbortException("Failed to find the extracted JDKs: " + paths);
// remove the intermediate directory
fs.pullUp(expectedLocation + '/' + paths.get(0), expectedLocation);
break;
case WINDOWS:
/*
Windows silent installation is full of bad know-how.
On Windows, command line argument to a process at the OS level is a single string,
not a string array like POSIX. When we pass arguments as string array, JRE eventually
turn it into a single string with adding quotes to "the right place". Unfortunately,
with the strange argument layout of InstallShield (like /v/qn" INSTALLDIR=foobar"),
it appears that the escaping done by JRE gets in the way, and prevents the installation.
Presumably because of this, my attempt to use /q/vn" INSTALLDIR=foo" didn't work with JDK5.
I tried to locate exactly how InstallShield parses the arguments (and why it uses
awkward option like /qn, but couldn't find any. Instead, experiments revealed that
"/q/vn ARG ARG ARG" works just as well. This is presumably due to the Visual C++ runtime library
(which does single string -> string array conversion to invoke the main method in most Win32 process),
and this consistently worked on JDK5 and JDK4.
Some of the official documentations are available at
- http://java.sun.com/j2se/1.5.0/sdksilent.html
- http://java.sun.com/j2se/1.4.2/docs/guide/plugin/developer_guide/silent.html
*/
String logFile = jdkBundle + ".install.log";
ArgumentListBuilder args = new ArgumentListBuilder();
args.add(jdkBundle);
args.add("/s");
// according to http://community.acresso.com/showthread.php?t=83301, \" is the trick to quote values with whitespaces.
// Oh Windows, oh windows, why do you have to be so difficult?
args.add("/v/qn REBOOT=Suppress INSTALLDIR=\\\"" + expectedLocation + "\\\" /L \\\"" + logFile + "\\\"");
int r = launcher.launch().cmds(args).stdout(out).pwd(new FilePath(launcher.getChannel(), expectedLocation)).join();
if (r != 0) {
out.println(Messages.JDKInstaller_FailedToInstallJDK(r));
// log file is in UTF-16
InputStreamReader in = new InputStreamReader(fs.read(logFile), "UTF-16");
try {
IOUtils.copy(in, new OutputStreamWriter(out));
} finally {
in.close();
}
throw new AbortException();
}
fs.delete(logFile);
break;
}
}
use of hudson.util.ArgumentListBuilder in project hudson-2.x by hudson.
the class SU method start.
/**
* Returns a {@link VirtualChannel} that's connected to the priviledge-escalated environment.
*
* @return
* Never null. This may represent a channel to a separate JVM, or just {@link LocalChannel}.
* Close this channel and the SU environment will be shut down.
*/
public static VirtualChannel start(final TaskListener listener, final String rootUsername, final String rootPassword) throws IOException, InterruptedException {
if (// on Windows
File.pathSeparatorChar == ';')
// TODO: perhaps use RunAs to run as an Administrator?
return newLocalChannel();
String os = Util.fixNull(System.getProperty("os.name"));
if (os.equals("Linux"))
return new UnixSu() {
protected String sudoExe() {
return "sudo";
}
protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
args.prepend(sudoExe(), "-S");
listener.getLogger().println("$ " + Util.join(args.toList(), " "));
ProcessBuilder pb = new ProcessBuilder(args.toCommandArray());
Process p = pb.start();
// TODO: use -p to detect prompt
// TODO: detect if the password didn't work
PrintStream ps = new PrintStream(p.getOutputStream());
ps.println(rootPassword);
ps.println(rootPassword);
ps.println(rootPassword);
return p;
}
}.start(listener, rootPassword);
if (os.equals("SunOS"))
return new UnixSu() {
protected String sudoExe() {
return "/usr/bin/pfexec";
}
protected Process sudoWithPass(ArgumentListBuilder args) throws IOException {
listener.getLogger().println("Running with embedded_su");
ProcessBuilder pb = new ProcessBuilder(args.prepend(sudoExe()).toCommandArray());
return EmbeddedSu.startWithSu(rootUsername, rootPassword, pb);
}
}.start(listener, rootUsername == null ? null : rootPassword);
// unsupported platform, take a chance
return newLocalChannel();
}
use of hudson.util.ArgumentListBuilder in project hudson-2.x by hudson.
the class Ant method perform.
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
ArgumentListBuilder args = new ArgumentListBuilder();
EnvVars env = build.getEnvironment(listener);
AntInstallation ai = getAnt();
if (ai == null) {
args.add(launcher.isUnix() ? "ant" : "ant.bat");
} else {
ai = ai.forNode(Computer.currentComputer().getNode(), listener);
ai = ai.forEnvironment(env);
String exe = ai.getExecutable(launcher);
if (exe == null) {
listener.fatalError(Messages.Ant_ExecutableNotFound(ai.getName()));
return false;
}
args.add(exe);
}
VariableResolver<String> vr = build.getBuildVariableResolver();
String buildFile = env.expand(this.buildFile);
String targets = Util.replaceMacro(env.expand(this.targets), vr);
FilePath buildFilePath = buildFilePath(build.getModuleRoot(), buildFile, targets);
if (!buildFilePath.exists()) {
// because of the poor choice of getModuleRoot() with CVS/Subversion, people often get confused
// with where the build file path is relative to. Now it's too late to change this behavior
// due to compatibility issue, but at least we can make this less painful by looking for errors
// and diagnosing it nicely. See HUDSON-1782
// first check if this appears to be a valid relative path from workspace root
FilePath buildFilePath2 = buildFilePath(build.getWorkspace(), buildFile, targets);
if (buildFilePath2.exists()) {
// This must be what the user meant. Let it continue.
buildFilePath = buildFilePath2;
} else {
// neither file exists. So this now really does look like an error.
listener.fatalError("Unable to find build script at " + buildFilePath);
return false;
}
}
if (buildFile != null) {
args.add("-file", buildFilePath.getName());
}
Set<String> sensitiveVars = build.getSensitiveBuildVariables();
args.addKeyValuePairs("-D", build.getBuildVariables(), sensitiveVars);
args.addKeyValuePairsFromPropertyString("-D", properties, vr, sensitiveVars);
args.addTokenized(targets.replaceAll("[\t\r\n]+", " "));
if (ai != null)
env.put("ANT_HOME", ai.getHome());
if (antOpts != null)
env.put("ANT_OPTS", env.expand(antOpts));
if (!launcher.isUnix()) {
args = args.toWindowsCommand();
// For some reason, ant on windows rejects empty parameters but unix does not.
// Add quotes for any empty parameter values:
List<String> newArgs = new ArrayList<String>(args.toList());
newArgs.set(newArgs.size() - 1, newArgs.get(newArgs.size() - 1).replaceAll("(?<= )(-D[^\" ]+)= ", "$1=\"\" "));
args = new ArgumentListBuilder(newArgs.toArray(new String[newArgs.size()]));
}
long startTime = System.currentTimeMillis();
try {
AntConsoleAnnotator aca = new AntConsoleAnnotator(listener.getLogger(), build.getCharset());
int r;
try {
r = launcher.launch().cmds(args).envs(env).stdout(aca).pwd(buildFilePath.getParent()).join();
} finally {
aca.forceEol();
}
return r == 0;
} catch (IOException e) {
Util.displayIOException(e, listener);
String errorMessage = Messages.Ant_ExecFailed();
if (ai == null && (System.currentTimeMillis() - startTime) < 1000) {
if (getDescriptor().getInstallations() == null)
// looks like the user didn't configure any Ant installation
errorMessage += Messages.Ant_GlobalConfigNeeded();
else
// There are Ant installations configured but the project didn't pick it
errorMessage += Messages.Ant_ProjectConfigNeeded();
}
e.printStackTrace(listener.fatalError(errorMessage));
return false;
}
}
use of hudson.util.ArgumentListBuilder in project hudson-2.x by hudson.
the class Maven method perform.
@Override
public boolean perform(AbstractBuild<?, ?> build, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
VariableResolver<String> vr = build.getBuildVariableResolver();
EnvVars env = build.getEnvironment(listener);
String targets = Util.replaceMacro(this.targets, vr);
targets = env.expand(targets);
String pom = env.expand(this.pom);
String properties = env.expand(this.properties);
int startIndex = 0;
int endIndex;
do {
// split targets into multiple invokations of maven separated by |
endIndex = targets.indexOf('|', startIndex);
if (-1 == endIndex) {
endIndex = targets.length();
}
String normalizedTarget = targets.substring(startIndex, endIndex).replaceAll("[\t\r\n]+", " ");
ArgumentListBuilder args = new ArgumentListBuilder();
MavenInstallation mi = getMaven();
if (mi == null) {
String execName = build.getWorkspace().act(new DecideDefaultMavenCommand(normalizedTarget));
args.add(execName);
} else {
mi = mi.forNode(Computer.currentComputer().getNode(), listener);
mi = mi.forEnvironment(env);
String exec = mi.getExecutable(launcher);
if (exec == null) {
listener.fatalError(Messages.Maven_NoExecutable(mi.getHome()));
return false;
}
args.add(exec);
}
if (pom != null)
args.add("-f", pom);
Set<String> sensitiveVars = build.getSensitiveBuildVariables();
args.addKeyValuePairs("-D", build.getBuildVariables(), sensitiveVars);
args.addKeyValuePairsFromPropertyString("-D", properties, vr, sensitiveVars);
if (usesPrivateRepository())
args.add("-Dmaven.repo.local=" + build.getWorkspace().child(".repository"));
args.addTokenized(normalizedTarget);
wrapUpArguments(args, normalizedTarget, build, launcher, listener);
buildEnvVars(env, mi);
try {
MavenConsoleAnnotator mca = new MavenConsoleAnnotator(listener.getLogger(), build.getCharset());
int r = launcher.launch().cmds(args).envs(env).stdout(mca).pwd(build.getModuleRoot()).join();
if (0 != r) {
return false;
}
} catch (IOException e) {
Util.displayIOException(e, listener);
e.printStackTrace(listener.fatalError(Messages.Maven_ExecFailed()));
return false;
}
startIndex = endIndex + 1;
} while (startIndex < targets.length());
return true;
}
Aggregations