use of com.google.gerrit.entities.Project in project gerrit by GerritCodeReview.
the class AllChangesIndexer method indexAll.
@Override
public Result indexAll(ChangeIndex index) {
// The simplest approach to distribute indexing would be to let each thread grab a project
// and index it fully. But if a site has one big project and 100s of small projects, then
// in the beginning all CPUs would be busy reindexing projects. But soon enough all small
// projects have been reindexed, and only the thread that reindexes the big project is
// still working. The other threads would idle. Reindexing the big project on a single
// thread becomes the critical path. Bringing in more CPUs would not speed up things.
//
// To avoid such situations, we split big repos into smaller parts and let
// the thread pool index these smaller parts. This splitting introduces an overhead in the
// workload setup and there might be additional slow-downs from multiple threads
// concurrently working on different parts of the same project. But for Wikimedia's Gerrit,
// which had 2 big projects, many middle sized ones, and lots of smaller ones, the
// splitting of repos into smaller parts reduced indexing time from 1.5 hours to 55 minutes
// in 2020.
Stopwatch sw = Stopwatch.createStarted();
AtomicBoolean ok = new AtomicBoolean(true);
mpm = multiProgressMonitorFactory.create(progressOut, TaskKind.INDEXING, "Reindexing changes");
doneTask = mpm.beginVolatileSubTask("changes");
failedTask = mpm.beginSubTask("failed", MultiProgressMonitor.UNKNOWN);
List<ListenableFuture<?>> futures;
try {
futures = new SliceScheduler(index, ok).schedule();
} catch (ProjectsCollectionFailure e) {
logger.atSevere().log("%s", e.getMessage());
return Result.create(sw, false, 0, 0);
}
try {
mpm.waitFor(transform(successfulAsList(futures), x -> {
mpm.end();
return null;
}, directExecutor()));
} catch (UncheckedExecutionException e) {
logger.atSevere().withCause(e).log("Error in batch indexer");
ok.set(false);
}
// If too many changes failed, maybe there was a bug in the indexer. Don't
// trust the results. This is not an exact percentage since we bump the same
// failure counter if a project can't be read, but close enough.
int nFailed = failedTask.getCount();
int nDone = doneTask.getCount();
int nTotal = nFailed + nDone;
double pctFailed = ((double) nFailed) / nTotal * 100;
if (pctFailed > 10) {
logger.atSevere().log("Failed %s/%s changes (%s%%); not marking new index as ready", nFailed, nTotal, Math.round(pctFailed));
ok.set(false);
} else if (nFailed > 0) {
logger.atWarning().log("Failed %s/%s changes", nFailed, nTotal);
}
return Result.create(sw, ok.get(), nDone, nFailed);
}
use of com.google.gerrit.entities.Project in project gerrit by GerritCodeReview.
the class TestSubmitRule method apply.
@Override
public Response<TestSubmitRuleInfo> apply(RevisionResource rsrc, TestSubmitRuleInput input) throws AuthException, PermissionBackendException, BadRequestException {
if (input == null) {
input = new TestSubmitRuleInput();
}
if (input.rule == null) {
throw new BadRequestException("rule is required");
}
if (!rules.isProjectRulesEnabled()) {
throw new AuthException("project rules are disabled");
}
input.filters = MoreObjects.firstNonNull(input.filters, filters);
Project.NameKey name = rsrc.getProject();
Optional<ProjectState> project = projectCache.get(name);
if (!project.isPresent()) {
throw new BadRequestException("project not found " + name);
}
ChangeData cd = changeDataFactory.create(rsrc.getNotes());
SubmitRecord record = prologRule.evaluate(cd, PrologOptions.dryRunOptions(input.rule, input.filters == Filters.SKIP));
AccountLoader accounts = accountInfoFactory.create(true);
TestSubmitRuleInfo out = newSubmitRuleInfo(record, accounts);
accounts.fill();
return Response.ok(out);
}
use of com.google.gerrit.entities.Project in project gerrit by GerritCodeReview.
the class ListTasks method apply.
@Override
public Response<List<TaskInfo>> apply(ConfigResource resource) throws AuthException, PermissionBackendException {
CurrentUser user = self.get();
if (!user.isIdentifiedUser()) {
throw new AuthException("Authentication required");
}
List<TaskInfo> allTasks = getTasks();
try {
permissionBackend.user(user).check(GlobalPermission.VIEW_QUEUE);
return Response.ok(allTasks);
} catch (AuthException e) {
// Fall through to filter tasks.
}
Map<String, Boolean> visibilityCache = new HashMap<>();
List<TaskInfo> visibleTasks = new ArrayList<>();
for (TaskInfo task : allTasks) {
if (task.projectName != null) {
Boolean visible = visibilityCache.get(task.projectName);
if (visible == null) {
Project.NameKey nameKey = Project.nameKey(task.projectName);
Optional<ProjectState> state = projectCache.get(nameKey);
if (!state.isPresent() || !state.get().statePermitsRead()) {
visible = false;
} else {
try {
permissionBackend.user(user).project(nameKey).check(ProjectPermission.ACCESS);
visible = true;
} catch (AuthException e) {
visible = false;
}
}
visibilityCache.put(task.projectName, visible);
}
if (visible) {
visibleTasks.add(task);
}
}
}
return Response.ok(visibleTasks);
}
use of com.google.gerrit.entities.Project in project gerrit by GerritCodeReview.
the class GitProtocolV2IT method testGitWireProtocolV2WithSsh.
@Test
public void testGitWireProtocolV2WithSsh() throws Exception {
try (ServerContext ctx = startServer()) {
ctx.getInjector().injectMembers(this);
// Create project
Project.NameKey project = Project.nameKey("foo");
gApi.projects().create(project.get());
// Set up project permission
projectOperations.project(project).forUpdate().add(deny(Permission.READ).ref("refs/heads/*").group(SystemGroupBackend.ANONYMOUS_USERS)).add(allow(Permission.READ).ref("refs/heads/master").group(SystemGroupBackend.REGISTERED_USERS)).update();
// Retrieve HTTP url
String url = config.getString("gerrit", null, "canonicalweburl");
String urlDestinationTemplate = url.substring(0, 7) + "%s:secret@" + url.substring(7, url.length()) + "/a/" + project.get();
// Retrieve SSH host and port
String sshDestinationTemplate = "ssh://%s@" + sshAddress.getHostName() + ":" + sshAddress.getPort() + "/" + project.get();
// Admin user was already created by the base class
setUpUserAuthentication(admin.username());
// Create non-admin user
TestAccount user = accountCreator.user1();
setUpUserAuthentication(user.username());
// Prepare data for new change on master branch
ChangeInput in = new ChangeInput(project.get(), "master", "Test public change");
in.newBranch = true;
// Create new change and retrieve SHA1 for the created patch set
String commit = gApi.changes().id(gApi.changes().create(in).info().changeId).current().commit(false).commit;
// Prepare new change on secret branch
in = new ChangeInput(project.get(), ADMIN_PASSWORD, "Test secret change");
in.newBranch = true;
// Create new change and retrieve SHA1 for the created patch set
String secretCommit = gApi.changes().id(gApi.changes().create(in).info().changeId).current().commit(false).commit;
// Read refs from target repository using git wire protocol v2 over HTTP for admin user
String out = execute(ImmutableList.<String>builder().add(GIT_LS_REMOTE).add(String.format(urlDestinationTemplate, admin.username())).build(), ImmutableMap.of("GIT_TRACE_PACKET", "1"));
assertGitProtocolV2Refs(commit, out);
assertThat(out).contains(secretCommit);
// Read refs from target repository using git wire protocol v2 over SSH for admin user
out = execute(ImmutableList.<String>builder().add(GIT_LS_REMOTE).add(String.format(sshDestinationTemplate, admin.username())).build(), ImmutableMap.of("GIT_SSH_COMMAND", GIT_SSH_COMMAND + sitePaths.data_dir.resolve(String.format("id_rsa_%s", admin.username())), "GIT_TRACE_PACKET", "1"));
assertGitProtocolV2Refs(commit, out);
assertThat(out).contains(secretCommit);
// Read refs from target repository using git wire protocol v2 over HTTP for non-admin user
out = execute(ImmutableList.<String>builder().add(GIT_LS_REMOTE).add(String.format(urlDestinationTemplate, user.username())).build(), ImmutableMap.of("GIT_TRACE_PACKET", "1"));
assertGitProtocolV2Refs(commit, out);
assertThat(out).doesNotContain(secretCommit);
// Read refs from target repository using git wire protocol v2 over SSH for non-admin user
out = execute(ImmutableList.<String>builder().add(GIT_LS_REMOTE).add(String.format(sshDestinationTemplate, user.username())).build(), ImmutableMap.of("GIT_SSH_COMMAND", GIT_SSH_COMMAND + sitePaths.data_dir.resolve(String.format("id_rsa_%s", user.username())), "GIT_TRACE_PACKET", "1"));
assertGitProtocolV2Refs(commit, out);
assertThat(out).doesNotContain(secretCommit);
}
}
use of com.google.gerrit.entities.Project in project gerrit by GerritCodeReview.
the class GitProtocolV2IT method testGitWireProtocolV2HidesRefMetaConfig.
@Test
public void testGitWireProtocolV2HidesRefMetaConfig() throws Exception {
try (ServerContext ctx = startServer()) {
ctx.getInjector().injectMembers(this);
String url = config.getString("gerrit", null, "canonicalweburl");
// Create project
Project.NameKey allRefsVisibleProject = Project.nameKey("all-refs-visible");
gApi.projects().create(allRefsVisibleProject.get());
// Set up project permission to allow reading all refs
projectOperations.project(allRefsVisibleProject).forUpdate().add(allow(Permission.READ).ref("refs/heads/*").group(SystemGroupBackend.ANONYMOUS_USERS)).add(allow(Permission.READ).ref("refs/changes/*").group(SystemGroupBackend.ANONYMOUS_USERS)).update();
// Create new change and retrieve refs for the created patch set
ChangeInput visibleChangeIn = new ChangeInput(allRefsVisibleProject.get(), "master", "Test public change");
visibleChangeIn.newBranch = true;
int visibleChangeNumber = gApi.changes().create(visibleChangeIn).info()._number;
Change.Id changeId = Change.id(visibleChangeNumber);
String visibleChangeNumberRef = RefNames.patchSetRef(PatchSet.id(changeId, 1));
String visibleChangeNumberMetaRef = RefNames.changeMetaRef(changeId);
// Read refs from target repository using git wire protocol v2 over HTTP anonymously
String outAnonymousLsRemote = execute(ImmutableList.<String>builder().add(GIT_CLONE_MIRROR).add(url + "/" + allRefsVisibleProject.get()).build(), ImmutableMap.of("GIT_TRACE_PACKET", "1"));
assertThat(outAnonymousLsRemote).contains("git< version 2");
assertThat(outAnonymousLsRemote).doesNotContain(RefNames.REFS_CONFIG);
assertThat(outAnonymousLsRemote).contains(visibleChangeNumberRef);
assertThat(outAnonymousLsRemote).contains(visibleChangeNumberMetaRef);
}
}
Aggregations