diff --git a/_support/benchmarking/.gitignore b/_support/benchmarking/.gitignore index 7b1864e6511e6068c1b0df00f47290796e70f369..7d6f92c819f64f1e248e4d8f5f1835c38484e535 100644 --- a/_support/benchmarking/.gitignore +++ b/_support/benchmarking/.gitignore @@ -2,6 +2,9 @@ /terraform/* !/terraform/main.tf !/terraform/locals.tf +/terraform-prepare/* +!/terraform-prepare/main.tf +!/terraform-prepare/locals.tf /group_vars/all.yml /results/* config.yml diff --git a/_support/benchmarking/.tool-versions b/_support/benchmarking/.tool-versions index db57b0f1554387ed0087fa1f9469d59a3f70d376..b9911e7b29d0b2e3a161c75d6af51239b1872068 100644 --- a/_support/benchmarking/.tool-versions +++ b/_support/benchmarking/.tool-versions @@ -1,2 +1,2 @@ -terraform 1.3.9 -python 3.11.2 +terraform 1.12.2 +python 3.13.5 diff --git a/_support/benchmarking/config.yml.example b/_support/benchmarking/config.yml.example index 30ba48f2ec00267f167fb2ce1a768602d6b08f14..92a241799b813fb7dc5635b03b6a570c13ad0915 100644 --- a/_support/benchmarking/config.yml.example +++ b/_support/benchmarking/config.yml.example @@ -13,3 +13,11 @@ benchmark_zone: "us-central1-a" use_regional_disk: false # One of these zones must be the zone for benchmark_zone regional_disk_replica_zones: ["us-central1-a", "us-central1-b"] + +# The list of repositories which will be cloned into Gitaly's storage disk. +repositories: + - "https://gitlab.com/gitlab-org/git.git" + - "https://gitlab.com/gitlab-org/gitlab" + - "https://gitlab.com/linux-kernel/linux.git" + - "https://github.com/Homebrew/homebrew-core.git" + - "https://chromium.googlesource.com/chromium/src" diff --git a/_support/benchmarking/requirements.txt b/_support/benchmarking/requirements.txt index 07d2c59e2081452582b438ab7e253a8af217c0dc..566d2dddd3e2e0ade6875f18901966e693623404 100644 --- a/_support/benchmarking/requirements.txt +++ b/_support/benchmarking/requirements.txt @@ -1,10 +1,10 @@ -ansible==7.2.0 -ansible-core==2.14.2 -cffi==1.15.1 +ansible==11.8.0 +ansible-core==2.18.7 +cffi==1.17.1 cryptography==39.0.1 Jinja2==3.1.2 MarkupSafe==2.1.2 packaging==23.0 pycparser==2.21 -PyYAML==6.0 +PyYAML==6.0.2 resolvelib==0.8.1 diff --git a/_support/benchmarking/roles/gitaly/tasks/setup_gitlab_shell.yml b/_support/benchmarking/roles/gitaly/tasks/setup_gitlab_shell.yml index 21143a729b79862a296f0757e6873257109ecd7c..3b752ccd88dff2e01475390293fbb4d3d203ac08 100644 --- a/_support/benchmarking/roles/gitaly/tasks/setup_gitlab_shell.yml +++ b/_support/benchmarking/roles/gitaly/tasks/setup_gitlab_shell.yml @@ -41,6 +41,7 @@ chdir: /src/gitlab-shell environment: PATH: '/usr/local/go/bin:{{ ansible_env.PATH }}' + become_user: git - name: Create gitlab-shell secret file: diff --git a/_support/benchmarking/setup-repositories.sh b/_support/benchmarking/setup-repositories.sh new file mode 100644 index 0000000000000000000000000000000000000000..0db5ff942a67536ead0e27232bb8bd222d778a15 --- /dev/null +++ b/_support/benchmarking/setup-repositories.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# This script is templated and will be executed when creating the +# `repository-setup-vm` Terraform resource. + +set -euxo pipefail + +disk_name="/dev/disk/by-id/google-repositories" +mountpoint="/mnt/disks/repositories" + +# Disks mounted to a GCP VM are prefixed with "google-" +# https://cloud.google.com/compute/docs/disks/format-mount-disk-linux#format_linux +# +# TODO make this configurable so we can test other filesystems, like btrfs. +mkfs.ext4 -m 0 -E lazy_itable_init=0,lazy_journal_init=0,discard "$${disk_name}" +mkdir -p "$${mountpoint}" +mount -o discard,defaults "$${disk_name}" "$${mountpoint}" +chmod a+w "$${mountpoint}" + +echo "repositories disk successfully mounted as an ext4 volume at $${mountpoint}}" + +cd "$${mountpoint}" + +%{for repo_url in repositories} +if ! git clone --bare "${repo_url}"; then +echo "WARNING: Failed to clone ${repo_url}, continuing with other repositories" >&2 +fi +%{endfor} + +shutdown -h now diff --git a/_support/benchmarking/terraform/main.tf b/_support/benchmarking/terraform/main.tf index 2dc528600031c94516df4308dbb3acf9d61be229..7103feafe58c035fb3020b0559dbd0a1d54a4922 100644 --- a/_support/benchmarking/terraform/main.tf +++ b/_support/benchmarking/terraform/main.tf @@ -13,15 +13,77 @@ provider "google" { zone = local.config.benchmark_zone } -data "google_compute_disk" "repository-disk" { - name = "git-repos" - project = local.config.project +# Temporary disk from which we create the `git-repositories-` disk image from. +resource "google_compute_disk" "prepare_repos" { + name = format("%s-prepare-repos-disk", var.gitaly_benchmarking_instance_name) + type = "pd-standard" + size = 100 +} + +# Temporary VM which clones and prepares the `git-repositories-` disk. +resource "google_compute_instance" "prepare_repos" { + name = format("%s-prepare-repos-vm", var.gitaly_benchmarking_instance_name) + machine_type = "n2d-standard-2" + zone = local.config.benchmark_zone + + boot_disk { + initialize_params { + image = local.config.os_image + } + } + + attached_disk { + source = google_compute_disk.prepare_repos.self_link + device_name = "repositories" + } + + network_interface { + network = "default" + access_config {} + } + + # If the script fails, you can SSH into the VM manually to debug the script: + # https://cloud.google.com/compute/docs/instances/startup-scripts/linux + metadata = { + startup-script = templatefile("${path.module}/../setup-repositories.sh", { + repositories = local.config.repositories + }) + } +} + +# Waits for the temporary setup VM to shut down, signalling the repos have been cloned. +resource "null_resource" "prepare_repos_wait" { + provisioner "local-exec" { + command = <<-EOF + timeout 7200 bash -c ' + while true; do + STATUS=$(gcloud compute instances describe ${google_compute_instance.prepare_repos.name} \ + --zone=${google_compute_instance.prepare_repos.zone} \ + --format="value(status)" \ + --project=${local.config.project}) + if [ "$STATUS" = "TERMINATED" ]; then + break + fi + sleep 30 + done + ' + EOF + } + + depends_on = [google_compute_instance.prepare_repos] +} + +resource "google_compute_image" "repos" { + name = "git-repos" + source_disk = google_compute_disk.prepare_repos.self_link + + depends_on = [null_resource.prepare_repos_wait] } resource "google_compute_disk" "repository-disk" { name = format("%s-repository-disk", var.gitaly_benchmarking_instance_name) type = local.config.repository_disk_type - image = format("projects/%s/global/images/git-repositories", local.config.project) + image = google_compute_image.repos.self_link } resource "google_compute_region_disk" "repository-region-disk" { @@ -69,10 +131,6 @@ resource "google_compute_instance" "gitaly" { } tags = ["gitaly"] - - lifecycle { - ignore_changes = [attached_disk] - } } resource "google_compute_instance" "client" {