Skip to content

Commit

Permalink
Merged PR #28 from casz/master
Browse files Browse the repository at this point in the history
* [JENKINS-28118] Fixed poll on ancestor

Poll failed searching in parents when “Show one stream at a time” was
checked.
Fixed regression in PR #25

* Improved logic for Workspace

Was not working with “One stream at a time” settings.

* Fixed Change log on Ignore Parent

getChangesFromStreams did not respect Ignore Stream Parent.

* Fixed getStreamRules.

IgnoreStreamParent should be the first to be considered, then One
Stream at a time on server, then find all streams.

* [JENKINS-31316] Fixed server rename

Introduced unique identifiers, also added a migrator to ensure best
compatibility moving forward.

* Fixed backwards compatibility

Made the Server UUID change fully backwards compatibility 🎉

* [JENKINS-13817] Mask the damn password already

I cannot believe this has been open since 2012...

* StringUtils used

* Allow empty password even with OBF

* Javadoc and removed unused migrate field

* [JENKINS-24710] filter out dispatch transactions

These usually originate from accurev sync.

* PR #24 fix PollOnMaster enabled when build using workspace

builds that use workspace or reftree definitely requires workspace even
if PollOnMaster enabled.
  • Loading branch information
Casz committed Sep 28, 2016
1 parent 686a4cf commit b8296bb
Show file tree
Hide file tree
Showing 18 changed files with 389 additions and 233 deletions.
20 changes: 14 additions & 6 deletions src/main/java/hudson/plugins/accurev/AccurevLauncher.java
Expand Up @@ -260,7 +260,7 @@ public static <TResult, TContext> TResult runCommand(//
final OutputStream stderrStream = stderr.getOutput();
final ProcStarter starter = createProcess(launcher, machineReadableCommand, masksOrNull,
environmentVariables, directoryToRunCommandFrom, stdoutStream, stderrStream);
logCommandExecution(machineReadableCommand, directoryToRunCommandFrom, loggerToLogFailuresTo,
logCommandExecution(humanReadableCommandName, machineReadableCommand, directoryToRunCommandFrom, loggerToLogFailuresTo,
listenerToLogFailuresTo);
try {
final int commandExitCode = runCommandToCompletion(starter, synchronizationLockObjectOrNull);
Expand Down Expand Up @@ -331,7 +331,7 @@ private static void logCommandFailure(//
final InputStream commandStderrOrNull, //
final Logger loggerToLogFailuresTo, //
final TaskListener taskListener) {
final String msg = commandDescription + " (" + command.toStringWithQuote() + ")" + " failed with exit code " + commandExitCode;
final String msg = commandDescription + " (" + maskCommandForPassword(commandDescription, command) + ")" + " failed with exit code " + commandExitCode;
String stderr = null;
try {
stderr = getCommandErrorOutput(commandStdoutOrNull, commandStderrOrNull);
Expand Down Expand Up @@ -395,7 +395,7 @@ private static void logCommandException(//
final Logger loggerToLogFailuresTo, //
final TaskListener taskListener) {
final String hostname = getRemoteHostname(directoryToRunCommandFrom);
final String msg = hostname + ": " + commandDescription + " (" + command.toStringWithQuote() + ")"
final String msg = hostname + ": " + commandDescription + " (" + maskCommandForPassword(commandDescription, command) + ")"
+ " failed with " + exception.toString();
logException(msg, exception, loggerToLogFailuresTo, taskListener);
}
Expand All @@ -416,22 +416,30 @@ static void logException(//
}

private static void logCommandExecution(//
final String commandDescription,
final ArgumentListBuilder command, //
final FilePath directoryToRunCommandFrom, //
final Logger loggerToLogFailuresTo, //
final TaskListener taskListener) {
if (loggerToLogFailuresTo != null && loggerToLogFailuresTo.isLoggable(Level.FINE)) {
final String hostname = getRemoteHostname(directoryToRunCommandFrom);
final String msg = hostname + ": " + command.toStringWithQuote();
final String msg = hostname + ": " + maskCommandForPassword(commandDescription, command);
loggerToLogFailuresTo.log(Level.FINE, msg);
}
}

private static String maskCommandForPassword(String desc, ArgumentListBuilder command) {
String cmd = command.toStringWithQuote();
if (desc.equalsIgnoreCase("login")) {
cmd = cmd.replaceAll("\\w+$", "********");
}
return cmd;
}

private static String getRemoteHostname(final FilePath directoryToRunCommandFrom) {
try {
final RemoteWorkspaceDetails act = directoryToRunCommandFrom.act(new DetermineRemoteHostname("."));
final String hostName = act.getHostName();
return hostName;
return act.getHostName();
} catch (UnknownHostException e) {
return "Unable to determine actual hostname, ensure proper FQDN.\n"+e.toString();
} catch (IOException e) {
Expand Down
63 changes: 63 additions & 0 deletions src/main/java/hudson/plugins/accurev/AccurevPlugin.java
@@ -0,0 +1,63 @@
package hudson.plugins.accurev;

import hudson.Plugin;
import hudson.init.Initializer;
import hudson.model.Project;
import jenkins.model.Jenkins;

import java.io.IOException;
import java.util.logging.Logger;

import static hudson.init.InitMilestone.COMPLETED;
import static hudson.init.InitMilestone.JOB_LOADED;

/**
* Created by josp on 21/09/16.
*/
public class AccurevPlugin extends Plugin {
private static final Logger LOGGER = Logger.getLogger(AccurevPlugin.class.getName());
/**
* Launches migration after plugin and jobs already initialized.
* Expected milestone: @Initializer(after = JOB_LOADED)
*
* @throws Exception Exceptions?
* @see #initializers()
*/
public static void runMigrator() throws Exception {
final Jenkins jenkins = Jenkins.getInstance();
if (jenkins == null) {
throw new IOException("Jenkins instance is not ready");
}
boolean changed = false;
AccurevSCM.AccurevSCMDescriptor descriptor = jenkins.getDescriptorByType(AccurevSCM.AccurevSCMDescriptor.class);
for (Project<?, ?> p : jenkins.getAllItems(Project.class)) {
if (p.getScm() instanceof AccurevSCM) {
AccurevSCM scm = (AccurevSCM) p.getScm();
String serverUUID = scm.getServerUUID();
if (UUIDUtils.isNotValid(serverUUID) || descriptor.getServer(serverUUID) == null) {
AccurevSCM.AccurevServer server = descriptor.getServer(scm.getServerName());
if (server == null) {
LOGGER.warning("No server found with that name, Project: " + p.getName() + " Server Name: " + scm.getServerName());
} else {
changed = true;
String uuid = server.getUUID();
scm.setServerUUID(uuid);
p.save();
}
}
}
}
if (changed) descriptor.save();

}

/**
* We need ensure that migrator will run after jobs are loaded
*
* @throws Exception Exceptions?
*/
@Initializer(after = JOB_LOADED, before = COMPLETED)
public static void initializers() throws Exception {
runMigrator();
}
}
82 changes: 64 additions & 18 deletions src/main/java/hudson/plugins/accurev/AccurevSCM.java
Expand Up @@ -15,6 +15,7 @@
import hudson.util.FormValidation;
import hudson.util.ListBoxModel;
import net.sf.json.JSONObject;
import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.DataBoundConstructor;
import org.kohsuke.stapler.QueryParameter;
import org.kohsuke.stapler.StaplerRequest;
Expand Down Expand Up @@ -45,6 +46,7 @@ public class AccurevSCM extends SCM {
public static final AccurevSCMDescriptor DESCRIPTOR = new AccurevSCMDescriptor();
private static final Logger logger = Logger.getLogger(AccurevSCM.class.getName());
static final Date NO_TRANS_DATE = new Date(0);
private String serverUUID;
private final String serverName;
private final String depot;
private final String stream;
Expand All @@ -69,6 +71,7 @@ public class AccurevSCM extends SCM {
/**
* Our constructor.
*
* @param serverUUID Unique identifier for server
* @param serverName name for the server
* @param depot depot
* @param stream stream
Expand All @@ -86,7 +89,9 @@ public class AccurevSCM extends SCM {
* @param ignoreStreamParent ignore Parent Stream
*/
@DataBoundConstructor
public AccurevSCM(String serverName,
public AccurevSCM(
String serverUUID,
String serverName,
String depot,
String stream,
String wspaceORreftree,
Expand All @@ -102,6 +107,7 @@ public AccurevSCM(String serverName,
String directoryOffset,
boolean ignoreStreamParent) {
super();
this.serverUUID = serverUUID;
this.serverName = serverName;
this.depot = depot;
this.stream = stream;
Expand Down Expand Up @@ -142,6 +148,27 @@ public String getServerName() {
return serverName;
}

/**
* Getter for property 'serverUUID'.
*
* @return Value for property 'serverUUID'.
*/
public String getServerUUID() {
return serverUUID;
}

/**
* Setter for property 'serverUUID'.
*
* @param uuid Value for property 'serverUUID'
*/
public void setServerUUID(String uuid) {
serverUUID = uuid;
}

public AccurevServer getServer() {
return ((AccurevSCMDescriptor)getDescriptor()).getServer(serverName);
}
/**
* Getter for property 'stream'.
*
Expand Down Expand Up @@ -348,8 +375,9 @@ public ChangeLogParser createChangeLogParser() {

@Override
public boolean requiresWorkspaceForPolling() {
if (DESCRIPTOR.isPollOnMaster()) {
// Polling on master; workspace not required.
boolean requiresWorkspace = AccurevMode.findMode(this).isRequiresWorkspace();
if (DESCRIPTOR.isPollOnMaster() && !requiresWorkspace) {
// Does not require workspace if Poll On Master is enabled; unless build is using workspace
return false;
}

Expand All @@ -358,7 +386,7 @@ public boolean requiresWorkspaceForPolling() {
activeProject = null;
}

if (AccurevMode.findMode(this).isRequiresWorkspace() && activeProject == null) {
if (requiresWorkspace && activeProject == null) {
return true;
}

Expand Down Expand Up @@ -480,9 +508,11 @@ public boolean configure(StaplerRequest req, JSONObject formData) throws FormExc
*/
@Override
public SCM newInstance(StaplerRequest req, JSONObject formData) throws FormException {

String serverUUID = req.getParameter("_.serverUUID");
String serverName = getServer(serverUUID).getName();
return new AccurevSCM( //
req.getParameter("_.serverName"), //
serverUUID, //
serverName, //
req.getParameter("_.depot"), //
req.getParameter("_.stream"), //
req.getParameter("accurev.wspaceORreftree"),//
Expand Down Expand Up @@ -544,28 +574,32 @@ public void setPollOnMaster(boolean pollOnMaster) {
this.pollOnMaster = pollOnMaster;
}

public AccurevServer getServer(String name) {
if (name == null) {
public AccurevServer getServer(String uuid) {
if (uuid == null) {
return null;
}
for (AccurevServer server : this._servers) {
if (name.equals(server.getName())) {
if (UUIDUtils.isValid(uuid) && uuid.equals(server.getUUID())) {
return server;
} else if (uuid.equals(server.getName())) {
// support old server name
return server;
}
}
return null;
}

// This method will populate the servers in the select box
public ListBoxModel doFillServerNameItems(@QueryParameter String serverName) {
public ListBoxModel doFillServerUUIDItems(@QueryParameter String serverUUID) {
ListBoxModel s = new ListBoxModel();
if (this._servers == null) {
descriptorlogger.warning("Failed to find AccuRev server. Add Server under AccuRev section in the Manage Jenkins > Configure System page.");
return s;
}
for (AccurevServer server : this._servers) {
s.add(server.getName(), server.getName());
s.add(server.getName(), server.getUUID());
}

return s;
}

Expand All @@ -579,8 +613,8 @@ private static String getExistingPath(String[] paths) {

}

private AccurevServer getServerAndPath(String serverName) {
final AccurevServer server = getServer(serverName);
private AccurevServer getServerAndPath(String serverUUID) {
final AccurevServer server = getServer(serverUUID);
String accurevBinName = "accurev";

if (server == null) {
Expand Down Expand Up @@ -660,9 +694,9 @@ private String getEnvBinDir() {

// This method will populate the depots in the select box depending upon the
// server selected.
public ListBoxModel doFillDepotItems(@QueryParameter String serverName, @QueryParameter String depot) {
public ListBoxModel doFillDepotItems(@QueryParameter String serverUUID, @QueryParameter String depot) {

final AccurevServer server = getServerAndPath(serverName);
final AccurevServer server = getServerAndPath(serverUUID);
if (server == null) {
return new ListBoxModel();
}
Expand All @@ -687,14 +721,14 @@ public ListBoxModel doFillDepotItems(@QueryParameter String serverName, @QueryPa
}
// Below while loop is for to retain the selected item when you open the
// Job to reconfigure
d.stream().filter(o -> depot.equals(o.name)).forEachOrdered(o -> o.selected = true);
d.stream().filter(o -> depot.equals(o.name)).forEach(o -> o.selected = true);
return d;
}

// Populating the streams
public ComboBoxModel doFillStreamItems(@QueryParameter String serverName, @QueryParameter String depot) {
public ComboBoxModel doFillStreamItems(@QueryParameter String serverUUID, @QueryParameter String depot) {
ComboBoxModel cbm = new ComboBoxModel();
final AccurevServer server = getServerAndPath(serverName);
final AccurevServer server = getServerAndPath(serverUUID);
if (server == null) {
//descriptorlogger.warning("Failed to find server.");
return new ComboBoxModel();
Expand Down Expand Up @@ -725,6 +759,7 @@ public static void unlock() {
// --------------------------- Inner Class ---------------------------------------------------
public static final class AccurevServer implements Serializable {

private UUID uuid;
private String name;
private String host;
private int port;
Expand Down Expand Up @@ -778,6 +813,7 @@ public AccurevServer() {

@DataBoundConstructor
public AccurevServer(//
String uuid,
String name, //
String host, //
int port, //
Expand All @@ -790,6 +826,8 @@ public AccurevServer(//
boolean useRestrictedShowStreams,
boolean useColor) {
this();
if (StringUtils.isEmpty(uuid)) this.uuid = UUID.randomUUID();
else this.uuid = UUID.fromString(uuid);
this.name = name;
this.host = host;
this.port = port;
Expand Down Expand Up @@ -817,9 +855,17 @@ private Object readResolve() {
if (nixCmdLocations == null) {
nixCmdLocations = new ArrayList<>(DEFAULT_NIX_CMD_LOCATIONS);
}
if (uuid == null) {
uuid = UUID.randomUUID();
}
return this;
}

public String getUUID() {
if (uuid == null) { uuid = UUID.randomUUID(); }
return uuid.toString();
}

/**
* Getter for property 'name'.
*
Expand Down
4 changes: 2 additions & 2 deletions src/main/java/hudson/plugins/accurev/AccurevStream.java
Expand Up @@ -35,8 +35,8 @@ public AccurevStream(String name, Long number, String depot, String basisName, L
this.basisNumber = basisNumber;
this.dynamic = dynamic;
this.type = type;
this.time = (Date) time.clone();
this.startTime = (Date) startTime.clone();
this.time = time == null ? null : (Date) time.clone();
this.startTime = startTime == null ? null : (Date) startTime.clone();
}

private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException {
Expand Down
5 changes: 3 additions & 2 deletions src/main/java/hudson/plugins/accurev/AccurevTransaction.java
Expand Up @@ -4,6 +4,7 @@
import hudson.scm.ChangeLogSet;
import hudson.scm.EditType;

import org.apache.commons.lang.StringUtils;
import org.kohsuke.stapler.export.Exported;
import org.kohsuke.stapler.export.ExportedBean;

Expand Down Expand Up @@ -113,7 +114,7 @@ public void setDate(Date date) {

@Exported
public String getMsg() {
return (null == msg ? "" : msg);
return (StringUtils.isEmpty(msg) ? "" : msg);
}

public void setMsg(String msg) {
Expand All @@ -122,7 +123,7 @@ public void setMsg(String msg) {

public void setAction(String action) {
this.action = action;
if ("chstream".equals(action) && (msg == null || "".equals(msg))) {
if ("chstream".equals(action) && StringUtils.isEmpty(msg)) {
msg = "Changed Parent Stream";
}
}
Expand Down

0 comments on commit b8296bb

Please sign in to comment.