use of jetbrains.buildServer.vcs.VcsException in project teamcity-rest by JetBrains.
the class BuildRequest method setVcsLabel.
/**
* Adds a label to build VCS roots.
* @param buildLocator specifies build to label.
* @param vcsRootLocator optional, specifies a VCS root to put a label on. If not present, label will be applied to all VCS roots.
* @param fields specifies result representation
* @param labelValue text of the label.
* @return added labels.
*/
@POST
@Path("/{buildLocator}/vcsLabels")
@Consumes("text/plain")
@Produces({ "application/xml", "application/json" })
@ApiOperation(value = "Add a VCS label to the matching build.", nickname = "addBuildVcsLabel")
public VcsLabels setVcsLabel(@ApiParam(format = LocatorName.BUILD) @PathParam("buildLocator") String buildLocator, @ApiParam(format = LocatorName.VCS_ROOT_INSTANCE) @QueryParam("locator") String vcsRootLocator, @QueryParam("fields") String fields, String labelValue) {
if (StringUtil.isEmpty(labelValue)) {
throw new BadRequestException("Label can not empty.");
}
SBuild build = getBuild(myBuildFinder.getBuildPromotion(null, buildLocator));
if (build == null) {
throw new NotFoundException("Cannot find a build using locator: " + buildLocator);
}
VcsLabelManager labelManager = myBeanContext.getSingletonService(VcsLabelManager.class);
List<VcsRootInstance> roots;
if (vcsRootLocator == null) {
roots = build.getVcsRootEntries().stream().map(VcsRootInstanceEntry::getVcsRoot).collect(Collectors.toList());
} else {
VcsRootInstanceFinder rootInstanceFinder = myBeanContext.getSingletonService(VcsRootInstanceFinder.class);
roots = Collections.singletonList(rootInstanceFinder.getItem(vcsRootLocator));
}
try {
labelManager.setLabel(build, labelValue, roots);
} catch (VcsException e) {
LOG.warn("Couldn't set a vcs label.", e);
}
Fields returnFields = new Fields(fields);
return new VcsLabels(labelManager.getLabels(build).stream().filter(l -> l.getLabelText().equals(labelValue)).map(l -> new VcsLabel(l, returnFields, myBeanContext)).collect(Collectors.toList()), returnFields);
}
use of jetbrains.buildServer.vcs.VcsException in project teamcity-git by JetBrains.
the class GitDiagnosticsTab method runTestConnectionForAllProjectRoots.
private void runTestConnectionForAllProjectRoots(@NotNull SProject project, @NotNull List<VcsRootInstance> vcsRootInstances, @NotNull Date timestamp) {
final String externalId = project.getExternalId();
boolean canceled = false;
try {
final Map<Integer, String> cachedResults = new HashMap<>();
final long start = System.currentTimeMillis();
int processed = 0;
int cacheHits = 0;
for (VcsRootInstance ri : vcsRootInstances) {
++processed;
if (!isGitRoot(ri) || ri.getUsages().isEmpty()) {
continue;
}
String error = null;
final Integer key = getKey(ri);
if (cachedResults.containsKey(key)) {
++cacheHits;
error = cachedResults.get(key);
// cached success
if (error == null)
continue;
} else {
boolean jGitSucceeded = true;
try {
IOGuard.allowNetworkAndCommandLine(() -> myVcsSupport.getRemoteRefs(ri, false));
} catch (VcsException e) {
jGitSucceeded = false;
cachedResults.put(key, null);
}
// if jgit fails, no need to check native git
if (jGitSucceeded) {
try {
IOGuard.allowNetworkAndCommandLine(() -> myVcsSupport.getRemoteRefs(ri, true));
cachedResults.put(key, null);
} catch (Throwable e) {
error = e.getMessage();
cachedResults.put(key, error);
}
}
}
final Lock lock = myLocks.get(externalId);
lock.lock();
try {
final VcsRootLink vcsRootLink = new VcsRootLink(ri.getParent());
final TestConnectionTask task = myTestConnectionsInProgress.get(externalId);
if (task == null) {
canceled = true;
break;
}
task.setRootsProcessed(processed);
if (error == null)
continue;
final List<TestConnectionError> rootErrors = task.getRootErrors(vcsRootLink);
rootErrors.add(new TestConnectionError(error, ri.getUsages().keySet().stream().map(bt -> new BuildTypeLink(bt)).collect(Collectors.toSet())));
} finally {
lock.unlock();
}
}
final long duration = System.currentTimeMillis() - start;
LOG.info("Native git TestConnection for " + LogUtil.describe(project) + (canceled ? " was canceled," : " finished") + " took " + TimeUnit.MILLISECONDS.toSeconds(duration) + "sec, cache size: " + cachedResults.size() + ", cache hits: " + cacheHits);
if (canceled)
return;
if (project.isRootProject()) {
FileUtil.delete(getTestConnectionResultsFolder());
final File storedFile = getStoredTestConnectionErrorsFile(timestamp);
deleteFile(storedFile);
FileUtil.createParentDirs(storedFile);
FileWriter writer = null;
try {
final Map<VcsRootLink, List<TestConnectionError>> errors;
final Lock lock = myLocks.get(externalId);
lock.lock();
try {
errors = myTestConnectionsInProgress.get(externalId).getErrors();
} finally {
lock.unlock();
}
writer = new FileWriter(storedFile);
GSON.toJson(errors, Map.class, writer);
} catch (Throwable e) {
LOG.warnAndDebugDetails("Exception while saving native git Test Connection results for " + LogUtil.describe(project) + " to " + storedFile, e);
deleteFile(storedFile);
} finally {
FileUtil.close(writer);
}
}
} finally {
final Lock lock = myLocks.get(externalId);
lock.lock();
try {
finishTask(externalId);
} finally {
lock.unlock();
}
}
}
use of jetbrains.buildServer.vcs.VcsException in project teamcity-git by JetBrains.
the class Cleanup method runNativeGC.
private void runNativeGC(final File bareGitDir) {
String pathToGit = myConfig.getPathToGit();
try {
final long start = System.currentTimeMillis();
GeneralCommandLine cl = new GeneralCommandLine();
cl.setWorkingDirectory(bareGitDir.getParentFile());
cl.setExePath(pathToGit);
cl.addParameter("--git-dir=" + bareGitDir.getCanonicalPath());
cl.addParameter("gc");
cl.addParameter("--auto");
cl.addParameter("--quiet");
ExecResult result = SimpleCommandLineProcessRunner.runCommand(cl, null, new SimpleCommandLineProcessRunner.ProcessRunCallback() {
public void onProcessStarted(Process ps) {
CLEANUP.info("Start 'git --git-dir=" + bareGitDir.getAbsolutePath() + " gc'");
}
public void onProcessFinished(Process ps) {
final long finish = System.currentTimeMillis();
CLEANUP.info("Finish 'git --git-dir=" + bareGitDir.getAbsolutePath() + " gc', duration: " + (finish - start) + "ms");
}
public Integer getOutputIdleSecondsTimeout() {
return 60 * myConfig.getNativeGCQuotaMinutes();
}
public Integer getMaxAcceptedOutputSize() {
return null;
}
@Override
public boolean terminateEntireProcessTree() {
return true;
}
});
VcsException commandError = CommandLineUtil.getCommandLineError("'git --git-dir=" + bareGitDir.getAbsolutePath() + " gc'", result);
if (commandError != null) {
CLEANUP.warnAndDebugDetails("Error while running 'git --git-dir=" + bareGitDir.getAbsolutePath() + " gc'", commandError);
}
if (result.getStderr().length() > 0) {
CLEANUP.debug("Output produced by 'git --git-dir=" + bareGitDir.getAbsolutePath() + " gc'");
CLEANUP.debug(result.getStderr());
}
} catch (Exception e) {
myGcErrors.registerError(bareGitDir, e);
CLEANUP.warnAndDebugDetails("Error while running 'git --git-dir=" + bareGitDir.getAbsolutePath() + " gc'", e);
}
}
use of jetbrains.buildServer.vcs.VcsException in project teamcity-git by JetBrains.
the class FetchCommandImpl method getTeamCityPrivateKey.
private File getTeamCityPrivateKey(@NotNull AuthSettings authSettings) throws VcsException {
if (authSettings.getAuthMethod() != AuthenticationMethod.TEAMCITY_SSH_KEY)
return null;
String keyId = authSettings.getTeamCitySshKeyId();
if (keyId == null)
return null;
VcsRoot root = authSettings.getRoot();
if (root == null)
return null;
TeamCitySshKey privateKey = mySshKeyManager.getKey(root);
if (privateKey == null)
return null;
try {
File privateKeyFile = FileUtil.createTempFile("private", "key");
FileUtil.writeToFile(privateKeyFile, privateKey.getPrivateKey());
return privateKeyFile;
} catch (IOException e) {
throw new VcsException(e);
}
}
use of jetbrains.buildServer.vcs.VcsException in project teamcity-git by JetBrains.
the class FetchCommandImpl method fetchInSeparateProcess.
private void fetchInSeparateProcess(@NotNull Repository repository, @NotNull URIish uri, @NotNull FetchSettings settings) throws VcsException {
final Collection<RefSpec> specs = settings.getRefSpecs();
final String debugInfo = getDebugInfo(repository, uri, specs);
final ProcessXmxProvider xmxProvider = new ProcessXmxProvider(new RepositoryXmxStorage(repository, "fetch"), myConfig, "fetch", debugInfo);
Integer xmx = xmxProvider.getNextXmx();
int attempt = 0;
while (xmx != null) {
attempt++;
File gitPropertiesFile = null;
File teamcityPrivateKey = null;
GitProcessStuckMonitor processStuckMonitor = null;
try {
File gcDump = getDumpFile(repository, "gc");
gitPropertiesFile = myFetcherProperties.getPropertiesFile();
teamcityPrivateKey = getTeamCityPrivateKey(settings.getAuthSettings());
final GeneralCommandLine cl = createFetcherCommandLine(repository, uri, xmx);
final String commandLineString = cl.getCommandLineString();
final GitProcessExecutor processExecutor = new GitProcessExecutor(cl);
processStuckMonitor = new GitProcessStuckMonitor(gcDump, xmx.longValue(), commandLineString) {
@Override
protected void stuckDetected() {
processExecutor.interrupt();
}
};
processStuckMonitor.start();
final GitProcessExecutor.GitExecResult gitResult = processExecutor.runProcess(getFetchProcessInputBytes(getAuthSettings(settings, teamcityPrivateKey), repository.getDirectory(), uri, specs, getDumpFile(repository, null), gcDump, gitPropertiesFile), myConfig.getFetchTimeout(), settings.createStdoutBuffer(), new ByteArrayOutputStream(), new GitProcessExecutor.ProcessExecutorAdapter() {
@Override
public void processStarted() {
if (LOG.isDebugEnabled())
LOG.debug("git fetch process for " + debugInfo + " started in separate process with command line: " + commandLineString);
settings.getProgress().reportProgress("git fetch " + uri);
}
@Override
public void processFinished() {
if (LOG.isDebugEnabled())
LOG.debug("git fetch process for " + debugInfo + " finished");
settings.getProgress().reportProgress("git fetch " + uri + " finished");
}
@Override
public void processFailed(@NotNull final ExecutionException e) {
if (LOG.isDebugEnabled())
LOG.debug("git fetch process for " + debugInfo + " failed");
settings.getProgress().reportProgress("git fetch " + uri + " failed");
}
});
final ExecResult result = gitResult.getExecResult();
VcsException commandError = CommandLineUtil.getCommandLineError("git fetch", " (repository dir: <TeamCity data dir>/system/caches/git/" + repository.getDirectory().getName() + ")", result, true, true);
if (commandError != null) {
commandError.setRecoverable(isRecoverable(commandError));
/* if the process had not enough memory or we killed it because gc */
if (gitResult.isOutOfMemoryError() || gitResult.isInterrupted()) {
final Integer nextXmx = xmxProvider.getNextXmx();
if (nextXmx != null) {
xmx = nextXmx;
clean(repository);
continue;
}
commandError = new VcsException("There is not enough memory for git fetch (last attempted -Xmx" + xmx + "M). Please contact your system administrator", commandError);
} else if (attempt == 1 && settings.getAuthSettings().doesTokenNeedRefresh()) {
LOG.debug("git fetch process failed due to suspected token expiration for \"" + uri + "\" in directory \"" + repository.getDirectory() + "\", took " + TimePrinter.createMillisecondsFormatter().formatTime(gitResult.getDuration()) + ". Retrying with token refresh.");
continue;
}
LOG.info("git fetch process failed for \"" + uri + "\" in directory \"" + repository.getDirectory() + "\", took " + TimePrinter.createMillisecondsFormatter().formatTime(gitResult.getDuration()));
if (gitResult.isTimeout()) {
logTimeout(debugInfo, getDumpFile(repository, null));
}
clean(repository);
throw commandError;
}
LOG.info("git fetch process finished for: " + uri + " in directory: " + repository.getDirectory() + ", took " + gitResult.getDuration() + "ms");
if (result.getStderr().length() > 0) {
LOG.warn("Error output produced by git fetch:\n" + result.getStderr());
}
LOG.debug("git fetch process output:\n" + result.getStdout());
break;
} finally {
if (teamcityPrivateKey != null) {
FileUtil.delete(teamcityPrivateKey);
}
if (gitPropertiesFile != null) {
FileUtil.delete(gitPropertiesFile);
}
if (processStuckMonitor != null) {
processStuckMonitor.finish();
}
}
}
}
Aggregations