Skip to content

GraphQL: Add runners to groups query [RUN AS-IF-FOSS]

What does this MR do?

This MR adds a runners field to the group GraphQL type, allowing to filter also by membership.

  • It first changes the way the Ci::RunnersFinder class accepts the group argument (to make it easier later for the RunnersResolver to pass it in in a generic way).
  • It then extracts the RunnersResolver context into a dedicated file so that it can easily be reused by the derived GroupRunnersResolver.
  • The following commits add the actual functionality and the changelog entry.
GraphQL query
query getGroupRunners {
  group(fullPath: "top-level-group/sub-group") {
    id
    fullName
    runners(membership:DESCENDANTS) {
      edges {
        node {
          id
          runnerType
          description
        }
      }
    }
  }
}
JSON output
{
  "data": {
    "group": {
      "id": "gid://gitlab/Group/111",
      "fullName": "top-level-group / sub-group",
      "runners": {
        "edges": [
          {
            "node": {
              "id": "gid://gitlab/Ci::Runner/2",
              "runnerType": "PROJECT_TYPE",
              "description": "docker-runner - updated"
            }
          }
        ]
      }
    }
  }
}

Screenshots or Screencasts (strongly suggested)

image

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

Does this MR contain changes to processing or storing of credentials or tokens, authorization and authentication methods or other items described in the security review guidelines? If not, then delete this Security section.

  • Label as security and @ mention @gitlab-com/gl-security/appsec
  • The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • Security reports checked/validated by a reviewer from the AppSec team

Database query plans

NOTE: The :descendants query matches the default currently on master so I'm not including the query plan here. The runners query is the same as what already exists at the top level.

Loading of :direct runners

Query plan link: https://gitlab.slack.com/archives/CLJMDRD8C/p1627403911288900

SQL query
SELECT
    "ci_runners".*
FROM
    "ci_runners"
    INNER JOIN "ci_runner_namespaces" ON "ci_runner_namespaces"."runner_id" = "ci_runners"."id"
WHERE
    "ci_runner_namespaces"."namespace_id" IN (
        SELECT
            "namespaces"."id"
        FROM
            "namespaces"
        WHERE
            "namespaces"."type" = 'Group'
            AND "namespaces"."id" = 111)
ORDER BY
    "ci_runners"."created_at" DESC,
    "ci_runners"."id" DESC
LIMIT 100
Execution plan
 Limit  (cost=29.00..29.01 rows=5 width=234) (actual time=4.238..4.240 rows=0 loops=1)
   Buffers: shared hit=6 read=3
   I/O Timings: read=3.777 write=0.000
   ->  Sort  (cost=29.00..29.01 rows=5 width=234) (actual time=4.236..4.238 rows=0 loops=1)
         Sort Key: ci_runners.created_at DESC, ci_runners.id DESC
         Sort Method: quicksort  Memory: 25kB
         Buffers: shared hit=6 read=3
         I/O Timings: read=3.777 write=0.000
         ->  Nested Loop  (cost=1.28..28.94 rows=5 width=234) (actual time=3.823..3.824 rows=0 loops=1)
               Buffers: shared read=3
               I/O Timings: read=3.777 write=0.000
               ->  Index Only Scan using index_namespaces_on_type_and_id_partial on public.namespaces  (cost=0.43..3.45 rows=1 width=4) (actual time=3.821..3.821 rows=0 loops=1)
                     Index Cond: ((namespaces.type = 'Group'::text) AND (namespaces.id = 111))
                     Heap Fetches: 0
                     Buffers: shared read=3
                     I/O Timings: read=3.777 write=0.000
               ->  Nested Loop  (cost=0.85..25.44 rows=5 width=238) (actual time=0.000..0.000 rows=0 loops=0)
                     I/O Timings: read=0.000 write=0.000
                     ->  Index Scan using index_ci_runner_namespaces_on_namespace_id on public.ci_runner_namespaces  (cost=0.42..8.22 rows=5 width=8) (actual time=0.000..0.000 rows=0 loops=0)
                           Index Cond: (ci_runner_namespaces.namespace_id = 111)
                           I/O Timings: read=0.000 write=0.000
                     ->  Index Scan using ci_runners_pkey on public.ci_runners  (cost=0.43..3.45 rows=1 width=234) (actual time=0.000..0.000 rows=0 loops=0)
                           Index Cond: (ci_runners.id = ci_runner_namespaces.runner_id)
                           I/O Timings: read=0.000 write=0.000

Closes #334686 (closed)

Edited by Pedro Pombeiro

Merge request reports