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
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,9 @@ lint-fix: golangci-lint ## Run golangci-lint linter and perform fixes
lint-config: golangci-lint ## Verify golangci-lint linter configuration
$(GOLANGCI_LINT) config verify

.PHONY: ci
ci: manifests generate fmt vet lint test build ## Run all CI checks: codegen, format, vet, lint, test, build.

##@ Build

.PHONY: build
Expand Down
17 changes: 17 additions & 0 deletions api/v1alpha1/memgraphcluster_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,23 @@ type MemgraphConfig struct {
// +kubebuilder:default=100000
// +optional
WALFlushEveryNTx int32 `json:"walFlushEveryNTx,omitempty"`

// SnapshotIntervalSec sets the periodic snapshot interval in seconds
// (Memgraph --storage-snapshot-interval-sec). Set to 0 to disable periodic
// snapshots entirely. If nil, Memgraph's built-in default (300s) is used.
// Pointer so that 0 (disabled) is distinguishable from unset.
// +optional
SnapshotIntervalSec *int32 `json:"snapshotIntervalSec,omitempty"`

// SnapshotRetentionCount sets how many periodic snapshots Memgraph keeps on
// disk (--storage-snapshot-retention-count). If nil, Memgraph's default is used.
// +optional
SnapshotRetentionCount *int32 `json:"snapshotRetentionCount,omitempty"`

// SnapshotOnExit controls whether Memgraph takes a snapshot on shutdown
// (--storage-snapshot-on-exit). If nil, Memgraph's default is used.
// +optional
SnapshotOnExit *bool `json:"snapshotOnExit,omitempty"`
}

// ReplicationSpec defines the replication settings
Expand Down
17 changes: 16 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 19 additions & 0 deletions config/crd/bases/memgraph.base14.io_memgraphclusters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -985,6 +985,25 @@ spec:
description: MemoryLimit sets the memory limit in MB for Memgraph
format: int32
type: integer
snapshotIntervalSec:
description: |-
SnapshotIntervalSec sets the periodic snapshot interval in seconds
(Memgraph --storage-snapshot-interval-sec). Set to 0 to disable periodic
snapshots entirely. If nil, Memgraph's built-in default (300s) is used.
Pointer so that 0 (disabled) is distinguishable from unset.
format: int32
type: integer
snapshotOnExit:
description: |-
SnapshotOnExit controls whether Memgraph takes a snapshot on shutdown
(--storage-snapshot-on-exit). If nil, Memgraph's default is used.
type: boolean
snapshotRetentionCount:
description: |-
SnapshotRetentionCount sets how many periodic snapshots Memgraph keeps on
disk (--storage-snapshot-retention-count). If nil, Memgraph's default is used.
format: int32
type: integer
walFlushEveryNTx:
default: 100000
description: WALFlushEveryNTx sets the number of transactions
Expand Down
16 changes: 15 additions & 1 deletion internal/controller/statefulset.go
Original file line number Diff line number Diff line change
Expand Up @@ -190,12 +190,26 @@ func buildMemgraphArgs(cluster *memgraphv1alpha1.MemgraphCluster) []string {
walFlushEveryNTx = defaultWALFlushEveryNTx
}

return []string{
args := []string{
fmt.Sprintf("--log-level=%s", logLevel),
fmt.Sprintf("--log-file=%s/memgraph.log", dataVolumePath),
fmt.Sprintf("--memory-limit=%d", memoryLimit),
fmt.Sprintf("--storage-wal-file-flush-every-n-tx=%d", walFlushEveryNTx),
}

// Snapshot flags are only emitted when explicitly configured; otherwise
// Memgraph's built-in defaults apply (interval 300s, retention 3, on-exit true).
if v := cluster.Spec.Config.SnapshotIntervalSec; v != nil {
args = append(args, fmt.Sprintf("--storage-snapshot-interval-sec=%d", *v))
}
if v := cluster.Spec.Config.SnapshotRetentionCount; v != nil {
args = append(args, fmt.Sprintf("--storage-snapshot-retention-count=%d", *v))
}
if v := cluster.Spec.Config.SnapshotOnExit; v != nil {
args = append(args, fmt.Sprintf("--storage-snapshot-on-exit=%t", *v))
}

return args
}

// buildInitContainers builds the init containers for the pod
Expand Down
57 changes: 57 additions & 0 deletions internal/controller/statefulset_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,63 @@ func TestBuildMemgraphArgs(t *testing.T) {
}
}

func TestBuildMemgraphArgsSnapshotFlags(t *testing.T) {
i32 := func(v int32) *int32 { return &v }
b := func(v bool) *bool { return &v }

hasArg := func(args []string, want string) bool {
for _, a := range args {
if a == want {
return true
}
}
return false
}

t.Run("no snapshot config emits no snapshot flags", func(t *testing.T) {
args := buildMemgraphArgs(&memgraphv1alpha1.MemgraphCluster{
Spec: memgraphv1alpha1.MemgraphClusterSpec{},
})
for _, a := range args {
if len(a) >= 18 && a[:18] == "--storage-snapshot" {
t.Errorf("unexpected snapshot flag %q; defaults should be left to Memgraph", a)
}
}
})

t.Run("interval 0 disables periodic snapshots", func(t *testing.T) {
args := buildMemgraphArgs(&memgraphv1alpha1.MemgraphCluster{
Spec: memgraphv1alpha1.MemgraphClusterSpec{
Config: memgraphv1alpha1.MemgraphConfig{SnapshotIntervalSec: i32(0)},
},
})
if !hasArg(args, "--storage-snapshot-interval-sec=0") {
t.Errorf("expected --storage-snapshot-interval-sec=0, got args: %v", args)
}
})

t.Run("all snapshot flags emitted when set", func(t *testing.T) {
args := buildMemgraphArgs(&memgraphv1alpha1.MemgraphCluster{
Spec: memgraphv1alpha1.MemgraphClusterSpec{
Config: memgraphv1alpha1.MemgraphConfig{
SnapshotIntervalSec: i32(3600),
SnapshotRetentionCount: i32(2),
SnapshotOnExit: b(false),
},
},
})
for _, want := range []string{
"--storage-snapshot-interval-sec=3600",
"--storage-snapshot-retention-count=2",
"--storage-snapshot-on-exit=false",
} {
if !hasArg(args, want) {
t.Errorf("expected %q, got args: %v", want, args)
}
}
})
}

func TestBuildInitContainers(t *testing.T) {
initContainers := buildInitContainers()

Expand Down
Loading