Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "Go",
// TODO: bump when available, see: https://github.com/devcontainers/images/tree/main/src/go
"image": "mcr.microsoft.com/devcontainers/go:1.25-bookworm",
"image": "mcr.microsoft.com/devcontainers/go:1.26-bookworm",
"features": {
"ghcr.io/devcontainers/features/docker-in-docker:3.0.1": {
"moby": true,
Expand Down
24 changes: 12 additions & 12 deletions .github/workflows/helm-release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ jobs:
env:
GITHUB_TOKEN: "${{ secrets.GHA_TOKEN }}"

olm:
name: Helm OLM
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 0
# olm:
# name: Helm OLM
# runs-on: ubuntu-latest
# steps:
# - name: Checkout
# uses: actions/checkout@v6
# with:
# fetch-depth: 0

- name: Dispatch helm OLM workflow
run: gh workflow run bundle.yaml --repo mariadb-operator/mariadb-operator-helm -f version=$(make helm-version)
env:
GITHUB_TOKEN: "${{ secrets.GHA_TOKEN }}"
# - name: Dispatch helm OLM workflow
# run: gh workflow run bundle.yaml --repo mariadb-operator/mariadb-operator-helm -f version=$(make helm-version)
# env:
# GITHUB_TOKEN: "${{ secrets.GHA_TOKEN }}"
2 changes: 1 addition & 1 deletion .github/workflows/helm.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Helm
on:
push:
branches:
- main
- "band/*"
paths:
- "deploy/charts/**"
pull_request:
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ name: Release
on:
push:
tags:
- "[0-9]+.[0-9]+.[0-9]+"
- "[0-9]+.[0-9]+.[0-9]+-bandwidth.[0-9]+"

env:
GORELEASER_VERSION: "v2.2.0"
Expand Down Expand Up @@ -136,7 +136,7 @@ jobs:
with:
fetch-depth: 0
token: "${{ secrets.GHA_TOKEN }}"
ref: "${{ github.event.repository.default_branch }}"
ref: "band/${{ needs.args.outputs.VERSION }}"

- name: Configure Git
run: |
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ endif
SHELL = /usr/bin/env bash -o pipefail
.SHELLFLAGS = -ec

VERSION ?= 26.6.0
VERSION ?= 26.6.0-bandwidth.1

# mariadb-operator
IMG_NAME ?= ghcr.io/mariadb-operator/mariadb-operator
Expand Down
12 changes: 12 additions & 0 deletions api/v1alpha1/backup_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,9 +51,16 @@ type BackupSpec struct {
// +operator-sdk:csv:customresourcedefinitions:type=spec
MaxRetention metav1.Duration `json:"maxRetention,omitempty" webhook:"inmutableinit"`
// Databases defines the logical databases to be backed up. If not provided, all databases are backed up.
// Mutually exclusive with Tables.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
Databases []string `json:"databases,omitempty"`
// Tables defines specific tables to be backed up, in "database.table" format. Entries may span
// multiple databases; when they do, --ignore-table flags are built at runtime by querying
// information_schema so that the dump remains a single consistent transaction. Mutually exclusive with Databases.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
Tables []string `json:"tables,omitempty"`
// IgnoreGlobalPriv indicates to ignore the mysql.global_priv in backups.
// If not provided, it will default to true when the referred MariaDB instance has Galera enabled and otherwise to false.
// See: https://github.com/mariadb-operator/mariadb-operator/issues/556
Expand Down Expand Up @@ -119,6 +126,11 @@ func (b *Backup) IsComplete() bool {
return meta.IsStatusConditionTrue(b.Status.Conditions, ConditionTypeComplete)
}

func (b *Backup) IsFailed() bool {
condition := meta.FindStatusCondition(b.Status.Conditions, ConditionTypeComplete)
return condition != nil && condition.Status == metav1.ConditionTrue && condition.Reason == ConditionReasonJobFailed
}

func (b *Backup) Validate() error {
if b.Spec.Schedule != nil {
if err := b.Spec.Schedule.Validate(); err != nil {
Expand Down
7 changes: 5 additions & 2 deletions api/v1alpha1/base_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -915,8 +915,11 @@ type Schedule struct {
}

func (s *Schedule) Validate() error {
_, err := CronParser.Parse(s.Cron)
return err
if s.Cron != "" {
_, err := CronParser.Parse(s.Cron)
return err
}
return nil
}

// CronJobTemplate defines parameters for configuring CronJob objects.
Expand Down
74 changes: 40 additions & 34 deletions api/v1alpha1/condition_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,40 +26,46 @@ const (
// ConditionTypeReplicationConfigured indicates that replication has been successfully configured.
ConditionTypeReplicationConfigured string = "ReplicationConfigured"

ConditionReasonStatefulSetNotReady string = "StatefulSetNotReady"
ConditionReasonStatefulSetReady string = "StatefulSetReady"
ConditionReasonRestoreBackup string = "RestoreBackup"
ConditionReasonRestorePhysicalBackup string = "RestorePhysicalBackup"
ConditionReasonArchiveBinlogs string = "ArchiveBinlogs"
ConditionReasonArchiveBinlogsError string = "ArchiveBinlogsError"
ConditionReasonReplayBinlogs string = "ReplayBinlogs"
ConditionReasonReplayBinlogsError string = "ReplayBinlogsError"
ConditionReasonReplayBinlogsSkipped string = "ReplayBinlogsSkipped"
ConditionReasonSwitchPrimary string = "SwitchPrimary"
ConditionReasonGaleraReady string = "GaleraReady"
ConditionReasonGaleraNotReady string = "GaleraNotReady"
ConditionReasonGaleraConfigured string = "GaleraConfigured"
ConditionReasonGaleraInitialized string = "GaleraInitialized"
ConditionReasonGaleraInitializing string = "GaleraInitializing"
ConditionReasonResizingStorage string = "ResizingStorage"
ConditionReasonWaitStorageResize string = "WaitStorageResize"
ConditionReasonStorageResized string = "StorageResized"
ConditionReasonInitializing string = "Initializing"
ConditionReasonInitialized string = "Initialized"
ConditionReasonInitError string = "InitError"
ConditionReasonScalingOut string = "ScalingOut"
ConditionReasonScaledOut string = "ScaledOut"
ConditionReasonScaleOutError string = "ScaleOutError"
ConditionReasonReplicaRecovering string = "ReplicaRecovering"
ConditionReasonReplicaRecovered string = "ReplicaRecovered"
ConditionReasonReplicaRecoverError string = "ReplicaRecoverError"
ConditionReasonReplicationConfigured string = "ReplicationConfigured"
ConditionReasonPendingUpdate string = "PendingUpdate"
ConditionReasonUpdating string = "Updating"
ConditionReasonUpdated string = "Updated"
ConditionReasonSuspended string = "Suspended"
ConditionReasonMaintenance string = "Maintenance"
ConditionReasonCordoned string = "Cordoned"
ConditionTypeExternalReplInitialized string = "ExternalReplInitialized"

ConditionReasonStatefulSetNotReady string = "StatefulSetNotReady"
ConditionReasonStatefulSetReady string = "StatefulSetReady"
ConditionReasonRestoreBackup string = "RestoreBackup"
ConditionReasonRestorePhysicalBackup string = "RestorePhysicalBackup"
ConditionReasonArchiveBinlogs string = "ArchiveBinlogs"
ConditionReasonArchiveBinlogsError string = "ArchiveBinlogsError"
ConditionReasonReplayBinlogs string = "ReplayBinlogs"
ConditionReasonReplayBinlogsError string = "ReplayBinlogsError"
ConditionReasonReplayBinlogsSkipped string = "ReplayBinlogsSkipped"
ConditionReasonSwitchPrimary string = "SwitchPrimary"
ConditionReasonGaleraReady string = "GaleraReady"
ConditionReasonGaleraNotReady string = "GaleraNotReady"
ConditionReasonGaleraConfigured string = "GaleraConfigured"
ConditionReasonGaleraInitialized string = "GaleraInitialized"
ConditionReasonGaleraInitializing string = "GaleraInitializing"
ConditionReasonResizingStorage string = "ResizingStorage"
ConditionReasonWaitStorageResize string = "WaitStorageResize"
ConditionReasonStorageResized string = "StorageResized"
ConditionReasonInitializing string = "Initializing"
ConditionReasonInitialized string = "Initialized"
ConditionReasonInitError string = "InitError"
ConditionReasonScalingOut string = "ScalingOut"
ConditionReasonScaledOut string = "ScaledOut"
ConditionReasonScaleOutError string = "ScaleOutError"
ConditionReasonReplicaRecovering string = "ReplicaRecovering"
ConditionReasonReplicaRecovered string = "ReplicaRecovered"
ConditionReasonReplicaRecoverError string = "ReplicaRecoverError"
ConditionReasonReplicationConfigured string = "ReplicationConfigured"
ConditionReasonPendingUpdate string = "PendingUpdate"
ConditionReasonUpdating string = "Updating"
ConditionReasonUpdated string = "Updated"
ConditionReasonSuspended string = "Suspended"
ConditionReasonMaintenance string = "Maintenance"
ConditionReasonCordoned string = "Cordoned"
ConditionReasonExternalReplInitError string = "ExternalReplInitError"
ConditionReasonExternalReplInitialized string = "ExternalReplInitialized"
ConditionReasonExternalReplInitializing string = "ExternalReplInitializing"
ConditionReasonPendingExternalReplInitialization string = "PendingExternalReplInitialization"

ConditionReasonMaxScaleNotReady string = "MaxScaleNotReady"
ConditionReasonMaxScaleReady string = "MaxScaleReady"
Expand Down
8 changes: 8 additions & 0 deletions api/v1alpha1/external_mariadb_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ import (
"k8s.io/utils/ptr"
)

// InternalServiceKey defines the key for the internal headless Service
func (m *ExternalMariaDB) InternalServiceKey() types.NamespacedName {
return types.NamespacedName{
Name: "",
Namespace: m.Namespace,
}
}

// TLSCABundleSecretKeyRef defines the key selector for the TLS Secret trust bundle
func (m *ExternalMariaDB) TLSCABundleSecretKeyRef() SecretKeySelector {
if m.Spec.TLS.ServerCASecretRef == nil {
Expand Down
29 changes: 29 additions & 0 deletions api/v1alpha1/external_mariadb_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ type ExternalMariaDBSpec struct {
// +kubebuilder:default=3306
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number","urn:alm:descriptor:com.tectonic.ui:advanced"}
Port int32 `json:"port,omitempty"`
// Binlog proxy router port of the external MariaDB. Useful when the external MariaDB is behind a Maxscale and using the Binlogrouter to expose the binlog stream.
// +optional
// +operator-sdk:csv:customresourcedefinitions:type=spec,xDescriptors={"urn:alm:descriptor:com.tectonic.ui:number","urn:alm:descriptor:com.tectonic.ui:advanced"}
BinlogProxyPort *int32 `json:"binlogPort,omitempty"`
// Username is the username to connect to the external MariaDB.
// +kubebuilder:validation:Required
// +operator-sdk:csv:customresourcedefinitions:type=spec
Expand Down Expand Up @@ -100,6 +104,11 @@ func (m *ExternalMariaDB) IsGaleraEnabled() bool {
return m.Status.IsGaleraEnabled
}

// Replication with defaulting accessor
func (m *ExternalMariaDB) Replication() Replication {
return Replication{}
}

// +kubebuilder:object:root=true
// +kubebuilder:resource:shortName=emdb
// +kubebuilder:subresource:status
Expand Down Expand Up @@ -127,6 +136,11 @@ func (m *ExternalMariaDB) SetDefaults(env *environment.OperatorEnv) error {
return nil
}

// Get MariaDB Object Meta
func (m *ExternalMariaDB) GetObjectMeta() *metav1.ObjectMeta {
return &m.ObjectMeta
}

// IsReady indicates whether the External MariaDB instance is ready
func (m *ExternalMariaDB) IsReady() bool {
return meta.IsStatusConditionTrue(m.Status.Conditions, ConditionTypeReady)
Expand Down Expand Up @@ -181,16 +195,31 @@ func (m *ExternalMariaDB) GetHost() string {
return m.Spec.Host
}

// Get specific MariaDB Pod hostname
func (m *ExternalMariaDB) GetPodHost(podIndex int) string {
return ""
}

// Get MariaDB port
func (m *ExternalMariaDB) GetPort() int32 {
return m.Spec.Port
}

// Get MariaDB binlog proxy router port
func (m *ExternalMariaDB) GetBinlogProxyPort() *int32 {
return m.Spec.BinlogProxyPort
}

// Get MariaDB replicas
func (m *ExternalMariaDB) GetReplicas() int32 {
return 0 // ExternalMariaDB does not make use of this
}

// IsHAEnabled indicates whether the MariaDB instance has HA enabled (Always false for external MariaDB)
func (m *ExternalMariaDB) IsHAEnabled() bool {
return false
}

// Get MariaDB Superuser name
func (m *ExternalMariaDB) GetSUName() string {
return ptr.Deref(m.Spec.Username, "root")
Expand Down
9 changes: 8 additions & 1 deletion api/v1alpha1/mariadb_keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,14 @@ func (m *MariaDB) BootstrapFromStagingPVCKey() types.NamespacedName {
// PITRJobKey defines the key for the PITR job used to replay the binary logs.
func (m *MariaDB) PITRJobKey() types.NamespacedName {
return types.NamespacedName{
Name: fmt.Sprintf("%s-pitr", m.Name),
Name: fmt.Sprintf("%s-pitr", m.Name),
}
}

// RestoreKey defines the key for the Restore resource used to bootstrap.
func (m *MariaDB) RestoreKeyInPod(podIndex int) types.NamespacedName {
return types.NamespacedName{
Name: fmt.Sprintf("%s-restore-%d", m.Name, podIndex),
Namespace: m.Namespace,
}
}
Expand Down
Loading
Loading