Search in sources :

Example 21 with Project

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);
}
Also used : SiteIndexer(com.google.gerrit.index.SiteIndexer) ListenableFuture(com.google.common.util.concurrent.ListenableFuture) ProjectCache(com.google.gerrit.server.project.ProjectCache) Futures.successfulAsList(com.google.common.util.concurrent.Futures.successfulAsList) Stopwatch(com.google.common.base.Stopwatch) MultiProgressMonitor(com.google.gerrit.server.git.MultiProgressMonitor) VolatileTask(com.google.gerrit.server.git.MultiProgressMonitor.VolatileTask) Inject(com.google.inject.Inject) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Callable(java.util.concurrent.Callable) ArrayList(java.util.ArrayList) TaskKind(com.google.gerrit.server.git.MultiProgressMonitor.TaskKind) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) ProgressMonitor(org.eclipse.jgit.lib.ProgressMonitor) IndexExecutor(com.google.gerrit.server.index.IndexExecutor) Change(com.google.gerrit.entities.Change) OnlineReindexMode(com.google.gerrit.server.index.OnlineReindexMode) BATCH(com.google.gerrit.server.git.QueueProvider.QueueType.BATCH) ImmutableSortedSet(com.google.common.collect.ImmutableSortedSet) ChangeNotesResult(com.google.gerrit.server.notedb.ChangeNotes.Factory.ChangeNotesResult) Task(com.google.gerrit.server.git.MultiProgressMonitor.Task) ScanResult(com.google.gerrit.server.notedb.ChangeNotes.Factory.ScanResult) ChangeNotes(com.google.gerrit.server.notedb.ChangeNotes) IOException(java.io.IOException) MoreExecutors.directExecutor(com.google.common.util.concurrent.MoreExecutors.directExecutor) ChangeData(com.google.gerrit.server.query.change.ChangeData) List(java.util.List) GitRepositoryManager(com.google.gerrit.server.git.GitRepositoryManager) AutoValue(com.google.auto.value.AutoValue) Project(com.google.gerrit.entities.Project) Futures.transform(com.google.common.util.concurrent.Futures.transform) FluentLogger(com.google.common.flogger.FluentLogger) Repository(org.eclipse.jgit.lib.Repository) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) UncheckedExecutionException(com.google.common.util.concurrent.UncheckedExecutionException) Stopwatch(com.google.common.base.Stopwatch) ListenableFuture(com.google.common.util.concurrent.ListenableFuture)

Example 22 with Project

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);
}
Also used : Project(com.google.gerrit.entities.Project) SubmitRecord(com.google.gerrit.entities.SubmitRecord) TestSubmitRuleInput(com.google.gerrit.extensions.common.TestSubmitRuleInput) AccountLoader(com.google.gerrit.server.account.AccountLoader) BadRequestException(com.google.gerrit.extensions.restapi.BadRequestException) AuthException(com.google.gerrit.extensions.restapi.AuthException) ProjectState(com.google.gerrit.server.project.ProjectState) ChangeData(com.google.gerrit.server.query.change.ChangeData) TestSubmitRuleInfo(com.google.gerrit.extensions.common.TestSubmitRuleInfo)

Example 23 with Project

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);
}
Also used : CurrentUser(com.google.gerrit.server.CurrentUser) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) AuthException(com.google.gerrit.extensions.restapi.AuthException) Project(com.google.gerrit.entities.Project) ProjectState(com.google.gerrit.server.project.ProjectState)

Example 24 with Project

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);
    }
}
Also used : Project(com.google.gerrit.entities.Project) ChangeInput(com.google.gerrit.extensions.common.ChangeInput) TestAccount(com.google.gerrit.acceptance.TestAccount) StandaloneSiteTest(com.google.gerrit.acceptance.StandaloneSiteTest) Test(org.junit.Test)

Example 25 with Project

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);
    }
}
Also used : Project(com.google.gerrit.entities.Project) ChangeInput(com.google.gerrit.extensions.common.ChangeInput) Change(com.google.gerrit.entities.Change) StandaloneSiteTest(com.google.gerrit.acceptance.StandaloneSiteTest) Test(org.junit.Test)

Aggregations

Project (com.google.gerrit.entities.Project)184 Test (org.junit.Test)109 AbstractDaemonTest (com.google.gerrit.acceptance.AbstractDaemonTest)67 Change (com.google.gerrit.entities.Change)43 Repository (org.eclipse.jgit.lib.Repository)34 ChangeInfo (com.google.gerrit.extensions.common.ChangeInfo)33 PushOneCommit (com.google.gerrit.acceptance.PushOneCommit)32 InMemoryRepository (org.eclipse.jgit.internal.storage.dfs.InMemoryRepository)31 BranchNameKey (com.google.gerrit.entities.BranchNameKey)30 Config (org.eclipse.jgit.lib.Config)26 ObjectId (org.eclipse.jgit.lib.ObjectId)26 IOException (java.io.IOException)25 ChangeNotes (com.google.gerrit.server.notedb.ChangeNotes)24 ProjectState (com.google.gerrit.server.project.ProjectState)23 Inject (com.google.inject.Inject)23 List (java.util.List)23 AuthException (com.google.gerrit.extensions.restapi.AuthException)22 ChangeData (com.google.gerrit.server.query.change.ChangeData)22 RevCommit (org.eclipse.jgit.revwalk.RevCommit)22 PatchSet (com.google.gerrit.entities.PatchSet)20