GitLabCore reconciler

Status: Implemented Issue: none Parent: none

Goal

An administrator describes a GitLab instance in one GitLabCore resource, and the Operator keeps the cluster in line with it. The Operator deploys the GitLab chart without Helm release storage and without widening what a writer of the resource may do.

Child specs:

Cleanup is shared with Siphon and has a spec of its own: Object cleanup. So does reading a version from a ConfigMap: Version reference.

Requirements

  • The reconciler runs only in a build with the bridge tag and with ENABLE_BRIDGE=true. Without either, the manager starts with no GitLabCore watch.
  • Each pass renders the chart version the instance converges to next, and applies every rendered object except definitions and RBAC.
  • An object deleted or edited by hand is restored on the next successful pass, at most 30 seconds after the previous one, with no change to the resource, unless the pass waits for the GitLabSecrets of the release.
  • A field another manager set on an applied object is taken back, and a field the chart stops rendering is removed.
  • The pre-install hooks of the chart run once per release: again when the spec changes, when the chart version changes, or when a pass failed or waited for the GitLabSecrets before they completed, and not on any other pass. For the wait, see GitLab secrets.
  • A chart version missing from the charts directory is pulled from the chart repository, and renders only once its signature verifies (see Chart provenance verification). With ENABLE_DYNAMIC_CHART_PULL=false, the version fails with an error that names the bundled ones.
  • No custom resource definition and no RBAC object is ever applied, hooks included.
  • An object whose API the cluster does not serve fails the pass, and Available names its kind.
  • The status reports Initialized once the hooks ran, and Available once every rendered workload has its replicas ready. While either is not True, the Bridge list shows its reason next to the phase, Initialized first and as an error when the phase is Failed, and its message in the expanded row, below the upgrade detail when there is one.
  • status.version reports the chart version applied, and status.gitlabVersion the GitLab version that chart deploys.
  • status.upgradeVersions lists the chart versions the instance can upgrade to, newest first: the newest patch of each minor above status.version, among the versions of the chart repository the Operator pulls from, or of its bundled charts with ENABLE_DYNAMIC_CHART_PULL=false. A repository out of reach for now keeps the versions listed before, and one that fails for good lists none. An instance not installed yet lists none.
  • The UpgradeVersionsListed condition of an installed instance says whether the last pass listed the versions to upgrade to, and why not when it did not.
  • The Bridge list offers Upgrade to these versions for a Static instance. It shows Latest version for an installed instance that lists none, and Newer versions unknown while UpgradeVersionsListed is not True. Once the versions are known, an unattended instance shows the newest listed version its type does not move to, such as a new major, as available.

Out of scope

  • The deprecated v1beta1 GitLab resource, which a separate controller serves.
  • Converting a GitLab into a GitLabCore.
  • Validating the chart values at admission.
  • Running the pre-upgrade, post-install, or pre-delete hooks.

FAQ

  • Why does the reconciler not watch the objects it applies? A release is hundreds of objects of kinds the Operator does not know ahead of time. The pass polls instead. For more information, see ADR 30.
  • Why are the hooks not run on every pass? Running them again deletes and recreates the shared secrets Job, and waits for its pod.
  • Why is RBAC never applied? It would turn the right to write a GitLabCore into the right to grant any permission the Operator holds. For more information, see ADR 31.
  • Is a pulled chart verified? Yes, against the GitLab chart signing key by default. For more information, see Chart provenance verification.
  • Why does the status list the versions to upgrade to, rather than Bridge reading the chart repository? Only the Operator knows which charts it bundles, whether it pulls, and which repository it reaches from inside the cluster. A client that reads the status lists what the Operator installs, behind a mirror and in a disconnected cluster too, with no permission beyond reading the GitLabCore. For more information, see ADR 32.
  • Why keep a list the Operator could not refresh, rather than clear it? A network blip would empty the upgrade picker. The condition says the list is out of date instead, which a client shows. A failure that lasts, such as a misconfigured repository, clears the list, because the versions listed before may come from another repository.
  • Why only the newest patch of each minor? An upgrade steps through the newest patch of each minor anyway, and an older patch lacks the fixes of the newest one. The list stays a few hundred bytes for an instance years behind. A Static version can still name any patch.
  • Where does status.gitlabVersion come from? From the render, not from a catalog, because a pulled chart is in no catalog. Siphon reads it to pin its table definitions.