Skip to content

Creating a project with ci_default_git_depth within group causes 500 when Enabling Group Runners

Summary

Creating a project with ci_default_git_depth: 1 succeeds but subsequent request to enable group runners from settings causes 500.

Steps to reproduce

  1. Create project in group. This request should succeed.
curl --request POST --header "PRIVATE-TOKEN: <redacted>" \
     --header "Content-Type: application/json" \
     --data '{"name": "test", "namespace_id": "47", "ci_default_git_depth": 1}' \
     --url 'https://<redacted>/api/v4/projects/'
  1. Visit CI/CD in Settings UI. In Runners section, click the Enable group runners button.
  2. 500 Occurs.

Example Project

https://gitlab.com/ytans-test/test

What is the current bug behavior?

500 Internal Server Error

What is the expected correct behavior?

This attribute is not listed for POST /projects endpoint. So 400 is expected.
Otherwise, this attribute should be supported and the project should be created with correct CI settings (Enable group runners shouldn't be the default, and there are currently issues with the values of other CI Settings also).

Relevant logs and/or screenshots

{
  "method": "POST",
  "path": "/test_group/test/-/runners/toggle_group_runners",
  "format": "html",
  "controller": "Projects::RunnersController",
  "action": "toggle_group_runners",
  "status": 500,
  "time": "2023-03-01T12:33:40.090Z",
  "params": [
    {
      "key": "_method",
      "value": "post"
    },
    {
      "key": "authenticity_token",
      "value": "[FILTERED]"
    },
    {
      "key": "namespace_id",
      "value": "test_group"
    },
    {
      "key": "project_id",
      "value": "test"
    }
  ],
  "correlation_id": "01GTEJKZ6CSFVQQB51478J12YM",
  "meta.caller_id": "Projects::RunnersController#toggle_group_runners",
  "meta.remote_ip": "<redacted>",
  "meta.feature_category": "runner",
  "meta.user": "yc",
  "meta.user_id": 2,
  "meta.project": "test_group/test",
  "meta.root_namespace": "test_group",
  "meta.client_id": "user/2",
  "remote_ip": "<redacted>",
  "user_id": 2,
  "username": "yc",
  "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/110.0.0.0 Safari/537.36",
  "queue_duration_s": 0.006395,
  "request_urgency": "low",
  "target_duration_s": 5,
  "redis_calls": 5,
  "redis_allowed_cross_slot_calls": 1,
  "redis_duration_s": 0.0008749999999999999,
  "redis_read_bytes": 183,
  "redis_write_bytes": 1215,
  "redis_sessions_calls": 4,
  "redis_sessions_allowed_cross_slot_calls": 1,
  "redis_sessions_duration_s": 0.000712,
  "redis_sessions_read_bytes": 183,
  "redis_sessions_write_bytes": 1162,
  "redis_shared_state_calls": 1,
  "redis_shared_state_duration_s": 0.000163,
  "redis_shared_state_write_bytes": 53,
  "db_count": 7,
  "db_write_count": 0,
  "db_cached_count": 1,
  "db_replica_count": 0,
  "db_primary_count": 7,
  "db_main_count": 7,
  "db_main_replica_count": 0,
  "db_replica_cached_count": 0,
  "db_primary_cached_count": 1,
  "db_main_cached_count": 1,
  "db_main_replica_cached_count": 0,
  "db_replica_wal_count": 0,
  "db_primary_wal_count": 0,
  "db_main_wal_count": 0,
  "db_main_replica_wal_count": 0,
  "db_replica_wal_cached_count": 0,
  "db_primary_wal_cached_count": 0,
  "db_main_wal_cached_count": 0,
  "db_main_replica_wal_cached_count": 0,
  "db_replica_duration_s": 0,
  "db_primary_duration_s": 0.005,
  "db_main_duration_s": 0.005,
  "db_main_replica_duration_s": 0,
  "cpu_s": 0.039587,
  "mem_objects": 18625,
  "mem_bytes": 2359816,
  "mem_mallocs": 4501,
  "mem_total_bytes": 3104816,
  "pid": 695,
  "worker_id": "puma_0",
  "rate_limiting_gates": [],
  "exception.class": "NoMethodError",
  "exception.message": "undefined method `toggle!' for nil:NilClass",
  "exception.backtrace": [
    "app/models/project.rb:2679:in `toggle_ci_cd_settings!'",
    "app/controllers/projects/runners_controller.rb:64:in `toggle_group_runners'",
    "app/controllers/application_controller.rb:532:in `set_current_admin'",
    "lib/gitlab/session.rb:11:in `with_session'",
    "app/controllers/application_controller.rb:523:in `set_session_storage'",
    "lib/gitlab/i18n.rb:107:in `with_locale'",
    "lib/gitlab/i18n.rb:113:in `with_user_locale'",
    "app/controllers/application_controller.rb:514:in `set_locale'",
    "app/controllers/application_controller.rb:507:in `set_current_context'",
    "lib/gitlab/metrics/elasticsearch_rack_middleware.rb:16:in `call'",
    "lib/gitlab/middleware/memory_report.rb:13:in `call'",
    "lib/gitlab/middleware/speedscope.rb:13:in `call'",
    "lib/gitlab/database/load_balancing/rack_middleware.rb:23:in `call'",
    "lib/gitlab/middleware/rails_queue_duration.rb:33:in `call'",
    "lib/gitlab/metrics/rack_middleware.rb:16:in `block in call'",
    "lib/gitlab/metrics/web_transaction.rb:46:in `run'",
    "lib/gitlab/metrics/rack_middleware.rb:16:in `call'",
    "lib/gitlab/jira/middleware.rb:19:in `call'",
    "lib/gitlab/middleware/go.rb:20:in `call'",
    "lib/gitlab/etag_caching/middleware.rb:21:in `call'",
    "lib/gitlab/middleware/query_analyzer.rb:11:in `block in call'",
    "lib/gitlab/database/query_analyzer.rb:37:in `within'",
    "lib/gitlab/middleware/query_analyzer.rb:11:in `call'",
    "lib/gitlab/middleware/multipart.rb:173:in `call'",
    "lib/gitlab/middleware/read_only/controller.rb:50:in `call'",
    "lib/gitlab/middleware/read_only.rb:18:in `call'",
    "lib/gitlab/middleware/same_site_cookies.rb:27:in `call'",
    "lib/gitlab/middleware/handle_malformed_strings.rb:21:in `call'",
    "lib/gitlab/middleware/basic_health_check.rb:25:in `call'",
    "lib/gitlab/middleware/handle_ip_spoof_attack_error.rb:25:in `call'",
    "lib/gitlab/middleware/request_context.rb:21:in `call'",
    "lib/gitlab/middleware/webhook_recursion_detection.rb:15:in `call'",
    "config/initializers/fix_local_cache_middleware.rb:11:in `call'",
    "lib/gitlab/middleware/compressed_json.rb:37:in `call'",
    "lib/gitlab/middleware/rack_multipart_tempfile_factory.rb:19:in `call'",
    "lib/gitlab/middleware/sidekiq_web_static.rb:20:in `call'",
    "lib/gitlab/metrics/requests_rack_middleware.rb:79:in `call'",
    "lib/gitlab/middleware/release_env.rb:13:in `call'"
  ],
  "db_duration_s": 0.003,
  "view_duration_s": 0,
  "duration_s": 0.02273
}

Output of checks

/label reproduced on GitLab.com

Results of GitLab environment info

Expand for output related to GitLab environment info
System information
System:		
Current User:	git
Using RVM:	no
Ruby Version:	2.7.7p221
Gem Version:	3.1.6
Bundler Version:2.3.15
Rake Version:	13.0.6
Redis Version:	6.2.8
Sidekiq Version:6.5.7
Go Version:	unknown

GitLab information
Version:	15.9.1
Revision:	de8f6619031
Directory:	/opt/gitlab/embedded/service/gitlab-rails
DB Adapter:	PostgreSQL
DB Version:	12.12
URL:		https://redacted
HTTP Clone URL:	https://redacted/some-group/some-project.git
SSH Clone URL:	git@redacted:some-group/some-project.git
Using LDAP:	no
Using Omniauth:	yes
Omniauth Providers:

GitLab Shell
Version:	14.17.0
Repository storages:
- default: 	unix:/var/opt/gitlab/gitaly/gitaly.socket
GitLab Shell path:		/opt/gitlab/embedded/service/gitlab-shell

Results of GitLab application Check

Expand for output related to the GitLab application check

Checking GitLab subtasks ...

Checking GitLab Shell ...

GitLab Shell: ... GitLab Shell version >= 14.17.0 ? ... OK (14.17.0) Running /opt/gitlab/embedded/service/gitlab-shell/bin/check Internal API available: OK Redis available via internal API: OK gitlab-shell self-check successful

Checking GitLab Shell ... Finished

Checking Gitaly ...

Gitaly: ... default ... OK

Checking Gitaly ... Finished

Checking Sidekiq ...

Sidekiq: ... Running? ... yes Number of Sidekiq processes (cluster/worker) ... 1/1

Checking Sidekiq ... Finished

Checking Incoming Email ...

Incoming Email: ... Reply by email is disabled in config/gitlab.yml

Checking Incoming Email ... Finished

Checking LDAP ...

LDAP: ... LDAP is disabled in config/gitlab.yml

Checking LDAP ... Finished

Checking GitLab App ...

Database config exists? ... yes All migrations up? ... yes Database contains orphaned GroupMembers? ... no GitLab config exists? ... yes GitLab config up to date? ... yes Cable config exists? ... yes Resque config exists? ... yes Log directory writable? ... yes Tmp directory writable? ... yes Uploads directory exists? ... yes Uploads directory has correct permissions? ... yes Uploads directory tmp has correct permissions? ... skipped (no tmp uploads folder yet) Systemd unit files or init script exist? ... skipped (omnibus-gitlab has neither init script nor systemd units) Systemd unit files or init script up-to-date? ... skipped (omnibus-gitlab has neither init script nor systemd units) Projects have namespace: ... 2/1 ... yes 3/2 ... yes 3/3 ... yes 3/4 ... yes 3/7 ... yes 3/9 ... yes 3/22 ... yes 3/23 ... yes 3/26 ... yes 3/27 ... yes 40/28 ... yes 40/29 ... yes 40/30 ... yes 40/31 ... yes 47/34 ... yes 47/35 ... yes Redis version >= 6.0.0? ... yes Ruby version >= 2.7.2 ? ... yes (2.7.7) Git user has default SSH configuration? ... yes Active users: ... 3 Is authorized keys file accessible? ... yes GitLab configured to store new projects in hashed storage? ... yes All projects are in hashed storage? ... yes

Checking GitLab App ... Finished

Checking GitLab subtasks ... Finished

Possible fixes

It seems like the issue is due to the combination of delegation to ci_cd_settings from project here and the way that association is normally created here

That is when a project is instantiated with a ci_default_git_depth the ci_cd_settings association is loaded and therefore not created later.

  1. To support ci_default_git_depth during project creation: A fix would involve handling ci_default_git_depth and other supported parameters that are attributes that are delegated to associations on projects (e.g ci_forward_deployment_enabled and so on) ahead of instantiating the project with them or otherwise reloading/creating the association as necessary
  2. To ignore ci_default_git_depth during project creation: Remove it from the declared parameters list for the grape endpoint.

Either of those will allow ci_cd_settings to be created properly

Edited by Jerry Seto