Skip to content

Commit c736cf7

Browse files
committed
init
1 parent 13f8427 commit c736cf7

File tree

14 files changed

+2849
-4
lines changed

14 files changed

+2849
-4
lines changed

api/v1/perconaservermysql_types.go

Lines changed: 69 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ type PerconaServerMySQLSpec struct {
8080
Toolkit *ToolkitSpec `json:"toolkit,omitempty"`
8181
UpgradeOptions UpgradeOptions `json:"upgradeOptions,omitempty"`
8282
UpdateStrategy appsv1.StatefulSetUpdateStrategyType `json:"updateStrategy,omitempty"`
83+
Hibernation *HibernationSpec `json:"hibernation,omitempty"`
8384

8485
// Deprecated: not supported since v0.12.0. Use initContainer instead
8586
InitImage string `json:"initImage,omitempty"`
@@ -629,7 +630,8 @@ type PerconaServerMySQLStatus struct { // INSERT ADDITIONAL STATUS FIELD - defin
629630
ToolkitVersion string `json:"toolkitVersion,omitempty"`
630631
Conditions []metav1.Condition `json:"conditions,omitempty"`
631632
// +optional
632-
Host string `json:"host"`
633+
Host string `json:"host"`
634+
Hibernation *HibernationStatus `json:"hibernation,omitempty"`
633635
}
634636

635637
func (s *PerconaServerMySQLStatus) CompareMySQLVersion(ver string) int {
@@ -960,6 +962,13 @@ func (cr *PerconaServerMySQL) CheckNSetDefaults(_ context.Context, serverVersion
960962
cr.Spec.MySQL.VaultSecretName = cr.Name + "-vault"
961963
}
962964

965+
// Validate hibernation configuration
966+
if cr.Spec.Hibernation != nil {
967+
if err := cr.Spec.Hibernation.Validate(); err != nil {
968+
return errors.Wrap(err, "invalid hibernation configuration")
969+
}
970+
}
971+
963972
return nil
964973
}
965974

@@ -1200,6 +1209,36 @@ func (cr *PerconaServerMySQL) PVCResizeInProgress() bool {
12001209
return ok
12011210
}
12021211

1212+
// Validate validates the hibernation specification.
1213+
func (h *HibernationSpec) Validate() error {
1214+
if h == nil || !h.Enabled {
1215+
return nil
1216+
}
1217+
1218+
if h.Schedule.Pause != "" {
1219+
if _, err := cron.ParseStandard(h.Schedule.Pause); err != nil {
1220+
return errors.Wrap(err, "invalid pause schedule")
1221+
}
1222+
}
1223+
1224+
if h.Schedule.Unpause != "" {
1225+
if _, err := cron.ParseStandard(h.Schedule.Unpause); err != nil {
1226+
return errors.Wrap(err, "invalid unpause schedule")
1227+
}
1228+
}
1229+
1230+
if h.Schedule.Pause == "" && h.Schedule.Unpause == "" {
1231+
return errors.New("at least one schedule (pause or unpause) must be specified when hibernation is enabled")
1232+
}
1233+
1234+
return nil
1235+
}
1236+
1237+
// IsHibernationEnabled checks if hibernation is enabled.
1238+
func (cr *PerconaServerMySQL) IsHibernationEnabled() bool {
1239+
return cr.Spec.Hibernation != nil && cr.Spec.Hibernation.Enabled
1240+
}
1241+
12031242
// Registers PerconaServerMySQL types with the SchemeBuilder.
12041243
func init() {
12051244
SchemeBuilder.Register(&PerconaServerMySQL{}, &PerconaServerMySQLList{})
@@ -1213,9 +1252,37 @@ type UpgradeOptions struct {
12131252
Apply string `json:"apply,omitempty"`
12141253
}
12151254

1255+
type HibernationSpec struct {
1256+
Enabled bool `json:"enabled,omitempty"`
1257+
Schedule HibernationSchedule `json:"schedule,omitempty"`
1258+
}
1259+
1260+
type HibernationSchedule struct {
1261+
Pause string `json:"pause,omitempty"` // Cron expression for pause (minute hour day month weekday)
1262+
Unpause string `json:"unpause,omitempty"` // Cron expression for unpause (minute hour day month weekday)
1263+
}
1264+
1265+
type HibernationStatus struct {
1266+
// State indicates the current hibernation state of the cluster
1267+
// +kubebuilder:validation:Enum=Active;Paused;Scheduled;Blocked;Disabled
1268+
State string `json:"state,omitempty"` // Current hibernation state
1269+
LastPauseTime *metav1.Time `json:"lastPauseTime,omitempty"` // When cluster was last paused
1270+
LastUnpauseTime *metav1.Time `json:"lastUnpauseTime,omitempty"` // When cluster was last unpaused
1271+
NextPauseTime *metav1.Time `json:"nextPauseTime,omitempty"` // When cluster will be paused next
1272+
NextUnpauseTime *metav1.Time `json:"nextUnpauseTime,omitempty"` // When cluster will be unpaused next
1273+
Reason string `json:"reason,omitempty"` // Why pause was skipped or additional info
1274+
}
1275+
12161276
const (
12171277
UpgradeStrategyDisabled = "disabled"
12181278
UpgradeStrategyNever = "never"
12191279
UpgradeStrategyRecommended = "recommended"
1220-
UpgradeStrategyLatest = "latest"
1280+
1281+
// Hibernation states
1282+
HibernationStateActive = "Active" // Cluster is running normally
1283+
HibernationStatePaused = "Paused" // Cluster is paused by hibernation
1284+
HibernationStateScheduled = "Scheduled" // Hibernation is scheduled but not yet active
1285+
HibernationStateBlocked = "Blocked" // Hibernation is blocked by active operations
1286+
HibernationStateDisabled = "Disabled" // Hibernation is disabled
1287+
UpgradeStrategyLatest = "latest"
12211288
)

api/v1/zz_generated.deepcopy.go

Lines changed: 72 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/manager/main.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import (
4444
"github.com/percona/percona-server-mysql-operator/pkg/clientcmd"
4545
"github.com/percona/percona-server-mysql-operator/pkg/controller/ps"
4646
"github.com/percona/percona-server-mysql-operator/pkg/controller/psbackup"
47+
"github.com/percona/percona-server-mysql-operator/pkg/controller/pshibernation"
4748
"github.com/percona/percona-server-mysql-operator/pkg/controller/psrestore"
4849
"github.com/percona/percona-server-mysql-operator/pkg/k8s"
4950
"github.com/percona/percona-server-mysql-operator/pkg/platform"
@@ -181,6 +182,14 @@ func main() {
181182
setupLog.Error(err, "unable to create controller", "controller", "PerconaServerMySQLRestore")
182183
os.Exit(1)
183184
}
185+
if err = (&pshibernation.PerconaServerMySQLHibernationReconciler{
186+
Client: nsClient,
187+
Scheme: mgr.GetScheme(),
188+
ServerVersion: serverVersion,
189+
}).SetupWithManager(mgr); err != nil {
190+
setupLog.Error(err, "unable to create controller", "controller", "pshibernation-controller")
191+
os.Exit(1)
192+
}
184193
//+kubebuilder:scaffold:builder
185194

186195
err = mgr.GetFieldIndexer().IndexField(

config/crd/bases/ps.percona.com_perconaservermysqls.yaml

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2681,6 +2681,18 @@ spec:
26812681
type: string
26822682
enableVolumeExpansion:
26832683
type: boolean
2684+
hibernation:
2685+
properties:
2686+
enabled:
2687+
type: boolean
2688+
schedule:
2689+
properties:
2690+
pause:
2691+
type: string
2692+
unpause:
2693+
type: string
2694+
type: object
2695+
type: object
26842696
ignoreAnnotations:
26852697
items:
26862698
type: string
@@ -10815,6 +10827,31 @@ spec:
1081510827
version:
1081610828
type: string
1081710829
type: object
10830+
hibernation:
10831+
properties:
10832+
lastPauseTime:
10833+
format: date-time
10834+
type: string
10835+
lastUnpauseTime:
10836+
format: date-time
10837+
type: string
10838+
nextPauseTime:
10839+
format: date-time
10840+
type: string
10841+
nextUnpauseTime:
10842+
format: date-time
10843+
type: string
10844+
reason:
10845+
type: string
10846+
state:
10847+
enum:
10848+
- Active
10849+
- Paused
10850+
- Scheduled
10851+
- Blocked
10852+
- Disabled
10853+
type: string
10854+
type: object
1081810855
host:
1081910856
type: string
1082010857
mysql:

deploy/bundle.yaml

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5014,6 +5014,18 @@ spec:
50145014
type: string
50155015
enableVolumeExpansion:
50165016
type: boolean
5017+
hibernation:
5018+
properties:
5019+
enabled:
5020+
type: boolean
5021+
schedule:
5022+
properties:
5023+
pause:
5024+
type: string
5025+
unpause:
5026+
type: string
5027+
type: object
5028+
type: object
50175029
ignoreAnnotations:
50185030
items:
50195031
type: string
@@ -13148,6 +13160,31 @@ spec:
1314813160
version:
1314913161
type: string
1315013162
type: object
13163+
hibernation:
13164+
properties:
13165+
lastPauseTime:
13166+
format: date-time
13167+
type: string
13168+
lastUnpauseTime:
13169+
format: date-time
13170+
type: string
13171+
nextPauseTime:
13172+
format: date-time
13173+
type: string
13174+
nextUnpauseTime:
13175+
format: date-time
13176+
type: string
13177+
reason:
13178+
type: string
13179+
state:
13180+
enum:
13181+
- Active
13182+
- Paused
13183+
- Scheduled
13184+
- Blocked
13185+
- Disabled
13186+
type: string
13187+
type: object
1315113188
host:
1315213189
type: string
1315313190
mysql:
@@ -13466,7 +13503,7 @@ spec:
1346613503
fieldPath: metadata.namespace
1346713504
- name: DISABLE_TELEMETRY
1346813505
value: "false"
13469-
image: perconalab/percona-server-mysql-operator:main
13506+
image: perconalab/percona-server-mysql-operator:main-h25
1347013507
imagePullPolicy: Always
1347113508
livenessProbe:
1347213509
httpGet:

deploy/cr.yaml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ metadata:
55
finalizers:
66
- percona.com/delete-mysql-pods-in-order
77
# - percona.com/delete-ssl
8-
# - percona.com/delete-mysql-pvc
8+
- percona.com/delete-mysql-pvc
99
spec:
1010
# metadata:
1111
# annotations:
@@ -28,6 +28,11 @@ spec:
2828
upgradeOptions:
2929
versionServiceEndpoint: https://check.percona.com
3030
apply: disabled
31+
hibernation:
32+
enabled: true
33+
schedule:
34+
pause: "55 12 * * 1-5" # Pause Mon-Fri at 8 PM
35+
unpause: "45 12 * * 1-5" # Unpause Mon-Fri at 8 AM
3136
# initContainer:
3237
# image: perconalab/percona-server-mysql-operator:main
3338
# containerSecurityContext:

0 commit comments

Comments
 (0)