Skip to content

levyn96/gitlab-upgrade-helper

Repository files navigation

GitLab Helper CLI

A command-line utility built with Python, Click, and Poetry to assist with managing GitLab self-managed installations, particularly around configuration changes often needed during upgrades.

Note: This tool modifies configuration files and executes commands remotely via SSH. Use with caution and ensure you understand the changes being made. Always have backups and test in a non-production environment first.

Features

  • Remote Configuration Editing: Modify specific settings in /etc/gitlab/gitlab.rb remotely.
  • Template-Based Configuration: Apply a full /etc/gitlab/gitlab.rb configuration generated from a Jinja2 template and a YAML variables file.
  • SSH Key Authentication: Uses PEM keys for secure SSH connections.
  • Optional Backups: Automatically create timestamped backups of /etc/gitlab/gitlab.rb before making changes.
  • Optional Reconfigure: Automatically trigger gitlab-ctl reconfigure after applying changes.

Prerequisites

  • Python 3.8+
  • Poetry (for installation and dependency management)
  • SSH access to the target GitLab server(s).
  • An SSH private key (PEM format) authorized to access the server as the specified user (often root or a user with passwordless sudo privileges).
  • Network connectivity between the machine running the CLI and the GitLab server(s) on the SSH port (default 22).

Installation

  1. Clone this repository (or create the project structure).
  2. Navigate to the project directory in your terminal.
  3. Install dependencies using Poetry:
    poetry install
    This creates a virtual environment and installs click, fabric, pyyaml, and jinja2.

Configuration

SSH Access

  • Ensure the user specified via the --user option (defaults to root) can log in to the target GitLab server using the provided --key-file.
  • The tool uses sudo to modify /etc/gitlab/gitlab.rb, create backups in /etc/gitlab/, move temporary files, and run gitlab-ctl reconfigure. The specified SSH user must have passwordless sudo privileges for these actions to work seamlessly. Configure /etc/sudoers on the target server accordingly if needed.

Usage

General

All commands are run through the Poetry environment:

poetry run gitlab-helper [COMMAND] [OPTIONS]
poetry run gitlab-helper --help
poetry run gitlab-helper set-config --help
poetry run gitlab-helper apply-template --help

set-config Command Modifies a single, simple setting in the remote /etc/gitlab/gitlab.rb file. It searches for the setting key (commented or uncommented) and replaces the line, or appends the setting if not found.

Note: This command is best suited for simple key-value pairs (like external_url, unicorn['worker_processes']). It is not reliable for modifying complex Ruby structures like Hashes or Arrays within the file. Use apply-template for comprehensive changes.

Arguments --host TEXT: (Required) IP address or hostname of the GitLab server. --key-file PATH: (Required) Path to the SSH private key (PEM) file. --setting TEXT: (Required) The gitlab.rb setting key (e.g., 'external_url', "gitlab_rails['some_setting']"). --value TEXT: (Required) The new value for the setting. IMPORTANT: Use valid Ruby syntax (e.g., strings require quotes: 'http://new.url', numbers don't: 123, booleans are true/false). --user TEXT: SSH username (Default: root). --port INTEGER: SSH port (Default: 22). --backup / --no-backup: Create a backup before modifying (Default: --backup). --reconfigure / --no-reconfigure: Run 'gitlab-ctl reconfigure' after modification (Default: --no-reconfigure).

Examples

Change the external URL and run reconfigure

poetry run gitlab-helper set-config \
    --host gitlab.example.com \
    --key-file ~/.ssh/gitlab_admin_id_rsa \
    --setting external_url \
    --value "'[https://gitlab.newdomain.com](https://gitlab.newdomain.com)'" \
    --user admin \
    --backup \
    --reconfigure

Change the number of Unicorn workers, no reconfigure yet

poetry run gitlab-helper set-config \
    --host 10.0.1.5 \
    --key-file /etc/ssh/keys/gitlab_prod.pem \
    --setting unicorn['worker_processes'] \
    --value "4" \
    --no-reconfigure

apply-template Command

Applies a Jinja2 template to generate the entire /etc/gitlab/gitlab.rb content and replaces the remote file, OR renders the template locally to stdout for preview. This is the recommended method for managing the full configuration robustly.

Arguments

  • --host TEXT: IP address or hostname (Required unless --render-only).
  • --key-file PATH: Path to the SSH private key (PEM) file (Required unless --render-only).
  • --template PATH: (Required) Path to the Jinja2 template file.
  • --vars PATH: (Required) Path to the YAML file with variables.
  • --render-only: (Flag) Render template locally and print to stdout; skip remote connection and actions.
  • --user TEXT: SSH username (Default: root, Ignored if --render-only).
  • --port INTEGER: SSH port (Default: 22, Ignored if --render-only).
  • --backup / --no-backup: Create backup before replacing (Default: --backup, Ignored if --render-only).
  • --reconfigure / --no-reconfigure: Run 'gitlab-ctl reconfigure' after applying (Default: --no-reconfigure, Ignored if --render-only).

Template and Variables Files

(Keep the existing explanation and examples for template and vars files here)

  • Example (templates/gitlab.rb.j2 snippet): ...
  • Example (config/production.yaml snippet): ...

Examples

# Apply production configuration remotely and reconfigure
poetry run gitlab-helper apply-template \
    --host gitlab.prod.internal \
    --key-file ~/.ssh/id_rsa_prod \
    --template templates/base_gitlab.rb.j2 \
    --vars config/prod_vars.yaml \
    --backup \
    --reconfigure

# Render the template locally using staging variables and print to screen
poetry run gitlab-helper apply-template \
    --template templates/base_gitlab.rb.j2 \
    --vars config/staging_vars.yaml \
    --render-only

# Apply staging configuration remotely without running reconfigure
poetry run gitlab-helper apply-template \
    --host gitlab.staging.internal \
    --key-file ~/.ssh/id_rsa_staging \
    --template templates/base_gitlab.rb.j2 \
    --vars config/staging_vars.yaml \
    --no-reconfigure

Example (templates/gitlab.rb.j2 snippet):

Django

```Jinja2
# Generated on {{ ansible_date_time.iso8601 }} by gitlab-helper apply-template
external_url '{{ gitlab_external_url }}'

{% if ldap_enabled %}
gitlab_rails['ldap_enabled'] = true
gitlab_rails['ldap_servers'] = {{ ldap_servers | to_nice_yaml | indent(2) }}
{% else %}
gitlab_rails['ldap_enabled'] = false
{% endif %}

unicorn['worker_processes'] = {{ unicorn_workers | default(2) }}
(Note: to_nice_yaml is a filter you might need to define or import if using complex structures)

Variables (--vars): A YAML file containing key-value pairs that correspond to the variables used in your Jinja2 template. This allows you to separate environment-specific settings from the main configuration structure.

Example (config/production.yaml snippet):

gitlab_external_url: '[https://gitlab.mycompany.com](https://www.google.com/search?q=https://gitlab.mycompany.com)'
unicorn_workers: 4
ldap_enabled: true
ldap_servers:
  main: # This key should match expected structure in gitlab.rb
    label: 'My LDAP'
    host: '[ldap.mycompany.com](https://www.google.com/search?q=ldap.mycompany.com)'
    port: 636
    uid: 'sAMAccountName'
    bind_dn: 'cn=gitlab-binder,ou=Service Accounts,dc=mycompany,dc=com'
    password: 'very_secret_password' # Consider using secrets management!
    encryption: 'simple_tls' # 'start_tls', 'simple_tls' or 'plain'
    verify_certificates: true
    base: 'ou=Users,dc=mycompany,dc=com'

Examples

Apply production configuration from template and vars files, then reconfigure

poetry run gitlab-helper apply-template
--host gitlab.prod.internal
--key-file ~/.ssh/id_rsa_prod
--template templates/base_gitlab.rb.j2
--vars config/prod_vars.yaml
--user deployer
--backup
--reconfigure

Apply staging configuration without running reconfigure immediately

poetry run gitlab-helper apply-template
--host gitlab.staging.internal
--key-file ~/.ssh/id_rsa_staging
--template templates/base_gitlab.rb.j2
--vars config/staging_vars.yaml
--no-reconfigure

Important Considerations

Security: Protect your SSH private keys. Ensure they have strict file permissions (e.g., chmod 400 or 600). Avoid storing sensitive data like passwords directly in YAML variables files if possible; consider environment variables or dedicated secrets management tools. Sudo: Passwordless sudo is generally required for the SSH user on the target machine for modifying /etc/gitlab/gitlab.rb, moving temporary files, creating backups in standard locations, and running gitlab-ctl reconfigure. Backups: While the tool offers a backup option (--backup), this only creates a single timestamped copy of /etc/gitlab/gitlab.rb just before modification. Maintain your own independent GitLab instance backup strategy (application data, database, config files, secrets). Idempotency: The apply-template command is generally idempotent (running it multiple times with the same inputs yields the same gitlab.rb content). The set-config command attempts to be idempotent for simple settings found in the file but may not be fully idempotent, especially if the setting is not found initially (it will be appended on each run). Error Handling: If an operation fails (especially during file upload or gitlab-ctl reconfigure), the GitLab instance might be left in an inconsistent state. Check the tool's output/logs and the relevant GitLab server logs (e.g., sudo gitlab-ctl status, /var/log/gitlab/...). Manual intervention may be required. If backups were enabled (--backup), the tool attempts to restore the previous gitlab.rb if the upload step fails. Testing: Test configuration changes thoroughly in a non-production (staging) environment before applying them to production systems. Verify GitLab functionality after running gitlab-ctl reconfigure. gitlab.rb Complexity: The gitlab.rb file is Ruby code. Ensure values provided via set-config or generated by templates are valid Ruby syntax. Incorrect syntax will cause gitlab-ctl reconfigure to fail.

Development

(Example commands for development tasks)

Format code with Black

poetry run black .

Lint code with Ruff

poetry run ruff check . poetry run ruff format . # If using Ruff for formatting

Run tests (assuming pytest is configured)

poetry run pytest -v tests/ License (Specify your project's license here, e.g., MIT License, Apache 2.0)

About

A cli for helping self managed gitlab admins perform upgrades

Resources

Stars

Watchers

Forks

Packages

No packages published