How to Get Started With GitLab’s Rails Console for Advanced Administration


GitLab logo

GitLab’s Rails console provides an interactive terminal that lets you directly manipulate data in your GitLab instance. You can use it to extract information, troubleshoot problems, and perform advanced administration tasks that aren’t supported in the GitLab web UI or API.

To access the console you must be running your own self-managed GitLab server. You’ll need superuser privileges on the machine that hosts your environment. The console provides unimpeded control over GitLab and your data so only trusted administrators should be allowed to use it. Actions can override normal safeguards and cause unprompted data destruction.

Starting the Console

The method used to start the console depends on the type of GitLab installation you’re running. Omnibus distributions installed from a package manager support the following command:

$ sudo gitlab-rails console

Use this alternative if you’ve manually installed GitLab from source:

$ sudo -u git -H bundle exec rails console -e production

The console’s also available to cloud-native GitLab instances running in Kubernetes. Use Kubectl to attach to GitLab’s toolbox Pod and start a console session:

$ kubectl --namespace gitlab exec -it toolbox -- /srv/gitlab/bin/rails console

GitLab versions older than 14.2 will have a task-runner Pod instead of toolbox. Substitute task-runner into the command shown above if you’re running one of these releases.

The Rails console can take several seconds to start up. It’ll display a summary of your Ruby, GitLab, and PostgreSQL versions before dropping you to a terminal prompt.

$ sudo gitlab-rails console
--------------------------------------------------------------------------------
 Ruby:         ruby 2.7.5p203 (2021-11-24 revision f69aeb8314) [x86_64-linux]
 GitLab:       15.0.0 (8a186dedfc1) FOSS
 GitLab Shell: 14.3.0
 PostgreSQL:   12.10
------------------------------------------------------------[ booted in 22.48s ]
Loading production environment (Rails 6.1.4.7)
irb(main):001:0>

You can start issuing Ruby commands when you see the prompt appear.

Basic Usage

The console provides access to GitLab’s Ruby on Rails environment. In-scope objects let you fetch, update, and query data in your GitLab database. A basic understanding of Ruby and Rails will help you to get started.

Rails uses the Active Record pattern to provide static data mapping methods on objects. You can call the following method to retrieve a user by their username:

$ demo = User.find_by_username("demo")
# <User id:1 @demo>

You can view the properties of the retrieved object by inspecting its attributes:

$ pp demo.attributes
{"id"=>1,
 "email"=>"demo@example.com",
...

To retrieve a specific property, access it by name:

$ demo.email
demo@example.com

You can use Rails methods to conveniently fetch multiple object instances that match a query:

$ admins = User.where(admin: true).where('email like ?', '%@example.com')

This fetches all the example.com users with GitLab administrator permissions.

You can change the properties of an object instance by assigning new values and calling save:

$ demo.email = "example@example.com"
$ demo.save

The save method will check the object’s in a valid state before saving it to the database. You can explicitly disable validation in situations where you want to force a particular change to apply:

$ demo.save!(validate: false)

This should only be used to investigate issues where the GitLab web UI or API is unexpectedly rejecting data.

Common Tasks

The GitLab Rails console has limitless applications as you can work with any aspect of your GitLab instance. Here are some useful operations to get you started.

Discover Methods Available On An Object

The console experience can be daunting to newcomers, especially if you don’t have much familiarity with Rails. Documentation on the console is relatively sparse but you can discover functionality by retrieving the method list associated with each object:

$ User.methods
[:before_add_for_closed_issues, :before_add_for_closed_issues=, :after_add_for_closed_issues, ...]

You can combine this with grep to quickly filter to methods with a particular root:

$ Project.methods.grep(/find/)
[:find_by_runners_token, :find_by_url, :find_by_full_path, ...]

This reveals you can fetch a project by its path with the following command:

$ Project.find_by_full_path("/user/project")

Retrieve a Project With Its Issues and Merge Requests

First use the Project object to get the project by matching on a unique attribute such as its ID, path, or URL:

$ project = Project.find_by_full_path("/user/project")

Now you can access the project’s issues and merge requests via its relation properties:

# Get all issues
$ project.issues.all

# Get the first issue
$ project.issues.first

# Get a specific merge request by its project-level ID
$ project.merge_requests.find_by(iid: 10)

Retrieve a CI Pipeline

The Pipeline object is nested inside the CI namespace:

# Get the pipeline with ID 100
$ pipeline = Ci::Pipeline.find(100)

# Get builds (jobs) associated with the pipeline
$ jobs = pipeline.builds

Reset an Admin’s Password

The console can rescue you if you ever get locked out of your account. Retrieve the affected user object and then reset its password:

$ user = User.find_by_username("demo")
$ user.password = "abc123"
$ user.password_confirmation = "abc123"
$ user.save

Make a Project Read-Only

GitLab supports read-only projects that keep the repository accessible but prevent modifications from being made. Read-only mode has to be enabled using the console:

$ project = Project.find_by_full_path("/user/project")
$ project.repository_read_only = true
$ project.save

Manually Run a Pipeline Schedule

Scheduled pipelines can be executed immediately using the console. This can sometimes help to debug issues which aren’t fully reported in the UI and API.

First retrieve the PipelineSchedule object:

$ schedule = Ci::PipelineSchedule.find_by(id: 10)

Next fetch the user you want to execute the pipeline as:

$ user = User.find_by_username("demo")

Now use this command to start a run through the schedule:

$ Ci::CreatePipelineService.new(schedule.project, user, ref: schedule.ref).execute!(:schedule, ignore_skip_ci: true, save_on_errors: false, schedule: schedule)

It creates a new pipeline from the schedule and commences its execution.

Enable Feature Flags

Some pre-release GitLab features are gated behind feature flags. Flags are also sometimes used to permit temporary reactivation of deprecated capabilities.

The console is the only mechanism by which feature flags can be enabled. Pass the ID of a feature flag to the Feature.enable() function:

$ Feature.enable(:certificate_based_clusters)

The change applies immediately without restarting GitLab. This example reactivates support for certificate-based Kubernetes clusters in GitLab 15.0.

You can check whether a flag’s enabled with a Feature.enabled?() call:

$ Feature.enabled?(:certificate_based_clusters)
=> true

To disable a feature flag, pass its ID to the Feature.disable() method:

$ Feature.disable(:certificate_based_clusters)

Test Email Delivery

The console lets you directly send test messages to verify your outbound email system is working:

$ Notify.test_email("example@example.com", "Test subject", "Test body").deliver_now

The email will be sent immediately using the same mechanism as messages created by GitLab application functions.

Running Ruby Scripts With the Rails Runner

An interactive console session isn’t always necessary. The Rails Runner is an alternative which makes it easier to run Ruby scripts in the context of your GitLab environment.

Use the gitlab-rails runner command to execute some Ruby code. Your script can reference the same GitLab variables and objects that are available to a Rails console session.

$ sudo gitlab-rails runner "puts User.find_by_username('demo').email"

Rails will run the script you provide and then terminate the process. The example shown above emits the email address of the GitLab user called demo. This alternative runs Ruby code provided as a file:

$ sudo gitlab-rails runner /scripts/gitlab-rails-script.rb

Scripts saved as Ruby files need to be accessible to the Unix git user. GitLab Rails always executes as git:git so scripts owned by other users could produce an error. Invalid file paths will be interpreted as Ruby code to run, producing a syntax error that can mask the true problem:

$ sudo gitlab-rails runner /scripts/invalid-file.rb
Please specify a valid ruby command or the path of a script to run.
Run 'rails runner -h' for help

Summary

The GitLab Rails console is a powerful utility for directly interacting with your GitLab instance. It can be an invaluable debugging tool when you’re experiencing problems with your installation. The console also lets you script admin tasks using plain Ruby code, instead of relying on the GitLab API. Some operations such as feature flag enablement can only be achieved with the console.

With power comes responsibility. The console is capable of ignoring guardrails and accepting operations in contexts which they’re not designed for. Incorrect use could cause data loss and unexpected behavior. By using the console you’re lifting the lid on GitLab’s codebase and its internal operations. The available methods and their effects lack a support guarantee and could change without warning.





Source link